From bcb40e0bf1b31077284c9a9dbcb75e98b6b0439e Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 12 Sep 2025 07:54:31 -0600 Subject: [PATCH 01/29] fixed plugin --- LZ4/src/H5Zlz4.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 6dbca2ba..6570b466 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -55,7 +55,7 @@ #include "H5PLextern.h" #include "lz4.h" -static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], +size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf); #define H5Z_FILTER_LZ4 32004 @@ -100,7 +100,7 @@ H5PLget_plugin_info(void) return H5Z_LZ4; } -static size_t +size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf) { @@ -146,7 +146,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value { int compressedBytes = LZ4_decompress_safe(rpos, roBuf, compressedBlockSize, blockSize); if (compressedBytes != blockSize) { - printf("decompressed size not the same: %d, != %d\n", compressedBytes, blockSize); + /* printf("decompressed size not the same: %d, != %d\n", compressedBytes, blockSize); */ goto error; } } @@ -163,7 +163,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value } else /* forward filter */ { - size_t blockSize; + size_t blockSize = DEFAULT_BLOCK_SIZE; size_t nBlocks; size_t outSize; /* size of the output buffer. Header size (12 bytes) is included */ size_t block; @@ -172,6 +172,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value size_t maxDestSize; char *rpos; /* pointer to current read position */ char *roBuf; /* pointer to current write position */ + int acceleration = 1; if (nbytes > INT32_MAX) { /* can only compress chunks up to 2GB */ @@ -179,10 +180,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value } if (cd_nelmts > 0 && cd_values[0] > 0) { - blockSize = cd_values[0]; - } - else { - blockSize = DEFAULT_BLOCK_SIZE; + acceleration = cd_values[0]; } if (blockSize > nbytes) { blockSize = nbytes; @@ -206,14 +204,18 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value outSize = 12; /* size of the output buffer. Header size (12 bytes) is included */ + /* printf("nbytes %ld nBlocks %ld\n", nbytes, nBlocks); */ for (block = 0; block < nBlocks; ++block) { uint32_t compBlockSize; /// reserve space for compBlockSize size_t origWritten = block * blockSize; if (nbytes - origWritten < blockSize) /* the last block may be < blockSize */ blockSize = nbytes - origWritten; - compBlockSize = LZ4_compress_default( - rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize + compBlockSize = LZ4_compress_fast( + rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), 1); /// reserve space for compBlockSize + /* printf("blockSize %ld compBlockSize %d\n", blockSize, compBlockSize); */ + /* compBlockSize = LZ4_compress_default( */ + /* rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize */ if (!compBlockSize) goto error; if (compBlockSize >= blockSize) /* compression did not save any space, do a memcpy instead */ From d20e2dd907e9337401a6191b1d849a7feee8e561 Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 12 Sep 2025 07:59:01 -0600 Subject: [PATCH 02/29] fixes --- LZ4/src/H5Zlz4.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 6570b466..90d8de08 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -204,7 +204,6 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value outSize = 12; /* size of the output buffer. Header size (12 bytes) is included */ - /* printf("nbytes %ld nBlocks %ld\n", nbytes, nBlocks); */ for (block = 0; block < nBlocks; ++block) { uint32_t compBlockSize; /// reserve space for compBlockSize size_t origWritten = block * blockSize; @@ -212,10 +211,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value blockSize = nbytes - origWritten; compBlockSize = LZ4_compress_fast( - rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), 1); /// reserve space for compBlockSize - /* printf("blockSize %ld compBlockSize %d\n", blockSize, compBlockSize); */ - /* compBlockSize = LZ4_compress_default( */ - /* rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize */ + rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), acceleration); /// reserve space for compBlockSize if (!compBlockSize) goto error; if (compBlockSize >= blockSize) /* compression did not save any space, do a memcpy instead */ From f9130002b4e7aed2fc9aff9c89d405c0a255b569 Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 12 Sep 2025 07:59:55 -0600 Subject: [PATCH 03/29] fixes --- LZ4/src/H5Zlz4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 90d8de08..db0db833 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -172,7 +172,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value size_t maxDestSize; char *rpos; /* pointer to current read position */ char *roBuf; /* pointer to current write position */ - int acceleration = 1; + int acceleration = 1; if (nbytes > INT32_MAX) { /* can only compress chunks up to 2GB */ From 89a93129ca2115b385f4ea14c1555cc71912c268 Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 12 Sep 2025 08:01:31 -0600 Subject: [PATCH 04/29] fixes --- LZ4/src/H5Zlz4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index db0db833..66ae9501 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -179,7 +179,8 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value goto error; } - if (cd_nelmts > 0 && cd_values[0] > 0) { + /* Acceleration can be from 1 to 9. */ + if (cd_nelmts > 0 && cd_values[0] > 0 && cd_values[0] < 10) { acceleration = cd_values[0]; } if (blockSize > nbytes) { From dfdfbe041a71ed3182629daf36c9fdb93caad45a Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 12 Sep 2025 08:10:35 -0600 Subject: [PATCH 05/29] restored static --- LZ4/src/H5Zlz4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 66ae9501..02ae0556 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -55,7 +55,7 @@ #include "H5PLextern.h" #include "lz4.h" -size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], +static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf); #define H5Z_FILTER_LZ4 32004 @@ -100,7 +100,7 @@ H5PLget_plugin_info(void) return H5Z_LZ4; } -size_t +static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf) { From 399d1a70c3c9676a6b2c21996d6620ed88a407af Mon Sep 17 00:00:00 2001 From: Ed Date: Sat, 13 Sep 2025 09:35:23 -0600 Subject: [PATCH 06/29] fixing jpeg --- Makefile.am | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 5ca9543d..353a82dd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,5 +17,10 @@ if BUILD_LZ4 LZ4 = LZ4 endif +# Does the user want to build lz4? +if BUILD_JPEG +JPEG = JPEG +endif + # Build the desired subdirectories. -SUBDIRS = libs $(BZIP2) $(LZ4) JPEG #BITGROOM #BITROUND #BSHUF # BLOSC BLOSC2 JPEG LZF +SUBDIRS = libs $(BZIP2) $(LZ4) $(JPEG) From bfd7b8552442795c59e5ca1e2048d1c00bdad4f3 Mon Sep 17 00:00:00 2001 From: Ed Date: Sat, 13 Sep 2025 10:00:35 -0600 Subject: [PATCH 07/29] fixes --- BZIP2/configure.ac | 8 +- BZIP2/m4/libtool.m4 | 250 ++++++++++++++++++++++++------------------ BZIP2/m4/ltversion.m4 | 13 ++- JPEG/configure.ac | 15 +-- JPEG/src/H5Zjpeg.c | 2 +- LZ4/configure.ac | 9 +- LZ4/src/H5Zlz4.c | 15 ++- configure.ac | 16 ++- 8 files changed, 186 insertions(+), 142 deletions(-) diff --git a/BZIP2/configure.ac b/BZIP2/configure.ac index d9bdbd74..5f5b8f91 100644 --- a/BZIP2/configure.ac +++ b/BZIP2/configure.ac @@ -7,9 +7,9 @@ # Allen Byrne, Ed Hartnett 1/14/19 # Initialize autoconf. -AC_PREREQ(2.59) -AC_INIT(H5BZ2, 1.0, help@hdfgroup.org) -AC_CONFIG_HEADER([bzip_config.h]) +AC_PREREQ([2.71]) +AC_INIT([H5BZ2],[1.0],[help@hdfgroup.org]) +AC_CONFIG_HEADERS([bzip_config.h]) AC_CONFIG_MACRO_DIR([m4]) # Initialize automake. @@ -46,8 +46,6 @@ AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) AC_CHECK_HEADERS([hdf5.h], [], [AC_MSG_ERROR([hdf5.h is required, set CPPFLAGS.])]) AC_SEARCH_LIBS([H5Fflush], [hdf5dll hdf5], [], [AC_MSG_ERROR([libhdf5 is required, set LDFLAGS.])]) -# Check for other header files we need. -AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h stdlib.h string.h]) # Checks for typedefs, structures, and compiler characteristics. diff --git a/BZIP2/m4/libtool.m4 b/BZIP2/m4/libtool.m4 index ee80844b..e7b68334 100644 --- a/BZIP2/m4/libtool.m4 +++ b/BZIP2/m4/libtool.m4 @@ -1,6 +1,7 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -31,7 +32,7 @@ m4_define([_LT_COPYING], [dnl # along with this program. If not, see . ]) -# serial 58 LT_INIT +# serial 59 LT_INIT # LT_PREREQ(VERSION) @@ -181,6 +182,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl @@ -219,8 +221,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -777,7 +779,7 @@ _LT_EOF # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -1041,8 +1043,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1066,17 +1068,12 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac @@ -1125,12 +1122,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1244,7 +1241,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) +[m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot @@ -1261,7 +1259,7 @@ case $with_sysroot in #( fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -1291,7 +1289,7 @@ ia64-*-hpux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -1308,7 +1306,7 @@ ia64-*-hpux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -1320,7 +1318,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -1342,7 +1340,7 @@ mips64*-*linux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -1350,7 +1348,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -1358,7 +1356,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -1378,14 +1376,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -1453,7 +1451,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -1492,9 +1490,22 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because thats what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS +_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. +_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], + [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no @@ -1713,7 +1724,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1756,7 +1767,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -2206,26 +2217,35 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) @@ -2548,7 +2568,7 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; @@ -2558,14 +2578,14 @@ m4_if([$1], [],[ ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -2584,7 +2604,7 @@ m4_if([$1], [],[ done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -2621,7 +2641,7 @@ m4_if([$1], [],[ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -2654,7 +2674,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -3465,7 +3485,7 @@ beos*) bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -3499,14 +3519,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -3520,7 +3540,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' @@ -3567,7 +3587,7 @@ netbsd* | netbsdelf*-gnu) newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -3694,13 +3714,13 @@ else mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -3726,7 +3746,7 @@ else # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -3966,7 +3986,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -3984,20 +4004,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -4021,7 +4041,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ @@ -4039,9 +4059,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -4063,7 +4083,8 @@ _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4328,7 +4349,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -4411,7 +4432,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4703,6 +4724,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -4747,7 +4774,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4930,7 +4957,7 @@ m4_if([$1], [CXX], [ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) @@ -4938,7 +4965,7 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -4998,15 +5025,15 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -5061,7 +5088,7 @@ dnl Note also adjust exclude_expsyms for C++ above. _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -5173,6 +5200,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) @@ -5187,7 +5215,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -5230,7 +5258,7 @@ _LT_EOF _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes @@ -5242,13 +5270,14 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -5258,7 +5287,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -5390,7 +5419,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -5573,12 +5602,12 @@ _LT_EOF cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5619,7 +5648,7 @@ _LT_EOF fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. @@ -5667,7 +5696,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5808,6 +5837,7 @@ _LT_EOF # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; @@ -5879,6 +5909,7 @@ _LT_EOF emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) @@ -6438,7 +6469,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -6649,8 +6680,8 @@ if test yes != "$_lt_caught_CXX_error"; then cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' @@ -6748,6 +6779,7 @@ if test yes != "$_lt_caught_CXX_error"; then emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) @@ -6778,7 +6810,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes @@ -6813,7 +6845,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6878,7 +6910,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6915,7 +6947,7 @@ if test yes != "$_lt_caught_CXX_error"; then # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -7055,13 +7087,13 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' @@ -7217,7 +7249,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -7301,7 +7333,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7312,7 +7344,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' @@ -8207,6 +8239,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) +# _LT_DECL_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_TOOL([FILECMD], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates diff --git a/BZIP2/m4/ltversion.m4 b/BZIP2/m4/ltversion.m4 index fa04b52a..b155d0ac 100644 --- a/BZIP2/m4/ltversion.m4 +++ b/BZIP2/m4/ltversion.m4 @@ -1,6 +1,7 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, +# Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +10,15 @@ # @configure_input@ -# serial 4179 ltversion.m4 +# serial 4245 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) +m4_define([LT_PACKAGE_VERSION], [2.4.7]) +m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' +[macro_version='2.4.7' +macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/JPEG/configure.ac b/JPEG/configure.ac index 52d0d5ba..3be5979a 100644 --- a/JPEG/configure.ac +++ b/JPEG/configure.ac @@ -7,9 +7,9 @@ # Ed Hartnett 1/16/19 # Initialize autoconf. -AC_PREREQ(2.59) -AC_INIT(H5JPEG, 0.1, help@hdfgroup.org) -AC_CONFIG_HEADER([jpeg_config.h]) +AC_PREREQ([2.71]) +AC_INIT([H5JPEG],[0.1],[help@hdfgroup.org]) +AC_CONFIG_HEADERS([jpeg_config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_MSG_NOTICE([*** This is a configure for JPEG ***]) @@ -23,9 +23,6 @@ AC_PROG_INSTALL LT_INIT(dlopen) -# If the env. variable HDF5_PLUGIN_DIR is set, or if -# --with-hdf5-plugin-dir=, use it as a place for the large -# (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} AC_ARG_WITH([hdf5-plugin-dir], @@ -36,8 +33,8 @@ AC_MSG_RESULT($HDF5_PLUGIN_DIR) AC_SUBST([HDF5_PLUGIN_DIR]) # Is the jpeg library present? -#AC_CHECK_HEADERS([jpeg.h], [], [AC_MSG_ERROR([jpeg.h is required, set CPPFLAGS.])]) -#AC_CHECK_LIB([jpeg], [JPEG_compress], [], [AC_MSG_ERROR([libjpeg is required, set LDFLAGS.])]) +AC_CHECK_HEADERS([jpeglib.h], [], [AC_MSG_ERROR([jpeglib.h is required, set CPPFLAGS.])]) +AC_CHECK_LIB([jpeg], [jpeg_abort], [], [AC_MSG_ERROR([libjpeg is required, set LDFLAGS.])]) # We need the math library AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) @@ -46,8 +43,6 @@ AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) AC_CHECK_HEADERS([hdf5.h], [], [AC_MSG_ERROR([hdf5.h is required, set CPPFLAGS.])]) AC_SEARCH_LIBS([H5Fflush], [hdf5dll hdf5], [], [AC_MSG_ERROR([libhdf5 is required, set LDFLAGS.])]) -# Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h stdlib.h string.h]) # Checks for typedefs, structures, and compiler characteristics. diff --git a/JPEG/src/H5Zjpeg.c b/JPEG/src/H5Zjpeg.c index 8a408422..4a529844 100644 --- a/JPEG/src/H5Zjpeg.c +++ b/JPEG/src/H5Zjpeg.c @@ -282,7 +282,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu PUSH_ERR("jpeg_h5_filter", H5E_CALLBACK, "Could not initialize JPEG compression object."); goto failed; } - jpegInfo.err = jpeg_std_error(&jpegErr); + jpegInfo.err = jpeg_std_error((struct jpeg_error_mgr *)&jpegErr); /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&jpegInfo); diff --git a/LZ4/configure.ac b/LZ4/configure.ac index 73655a98..f6dccc93 100644 --- a/LZ4/configure.ac +++ b/LZ4/configure.ac @@ -7,9 +7,9 @@ # Allen Byrne, Ed Hartnett 1/14/19 # Initialize autoconf. -AC_PREREQ(2.59) -AC_INIT(H5LZ4, 1.0, help@hdfgroup.org) -AC_CONFIG_HEADER([lz4_config.h]) +AC_PREREQ([2.71]) +AC_INIT([H5LZ4],[1.0],[help@hdfgroup.org]) +AC_CONFIG_HEADERS([lz4_config.h]) AC_CONFIG_MACRO_DIR([m4]) # Initialize automake. @@ -44,8 +44,6 @@ AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) AC_CHECK_HEADERS([hdf5.h], [], [AC_MSG_ERROR([hdf5.h is required, set CPPFLAGS.])]) AC_SEARCH_LIBS([H5Fflush], [hdf5dll hdf5], [], [AC_MSG_ERROR([libhdf5 is required, set LDFLAGS.])]) -# Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h stdlib.h string.h arpa/inet.h]) # Checks for typedefs, structures, and compiler characteristics. @@ -65,6 +63,7 @@ then PLUGIN_H5LZ4=1 fi AM_CONDITIONAL(H5LZ4, test "$PLUGIN_H5LZ4") +AM_CONDITIONAL(BUILD_LZ4, true) # These files will be generated by configure. AC_CONFIG_FILES([Makefile diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 02ae0556..6570b466 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -55,7 +55,7 @@ #include "H5PLextern.h" #include "lz4.h" -static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], +size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf); #define H5Z_FILTER_LZ4 32004 @@ -100,7 +100,7 @@ H5PLget_plugin_info(void) return H5Z_LZ4; } -static size_t +size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf) { @@ -172,15 +172,14 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value size_t maxDestSize; char *rpos; /* pointer to current read position */ char *roBuf; /* pointer to current write position */ - int acceleration = 1; + int acceleration = 1; if (nbytes > INT32_MAX) { /* can only compress chunks up to 2GB */ goto error; } - /* Acceleration can be from 1 to 9. */ - if (cd_nelmts > 0 && cd_values[0] > 0 && cd_values[0] < 10) { + if (cd_nelmts > 0 && cd_values[0] > 0) { acceleration = cd_values[0]; } if (blockSize > nbytes) { @@ -205,6 +204,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value outSize = 12; /* size of the output buffer. Header size (12 bytes) is included */ + /* printf("nbytes %ld nBlocks %ld\n", nbytes, nBlocks); */ for (block = 0; block < nBlocks; ++block) { uint32_t compBlockSize; /// reserve space for compBlockSize size_t origWritten = block * blockSize; @@ -212,7 +212,10 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value blockSize = nbytes - origWritten; compBlockSize = LZ4_compress_fast( - rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), acceleration); /// reserve space for compBlockSize + rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), 1); /// reserve space for compBlockSize + /* printf("blockSize %ld compBlockSize %d\n", blockSize, compBlockSize); */ + /* compBlockSize = LZ4_compress_default( */ + /* rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize */ if (!compBlockSize) goto error; if (compBlockSize >= blockSize) /* compression did not save any space, do a memcpy instead */ diff --git a/configure.ac b/configure.ac index b2a30e2b..29ff5679 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,15 @@ test "x$enable_lz4" = xno || enable_lz4=yes AC_MSG_RESULT($enable_lz4) AM_CONDITIONAL(BUILD_LZ4, [test "x$enable_lz4" = xyes]) +# Does the user want JPEG? +AC_MSG_CHECKING([whether JPEG filter library should be built and installed]) +AC_ARG_ENABLE([jpeg], + [AS_HELP_STRING([--disable-jpeg], + [Disable the build and install of jpeg filter library.])]) +test "x$enable_jpeg" = xno || enable_jpeg=yes +AC_MSG_RESULT($enable_jpeg) +AM_CONDITIONAL(BUILD_JPEG, [test "x$enable_jpeg" = xyes]) + # Build the filter libraries as desired. if test "x$enable_bzip2" = xyes; then AC_CONFIG_SUBDIRS([BZIP2]) @@ -55,12 +64,11 @@ fi if test "x$enable_lz4" = xyes; then AC_CONFIG_SUBDIRS([LZ4]) fi +if test "x$enable_jpeg" = xyes; then + AC_CONFIG_SUBDIRS([JPEG]) +fi #AC_CONFIG_SUBDIRS([BLOSC]) #AC_CONFIG_SUBDIRS([BLOSC2]) -#AC_CONFIG_SUBDIRS([BITGROOM]) -#AC_CONFIG_SUBDIRS([BITROUND]) -#AC_CONFIG_SUBDIRS([BSHUF]) -AC_CONFIG_SUBDIRS([JPEG]) #AC_CONFIG_SUBDIRS([LZF]) # These files will be created when the configure script is run. From b2017e0b1ec66807bf87348cf04e893a0dd5a458 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sat, 13 Sep 2025 17:39:57 -0600 Subject: [PATCH 08/29] switched to HDF5_PLUGIN_PATH --- configure.ac | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index 29ff5679..0c223d8c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # This is the main configure file for the hdf5_plugins project. -# Ed Hartnett 12/24/2019 +# Edward Hartnett, Intelligent Data Design, Inc. 9/13/25 AC_PREREQ([2.59]) @@ -16,19 +16,15 @@ AC_CONFIG_MACRO_DIR([m4]) LT_PREREQ([2.4]) LT_INIT() -# If the env. variable HDF5_PLUGIN_DIR is set, or if -# --with-hdf5-plugin-dir=, use it as a place for the large -# (i.e. > 2 GiB) files created during the large file testing. This is -# necessary at the top level to provide the help message and --with -# option. If used, the option will be passed to the subdirs, and also -# handled by the configure in each filter subdirectory. +# If the env. variable HDF5_PLUGIN_PATH is set, or if +# --with-hdf5-plugin-dir=, use it. AC_MSG_CHECKING([where to put HDF5 plugins]) -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-.} -AC_MSG_RESULT($HDF5_PLUGIN_DIR) +AC_ARG_WITH([hdf5-plugin-path], + [AS_HELP_STRING([--with-hdf5-plugin-path=], + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_dir]) +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-.} +AC_MSG_RESULT($HDF5_PLUGIN_PATH) # Does the user want BZIP2? AC_MSG_CHECKING([whether BZIP2 filter library should be built and installed]) @@ -48,15 +44,6 @@ test "x$enable_lz4" = xno || enable_lz4=yes AC_MSG_RESULT($enable_lz4) AM_CONDITIONAL(BUILD_LZ4, [test "x$enable_lz4" = xyes]) -# Does the user want JPEG? -AC_MSG_CHECKING([whether JPEG filter library should be built and installed]) -AC_ARG_ENABLE([jpeg], - [AS_HELP_STRING([--disable-jpeg], - [Disable the build and install of jpeg filter library.])]) -test "x$enable_jpeg" = xno || enable_jpeg=yes -AC_MSG_RESULT($enable_jpeg) -AM_CONDITIONAL(BUILD_JPEG, [test "x$enable_jpeg" = xyes]) - # Build the filter libraries as desired. if test "x$enable_bzip2" = xyes; then AC_CONFIG_SUBDIRS([BZIP2]) @@ -64,11 +51,12 @@ fi if test "x$enable_lz4" = xyes; then AC_CONFIG_SUBDIRS([LZ4]) fi -if test "x$enable_jpeg" = xyes; then - AC_CONFIG_SUBDIRS([JPEG]) -fi #AC_CONFIG_SUBDIRS([BLOSC]) #AC_CONFIG_SUBDIRS([BLOSC2]) +#AC_CONFIG_SUBDIRS([BITGROOM]) +#AC_CONFIG_SUBDIRS([BITROUND]) +#AC_CONFIG_SUBDIRS([BSHUF]) +AC_CONFIG_SUBDIRS([JPEG]) #AC_CONFIG_SUBDIRS([LZF]) # These files will be created when the configure script is run. From 4ea15c3170ffb2b60c7fd4c602be4a8b946b7390 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sat, 13 Sep 2025 17:59:51 -0600 Subject: [PATCH 09/29] fixing JPEG --- configure.ac | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/configure.ac b/configure.ac index 0c223d8c..5fa8fcd3 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,15 @@ test "x$enable_lz4" = xno || enable_lz4=yes AC_MSG_RESULT($enable_lz4) AM_CONDITIONAL(BUILD_LZ4, [test "x$enable_lz4" = xyes]) +# Does the user want JPEG? +AC_MSG_CHECKING([whether JPEG filter library should be built and installed]) +AC_ARG_ENABLE([jpeg], + [AS_HELP_STRING([--disable-jpeg], + [Disable the build and install of jpeg filter library.])]) +test "x$enable_jpeg" = xno || enable_jpeg=yes +AC_MSG_RESULT($enable_jpeg) +AM_CONDITIONAL(BUILD_JPEG, [test "x$enable_jpeg" = xyes]) + # Build the filter libraries as desired. if test "x$enable_bzip2" = xyes; then AC_CONFIG_SUBDIRS([BZIP2]) @@ -51,6 +60,9 @@ fi if test "x$enable_lz4" = xyes; then AC_CONFIG_SUBDIRS([LZ4]) fi +if test "x$enable_jpeg" = xyes; then + AC_CONFIG_SUBDIRS([JPEG]) +fi #AC_CONFIG_SUBDIRS([BLOSC]) #AC_CONFIG_SUBDIRS([BLOSC2]) #AC_CONFIG_SUBDIRS([BITGROOM]) From 70efd27da868044455cca97cf65171a922c35e60 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sat, 13 Sep 2025 18:03:20 -0600 Subject: [PATCH 10/29] fixing JPEG --- configure.ac | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configure.ac b/configure.ac index 5fa8fcd3..228b40b2 100644 --- a/configure.ac +++ b/configure.ac @@ -65,10 +65,6 @@ if test "x$enable_jpeg" = xyes; then fi #AC_CONFIG_SUBDIRS([BLOSC]) #AC_CONFIG_SUBDIRS([BLOSC2]) -#AC_CONFIG_SUBDIRS([BITGROOM]) -#AC_CONFIG_SUBDIRS([BITROUND]) -#AC_CONFIG_SUBDIRS([BSHUF]) -AC_CONFIG_SUBDIRS([JPEG]) #AC_CONFIG_SUBDIRS([LZF]) # These files will be created when the configure script is run. From fe0e578b2509c808a81c7d3d5366cd37ce03a5c5 Mon Sep 17 00:00:00 2001 From: Edward Hartnett Date: Sat, 13 Sep 2025 18:15:11 -0600 Subject: [PATCH 11/29] more path --- BZIP2/configure.ac | 12 ++++++------ JPEG/configure.ac | 10 +++++----- LZ4/configure.ac | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/BZIP2/configure.ac b/BZIP2/configure.ac index 5f5b8f91..7fb67668 100644 --- a/BZIP2/configure.ac +++ b/BZIP2/configure.ac @@ -23,17 +23,17 @@ AC_PROG_INSTALL # Initialize libtool, checking for dlopen. LT_INIT(dlopen) -# If the env. variable HDF5_PLUGIN_DIR is set, or if +# If the env. variable HDF5_PLUGIN_PATH is set, or if # --with-hdf5-plugin-dir=, use it as a place for the large # (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} AC_ARG_WITH([hdf5-plugin-dir], [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) +AC_MSG_RESULT($HDF5_PLUGIN_PATH) +AC_SUBST([HDF5_PLUGIN_PATH]) # Is the bzip2 library and header present? AC_CHECK_HEADERS([bzlib.h], [], [AC_MSG_ERROR([bzlib.h is required, set CPPFLAGS.])]) diff --git a/JPEG/configure.ac b/JPEG/configure.ac index 3be5979a..9002e3b3 100644 --- a/JPEG/configure.ac +++ b/JPEG/configure.ac @@ -24,13 +24,13 @@ AC_PROG_INSTALL LT_INIT(dlopen) AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} AC_ARG_WITH([hdf5-plugin-dir], [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) +AC_MSG_RESULT($HDF5_PLUGIN_PATH) +AC_SUBST([HDF5_PLUGIN_PATH]) # Is the jpeg library present? AC_CHECK_HEADERS([jpeglib.h], [], [AC_MSG_ERROR([jpeglib.h is required, set CPPFLAGS.])]) diff --git a/LZ4/configure.ac b/LZ4/configure.ac index f6dccc93..178e3fe8 100644 --- a/LZ4/configure.ac +++ b/LZ4/configure.ac @@ -21,17 +21,17 @@ AC_PROG_INSTALL LT_INIT(dlopen) -# If the env. variable HDF5_PLUGIN_DIR is set, or if +# If the env. variable HDF5_PLUGIN_PATH is set, or if # --with-hdf5-plugin-dir=, use it as a place for the large # (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} AC_ARG_WITH([hdf5-plugin-dir], [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) +AC_MSG_RESULT($HDF5_PLUGIN_PATH) +AC_SUBST([HDF5_PLUGIN_PATH]) # Is the lz4 library present? AC_CHECK_HEADERS([lz4.h], [], [AC_MSG_ERROR([lz4.h is required, set CPPFLAGS.])]) From 6c74e921de46f629ea0c080a3a89c47b27bbc0a0 Mon Sep 17 00:00:00 2001 From: Ed Date: Sun, 14 Sep 2025 07:54:18 -0600 Subject: [PATCH 12/29] more fixes --- BZIP2/configure.ac | 12 ++++++------ BZIP2/src/Makefile.am | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BZIP2/configure.ac b/BZIP2/configure.ac index 5f5b8f91..7fb67668 100644 --- a/BZIP2/configure.ac +++ b/BZIP2/configure.ac @@ -23,17 +23,17 @@ AC_PROG_INSTALL # Initialize libtool, checking for dlopen. LT_INIT(dlopen) -# If the env. variable HDF5_PLUGIN_DIR is set, or if +# If the env. variable HDF5_PLUGIN_PATH is set, or if # --with-hdf5-plugin-dir=, use it as a place for the large # (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} AC_ARG_WITH([hdf5-plugin-dir], [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) +AC_MSG_RESULT($HDF5_PLUGIN_PATH) +AC_SUBST([HDF5_PLUGIN_PATH]) # Is the bzip2 library and header present? AC_CHECK_HEADERS([bzlib.h], [], [AC_MSG_ERROR([bzlib.h is required, set CPPFLAGS.])]) diff --git a/BZIP2/src/Makefile.am b/BZIP2/src/Makefile.am index b644e4de..a9febe94 100644 --- a/BZIP2/src/Makefile.am +++ b/BZIP2/src/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = -I$(HDF5_ROOT)/include -I$(BZ2_ROOT)/include # This is where HDF5 wants us to install plugins. -plugindir = @HDF5_PLUGIN_DIR@ +plugindir = @HDF5_PLUGIN_PATH@ # This linker flag specifies libtool version info. # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning From 3b8d0aefe5938645122f6c2e0a6b78d060c9e675 Mon Sep 17 00:00:00 2001 From: Ed Date: Sun, 14 Sep 2025 07:55:48 -0600 Subject: [PATCH 13/29] fix --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 228b40b2..8c03d4ee 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_MSG_CHECKING([where to put HDF5 plugins]) AC_ARG_WITH([hdf5-plugin-path], [AS_HELP_STRING([--with-hdf5-plugin-path=], [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], - [HDF5_PLUGIN_PATH=$with_hdf5_plugin_dir]) + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-.} AC_MSG_RESULT($HDF5_PLUGIN_PATH) From 1befb596f4cbd8ad3409b46d180b88e99b1df804 Mon Sep 17 00:00:00 2001 From: Ed Date: Sun, 14 Sep 2025 08:08:18 -0600 Subject: [PATCH 14/29] fix --- JPEG/src/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/JPEG/src/Makefile.am b/JPEG/src/Makefile.am index 601290f5..5edb554d 100644 --- a/JPEG/src/Makefile.am +++ b/JPEG/src/Makefile.am @@ -1,12 +1,12 @@ # Copyright by The HDF Group. All rights reserved. -# This is the Makefile.am for the HDF5 LZ4 filter library. This allows -# the use of LZ4 compression/decompression on HDF5 datasets. +# This is the Makefile.am for the HDF5 JPEG filter library. This allows +# the use of JPEG compression/decompression on HDF5 datasets. # -# Ed Hartnett 1/15/19 +# Ed Hartnett 9/14/25 # This is where HDF5 wants us to install plugins. -plugindir = @HDF5_PLUGIN_DIR@ +plugindir = @HDF5_PLUGIN_PATH@ # This linker flag specifies libtool version info. # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning From 53b879b7d0efb522f9dff2d8f37e98cbc331a2cb Mon Sep 17 00:00:00 2001 From: Ed Date: Sun, 14 Sep 2025 08:29:45 -0600 Subject: [PATCH 15/29] fix --- LZ4/src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LZ4/src/Makefile.am b/LZ4/src/Makefile.am index 80f5abbf..d6563881 100644 --- a/LZ4/src/Makefile.am +++ b/LZ4/src/Makefile.am @@ -6,7 +6,7 @@ # Allen Byrne, Ed Hartnett 1/14/19 # This is where HDF5 wants us to install plugins. -plugindir = @HDF5_PLUGIN_DIR@ +plugindir = @HDF5_PLUGIN_PATH@ # This linker flag specifies libtool version info. # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning From b38051cb67ac9d107c0f8624cc61c7062c4bec69 Mon Sep 17 00:00:00 2001 From: Ed Date: Sun, 14 Sep 2025 08:52:33 -0600 Subject: [PATCH 16/29] adding lzf to the mix --- LZF/configure.ac | 31 +++++++++++++------------------ LZF/example/h5ex_d_lzf.c | 2 +- LZF/src/Makefile.am | 2 +- Makefile.am | 9 +++++++-- configure.ac | 13 ++++++++++++- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/LZF/configure.ac b/LZF/configure.ac index a49f72ba..c00b9800 100644 --- a/LZF/configure.ac +++ b/LZF/configure.ac @@ -4,12 +4,13 @@ # library that enables lzf compression/decompression as a HDF5 # filter. This is part of the hdf5_plugin project. -# Allen Byrne, Ed Hartnett 1/14/19 +# Allen Byrne, Edward Hartnett 1/14/19 +# Edward Hartnett, 9/14/25 # Initialize autoconf. -AC_PREREQ(2.59) -AC_INIT(H5LZF, 0.1, help@hdfgroup.org) -AC_CONFIG_HEADER([lzf_config.h]) +AC_PREREQ([2.71]) +AC_INIT([H5LZF],[0.1],[help@hdfgroup.org]) +AC_CONFIG_HEADERS([lzf_config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_MSG_NOTICE([*** This is a configure for LZ4 ***]) @@ -23,21 +24,18 @@ AC_PROG_INSTALL LT_INIT(dlopen) -# If the env. variable HDF5_PLUGIN_DIR is set, or if -# --with-hdf5-plugin-dir=, use it as a place for the large -# (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) +HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} +AC_ARG_WITH([hdf5-plugin-path], + [AS_HELP_STRING([--with-hdf5-plugin-path=], + [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], + [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) +AC_MSG_RESULT($HDF5_PLUGIN_PATH) +AC_SUBST([HDF5_PLUGIN_PATH]) # Is the lzf library present? AC_CHECK_HEADERS([lzf.h], [], [AC_MSG_ERROR([lzf.h is required, set CPPFLAGS.])]) -AC_CHECK_LIB([lzf], [LZF_compress], [], [AC_MSG_ERROR([liblzf is required, set LDFLAGS.])]) +AC_CHECK_LIB([lzf], [lzf_compress], [], [AC_MSG_ERROR([liblzf is required, set LDFLAGS.])]) # We need the math library AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) @@ -45,9 +43,6 @@ AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) # We need the HDF5 headers and library. AC_CHECK_HEADERS([hdf5.h], [], [AC_MSG_ERROR([hdf5.h is required, set CPPFLAGS.])]) AC_SEARCH_LIBS([H5Fflush], [hdf5dll hdf5], [], [AC_MSG_ERROR([libhdf5 is required, set LDFLAGS.])]) - -# Checks for header files. -AC_HEADER_STDC AC_CHECK_HEADERS([fcntl.h stdlib.h string.h]) # Checks for typedefs, structures, and compiler characteristics. diff --git a/LZF/example/h5ex_d_lzf.c b/LZF/example/h5ex_d_lzf.c index 26c6b38a..5a7017ed 100644 --- a/LZF/example/h5ex_d_lzf.c +++ b/LZF/example/h5ex_d_lzf.c @@ -176,7 +176,7 @@ main(void) switch (filter_id) { case H5Z_FILTER_LZF: printf("%d\n", filter_id); - printf(" Number of parameters is %d with the value %u\n", nelmts, values_out[0]); + printf(" Number of parameters is %ld with the value %u\n", nelmts, values_out[0]); printf(" To find more about the filter check %s\n", filter_name); break; default: diff --git a/LZF/src/Makefile.am b/LZF/src/Makefile.am index 58026106..d67d73e1 100644 --- a/LZF/src/Makefile.am +++ b/LZF/src/Makefile.am @@ -6,7 +6,7 @@ # Allen Byrne, Ed Hartnett 1/15/19 # This is where HDF5 wants us to install plugins. -plugindir = @HDF5_PLUGIN_DIR@ +plugindir = @HDF5_PLUGIN_PATH@ # This linker flag specifies libtool version info. # See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning diff --git a/Makefile.am b/Makefile.am index 353a82dd..098a1a82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # This file builds main directory for the hdf5_plugings project. -# Ed Hartnett 12/24/2019 +# Edward Hartnett 12/24/2019 # This directory stores libtool macros, put there by aclocal. ACLOCAL_AMFLAGS = -I m4 @@ -22,5 +22,10 @@ if BUILD_JPEG JPEG = JPEG endif +# Does the user want to build lz4? +if BUILD_LZF +LZF = LZF +endif + # Build the desired subdirectories. -SUBDIRS = libs $(BZIP2) $(LZ4) $(JPEG) +SUBDIRS = libs $(BZIP2) $(LZ4) $(JPEG) $(LZF) diff --git a/configure.ac b/configure.ac index 8c03d4ee..03444c15 100644 --- a/configure.ac +++ b/configure.ac @@ -53,6 +53,15 @@ test "x$enable_jpeg" = xno || enable_jpeg=yes AC_MSG_RESULT($enable_jpeg) AM_CONDITIONAL(BUILD_JPEG, [test "x$enable_jpeg" = xyes]) +# Does the user want LZF? +AC_MSG_CHECKING([whether LZF filter library should be built and installed]) +AC_ARG_ENABLE([lzf], + [AS_HELP_STRING([--disable-lzf], + [Disable the build and install of lzf filter library.])]) +test "x$enable_lzf" = xno || enable_lzf=yes +AC_MSG_RESULT($enable_lzf) +AM_CONDITIONAL(BUILD_LZF, [test "x$enable_lzf" = xyes]) + # Build the filter libraries as desired. if test "x$enable_bzip2" = xyes; then AC_CONFIG_SUBDIRS([BZIP2]) @@ -63,9 +72,11 @@ fi if test "x$enable_jpeg" = xyes; then AC_CONFIG_SUBDIRS([JPEG]) fi +if test "x$enable_lzf" = xyes; then + AC_CONFIG_SUBDIRS([LZF]) +fi #AC_CONFIG_SUBDIRS([BLOSC]) #AC_CONFIG_SUBDIRS([BLOSC2]) -#AC_CONFIG_SUBDIRS([LZF]) # These files will be created when the configure script is run. AC_CONFIG_FILES([Makefile From a44e39873e923c5ce9da90daea2f9b3850ce8229 Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 15 Sep 2025 06:44:03 -0600 Subject: [PATCH 17/29] fixing LZ4 filter --- LZ4/src/H5Zlz4.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 6570b466..62976fe0 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -212,10 +212,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value blockSize = nbytes - origWritten; compBlockSize = LZ4_compress_fast( - rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), 1); /// reserve space for compBlockSize - /* printf("blockSize %ld compBlockSize %d\n", blockSize, compBlockSize); */ - /* compBlockSize = LZ4_compress_default( */ - /* rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize */ + rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), acceleration); /// reserve space for compBlockSize if (!compBlockSize) goto error; if (compBlockSize >= blockSize) /* compression did not save any space, do a memcpy instead */ From d56a438aba02a97663e40684446666ae387f7591 Mon Sep 17 00:00:00 2001 From: Ed Date: Mon, 15 Sep 2025 07:11:18 -0600 Subject: [PATCH 18/29] more path fixes --- BZIP2/configure.ac | 6 +++--- JPEG/configure.ac | 4 ++-- LZ4/configure.ac | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BZIP2/configure.ac b/BZIP2/configure.ac index 7fb67668..eb632fa9 100644 --- a/BZIP2/configure.ac +++ b/BZIP2/configure.ac @@ -24,12 +24,12 @@ AC_PROG_INSTALL LT_INIT(dlopen) # If the env. variable HDF5_PLUGIN_PATH is set, or if -# --with-hdf5-plugin-dir=, use it as a place for the large +# --with-hdf5-plugin-path=, use it as a place for the large # (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], +AC_ARG_WITH([hdf5-plugin-path], + [AS_HELP_STRING([--with-hdf5-plugin-path=], [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) AC_MSG_RESULT($HDF5_PLUGIN_PATH) diff --git a/JPEG/configure.ac b/JPEG/configure.ac index 9002e3b3..4d0ae6bf 100644 --- a/JPEG/configure.ac +++ b/JPEG/configure.ac @@ -25,8 +25,8 @@ LT_INIT(dlopen) AC_MSG_CHECKING([where to put HDF5 plugins]) HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], +AC_ARG_WITH([hdf5-plugin-path], + [AS_HELP_STRING([--with-hdf5-plugin-path=], [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) AC_MSG_RESULT($HDF5_PLUGIN_PATH) diff --git a/LZ4/configure.ac b/LZ4/configure.ac index 178e3fe8..7ec2e0e4 100644 --- a/LZ4/configure.ac +++ b/LZ4/configure.ac @@ -26,8 +26,8 @@ LT_INIT(dlopen) # (i.e. > 2 GiB) files created during the large file testing. AC_MSG_CHECKING([where to put HDF5 plugins]) HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH-'/usr/local/hdf5/lib/plugin'} -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], +AC_ARG_WITH([hdf5-plugin-path], + [AS_HELP_STRING([--with-hdf5-plugin-path=], [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_PATH, if set)])], [HDF5_PLUGIN_PATH=$with_hdf5_plugin_path]) AC_MSG_RESULT($HDF5_PLUGIN_PATH) From 23b427464dfa40cc5171ce51b339d5aeacb4b21d Mon Sep 17 00:00:00 2001 From: Ed Date: Tue, 16 Sep 2025 05:02:38 -0600 Subject: [PATCH 19/29] more fixes --- JPEG/example/Makefile.am | 13 ++++++------- LZ4/example/Makefile.am | 6 +++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/JPEG/example/Makefile.am b/JPEG/example/Makefile.am index b9e76e2a..d8dd43a0 100644 --- a/JPEG/example/Makefile.am +++ b/JPEG/example/Makefile.am @@ -2,15 +2,14 @@ # This builds the JPEG example directory. -# Ed Hartnett 1/14/19 +# Edward Hartnett 9/15/25 -# # Link to our filter library. -# AM_LDFLAGS = ${top_builddir}/src/libh5jpeg.la -# LDADD = ${top_builddir}/src/libh5jpeg.la +# Link to our filter library. +LDADD = ${top_builddir}/src/libh5jpeg.la -# # Build example program and run it as a test. -# check_PROGRAMS = h5ex_d_jpeg -# TESTS = h5ex_d_jpeg +# Build example program and run it as a test. +check_PROGRAMS = h5ex_d_jpeg +TESTS = h5ex_d_jpeg # Clean up HDF5 file created by example. CLEANFILES = *.h5 diff --git a/LZ4/example/Makefile.am b/LZ4/example/Makefile.am index 27e5aa9a..4c233613 100644 --- a/LZ4/example/Makefile.am +++ b/LZ4/example/Makefile.am @@ -8,4 +8,8 @@ LDADD = ${top_builddir}/src/libh5lz4.la # Build example program. -noinst_PROGRAMS = h5ex_d_lz4 +check_PROGRAMS = h5ex_d_lz4 +TESTS = h5ex_d_lz4 + +# Clean up HDF5 file created by example. +CLEANFILES = *.h5 From e829f73fe7368a8e1241e6bdbecbc0dd7a376e44 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 17 Sep 2025 06:18:46 -0600 Subject: [PATCH 20/29] adding run_tests.sh --- JPEG/example/Makefile.am | 5 ++++- JPEG/example/h5ex_d_jpeg.c | 6 +++--- JPEG/example/run_tests.sh | 9 +++++++++ JPEG/src/H5Zjpeg.c | 13 +++++++------ 4 files changed, 23 insertions(+), 10 deletions(-) create mode 100755 JPEG/example/run_tests.sh diff --git a/JPEG/example/Makefile.am b/JPEG/example/Makefile.am index d8dd43a0..17748322 100644 --- a/JPEG/example/Makefile.am +++ b/JPEG/example/Makefile.am @@ -9,7 +9,10 @@ LDADD = ${top_builddir}/src/libh5jpeg.la # Build example program and run it as a test. check_PROGRAMS = h5ex_d_jpeg -TESTS = h5ex_d_jpeg +TESTS = run_tests.sh # Clean up HDF5 file created by example. CLEANFILES = *.h5 + +EXTRA_DIST = run_tests.sh + diff --git a/JPEG/example/h5ex_d_jpeg.c b/JPEG/example/h5ex_d_jpeg.c index 159cd735..3193c98e 100644 --- a/JPEG/example/h5ex_d_jpeg.c +++ b/JPEG/example/h5ex_d_jpeg.c @@ -29,7 +29,7 @@ #define DIM0 512 #define DIM1 1024 #define NUM_IMAGES 10 -#define JPEG_QUALITY 100 +#define JPEG_QUALITY 50 #define CHUNK0 1 #define CHUNK1 DIM0 #define CHUNK2 DIM1 @@ -58,7 +58,7 @@ main(void) /* Number of columns */ /* Number of rows */ /* Color mode (0=Mono, 1=RGB) */ - const unsigned int cd_values[4] = {JPEG_QUALITY, DIM0, DIM1, 0}; /* jpeg default level is 2 */ + const unsigned int cd_values[4] = {JPEG_QUALITY, DIM0, DIM1, 0}; unsigned int values_out[4] = {99, 99, 99, 99}; unsigned char *wdata; /* Write buffer */ unsigned char *rdata; /* Read buffer */ @@ -187,7 +187,7 @@ main(void) switch (filter_id) { case H5Z_FILTER_JPEG: printf("%d\n", filter_id); - printf(" Number of parameters is %d with the value %u\n", nelmts, values_out[0]); + printf(" Number of parameters is %ld with the value %u\n", nelmts, values_out[0]); printf(" To find more about the filter check %s\n", filter_name); break; default: diff --git a/JPEG/example/run_tests.sh b/JPEG/example/run_tests.sh new file mode 100755 index 00000000..079e1eb6 --- /dev/null +++ b/JPEG/example/run_tests.sh @@ -0,0 +1,9 @@ +# This script runs the JPEG examples in the hdf5_plugins project. +# +# Edward Hartnett 9/17/25 + +# Set the plugin path to find plugin. +export HDF5_PLUGIN_PATH=../src/.libs + +# Run the example. +./h5ex_d_jpeg diff --git a/JPEG/src/H5Zjpeg.c b/JPEG/src/H5Zjpeg.c index 4a529844..3846827a 100644 --- a/JPEG/src/H5Zjpeg.c +++ b/JPEG/src/H5Zjpeg.c @@ -156,9 +156,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu int err = 0; unsigned char *output = NULL; -#ifdef JPEG_DEBUG - fprintf(stderr, " decompressing nbytes: %ld\n", nbytes); -#endif + printf("**** decompressing nbytes: %ld\n", nbytes); /* allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ @@ -197,6 +195,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu output = out_buf; while (jpegInfo.output_scanline < jpegInfo.output_height) { + printf("**** jpegInfo.output_scanline: %d\n", jpegInfo.output_scanline); unsigned char *row_pointer[1] = {output}; err = jpeg_read_scanlines(&jpegInfo, row_pointer, 1); @@ -235,9 +234,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu int nwrite = 0; size_t expectedSize; -#ifdef JPEG_DEBUG - fprintf(stderr, " compressing nbytes: %ld\n", nbytes); -#endif + printf("**** compressing nbytes: %ld cd_nelmts %ld\n", nbytes, cd_nelmts); if (cd_nelmts != 4) { PUSH_ERR("jpeg_h5_filter", H5E_CALLBACK, "cd_nelmts must be 4"); goto failed; @@ -250,6 +247,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu sizeX = cd_values[1]; sizeY = cd_values[2]; colorMode = cd_values[3]; + printf("**** qualityFactor %d sizeX %d sizeY %d colorMode %d\n", qualityFactor, sizeX, sizeY, colorMode); /* Sanity check to make sure we have been passed a complete image */ expectedSize = sizeX * sizeY; @@ -320,10 +318,12 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu * Pass TRUE unless you are very sure of what you're doing. */ jpeg_start_compress(&jpegInfo, TRUE); + printf("**** starting compression\n"); pData = (unsigned char *)*buf; while ((int)jpegInfo.next_scanline < sizeY) { + printf("**** jpegInfo.next_scanline: %d\n", jpegInfo.next_scanline); row_pointer[0] = pData; nwrite = jpeg_write_scanlines(&jpegInfo, row_pointer, 1); pData += sizeX * jpegInfo.input_components; @@ -336,6 +336,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu /* Finish compression */ jpeg_finish_compress(&jpegInfo); buf_size_out = outSize; + printf("**** compressed size: %ld\n", buf_size_out); out_buf = malloc(buf_size_out); if (!out_buf) { From c5daa916696c67570b07a8a3fc1da3a3beaba105 Mon Sep 17 00:00:00 2001 From: Ed Date: Wed, 17 Sep 2025 06:26:42 -0600 Subject: [PATCH 21/29] more fixes --- BZIP2/example/Makefile.am | 11 +++++++++-- JPEG/example/Makefile.am | 2 -- JPEG/src/H5Zjpeg.c | 14 +++++++------- LZ4/example/Makefile.am | 5 ++++- LZF/example/Makefile.am | 5 +++-- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/BZIP2/example/Makefile.am b/BZIP2/example/Makefile.am index 464da10d..b9749b72 100644 --- a/BZIP2/example/Makefile.am +++ b/BZIP2/example/Makefile.am @@ -7,6 +7,13 @@ # Link to our filter library. LDADD = ${top_builddir}/src/libh5bz2.la -# Build example program. -noinst_PROGRAMS = h5ex_d_bzip2 +# Build example program and run it as a test. +check_PROGRAMS = h5ex_d_bzip2 +TESTS = run_tests.sh + +# Clean up HDF5 file created by example. +CLEANFILES = *.h5 + +EXTRA_DIST = run_tests.sh + diff --git a/JPEG/example/Makefile.am b/JPEG/example/Makefile.am index 17748322..7bf73061 100644 --- a/JPEG/example/Makefile.am +++ b/JPEG/example/Makefile.am @@ -1,5 +1,3 @@ -# Copyright by The HDF Group. All rights reserved. - # This builds the JPEG example directory. # Edward Hartnett 9/15/25 diff --git a/JPEG/src/H5Zjpeg.c b/JPEG/src/H5Zjpeg.c index 3846827a..e6abef0b 100644 --- a/JPEG/src/H5Zjpeg.c +++ b/JPEG/src/H5Zjpeg.c @@ -156,7 +156,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu int err = 0; unsigned char *output = NULL; - printf("**** decompressing nbytes: %ld\n", nbytes); + /* printf("**** decompressing nbytes: %ld\n", nbytes); */ /* allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ @@ -195,7 +195,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu output = out_buf; while (jpegInfo.output_scanline < jpegInfo.output_height) { - printf("**** jpegInfo.output_scanline: %d\n", jpegInfo.output_scanline); + /* printf("**** jpegInfo.output_scanline: %d\n", jpegInfo.output_scanline); */ unsigned char *row_pointer[1] = {output}; err = jpeg_read_scanlines(&jpegInfo, row_pointer, 1); @@ -234,7 +234,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu int nwrite = 0; size_t expectedSize; - printf("**** compressing nbytes: %ld cd_nelmts %ld\n", nbytes, cd_nelmts); + /* printf("**** compressing nbytes: %ld cd_nelmts %ld\n", nbytes, cd_nelmts); */ if (cd_nelmts != 4) { PUSH_ERR("jpeg_h5_filter", H5E_CALLBACK, "cd_nelmts must be 4"); goto failed; @@ -247,7 +247,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu sizeX = cd_values[1]; sizeY = cd_values[2]; colorMode = cd_values[3]; - printf("**** qualityFactor %d sizeX %d sizeY %d colorMode %d\n", qualityFactor, sizeX, sizeY, colorMode); + /* printf("**** qualityFactor %d sizeX %d sizeY %d colorMode %d\n", qualityFactor, sizeX, sizeY, colorMode); */ /* Sanity check to make sure we have been passed a complete image */ expectedSize = sizeX * sizeY; @@ -318,12 +318,12 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu * Pass TRUE unless you are very sure of what you're doing. */ jpeg_start_compress(&jpegInfo, TRUE); - printf("**** starting compression\n"); + /* printf("**** starting compression\n"); */ pData = (unsigned char *)*buf; while ((int)jpegInfo.next_scanline < sizeY) { - printf("**** jpegInfo.next_scanline: %d\n", jpegInfo.next_scanline); + /* printf("**** jpegInfo.next_scanline: %d\n", jpegInfo.next_scanline); */ row_pointer[0] = pData; nwrite = jpeg_write_scanlines(&jpegInfo, row_pointer, 1); pData += sizeX * jpegInfo.input_components; @@ -336,7 +336,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu /* Finish compression */ jpeg_finish_compress(&jpegInfo); buf_size_out = outSize; - printf("**** compressed size: %ld\n", buf_size_out); + /* printf("**** compressed size: %ld\n", buf_size_out); */ out_buf = malloc(buf_size_out); if (!out_buf) { diff --git a/LZ4/example/Makefile.am b/LZ4/example/Makefile.am index 4c233613..89d07329 100644 --- a/LZ4/example/Makefile.am +++ b/LZ4/example/Makefile.am @@ -9,7 +9,10 @@ LDADD = ${top_builddir}/src/libh5lz4.la # Build example program. check_PROGRAMS = h5ex_d_lz4 -TESTS = h5ex_d_lz4 +TESTS = run_tests.sh # Clean up HDF5 file created by example. CLEANFILES = *.h5 + +EXTRA_DIST = run_tests.sh + diff --git a/LZF/example/Makefile.am b/LZF/example/Makefile.am index c44133d0..d28e4d62 100644 --- a/LZF/example/Makefile.am +++ b/LZF/example/Makefile.am @@ -5,12 +5,13 @@ # Ed Hartnett 1/15/19 # Link to our filter library. -AM_LDFLAGS = ${top_builddir}/src/libh5lzf.la LDADD = ${top_builddir}/src/libh5lzf.la # Build example program and run it as a test. check_PROGRAMS = h5ex_d_lzf -#TESTS = h5ex_d_lzf +TESTS = run_tests.sh # Clean up HDF5 file created by example. CLEANFILES = *.h5 + +EXTRA_DIST = run_tests.sh From a485e85f1a74a0a8c79b477eb0cc4f4a1afe9824 Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Tue, 2 Dec 2025 14:50:29 -0500 Subject: [PATCH 22/29] Remove HDF copyright from community maintained file --- JPEG/src/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/JPEG/src/Makefile.am b/JPEG/src/Makefile.am index 5edb554d..7b6e1f89 100644 --- a/JPEG/src/Makefile.am +++ b/JPEG/src/Makefile.am @@ -1,5 +1,3 @@ -# Copyright by The HDF Group. All rights reserved. - # This is the Makefile.am for the HDF5 JPEG filter library. This allows # the use of JPEG compression/decompression on HDF5 datasets. # From 8ebba1f9786ac8f12a440689b3561b2714e3cd36 Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Tue, 2 Dec 2025 14:51:58 -0500 Subject: [PATCH 23/29] Restore back LZ4 filter plugin code The proposed changes need more discussion. --- LZ4/src/H5Zlz4.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/LZ4/src/H5Zlz4.c b/LZ4/src/H5Zlz4.c index 62976fe0..6dbca2ba 100644 --- a/LZ4/src/H5Zlz4.c +++ b/LZ4/src/H5Zlz4.c @@ -55,7 +55,7 @@ #include "H5PLextern.h" #include "lz4.h" -size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], +static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf); #define H5Z_FILTER_LZ4 32004 @@ -100,7 +100,7 @@ H5PLget_plugin_info(void) return H5Z_LZ4; } -size_t +static size_t H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, void **buf) { @@ -146,7 +146,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value { int compressedBytes = LZ4_decompress_safe(rpos, roBuf, compressedBlockSize, blockSize); if (compressedBytes != blockSize) { - /* printf("decompressed size not the same: %d, != %d\n", compressedBytes, blockSize); */ + printf("decompressed size not the same: %d, != %d\n", compressedBytes, blockSize); goto error; } } @@ -163,7 +163,7 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value } else /* forward filter */ { - size_t blockSize = DEFAULT_BLOCK_SIZE; + size_t blockSize; size_t nBlocks; size_t outSize; /* size of the output buffer. Header size (12 bytes) is included */ size_t block; @@ -172,7 +172,6 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value size_t maxDestSize; char *rpos; /* pointer to current read position */ char *roBuf; /* pointer to current write position */ - int acceleration = 1; if (nbytes > INT32_MAX) { /* can only compress chunks up to 2GB */ @@ -180,7 +179,10 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value } if (cd_nelmts > 0 && cd_values[0] > 0) { - acceleration = cd_values[0]; + blockSize = cd_values[0]; + } + else { + blockSize = DEFAULT_BLOCK_SIZE; } if (blockSize > nbytes) { blockSize = nbytes; @@ -204,15 +206,14 @@ H5Z_filter_lz4(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value outSize = 12; /* size of the output buffer. Header size (12 bytes) is included */ - /* printf("nbytes %ld nBlocks %ld\n", nbytes, nBlocks); */ for (block = 0; block < nBlocks; ++block) { uint32_t compBlockSize; /// reserve space for compBlockSize size_t origWritten = block * blockSize; if (nbytes - origWritten < blockSize) /* the last block may be < blockSize */ blockSize = nbytes - origWritten; - compBlockSize = LZ4_compress_fast( - rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize), acceleration); /// reserve space for compBlockSize + compBlockSize = LZ4_compress_default( + rpos, roBuf + 4, blockSize, LZ4_compressBound(blockSize)); /// reserve space for compBlockSize if (!compBlockSize) goto error; if (compBlockSize >= blockSize) /* compression did not save any space, do a memcpy instead */ From b9af703ade42e8471c3d7eb0deffd7e3792f8a14 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:09:43 +0000 Subject: [PATCH 24/29] Committing clang-format changes --- JPEG/src/H5Zjpeg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/JPEG/src/H5Zjpeg.c b/JPEG/src/H5Zjpeg.c index e6abef0b..4dd48c7e 100644 --- a/JPEG/src/H5Zjpeg.c +++ b/JPEG/src/H5Zjpeg.c @@ -195,7 +195,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu output = out_buf; while (jpegInfo.output_scanline < jpegInfo.output_height) { - /* printf("**** jpegInfo.output_scanline: %d\n", jpegInfo.output_scanline); */ + /* printf("**** jpegInfo.output_scanline: %d\n", jpegInfo.output_scanline); */ unsigned char *row_pointer[1] = {output}; err = jpeg_read_scanlines(&jpegInfo, row_pointer, 1); @@ -247,7 +247,8 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu sizeX = cd_values[1]; sizeY = cd_values[2]; colorMode = cd_values[3]; - /* printf("**** qualityFactor %d sizeX %d sizeY %d colorMode %d\n", qualityFactor, sizeX, sizeY, colorMode); */ + /* printf("**** qualityFactor %d sizeX %d sizeY %d colorMode %d\n", qualityFactor, sizeX, sizeY, + * colorMode); */ /* Sanity check to make sure we have been passed a complete image */ expectedSize = sizeX * sizeY; @@ -318,12 +319,12 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu * Pass TRUE unless you are very sure of what you're doing. */ jpeg_start_compress(&jpegInfo, TRUE); - /* printf("**** starting compression\n"); */ + /* printf("**** starting compression\n"); */ pData = (unsigned char *)*buf; while ((int)jpegInfo.next_scanline < sizeY) { - /* printf("**** jpegInfo.next_scanline: %d\n", jpegInfo.next_scanline); */ + /* printf("**** jpegInfo.next_scanline: %d\n", jpegInfo.next_scanline); */ row_pointer[0] = pData; nwrite = jpeg_write_scanlines(&jpegInfo, row_pointer, 1); pData += sizeX * jpegInfo.input_components; From 9f226d5acd299f4e7f5c901a11bcecdc5b4cac7c Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Tue, 9 Dec 2025 11:48:40 -0500 Subject: [PATCH 25/29] Switch from %ld to %zu for size_t vars in JPEG/example/h5ex_d_jpeg.c Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --- JPEG/example/h5ex_d_jpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JPEG/example/h5ex_d_jpeg.c b/JPEG/example/h5ex_d_jpeg.c index 3193c98e..b3dffc83 100644 --- a/JPEG/example/h5ex_d_jpeg.c +++ b/JPEG/example/h5ex_d_jpeg.c @@ -187,7 +187,7 @@ main(void) switch (filter_id) { case H5Z_FILTER_JPEG: printf("%d\n", filter_id); - printf(" Number of parameters is %ld with the value %u\n", nelmts, values_out[0]); + printf(" Number of parameters is %zu with the value %u\n", nelmts, values_out[0]); printf(" To find more about the filter check %s\n", filter_name); break; default: From dd94d82c05c00ef7d03e4f0f4ec19e45846599a3 Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Tue, 9 Dec 2025 13:18:02 -0500 Subject: [PATCH 26/29] Fixed typos --- BZIP2/m4/libtool.m4 | 2 +- Makefile.am | 4 ++-- configure.ac | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BZIP2/m4/libtool.m4 b/BZIP2/m4/libtool.m4 index e7b68334..817e3022 100644 --- a/BZIP2/m4/libtool.m4 +++ b/BZIP2/m4/libtool.m4 @@ -8245,7 +8245,7 @@ AC_SUBST([DLLTOOL]) m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) -])# _LD_DECL_FILECMD +])# _LT_DECL_FILECMD # _LT_DECL_SED # ------------ diff --git a/Makefile.am b/Makefile.am index 098a1a82..b8798830 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,12 +17,12 @@ if BUILD_LZ4 LZ4 = LZ4 endif -# Does the user want to build lz4? +# Does the user want to build JPEG? if BUILD_JPEG JPEG = JPEG endif -# Does the user want to build lz4? +# Does the user want to build LZF? if BUILD_LZF LZF = LZF endif diff --git a/configure.ac b/configure.ac index 03444c15..18c6f68a 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ LT_PREREQ([2.4]) LT_INIT() # If the env. variable HDF5_PLUGIN_PATH is set, or if -# --with-hdf5-plugin-dir=, use it. +# --with-hdf5-plugin-path=, use it. AC_MSG_CHECKING([where to put HDF5 plugins]) AC_ARG_WITH([hdf5-plugin-path], [AS_HELP_STRING([--with-hdf5-plugin-path=], From 372067197496828c3d32beaea4fa03256b569afe Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Tue, 9 Dec 2025 16:42:12 -0500 Subject: [PATCH 27/29] Remove duplicate jpeg_std_error() call --- JPEG/src/H5Zjpeg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JPEG/src/H5Zjpeg.c b/JPEG/src/H5Zjpeg.c index 4dd48c7e..f399e4df 100644 --- a/JPEG/src/H5Zjpeg.c +++ b/JPEG/src/H5Zjpeg.c @@ -281,7 +281,7 @@ H5Z_filter_jpeg(unsigned int flags, size_t cd_nelmts, const unsigned int cd_valu PUSH_ERR("jpeg_h5_filter", H5E_CALLBACK, "Could not initialize JPEG compression object."); goto failed; } - jpegInfo.err = jpeg_std_error((struct jpeg_error_mgr *)&jpegErr); + /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&jpegInfo); From da1fab332df0176f2b430dda65eab2afcc835a39 Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Mon, 22 Dec 2025 22:48:17 -0500 Subject: [PATCH 28/29] Update example JPEG expected output test files --- JPEG/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst | 4 ++-- JPEG/example/testfiles/h5ex_d_jpeg.tst | 4 ++-- config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/JPEG/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst b/JPEG/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst index 71c5e3da..b0527559 100644 --- a/JPEG/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst +++ b/JPEG/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst @@ -4,8 +4,8 @@ jpeg filter is available for encoding and decoding. ....Close the file and reopen for reading ........ Filter info is available from the dataset creation property Filter identifier is 32019 - Number of parameters is 4 with the value 100 + Number of parameters is 4 with the value 50 To find more about the filter check HDF5 jpeg filter; see https://github.com/HDFGroup/hdf5_plugins/blob/master/docs/RegisteredFilterPlugins.md ....Reading jpeg compressed data ................ -JPEG quality=100, percent of differing array elements=0.000000 +JPEG quality=50, percent of differing array elements=49.609375 jpeg filter is available now since H5Dread triggered loading of the filter. diff --git a/JPEG/example/testfiles/h5ex_d_jpeg.tst b/JPEG/example/testfiles/h5ex_d_jpeg.tst index 71c5e3da..b0527559 100644 --- a/JPEG/example/testfiles/h5ex_d_jpeg.tst +++ b/JPEG/example/testfiles/h5ex_d_jpeg.tst @@ -4,8 +4,8 @@ jpeg filter is available for encoding and decoding. ....Close the file and reopen for reading ........ Filter info is available from the dataset creation property Filter identifier is 32019 - Number of parameters is 4 with the value 100 + Number of parameters is 4 with the value 50 To find more about the filter check HDF5 jpeg filter; see https://github.com/HDFGroup/hdf5_plugins/blob/master/docs/RegisteredFilterPlugins.md ....Reading jpeg compressed data ................ -JPEG quality=100, percent of differing array elements=0.000000 +JPEG quality=50, percent of differing array elements=49.609375 jpeg filter is available now since H5Dread triggered loading of the filter. diff --git a/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst b/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst index 71c5e3da..b0527559 100644 --- a/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst +++ b/config/cmake/binex/example/testfiles/h5ex_d_jpeg.tst @@ -4,8 +4,8 @@ jpeg filter is available for encoding and decoding. ....Close the file and reopen for reading ........ Filter info is available from the dataset creation property Filter identifier is 32019 - Number of parameters is 4 with the value 100 + Number of parameters is 4 with the value 50 To find more about the filter check HDF5 jpeg filter; see https://github.com/HDFGroup/hdf5_plugins/blob/master/docs/RegisteredFilterPlugins.md ....Reading jpeg compressed data ................ -JPEG quality=100, percent of differing array elements=0.000000 +JPEG quality=50, percent of differing array elements=49.609375 jpeg filter is available now since H5Dread triggered loading of the filter. From 01f6a58abec50511d7f10ef28c191f1d6a6f1245 Mon Sep 17 00:00:00 2001 From: Aleksandar Jelenak Date: Fri, 23 Jan 2026 22:14:01 -0500 Subject: [PATCH 29/29] Merge master branch --- .github/CODEOWNERS | 8 +- .github/workflows/clang-format-check.yml | 2 +- .github/workflows/clang-format-fix.yml | 2 +- .github/workflows/daily-build.yml | 9 +- .github/workflows/publish-release.yml | 2 +- .github/workflows/tarball.yml | 14 +- README.md | 88 +- ZFP/CMakeLists.txt | 360 +++---- ZFP/H5Z-ZFP/.github/codeql-config.yml | 11 + ZFP/H5Z-ZFP/.github/dependabot.yml | 29 + ZFP/H5Z-ZFP/.github/workflows/codeql.yml | 148 +++ ZFP/H5Z-ZFP/.github/workflows/codespell.yml | 14 + ZFP/H5Z-ZFP/.github/workflows/main.yml | 235 +++++ ZFP/H5Z-ZFP/.gitignore | 33 + ZFP/H5Z-ZFP/.readthedocs.yaml | 22 + ZFP/H5Z-ZFP/.travis.yml | 38 + ZFP/H5Z-ZFP/CMakeLists.txt | 112 ++ ZFP/{Additional_Legal => H5Z-ZFP}/LICENSE | 0 ZFP/H5Z-ZFP/Makefile | 65 ++ ZFP/H5Z-ZFP/README.md | 38 + ZFP/H5Z-ZFP/cmake/HDFMacros.cmake | 285 +++++ .../cmake/h5z_zfp-config-version.cmake.in | 15 + ZFP/H5Z-ZFP/cmake/h5z_zfp-config.cmake.in | 59 ++ ZFP/{ => H5Z-ZFP}/config.make | 68 +- ZFP/{ => H5Z-ZFP}/docs/Makefile | 0 ZFP/H5Z-ZFP/docs/cd_vals.rst | 40 + ZFP/{ => H5Z-ZFP}/docs/conf.py | 16 +- .../h5repack.rst => H5Z-ZFP/docs/direct.rst} | 7 +- ZFP/H5Z-ZFP/docs/endian_issues.rst | 26 + ZFP/H5Z-ZFP/docs/h5repack.rst | 104 ++ ZFP/H5Z-ZFP/docs/hdf5_chunking.rst | 155 +++ ZFP/H5Z-ZFP/docs/index.rst | 23 + ZFP/H5Z-ZFP/docs/installation.rst | 291 ++++++ ZFP/H5Z-ZFP/docs/interfaces.rst | 141 +++ ZFP/H5Z-ZFP/docs/requirements.txt | 2 + ZFP/{ => H5Z-ZFP}/docs/tests.rst | 6 +- ZFP/H5Z-ZFP/src/CMakeLists.txt | 75 ++ ZFP/{ => H5Z-ZFP}/src/H5Zzfp.c | 516 ++++------ ZFP/{ => H5Z-ZFP}/src/H5Zzfp.h | 0 ZFP/{ => H5Z-ZFP}/src/H5Zzfp_lib.h | 0 ZFP/H5Z-ZFP/src/H5Zzfp_plugin.h | 70 ++ ZFP/H5Z-ZFP/src/H5Zzfp_props.c | 177 ++++ ZFP/{ => H5Z-ZFP}/src/H5Zzfp_props.h | 14 +- ZFP/H5Z-ZFP/src/H5Zzfp_props_f.F90 | 147 +++ ZFP/{ => H5Z-ZFP}/src/H5Zzfp_props_private.h | 6 +- ZFP/{ => H5Z-ZFP}/src/H5Zzfp_version.h | 8 +- ZFP/H5Z-ZFP/src/Makefile | 68 ++ ZFP/H5Z-ZFP/test/CMakeLists.txt | 973 ++++++++++++++++++ ZFP/H5Z-ZFP/test/Makefile | 747 ++++++++++++++ ZFP/H5Z-ZFP/test/bigendian.h5 | Bin 0 -> 22048 bytes ZFP/H5Z-ZFP/test/h5dump-rate.bsh | 31 + ZFP/H5Z-ZFP/test/h5dump-rate.cmake | 46 + ZFP/H5Z-ZFP/test/h5repack-filesizes.bsh | 31 + ZFP/H5Z-ZFP/test/h5repack-filesizes.cmake | 33 + ZFP/H5Z-ZFP/test/h5repack_parse.patch | 46 + ZFP/H5Z-ZFP/test/mesh.h5 | Bin 0 -> 1151188 bytes ZFP/H5Z-ZFP/test/print_h5repack_farg.c | 116 +++ ZFP/H5Z-ZFP/test/test_common.h | 145 +++ ZFP/H5Z-ZFP/test/test_error.c | 203 ++++ ZFP/H5Z-ZFP/test/test_read.c | 166 +++ ZFP/H5Z-ZFP/test/test_rw_fortran.F90 | 465 +++++++++ ZFP/H5Z-ZFP/test/test_write.c | 602 +++++++++++ ZFP/H5Z-ZFP/test/test_zfp_030040.h5 | Bin 0 -> 24328 bytes ZFP/H5Z-ZFP/test/test_zfp_030235.h5 | Bin 0 -> 23460 bytes ZFP/H5Z-ZFP/test/test_zfp_050.h5 | Bin 0 -> 15064 bytes ZFP/H5Z-ZFP/test/test_zfp_052.h5 | Bin 0 -> 15064 bytes ZFP/H5Z-ZFP/test/test_zfp_054.h5 | Bin 0 -> 15064 bytes ZFP/H5Z-ZFP/test/test_zfp_110050.h5 | Bin 0 -> 13872 bytes ZFP/H5Z-ZFP/test/test_zfp_110xxx.h5 | Bin 0 -> 13872 bytes ZFP/H5Z-ZFP/test/test_zfp_be.h5 | Bin 0 -> 20280 bytes ZFP/H5Z-ZFP/test/test_zfp_le.h5 | Bin 0 -> 20280 bytes ZFP/Makefile | 48 - ZFP/Makefile.am | 11 - ZFP/README.md | 110 +- ZFP/UPDATING_ZFP_SUBTREE.md | 199 ++++ ZFP/config.h.in | 86 -- ZFP/configure.ac | 92 -- ZFP/docs/cmake.rst | 93 -- ZFP/docs/endian_issues.rst | 31 - ZFP/docs/hdf5_chunking.rst | 143 --- ZFP/docs/index.rst | 29 - ZFP/docs/installation.rst | 182 ---- ZFP/docs/interfaces.rst | 188 ---- ZFP/example/testfiles/h5ex_d_zfp.tst | 2 +- ZFP/src/CMakeLists.txt | 87 -- ZFP/src/H5Zzfp_plugin.h | 102 -- ZFP/src/H5Zzfp_props.c | 134 --- ZFP/src/Makefile.am | 13 - config/cmake/binex/example/CMakeLists.txt | 19 + config/cmake/cacheinit.cmake | 2 +- docs/RegisteredFilterPlugins.md | 17 + 91 files changed, 6885 insertions(+), 1856 deletions(-) create mode 100644 ZFP/H5Z-ZFP/.github/codeql-config.yml create mode 100644 ZFP/H5Z-ZFP/.github/dependabot.yml create mode 100644 ZFP/H5Z-ZFP/.github/workflows/codeql.yml create mode 100644 ZFP/H5Z-ZFP/.github/workflows/codespell.yml create mode 100644 ZFP/H5Z-ZFP/.github/workflows/main.yml create mode 100644 ZFP/H5Z-ZFP/.gitignore create mode 100644 ZFP/H5Z-ZFP/.readthedocs.yaml create mode 100644 ZFP/H5Z-ZFP/.travis.yml create mode 100644 ZFP/H5Z-ZFP/CMakeLists.txt rename ZFP/{Additional_Legal => H5Z-ZFP}/LICENSE (100%) create mode 100644 ZFP/H5Z-ZFP/Makefile create mode 100644 ZFP/H5Z-ZFP/README.md create mode 100644 ZFP/H5Z-ZFP/cmake/HDFMacros.cmake create mode 100644 ZFP/H5Z-ZFP/cmake/h5z_zfp-config-version.cmake.in create mode 100644 ZFP/H5Z-ZFP/cmake/h5z_zfp-config.cmake.in rename ZFP/{ => H5Z-ZFP}/config.make (79%) rename ZFP/{ => H5Z-ZFP}/docs/Makefile (100%) create mode 100644 ZFP/H5Z-ZFP/docs/cd_vals.rst rename ZFP/{ => H5Z-ZFP}/docs/conf.py (95%) rename ZFP/{docs/h5repack.rst => H5Z-ZFP/docs/direct.rst} (84%) create mode 100644 ZFP/H5Z-ZFP/docs/endian_issues.rst create mode 100644 ZFP/H5Z-ZFP/docs/h5repack.rst create mode 100644 ZFP/H5Z-ZFP/docs/hdf5_chunking.rst create mode 100644 ZFP/H5Z-ZFP/docs/index.rst create mode 100644 ZFP/H5Z-ZFP/docs/installation.rst create mode 100644 ZFP/H5Z-ZFP/docs/interfaces.rst create mode 100644 ZFP/H5Z-ZFP/docs/requirements.txt rename ZFP/{ => H5Z-ZFP}/docs/tests.rst (97%) create mode 100644 ZFP/H5Z-ZFP/src/CMakeLists.txt rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp.c (56%) rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp.h (100%) rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp_lib.h (100%) create mode 100644 ZFP/H5Z-ZFP/src/H5Zzfp_plugin.h create mode 100644 ZFP/H5Z-ZFP/src/H5Zzfp_props.c rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp_props.h (74%) create mode 100644 ZFP/H5Z-ZFP/src/H5Zzfp_props_f.F90 rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp_props_private.h (80%) rename ZFP/{ => H5Z-ZFP}/src/H5Zzfp_version.h (69%) create mode 100644 ZFP/H5Z-ZFP/src/Makefile create mode 100644 ZFP/H5Z-ZFP/test/CMakeLists.txt create mode 100644 ZFP/H5Z-ZFP/test/Makefile create mode 100644 ZFP/H5Z-ZFP/test/bigendian.h5 create mode 100755 ZFP/H5Z-ZFP/test/h5dump-rate.bsh create mode 100644 ZFP/H5Z-ZFP/test/h5dump-rate.cmake create mode 100755 ZFP/H5Z-ZFP/test/h5repack-filesizes.bsh create mode 100644 ZFP/H5Z-ZFP/test/h5repack-filesizes.cmake create mode 100644 ZFP/H5Z-ZFP/test/h5repack_parse.patch create mode 100644 ZFP/H5Z-ZFP/test/mesh.h5 create mode 100644 ZFP/H5Z-ZFP/test/print_h5repack_farg.c create mode 100644 ZFP/H5Z-ZFP/test/test_common.h create mode 100644 ZFP/H5Z-ZFP/test/test_error.c create mode 100644 ZFP/H5Z-ZFP/test/test_read.c create mode 100644 ZFP/H5Z-ZFP/test/test_rw_fortran.F90 create mode 100644 ZFP/H5Z-ZFP/test/test_write.c create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_030040.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_030235.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_050.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_052.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_054.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_110050.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_110xxx.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_be.h5 create mode 100644 ZFP/H5Z-ZFP/test/test_zfp_le.h5 delete mode 100644 ZFP/Makefile delete mode 100644 ZFP/Makefile.am create mode 100644 ZFP/UPDATING_ZFP_SUBTREE.md delete mode 100644 ZFP/config.h.in delete mode 100644 ZFP/configure.ac delete mode 100644 ZFP/docs/cmake.rst delete mode 100644 ZFP/docs/endian_issues.rst delete mode 100644 ZFP/docs/hdf5_chunking.rst delete mode 100644 ZFP/docs/index.rst delete mode 100644 ZFP/docs/installation.rst delete mode 100644 ZFP/docs/interfaces.rst delete mode 100644 ZFP/src/CMakeLists.txt delete mode 100644 ZFP/src/H5Zzfp_plugin.h delete mode 100644 ZFP/src/H5Zzfp_props.c delete mode 100644 ZFP/src/Makefile.am diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 759f7c1c..09607226 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,12 +2,12 @@ # Each line is a file pattern followed by one or more owners. # These owners will be the default owners for everything in the repo. -* @lrknox @byrnHDF @fortnern @jhendersonHDF @bmribler @glennsong09 @mattjala @brtnfld @ajelenak +* @lrknox @fortnern @jhendersonHDF @bmribler @glennsong09 @mattjala @brtnfld @ajelenak # Order is important. The last matching pattern has the most precedence. # So if a pull request only touches javascript files, only these owners # will be requested to review. /ZSTD/ @mkitti @nhz2 -*.cmake @byrnHDF @ajelenak -CMakeLists.txt @byrnHDF @ajelenak -CMakeTests.* @byrnHDF @ajelenak +*.cmake @jhendersonHDF @ajelenak +CMakeLists.txt @jhendersonHDF @ajelenak +CMakeTests.* @jhendersonHDF @ajelenak diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml index f4ef0b6f..dedff2f0 100644 --- a/.github/workflows/clang-format-check.yml +++ b/.github/workflows/clang-format-check.yml @@ -20,4 +20,4 @@ jobs: extensions: 'c,h,cpp,hpp,java' clangFormatVersion: 17 style: file - exclude: './community' + exclude: './community ./ZFP/H5Z-ZFP' diff --git a/.github/workflows/clang-format-fix.yml b/.github/workflows/clang-format-fix.yml index 894148d9..93ed6506 100644 --- a/.github/workflows/clang-format-fix.yml +++ b/.github/workflows/clang-format-fix.yml @@ -33,7 +33,7 @@ jobs: clangFormatVersion: 17 inplace: True style: file - exclude: './community' + exclude: './community ./ZFP/H5Z-ZFP' - uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4 with: diff --git a/.github/workflows/daily-build.yml b/.github/workflows/daily-build.yml index 24264137..60b697b2 100644 --- a/.github/workflows/daily-build.yml +++ b/.github/workflows/daily-build.yml @@ -55,7 +55,7 @@ jobs: - name: Read inputs id: getinputs run: | - echo "INPUTS_IGNORE=${{ inputs.use_ignore }}" >> $GITHUB_OUTPUT + echo "INPUTS_IGNORE=${{ inputs.use_ignore || 'check' }}" >> $GITHUB_OUTPUT - run: echo "use_ignore is ${{ steps.getinputs.outputs.INPUTS_IGNORE }}." @@ -75,7 +75,7 @@ jobs: file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} use_hdf: ${{ needs.get-old-names.outputs.hdf5-name }} use_environ: snapshots - if: ${{ ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) }} + if: ${{ (github.event_name != 'pull_request') && ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) }} call-workflow-ctest: needs: [get-old-names, call-workflow-tarball] @@ -108,6 +108,7 @@ jobs: use_hdf: ${{ needs.get-old-names.outputs.hdf5-name }} file_base: ${{ needs.call-workflow-tarball.outputs.file_base }} use_environ: snapshots + if: ${{ github.event_name != 'pull_request' }} call-workflow-release: needs: [get-old-names, call-workflow-tarball, call-workflow-ctest] @@ -120,7 +121,7 @@ jobs: file_sha: ${{ needs.call-workflow-tarball.outputs.file_sha }} use_tag: snapshot use_environ: snapshots - if: ${{ ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) }} + if: ${{ (github.event_name != 'pull_request') && ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) }} call-workflow-remove: needs: [get-old-names, call-workflow-tarball, call-workflow-ctest, call-workflow-release] @@ -131,7 +132,7 @@ jobs: file_base: ${{ needs.get-old-names.outputs.plugin-name }} use_tag: snapshot use_environ: snapshots - if: ${{ ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) && (needs.get-old-names.outputs.hdf5-name != needs.call-workflow-tarball.outputs.file_base) }} + if: ${{ (github.event_name != 'pull_request') && ((needs.call-workflow-tarball.outputs.has_changes == 'true') || (needs.get-old-names.outputs.run-ignore == 'ignore')) && (needs.get-old-names.outputs.hdf5-name != needs.call-workflow-tarball.outputs.file_base) }} call-workflow-versions: uses: ./.github/workflows/check-releases.yml diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 53cd00bf..7622f8b6 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -1,4 +1,4 @@ -name: hdf5 plugins publishrelease +name: hdf5 plugins publish release # Triggers the workflow on demand on: diff --git a/.github/workflows/tarball.yml b/.github/workflows/tarball.yml index 7e2be850..0b9150e6 100644 --- a/.github/workflows/tarball.yml +++ b/.github/workflows/tarball.yml @@ -44,7 +44,7 @@ jobs: name: Check for recent commits runs-on: ubuntu-latest outputs: - has_changes: ${{ steps.check-new-commits.outputs.has-new-commits }} + has_changes: ${{ steps.check-new-commits.outputs.has-new-commits || steps.set-pr-commits.outputs.has-new-commits }} branch_ref: ${{ steps.get-branch-name.outputs.BRANCH_REF }} branch_sha: ${{ steps.get-branch-sha.outputs.BRANCH_SHA }} steps: @@ -73,8 +73,14 @@ jobs: uses: adriangl/check-new-commits-action@v1 with: seconds: 86400 # One day in seconds - branch: '${{ steps.get-branch-name.outputs.branch_ref }}' - if: ${{ (inputs.use_environ == 'snapshots' && inputs.use_ignore == 'check') }} + branch: '${{ steps.get-branch-name.outputs.BRANCH_REF }}' + token: ${{ secrets.GITHUB_TOKEN }} + if: ${{ (inputs.use_environ == 'snapshots' && inputs.use_ignore == 'check' && github.event_name != 'pull_request') }} + + - name: Set has-new-commits for pull requests + id: set-pr-commits + run: echo "has-new-commits=true" >> $GITHUB_OUTPUT + if: ${{ github.event_name == 'pull_request' }} - run: echo "You have ${{ steps.check-new-commits.outputs.new-commits-number }} new commit(s) in ${{ steps.get-branch-name.outputs.BRANCH_REF }} ✅!" if: ${{ steps.check-new-commits.outputs.has-new-commits == 'true' }} @@ -95,7 +101,7 @@ jobs: uses: actions/checkout@v4.1.7 with: path: hdfsrc - ref: '${{needs.check_commits.outputs.branch_ref }}' + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || needs.check_commits.outputs.branch_ref }} - name: Retrieve version id: version diff --git a/README.md b/README.md index 2be3b690..57fd153d 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,43 @@ -HDF5 Compression Plugins ------------------------- +# Select HDF5 Filter Plugins Repository -*Please refer to the Building.txt file for installation instructions.* +[![Daily Build](https://github.com/HDFGroup/hdf5_plugins/actions/workflows/daily-build.yml/badge.svg)](https://github.com/HDFGroup/hdf5_plugins/actions/workflows/daily-build.yml) -This repository contains compression plugin code for the library that implement the -HDF5® data model API. The HDF5® data model has been adopted across -many industries and this implementation has become a de facto data management standard -in science, engineering, and research communities worldwide. +This repository contains a select number of registered HDF5® filter plugins for use in HDF Group's development and testing activities of the HDF5® library. The HDF Group is the developer, maintainer, and steward of the HDF5® software. Find more +information about The HDF Group, the HDF5® Community, and other HDF5® software projects, +tools, and services at [The HDF Group's website](https://www.hdfgroup.org/). -HDF5 compression plugins are divided into two categories: +## Documentation -1) Maintained +Official information about registered HDF5® filter plugins: +https://github.com/HDFGroup/hdf5_plugins/blob/master/docs/RegisteredFilterPlugins.md. -These filters get their own directory off the root, are actively maintained, -and are deployed with the HDF5 library when we create a release. +Instructions about creating a filter plugin are in the HDF5® [documentation](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_p_l__u_g.html#sec_filter_plugins). How filters fit in the library data I/O operations is described in the [Data Pipeline](https://support.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html#subsubsec_dataset_transfer_pipe) documentation. -2) Community +> [!NOTE] +> See the [Building.txt](./Building.txt) file for installation instructions. -These are located in the `community` directory and may not be actively maintained. -This directory is instead intended to be a one-stop-shopping location for information about -filters found in the wild, with links to code and maintainers. The hope is that, even -if the filters become unmaintained, enough information can be found here to decode -the data in the file, even if that would require more effort, such as having to -adapt code that hasn't been maintained in a long time. +For all HDF Group's software documentation go to: +https://support.hdfgroup.org/documentation/index.html. -This repository only contains information about compression plugins. VFDs and VOL -connectors are not maintained here. +## Forum and News -The HDF Group is the developer, maintainer, and steward of HDF5 software. Find more -information about The HDF Group, the HDF5 Community, and other HDF5 software projects, -tools, and services at [The HDF Group's website](https://www.hdfgroup.org/). +The [HDF Forum](https://forum.hdfgroup.org) is provided for public announcements and discussions of interest to the general HDF5® Community. -DOCUMENTATION -------------- -Documentation for all HDF software is available at: +* [News and Announcements](https://forum.hdfgroup.org/c/news-and-announcements-from-the-hdf-group) - https://support.hdfgroup.org/documentation/index.html - -Documentation for the current HDF5 library release is available at: - - https://support.hdfgroup.org/documentation/hdf5/latest/index.html - -HELP AND SUPPORT ----------------- -Information regarding Help Desk and Support services is available at - - https://help.hdfgroup.org - - - -FORUM and NEWS --------------- -The [HDF Forum](https://forum.hdfgroup.org) is provided for public announcements and discussions -of interest to the general HDF5 Community. - - - News and Announcements - https://forum.hdfgroup.org/c/news-and-announcements-from-the-hdf-group - - - HDF5 Topics - https://forum.hdfgroup.org/c/hdf5 +* [HDF5® Topics](https://forum.hdfgroup.org/c/hdf5) These forums are provided as an open and public service for searching and reading. Posting requires completing a simple registration and allows one to join in the -conversation. Please read the [instructions](https://forum.hdfgroup.org/t/quickstart-guide-welcome-to-the-new-hdf-forum -) pertaining to the Forum's use and configuration. - - -HDF5 SNAPSHOTS, PREVIOUS RELEASES AND SOURCE CODE --------------------------------------------- -Periodically development code snapshots are provided at the following URL: - - https://github.com/HDFGroup/hdf5_plugins/releases/tag/snapshot +conversation. Please read the [instructions](https://forum.hdfgroup.org/t/quickstart-guide-welcome-to-the-new-hdf-forum) pertaining to the Forum's use and configuration. -Source packages for current and previous releases are located at: +## HDF5® Plugin Repository Snapshots and Releases - hdf5 1.16 releases: - https://support.hdfgroup.org/releases/hdf5/v1_16/index.html +Periodically development code snapshots are provided at https://github.com/HDFGroup/hdf5_plugins/releases/tag/snapshot. -Development code is available at our Github location: +Source packages for current and previous releases are located at +https://support.hdfgroup.org/releases/hdf5/index.html. - https://github.com/HDFGroup/hdf5.git +## Help and Support +Information regarding Help Desk and Support services is available at https://help.hdfgroup.org. diff --git a/ZFP/CMakeLists.txt b/ZFP/CMakeLists.txt index f711e2e6..8b7a01fd 100644 --- a/ZFP/CMakeLists.txt +++ b/ZFP/CMakeLists.txt @@ -9,18 +9,23 @@ # If you do not have access to either file, you may request a copy from # help@hdfgroup.org. # -cmake_minimum_required (VERSION 3.18) -project (H5ZFP C) + +# Wrapper CMakeLists.txt for H5Z-ZFP subtree integration +# This integrates the upstream H5Z-ZFP filter (via git subtree) with +# the HDF Group's hdf5_plugins build system and testing infrastructure. + +cmake_minimum_required(VERSION 3.18) +project(H5ZFP C) if (POLICY CMP0074) # find_package() uses _ROOT variables. - cmake_policy (SET CMP0074 NEW) + cmake_policy(SET CMP0074 NEW) endif () if (POLICY CMP0083) # To control generation of Position Independent Executable (PIE) or not, # some flags are required at link time. - cmake_policy (SET CMP0083 NEW) + cmake_policy(SET CMP0083 NEW) endif () # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: @@ -29,232 +34,241 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") endif() #----------------------------------------------------------------------------- -# Basic H5ZFP stuff here +# Verify H5Z-ZFP subtree exists #----------------------------------------------------------------------------- -if (NOT H5PL_RESOURCES_DIR) - include (${H5ZFP_SOURCE_DIR}/config/cmake/HDFMacros.cmake) - include (${H5ZFP_SOURCE_DIR}/config/cmake/HDFPluginMacros.cmake) - include (${H5ZFP_SOURCE_DIR}/config/CacheURLs.cmake) +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP/CMakeLists.txt") + message(FATAL_ERROR + "H5Z-ZFP not found at ${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP\n" + "The upstream H5Z-ZFP code should be present via git subtree.") +endif() - SET_HDF_BUILD_TYPE() -endif () -BASIC_SETTINGS (${ZFP_PACKAGE_NAME}) +message(STATUS "Using H5Z-ZFP from subtree at ${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP") #----------------------------------------------------------------------------- -# Specific H5ZFP here -#----------------------------------------------------------------------------- -# Define some CMake variables for use later in the project -#----------------------------------------------------------------------------- -set (H5ZFP_SRC_LIBZFP_DIR ${H5ZFP_SOURCE_DIR}/src/libzfp) -#----------------------------------------------------------------------------- -# Set the core names of all the libraries -#----------------------------------------------------------------------------- -set (ZFP_LIB_CORENAME "zfp") -#----------------------------------------------------------------------------- -# Set the true names of all the libraries if customized by external project -#----------------------------------------------------------------------------- -set (ZFP_LIB_NAME "${H5ZFP_EXTERNAL_LIB_PREFIX}${ZFP_LIB_CORENAME}") -#----------------------------------------------------------------------------- -# Set the target names of all the libraries -#----------------------------------------------------------------------------- -set (ZFP_LIB_TARGET ${ZFP_LIB_CORENAME}) +# Basic H5ZFP stuff - integrate with HDF Group build system #----------------------------------------------------------------------------- +if (NOT H5PL_RESOURCES_DIR) + include(${H5ZFP_SOURCE_DIR}/config/cmake/HDFMacros.cmake) + include(${H5ZFP_SOURCE_DIR}/config/cmake/HDFPluginMacros.cmake) + include(${H5ZFP_SOURCE_DIR}/config/CacheURLs.cmake) -set (H5ZFP_VERS_MAJOR 1) -set (H5ZFP_VERS_MINOR 0) -set (H5ZFP_VERS_RELEASE 0) + SET_HDF_BUILD_TYPE() +endif () -set (H5ZFP_SOVERS_MAJOR 1) -set (H5ZFP_SOVERS_MINOR 0) -set (H5ZFP_SOVERS_INTERFACE 1) -set (H5ZFP_SOVERS_RELEASE 0) -math (EXPR H5ZFP_SOVERS_MAJOR ${H5ZFP_SOVERS_INTERFACE}-${H5ZFP_SOVERS_RELEASE}) +# Set up package name for HDF Group infrastructure +if (NOT H5ZFP_PACKAGE_NAME) + set(H5ZFP_PACKAGE_NAME "zfp") +endif() -#----------------------------------------------------------------------------- -set (H5ZFP_PACKAGE_VERSION "${H5ZFP_VERS_MAJOR}.${H5ZFP_VERS_MINOR}") -set (H5ZFP_PACKAGE_VERSION_STRING "${H5ZFP_PACKAGE_VERSION}") -set (H5ZFP_PACKAGE_VERSION_MAJOR "${H5ZFP_VERS_MAJOR}") -set (H5ZFP_PACKAGE_VERSION_MINOR "${H5ZFP_VERS_MINOR}") -set (H5ZFP_PACKAGE_STRING "${H5ZFP_PACKAGE_NAME} ${H5ZFP_PACKAGE_VERSION}") -set (H5ZFP_PACKAGE_TARNAME "${H5ZFP_PACKAGE_NAME}{HDF_PACKAGE_EXT}") -set (H5ZFP_PACKAGE_URL "http://www.hdfgroup.org") -set (H5ZFP_PACKAGE_BUGREPORT "help@hdfgroup.org") -set (H5ZFP_PACKAGE_SOVERSION "${H5ZFP_SOVERS_MAJOR}.${H5ZFP_SOVERS_RELEASE}.${H5ZFP_SOVERS_MINOR}") -set (H5ZFP_PACKAGE_SOVERSION_MAJOR "${H5ZFP_SOVERS_MAJOR}") -message(STATUS "Configuring for zfp HDF5 Plugin version: " ${H5ZFP_PACKAGE_STRING}) +BASIC_SETTINGS(${H5ZFP_PACKAGE_NAME}) #----------------------------------------------------------------------------- -# Include some macros for reusable code +# Version information (read from H5Z-ZFP) #----------------------------------------------------------------------------- -include (${H5ZFP_RESOURCES_DIR}/H5ZFPMacros.cmake) +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_MAJOR") +string(REGEX REPLACE "^.*MAJOR " "" H5ZFP_VERS_MAJOR "${H5Z_ZFP_H}") +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_MINOR") +string(REGEX REPLACE "^.*MINOR " "" H5ZFP_VERS_MINOR "${H5Z_ZFP_H}") +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_PATCH") +string(REGEX REPLACE "^.*PATCH " "" H5ZFP_VERS_RELEASE "${H5Z_ZFP_H}") + +set(H5ZFP_PACKAGE_VERSION "${H5ZFP_VERS_MAJOR}.${H5ZFP_VERS_MINOR}.${H5ZFP_VERS_RELEASE}") +set(H5ZFP_PACKAGE_VERSION_STRING "${H5ZFP_PACKAGE_VERSION}") +set(H5ZFP_PACKAGE_VERSION_MAJOR "${H5ZFP_VERS_MAJOR}") +set(H5ZFP_PACKAGE_VERSION_MINOR "${H5ZFP_VERS_MINOR}") +set(H5ZFP_PACKAGE_STRING "${H5ZFP_PACKAGE_NAME} ${H5ZFP_PACKAGE_VERSION}") +set(H5ZFP_PACKAGE_URL "http://www.hdfgroup.org") +set(H5ZFP_PACKAGE_BUGREPORT "help@hdfgroup.org") + +message(STATUS "Configuring ZFP HDF5 Plugin version: ${H5ZFP_PACKAGE_STRING} (from upstream H5Z-ZFP)") #----------------------------------------------------------------------------- -# Run all the CMake configuration tests for our build environment +# Include HDF Group macros #----------------------------------------------------------------------------- -include (${H5ZFP_RESOURCES_DIR}/ConfigureChecks.cmake) +include(${H5ZFP_RESOURCES_DIR}/H5ZFPMacros.cmake) +include(${H5ZFP_RESOURCES_DIR}/ConfigureChecks.cmake) #----------------------------------------------------------------------------- -# The ZFP filter options +# HDF5 support #----------------------------------------------------------------------------- -option (COND_MAIN_ENCODER "Enable encoding" ON) -if (COND_MAIN_ENCODER) - set (HAVE_MAIN_ENCODER 1) -endif () -option (COND_MAIN_DECODER "Enable decoding" ON) -if (COND_MAIN_DECODER) - set (HAVE_MAIN_DECODER 1) -endif () -option (COND_CHECK_CRC32 "Enable check crc32" ON) -if (COND_CHECK_CRC32) - set (HAVE_CHECK_CRC32 1) -endif () -option (COND_CHECK_CRC64 "Enable check crc64" ON) -if (COND_CHECK_CRC64) - set (HAVE_CHECK_CRC64 1) -endif () -option (COND_CHECK_SHA256 "Enable check sha256" ON) -if (COND_CHECK_SHA256) - set (HAVE_CHECK_SHA256 1) -endif () -option (COND_FILTER_LZ "Enable lz filter" ON) -if (COND_FILTER_LZ) - set (HAVE_FILTER_LZ 1) -endif () -option (COND_ENCODER_LZ "Enable lz encoder" ON) -if (COND_ENCODER_LZ) - set (HAVE_ENCODER_LZ 1) -endif () -option (COND_DECODER_LZ "Enable lz decoder" ON) -if (COND_DECODER_LZ) - set (HAVE_DECODER_LZ 1) -endif () -option (COND_FILTER_LZMA1 "Enable lzma1 filter" ON) -if (COND_FILTER_LZMA1) - set (HAVE_FILTER_LZMA1) -endif () -option (COND_ENCODER_LZMA1 "Enable lzma1 encoder" ON) -if (COND_ENCODER_LZMA1) - set (HAVE_ENCODER_LZMA1 1) -endif () -option (COND_DECODER_LZMA1 "Enable lzma1 decoder" ON) -if (COND_DECODER_LZMA1) - set (HAVE_DECODER_LZMA1 1) -endif () -option (COND_ENCODER_LZMA2 "Enable lzma2 encoder" ON) -if (COND_ENCODER_LZMA2) - set (HAVE_ENCODER_LZMA2 1) -endif () -option (COND_DECODER_LZMA2 "Enable lzma2 decoder" ON) -if (COND_DECODER_LZMA2) - set (HAVE_DECODER_LZMA2 1) -endif () -option (COND_FILTER_DELTA "Enable delta filter" ON) -if (COND_FILTER_DELTA) - set (HAVE_FILTER_DELTA 1) -endif () -option (COND_ENCODER_SIMPLE "Enable delta encoder" ON) -if (COND_MAIN_ENCODER) - set (HAVE_MAIN_ENCODER 1) -endif () -option (COND_DECODER_DELTA "Enable delta decoder" ON) -if (COND_MAIN_ENCODER) - set (HAVE_MAIN_ENCODER 1) -endif () -option (COND_FILTER_SIMPLE "Enable simple filter" ON) -if (COND_FILTER_SIMPLE) - set (HAVE_FILTER_SIMPLE 1) -endif () -option (COND_ENCODER_SIMPLE "Enable simple encoder" ON) -if (COND_ENCODER_SIMPLE) - set (HAVE_ENCODER_SIMPLE 1) -endif () -option (COND_DECODER_SIMPLE "Enable simple decoder" ON) -if (COND_DECODER_SIMPLE) - set (HAVE_DECODER_SIMPLE 1) -endif () +HDF5_SUPPORT(TRUE) +message(STATUS "H5ZFP link libs: ${H5PL_LINK_LIBS}") #----------------------------------------------------------------------------- -# HDF5 support +# ZFP compression library handling #----------------------------------------------------------------------------- -HDF5_SUPPORT (TRUE) -message (STATUS "H5ZFP link libs: ${H5PL_LINK_LIBS}") +include(ExternalProject) +include(FetchContent) +option(H5PL_ALLOW_EXTERNAL_SUPPORT "Allow External Library Building (NO GIT TGZ)" "NO") +set(H5PL_ALLOW_EXTERNAL_SUPPORT "NO" CACHE STRING "Allow External Library Building (NO GIT TGZ)") +set_property(CACHE H5PL_ALLOW_EXTERNAL_SUPPORT PROPERTY STRINGS NO GIT TGZ) -include (ExternalProject) -option (H5PL_ALLOW_EXTERNAL_SUPPORT "Allow External Library Building (NO GIT TGZ)" "NO") -set (H5PL_ALLOW_EXTERNAL_SUPPORT "NO" CACHE STRING "Allow External Library Building (NO GIT TGZ)") -set_property (CACHE H5PL_ALLOW_EXTERNAL_SUPPORT PROPERTY STRINGS NO GIT TGZ) if (H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") - option (ZFP_USE_EXTERNAL "Use External Library Building for ZFP" 1) + option(ZFP_USE_EXTERNAL "Use External Library Building for ZFP" 1) if (H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT") - set (ZFP_URL ${ZFP_GIT_URL} CACHE STRING "Path to zfp git repository") - set (ZFP_BRANCH ${ZFP_GIT_BRANCH}) + set(ZFP_URL ${ZFP_GIT_URL} CACHE STRING "Path to zfp git repository") + set(ZFP_BRANCH ${ZFP_GIT_BRANCH}) elseif (H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") if (NOT H5PL_COMP_TGZPATH) - set (H5PL_COMP_TGZPATH ${H5ZFP_SOURCE_DIR}) + set(H5PL_COMP_TGZPATH ${H5ZFP_SOURCE_DIR}) endif () - set (ZFP_URL ${H5PL_COMP_TGZPATH}/${ZFP_TGZ_NAME}) + set(ZFP_URL ${H5PL_COMP_TGZPATH}/${ZFP_TGZ_NAME}) else () - set (ZFP_USE_EXTERNAL 0) + set(ZFP_USE_EXTERNAL 0) endif () endif () #----------------------------------------------------------------------------- -# zfp Library Settings +# Find or build ZFP compression library (not the filter) #----------------------------------------------------------------------------- if (NOT ZFP_USE_EXTERNAL) - find_package (ZFP NAMES ${ZFP_PACKAGE_NAME}) + find_package(ZFP NAMES ${ZFP_PACKAGE_NAME}) if (NOT ZFP_FOUND) - find_package (ZFP) # Legacy find - if (ZFP_FOUND) - set (H5PL_LINK_LIBS ${H5PL_LINK_LIBS} ${ZFP_LIBRARIES}) - endif () + find_package(ZFP) # Legacy find endif () endif () + if (ZFP_FOUND) - set (H5_HAVE_ZFP_H 1) - set (H5_HAVE_ZFP 1) - set (H5_ZFP_HEADER "zfp.h") - set (ZFP_INCLUDE_DIR_GEN ${ZFP_INCLUDE_DIR}) - set (ZFP_INCLUDE_DIRS ${ZFP_INCLUDE_DIR}) + set(H5_HAVE_ZFP_H 1) + set(H5_HAVE_ZFP 1) + set(H5_ZFP_HEADER "zfp.h") + set(ZFP_INCLUDE_DIR_GEN ${ZFP_INCLUDE_DIR}) + set(ZFP_INCLUDE_DIRS ${ZFP_INCLUDE_DIR}) + message(STATUS "Found ZFP library: ${ZFP_LIBRARIES}") + + # Create zfp::zfp target if legacy installation doesn't provide it + # H5Z-ZFP requires the modern imported target + if (NOT TARGET zfp::zfp) + add_library(zfp::zfp INTERFACE IMPORTED) + target_link_libraries(zfp::zfp INTERFACE ${ZFP_LIBRARIES}) + target_include_directories(zfp::zfp INTERFACE ${ZFP_INCLUDE_DIRS}) + message(STATUS "Created zfp::zfp imported target for legacy ZFP installation") + endif () else () if (H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR H5PL_ALLOW_EXTERNAL_SUPPORT MATCHES "TGZ") - EXTERNAL_ZFP_LIBRARY (${H5PL_ALLOW_EXTERNAL_SUPPORT}) - set (H5_HAVE_ZFP_H 1) - set (H5_HAVE_ZFP 1) - message (STATUS "Filter ZFP is built") + EXTERNAL_ZFP_LIBRARY(${H5PL_ALLOW_EXTERNAL_SUPPORT}) + set(H5_HAVE_ZFP_H 1) + set(H5_HAVE_ZFP 1) + set(ZFP_FOUND 1) + message(STATUS "ZFP library built from external source") + message(STATUS " ZFP_INCLUDE_DIRS: ${ZFP_INCLUDE_DIRS}") + message(STATUS " ZFP_LIBRARIES: ${ZFP_LIBRARIES}") else () - message (FATAL_ERROR " ZFP is Required for ${H5ZFP_PACKAGE_NAME} library") + message(FATAL_ERROR "ZFP library is required for ${H5ZFP_PACKAGE_NAME} filter plugin") endif () endif () -message (STATUS "zfp found: INC=${ZFP_INCLUDE_DIR} TOOLS=${ZFP_LIBRARIES}") -set (H5PL_LINK_LIBS ${H5PL_LINK_LIBS} ${ZFP_LIBRARIES}) + +set(H5PL_LINK_LIBS ${H5PL_LINK_LIBS} ${ZFP_LIBRARIES}) + +# Create zfp::zfp target if it doesn't exist +# H5Z-ZFP requires the modern namespaced target (lowercase namespace) +if (TARGET zfp AND NOT TARGET zfp::zfp) + # ZFP was built via FetchContent, create alias in the same scope + add_library(zfp::zfp ALIAS zfp) + message(STATUS "Created zfp::zfp alias for FetchContent-built ZFP") +endif () + +# Also create uppercase ZFP::zfp for compatibility with other code that may expect it +if (TARGET zfp AND NOT TARGET ZFP::zfp) + add_library(ZFP::zfp ALIAS zfp) + message(STATUS "Created ZFP::zfp alias for FetchContent-built ZFP") +endif () #----------------------------------------------------------------------------- -# Generate the zfp_config.h file containing user settings needed by compilation +# Add the upstream H5Z-ZFP filter source via subdirectory +# Note: H5Z-ZFP's CMakeLists.txt will build the filter plugin #----------------------------------------------------------------------------- -configure_file (${H5ZFP_RESOURCES_DIR}/config.h.in ${H5ZFP_BINARY_DIR}/zfp_config.h @ONLY) +message(STATUS "Building H5Z-ZFP filter from subtree") + +# H5Z-ZFP uses CMAKE_SOURCE_DIR which points to the top-level project +# We need to override paths it uses for add_subdirectory +# Set the source directory to H5Z-ZFP's location before adding it +set(H5Z_ZFP_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP") + +# We can't change CMAKE_SOURCE_DIR, but we can build the src/ directly +# Instead of using add_subdirectory(H5Z-ZFP), include its src build +# Set HDF5_INCLUDE_DIRS for H5Z-ZFP to use +if (NOT DEFINED HDF5_INCLUDE_DIRS) + set(HDF5_INCLUDE_DIRS ${H5PL_HDF5_INCLUDE_DIRS}) +endif () +if (NOT DEFINED HDF5_LIBRARIES) + set(HDF5_LIBRARIES ${H5PL_HDF5_LINK_LIBS}) +endif () + +add_subdirectory(H5Z-ZFP/src) + +# Copy the plugin to the global plugins directory for testing +# H5Z-ZFP builds to its own plugin/ dir, but tests expect plugins in build/plugins/ +# Use a custom target since add_custom_command(TARGET) only works in same directory +add_custom_target(copy_zfp_plugin ALL + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/plugins" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "${CMAKE_BINARY_DIR}/plugins/$" + DEPENDS h5z_zfp_shared + COMMENT "Copying ZFP plugin to ${CMAKE_BINARY_DIR}/plugins/" +) + +# Optionally build tests from H5Z-ZFP if requested +# Note: H5Z-ZFP upstream tests are disabled - they have compatibility issues +# with the ZFP library version macros. Use H5PL_BUILD_TESTING for HDF Group tests instead. +option(BUILD_TESTING "Build h5z-zfp Unit Testing" OFF) +if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/H5Z-ZFP/test") + message(STATUS "H5Z-ZFP upstream tests are disabled due to version macro compatibility issues") + message(STATUS "Use H5PL_BUILD_TESTING=ON for HDF Group tests instead") + # add_subdirectory(H5Z-ZFP/test) # Disabled - ZFP_LIB_VERSION macro issues +endif () + +#----------------------------------------------------------------------------- +# Create compatibility alias for old target name +#----------------------------------------------------------------------------- +# The old HDF Group build created a target named ${H5ZFP_LIB_TARGET} (h5zfp) +# H5Z-ZFP creates h5z_zfp_shared, so create an alias for compatibility +if (TARGET h5z_zfp_shared) + # Get the library corename from BASIC_SETTINGS + set(H5ZFP_LIB_CORENAME "h5zfp") + set(H5ZFP_LIB_TARGET ${H5ZFP_LIB_CORENAME}) + + # Create alias so parent build system can find it by the old name + add_library(${H5ZFP_LIB_TARGET} ALIAS h5z_zfp_shared) + + message(STATUS "Created alias: ${H5ZFP_LIB_TARGET} -> h5z_zfp_shared") +endif () + +#----------------------------------------------------------------------------- +# Export the library for parent build system +#----------------------------------------------------------------------------- +# Export the expected target name for the parent build system +set(H5ZFP_LIBRARIES_TO_EXPORT "${H5ZFP_LIB_TARGET}" CACHE STRING "H5ZFP libraries to export" FORCE) #----------------------------------------------------------------------------- # Dashboard and Testing Settings #----------------------------------------------------------------------------- -option (H5PL_BUILD_TESTING "Build h5zfp Unit Testing" OFF) +option(H5PL_BUILD_TESTING "Build h5zfp Unit Testing" OFF) if (H5PL_BUILD_TESTING) - set (DART_TESTING_TIMEOUT 1200 CACHE STRING + set(DART_TESTING_TIMEOUT 1200 CACHE STRING "Timeout in seconds for each test (default 1200=20minutes)") - enable_testing () - include (CTest) - include (${PROJECT_SOURCE_DIR}/CTestConfig.cmake) - configure_file (${${PLUGIN_PACKAGE_NAME}_RESOURCES_DIR}/CTestCustom.cmake ${PROJECT_BINARY_DIR}/CTestCustom.ctest @ONLY) + enable_testing() + include(CTest) + include(${PROJECT_SOURCE_DIR}/CTestConfig.cmake) + configure_file(${${PLUGIN_PACKAGE_NAME}_RESOURCES_DIR}/CTestCustom.cmake ${PROJECT_BINARY_DIR}/CTestCustom.ctest @ONLY) endif () -add_subdirectory (src) +#----------------------------------------------------------------------------- +# Add HDF Group examples +#----------------------------------------------------------------------------- +# Examples are needed for testing, so enable them if testing is enabled +if (H5PL_BUILD_TESTING AND NOT H5PL_BUILD_EXAMPLES) + set(H5PL_BUILD_EXAMPLES ON CACHE BOOL "Build h5zfp Examples (required for testing)" FORCE) + message(STATUS "Enabling H5PL_BUILD_EXAMPLES (required for H5PL_BUILD_TESTING)") +endif () -option (H5PL_BUILD_EXAMPLES "Build h5zfp Examples" OFF) +option(H5PL_BUILD_EXAMPLES "Build h5zfp Examples" OFF) if (H5PL_BUILD_EXAMPLES) - add_subdirectory (example) + add_subdirectory(example) endif () #----------------------------------------------------------------------------- # Add file(s) to CMake Install #----------------------------------------------------------------------------- -INSTALL_SUPPORT (H5ZFP) +INSTALL_SUPPORT(H5ZFP) diff --git a/ZFP/H5Z-ZFP/.github/codeql-config.yml b/ZFP/H5Z-ZFP/.github/codeql-config.yml new file mode 100644 index 00000000..333b78fb --- /dev/null +++ b/ZFP/H5Z-ZFP/.github/codeql-config.yml @@ -0,0 +1,11 @@ +query-filters: + - exclude: + # See: https://codeql.github.com/codeql-query-help/cpp/cpp-short-global-name/ + id: cpp/short-global-name + - exclude: + # See: https://codeql.github.com/codeql-query-help/cpp/cpp-guarded-free/ + id: cpp/guarded-free + - exclude: + # See: https://codeql.github.com/codeql-query-help/cpp/cpp-unused-static-function/ + id: cpp/unused-static-function + diff --git a/ZFP/H5Z-ZFP/.github/dependabot.yml b/ZFP/H5Z-ZFP/.github/dependabot.yml new file mode 100644 index 00000000..a0ff3f4c --- /dev/null +++ b/ZFP/H5Z-ZFP/.github/dependabot.yml @@ -0,0 +1,29 @@ +# Dependabot configuration for automatic dependency updates +# This will automatically create pull requests to update GitHub Actions to their latest versions +# See: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every week + interval: "weekly" + day: "monday" + time: "09:00" + # Automatically merge minor and patch updates + open-pull-requests-limit: 10 + # Add labels to PRs + labels: + - "dependencies" + - "github-actions" + # Group all GitHub Actions updates into a single PR when possible + groups: + github-actions: + patterns: + - "*" + # Commit message prefix + commit-message: + prefix: "ci" + include: "scope" diff --git a/ZFP/H5Z-ZFP/.github/workflows/codeql.yml b/ZFP/H5Z-ZFP/.github/workflows/codeql.yml new file mode 100644 index 00000000..025cbf4c --- /dev/null +++ b/ZFP/H5Z-ZFP/.github/workflows/codeql.yml @@ -0,0 +1,148 @@ +name: "CodeQL Advanced" + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + schedule: + - cron: "16 7 * * 0" + +jobs: + analyze: + name: Analyze + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ubuntu-latest + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + strategy: + fail-fast: false + matrix: + include: + - language: c-cpp + build-mode: manual + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Install Dependencies (Linux) + run: | + sudo gem install apt-spy2 + sudo apt-spy2 check + sudo apt-spy2 fix --commit + sudo apt update + sudo apt upgrade + sudo apt-get install -qq libhdf5-dev + sudo apt-get install -qq hdf5-tools + echo "HDF5_HOME=/usr/include/hdf5/serial,/usr/lib/x86_64-linux-gnu/hdf5/serial,/usr/bin" >> $GITHUB_ENV + # Set env vars + echo "CC=gcc" >> $GITHUB_ENV + echo "FC=gfortran" >> $GITHUB_ENV + echo "CXX=g++" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v6 + +################################## +# INSTALL ZFP +################################## + + - name: install ZFP + run: | + git clone https://github.com/LLNL/zfp.git + export HOME_DIR=$(echo ~) + cd zfp + mkdir build;cd build + cmake -D ZFP_BIT_STREAM_WORD_SIZE=8 -D BUILD_CFP=ON -D CMAKE_INSTALL_PREFIX=$PWD/zfp -D BUILD_TESTING=OFF -D BUILD_UTILITIES=OFF .. + make install + echo "ZFP_HOME=$PWD/zfp" >> $GITHUB_ENV + echo "ZFP_DIR=$PWD/zfp" >> $GITHUB_ENV + shell: bash + +################################## +# BUILD AND TEST H5Z-ZFP +################################## + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: c-cpp + build-mode: manual + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: + #https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + + config: | + query-filters: + - exclude: + # See: https://codeql.github.com/codeql-query-help/cpp/cpp-guarded-free/ + id: cpp/guarded-free + - exclude: + # See: https://codeql.github.com/codeql-query-help/cpp/cpp-unused-static-function/ + id: cpp/unused-static-function + + queries: +security-extended,security-and-quality + + - name: configure h5z-zfp + run: | + mkdir build; cd build + cmake -D FORTRAN_INTERFACE=ON -D CMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON .. + shell: bash + + - name: build and test + run: | + cd build + cmake --build . + ctest -C Debug . + shell: bash + +# NOTE: C/C++ does not support path-based filtering when using the manual build mode. +# The "paths" and "paths-ignore" configuration properties will have no effect for this +# language. If desired, you can use the advanced-security/filter-sarif Action to rewrite +# the SARIF file to exclude alerts from these paths. For more information, +# see https://github.com/advanced-security/filter-sarif + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:c-cpp" + output: sarif-results + upload: failure-only + + - name: filter-sarif + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + -**/* + src/**/* + input: sarif-results/cpp.sarif + output: sarif-results/cpp.sarif + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: sarif-results/cpp.sarif + + - name: Upload loc as a Build Artifact + uses: actions/upload-artifact@v6 + with: + name: sarif-results + path: sarif-results + retention-days: 1 diff --git a/ZFP/H5Z-ZFP/.github/workflows/codespell.yml b/ZFP/H5Z-ZFP/.github/workflows/codespell.yml new file mode 100644 index 00000000..53b5d761 --- /dev/null +++ b/ZFP/H5Z-ZFP/.github/workflows/codespell.yml @@ -0,0 +1,14 @@ +# GitHub Action to automate the identification of common misspellings in text files +# https://github.com/codespell-project/codespell +# https://github.com/codespell-project/actions-codespell +name: codespell +on: [push, pull_request] +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: codespell-project/actions-codespell@v2 + with: + ignore_words_list: siz, textin diff --git a/ZFP/H5Z-ZFP/.github/workflows/main.yml b/ZFP/H5Z-ZFP/.github/workflows/main.yml new file mode 100644 index 00000000..e0393425 --- /dev/null +++ b/ZFP/H5Z-ZFP/.github/workflows/main.yml @@ -0,0 +1,235 @@ +name: h5z-zfp + +# Controls when the action will run. +#Triggers the workflow on push or pull requests. + +# TODO: REMOVE feat-cmake_tests before merging +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# Using concurrency to cancel any in-progress job or run +concurrency: + group: ${{ github.workflow }}-${{ github.sha || github.event.pull_request.number }} + cancel-in-progress: true + +# A workflow run is made up of one or more jobs that +# can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + linux-build: + strategy: + matrix: + name: ["Ubuntu Latest GCC"] + include: + - name: "Ubuntu Latest GCC" + artifact: "Linux.tar.xz" + os: ubuntu-latest + + name: ${{ matrix.name }} + # The type of runner that the job will run on. + runs-on: ${{ matrix.os }} + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + # Steps represent a sequence of tasks that will be executed + # as part of the job. + steps: + - name: Install Dependencies (Linux) + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -qq libhdf5-dev + sudo apt-get install -qq hdf5-tools + echo "HDF5_HOME=/usr/include/hdf5/serial,/usr/lib/x86_64-linux-gnu/hdf5/serial,/usr/bin" >> $GITHUB_ENV + # Set env vars + echo "CC=gcc" >> $GITHUB_ENV + echo "FC=gfortran" >> $GITHUB_ENV + echo "CXX=g++" >> $GITHUB_ENV + + # Checks-out the repository under $GITHUB_WORKSPACE so the job can access it. + - name: Get Sources + uses: actions/checkout@v6 + +################################## +# INSTALL ZFP +################################## + + - name: install ZFP + run: | + git clone https://github.com/LLNL/zfp.git + export HOME_DIR=$(echo ~) + cd zfp + git checkout 1.0.0 + mkdir build;cd build + cmake -D ZFP_BIT_STREAM_WORD_SIZE=8 -D BUILD_CFP=ON -D CMAKE_INSTALL_PREFIX=$PWD/zfp -D BUILD_TESTING=OFF -D BUILD_UTILITIES=OFF .. + make install + echo "ZFP_HOME=$PWD/zfp" >> $GITHUB_ENV + echo "ZFP_DIR=$PWD/zfp" >> $GITHUB_ENV + shell: bash + +################################## +# BUILD AND TEST H5Z-ZFP +################################## + + - name: build (autotools) and check + run: | + make all + make check + shell: bash + + - name: build (cmake) and test + run: | + mkdir build; cd build + cmake -D FORTRAN_INTERFACE=ON -D CMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON .. + sudo cmake --build . --target install + ctest -C Release . + shell: bash + + + linux-hdf5-versions: + strategy: + matrix: + hdf5_version: ["develop", "hdf5_1_14_3"] + include: + - hdf5_version: "develop" + hdf5_branch: "develop" + hdf5_name: "HDF5 develop" + - hdf5_version: "hdf5_1_14_3" + hdf5_branch: "hdf5-1_14_3" + hdf5_name: "HDF5 1.14.3" + + name: Ubuntu Latest GCC with ${{ matrix.hdf5_name }} + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, 'skip-ci')" + + steps: + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -qq cmake gfortran + # Set env vars + echo "CC=gcc" >> $GITHUB_ENV + echo "FC=gfortran" >> $GITHUB_ENV + echo "CXX=g++" >> $GITHUB_ENV + + - name: Get Sources + uses: actions/checkout@v6 + + - name: Build HDF5 from source + run: | + git clone --depth 1 --branch ${{ matrix.hdf5_branch }} https://github.com/HDFGroup/hdf5.git + cd hdf5 + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release \ + -DHDF5_BUILD_FORTRAN=ON \ + -DHDF5_BUILD_TOOLS=ON \ + -DHDF5_BUILD_EXAMPLES=OFF \ + -DHDF5_BUILD_HL_LIB=OFF \ + -DBUILD_TESTING=OFF \ + -DHDF5_BUILD_DOC=OFF \ + -DBUILD_SHARED_LIBS=ON \ + -DBUILD_STATIC_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX=$HOME/hdf5-install \ + .. + make -j$(nproc) + make install + echo "HDF5_ROOT=$HOME/hdf5-install" >> $GITHUB_ENV + echo "HDF5_DIR=$HOME/hdf5-install/share/cmake" >> $GITHUB_ENV + echo "$HOME/hdf5-install/bin" >> $GITHUB_PATH + shell: bash + + - name: Install ZFP + run: | + git clone https://github.com/LLNL/zfp.git + cd zfp + git checkout 1.0.0 + mkdir build + cd build + cmake -DZFP_BIT_STREAM_WORD_SIZE=8 \ + -DBUILD_CFP=ON \ + -DCMAKE_INSTALL_PREFIX=$HOME/zfp-install \ + -DBUILD_TESTING=OFF \ + -DBUILD_UTILITIES=OFF \ + .. + make -j$(nproc) + make install + echo "ZFP_HOME=$HOME/zfp-install" >> $GITHUB_ENV + echo "ZFP_DIR=$HOME/zfp-install" >> $GITHUB_ENV + shell: bash + + - name: Build H5Z-ZFP (CMake) and test + run: | + mkdir build + cd build + cmake -DFORTRAN_INTERFACE=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=ON \ + .. + make -j$(nproc) + ctest -C Release . --output-on-failure + shell: bash + + windows-build: + name: 'Windows MSVC/Clang' + defaults: + run: + shell: bash + runs-on: windows-2022 + steps: + - name: checkout repository + uses: actions/checkout@v6 + - name: install prerequisites + run: | + choco install \ + unzip \ + wget + - name: setup MSVC Tools + uses: ilammy/msvc-dev-cmd@v1 + - name: download HDF5 for Windows + run: | + wget --quiet \ + https://support.hdfgroup.org/releases/hdf5/v1_14/v1_14_5/downloads/hdf5-1.14.5-win-vs2022_cl.msi + - name: Install HDF5 for Windows + run: msiexec /i "hdf5-1.14.5-win-vs2022_cl.msi" /qn + shell: cmd + - name: Download and install ZFP + run: | + git clone https://github.com/LLNL/zfp.git + cd zfp + git checkout 1.0.0 + mkdir -p build + cd build + cmake .. \ + -G "Visual Studio 17 2022" -A "x64" \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DBUILD_UTILITIES=OFF \ + -DBUILD_TESTING=OFF \ + -DBUILD_CFP=ON \ + -DZFP_BIT_STREAM_WORD_SIZE=8 + cmake --build . --config Release -j 3 + cmake --build . --config Release --target install + - name: Set build and test variables + run: | + echo "C:/Program Files/H5Z_ZFP/plugin" >> $GITHUB_PATH + echo "C:/Program Files/ZFP/bin" >> $GITHUB_PATH + echo "C:/Program Files/ZFP/lib" >> $GITHUB_PATH + echo "C:/Program Files/HDF_Group/HDF5/1.14.5/bin" >> $GITHUB_PATH + echo "HDF5_PLUGIN_PATH=C:/Program Files/H5Z_ZFP/plugin" >> $GITHUB_ENV + echo "HDF5_DIR=C:/Program Files/HDF_Group/HDF5/1.14.5" >> $GITHUB_ENV + echo "HDF5_ROOT=C:/Program Files/HDF_Group/HDF5/1.14.5" >> $GITHUB_ENV + echo "ZFP_DIR=C:/Program Files/ZFP" >> $GITHUB_ENV + - name: Build H5Z-ZFP (CMake) and test + run: | + mkdir build + cd build + cmake .. \ + -G "Visual Studio 17 2022" -A "x64" \ + -DCMAKE_CONFIGURATION_TYPES=Release \ + -DBUILD_TESTING=ON \ + -DFORTRAN_INTERFACE=OFF \ + -TClangCL + cmake --build . --config Release --target install + ctest -C Release . diff --git a/ZFP/H5Z-ZFP/.gitignore b/ZFP/H5Z-ZFP/.gitignore new file mode 100644 index 00000000..f805e810 --- /dev/null +++ b/ZFP/H5Z-ZFP/.gitignore @@ -0,0 +1,33 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su diff --git a/ZFP/H5Z-ZFP/.readthedocs.yaml b/ZFP/H5Z-ZFP/.readthedocs.yaml new file mode 100644 index 00000000..9712e405 --- /dev/null +++ b/ZFP/H5Z-ZFP/.readthedocs.yaml @@ -0,0 +1,22 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# We recommend specifying your dependencies to enable reproducible builds: +# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt diff --git a/ZFP/H5Z-ZFP/.travis.yml b/ZFP/H5Z-ZFP/.travis.yml new file mode 100644 index 00000000..8e8441a1 --- /dev/null +++ b/ZFP/H5Z-ZFP/.travis.yml @@ -0,0 +1,38 @@ +language: C + + +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y gfortran + - pwd + - ls + - pushd /tmp + - wget https://github.com/LLNL/zfp/releases/download/0.5.5/zfp-0.5.5.tar.gz + - tar -xzf zfp-0.5.5.tar.gz + - pushd zfp-0.5.5 + - make DEFS=-DBIT_STREAM_WORD_TYPE=uint8 + - popd + - wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-1.8.14/src/hdf5-1.8.14.tar.gz + - tar -xzf hdf5-1.8.14.tar.gz + - pushd hdf5-1.8.14 + - patch ./tools/h5repack/h5repack_parse.c /home/travis/build/LLNL/H5Z-ZFP/test/h5repack_parse.patch + - ./configure --prefix=`pwd`/my_install --enable-production --enable-fortran --enable-fortran2003 --enable-silent-rules + - make -j4 install 1>/dev/null 2>&1 + - popd + - popd + +install: true + +script: + - make FCFLAGS="-O0 -fPIC --coverage -fprofile-arcs -ftest-coverage" \ + CFLAGS="-O0 -fPIC --coverage" \ + LDFLAGS="--coverage -lm" \ + FC=gfortran CC=gcc \ + ZFP_HOME=/tmp/zfp-0.5.5 \ + HDF5_HOME=/tmp/hdf5-1.8.14/my_install check + - pushd src; gcov -a H5Zzfp_lib H5Zzfp_plugin H5Zzfp_props; popd + - pushd test; gcov -a test_read_lib test_write_lib test_write_plugin; popd + +after_success: + - bash <(curl -s https://codecov.io/bash) + diff --git a/ZFP/H5Z-ZFP/CMakeLists.txt b/ZFP/H5Z-ZFP/CMakeLists.txt new file mode 100644 index 00000000..acd989d5 --- /dev/null +++ b/ZFP/H5Z-ZFP/CMakeLists.txt @@ -0,0 +1,112 @@ +cmake_minimum_required(VERSION 3.10) + +# Fail immediately if not using an out-of-source build +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + message(FATAL_ERROR + "In-source builds are not supported. Please create a build directory " + "separate from the source directory") +endif () + +if (POLICY CMP0074) + # find_package() uses _ROOT variables. + cmake_policy (SET CMP0074 NEW) +endif () + +if (POLICY CMP0083) + # To control generation of Position Independent Executable (PIE) or not, + # some flags are required at link time. + cmake_policy (SET CMP0083 NEW) +endif () + +# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) +endif() + +get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + +#------------------------------------------------------------------------------# +# Parse version number from H5Zzfp_version.h +#------------------------------------------------------------------------------# +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_MAJOR") +string(REGEX REPLACE "^.*MAJOR " "" H5Z_ZFP_VERSION_MAJOR "${H5Z_ZFP_H}") +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_MINOR") +string(REGEX REPLACE "^.*MINOR " "" H5Z_ZFP_VERSION_MINOR "${H5Z_ZFP_H}") +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/src/H5Zzfp_version.h" H5Z_ZFP_H REGEX "^\#define H5Z_FILTER_ZFP_VERSION_PATCH") +string(REGEX REPLACE "^.*PATCH " "" H5Z_ZFP_VERSION_PATCH "${H5Z_ZFP_H}") +set(H5Z_ZFP_VERSION "${H5Z_ZFP_VERSION_MAJOR}.${H5Z_ZFP_VERSION_MINOR}.${H5Z_ZFP_VERSION_PATCH}") + +project(H5Z_ZFP VERSION ${H5Z_ZFP_VERSION} LANGUAGES C) + +# setup common output folders +include (cmake/HDFMacros.cmake) +SET_HDF_BUILD_TYPE() +DEFAULT_FOLDERS() + +#------------------------------------------------------------------------------# +# Compile options. +#------------------------------------------------------------------------------# +option(FORTRAN_INTERFACE "Enable the Fortran interface" ON) +if (FORTRAN_INTERFACE) + enable_language(Fortran) +endif () +#------------------------------------------------------------------------------# +# Some boilerplate to setup nice output directories +#------------------------------------------------------------------------------# +set(CMAKE_INSTALL_BINDIR bin) +set(CMAKE_INSTALL_LIBDIR lib) +set(CMAKE_INSTALL_INCLUDEDIR include) +set(CMAKE_INSTALL_CMAKEDIR lib/cmake/h5z_zfp) + +#------------------------------------------------------------------------------# +# Required packages +#------------------------------------------------------------------------------# +# Find HDF5, relies on HDF5_DIR or HDF5_ROOT being set in environment. +HDF5_SUPPORT () +if (NOT HDF5_FOUND) + message (FATAL_ERROR "HDF5 is Required for h5z_zfp") +endif () + +# Find MPI depending on if HDF5 needs MPI. +if ((HDF5_IS_PARALLEL OR HDF5_ENABLE_PARALLEL) AND ("${HDF5_VERSION}" VERSION_EQUAL "1.14.0")) + find_package(MPI REQUIRED COMPONENTS C) +endif() + +# Find ZFP, relies on ZFP_DIR or ZFP_ROOT being set in environment. +find_package(ZFP REQUIRED CONFIG) +if (NOT ZFP_FOUND) + message (FATAL_ERROR "ZFP is Required for h5z_zfp") +endif () + +#------------------------------------------------------------------------------# +# Add source +#------------------------------------------------------------------------------# +add_subdirectory(${CMAKE_SOURCE_DIR}/src) + +#----------------------------------------------------------------------------- +# Dashboard and Testing Settings +#----------------------------------------------------------------------------- +option (BUILD_TESTING "Build h5z-zfp Unit Testing" OFF) +if (BUILD_TESTING) + set (DART_TESTING_TIMEOUT 1200 CACHE STRING + "Timeout in seconds for each test (default 1200=20minutes)") + enable_testing () + include (CTest) + + add_subdirectory(${CMAKE_SOURCE_DIR}/test) +endif () + +#------------------------------------------------------------------------------# +# Packaging +#------------------------------------------------------------------------------# +# Install h5z_zfp-config.cmake and h5z_zfp-config-version.cmake +set(H5Z_ZFP_CONFIG_IN ${CMAKE_CURRENT_SOURCE_DIR}/cmake/h5z_zfp-config.cmake.in) +set(H5Z_ZFP_CONFIG_OUT ${CMAKE_CURRENT_BINARY_DIR}/cmake/h5z_zfp-config.cmake) +configure_file(${H5Z_ZFP_CONFIG_IN} ${H5Z_ZFP_CONFIG_OUT} @ONLY) +set(H5Z_ZFP_CONFIG_VERSION_IN ${CMAKE_CURRENT_SOURCE_DIR}/cmake/h5z_zfp-config-version.cmake.in) +set(H5Z_ZFP_CONFIG_VERSION_OUT ${CMAKE_CURRENT_BINARY_DIR}/cmake/h5z_zfp-config-version.cmake) +configure_file(${H5Z_ZFP_CONFIG_VERSION_IN} ${H5Z_ZFP_CONFIG_VERSION_OUT} @ONLY) +install(FILES ${H5Z_ZFP_CONFIG_OUT} + DESTINATION ${CMAKE_INSTALL_CMAKEDIR}) +install(FILES ${H5Z_ZFP_CONFIG_VERSION_OUT} + DESTINATION ${CMAKE_INSTALL_CMAKEDIR}) diff --git a/ZFP/Additional_Legal/LICENSE b/ZFP/H5Z-ZFP/LICENSE similarity index 100% rename from ZFP/Additional_Legal/LICENSE rename to ZFP/H5Z-ZFP/LICENSE diff --git a/ZFP/H5Z-ZFP/Makefile b/ZFP/H5Z-ZFP/Makefile new file mode 100644 index 00000000..a29bb266 --- /dev/null +++ b/ZFP/H5Z-ZFP/Makefile @@ -0,0 +1,65 @@ +# Include config.make only if we're not looking for help +ifeq ($(findstring help, $(strip $(MAKECMDGOALS))),) + ifeq ($(findstring tools, $(strip $(MAKECMDGOALS))),) + ifeq ($(findstring clean, $(strip $(MAKECMDGOALS))),) + ifeq ($(findstring dist, $(strip $(MAKECMDGOALS))),) + include config.make + endif + endif + endif +endif + +# Get version string from H5Z-ZFP +H5Z_ZFP_VERSINFO := $(shell grep '^\#define H5Z_FILTER_ZFP_VERSION_[MP]' src/H5Zzfp_version.h | cut -d' ' -f3 | tr '\n' '.' | cut -d'.' -f-3 2>/dev/null) + +.PHONY: help all clean dist install + +help: + @echo "" + @echo "" + @echo "" + @echo " This is H5Z-ZFP version $(H5Z_ZFP_VERSINFO)." + @echo "See http://h5z-zfp.readthedocs.io/en/latest/ file for more info." + @echo "" + @echo "Typical make command is..." + @echo "" + @echo " make CC= HDF5_HOME= ZFP_HOME= PREFIX= all" + @echo "" + @echo "where is a dir whose children are include/lib/bin subdirs." + @echo "HDF5_HOME can also be set using an INC,LIB,BIN triplet specifying" + @echo "HDF5 include, library and binary dirs separated by commas." + @echo "Standard make variables (e.g. CFLAGS, LD, etc.) can be set as usual." + @echo "Optionally, add FC= to include Fortran support and tests." + @echo "" + @echo "Available make targets are..." + @echo " all - build everything needed for H5Z-ZFP plugin/lib" + @echo " check - all + run tests" + @echo " tools - build tools (currently just print_h5repack_farg)" + @echo " install - install plugin/lib" + @echo " clean - clean away all derived targets" + @echo " dist - create distribution tarfile" + @echo " help - this help message" + +all: + cd src; $(MAKE) $(MAKEVARS) $@ + +check: all + cd test; $(MAKE) $(MAKEVARS) $@ + +tools: + cd test; $(MAKE) $(MAKEVARS) print_h5repack_farg + +install: all + cd src; $(MAKE) $(MAKEVARS) $@ + +clean: + rm -f H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz + cd src; $(MAKE) $(MAKEVARS) $@ + cd test; $(MAKE) $(MAKEVARS) $@ + +dist: clean + rm -rf H5Z-ZFP-$(H5Z_ZFP_VERSINFO) H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz; \ + mkdir H5Z-ZFP-$(H5Z_ZFP_VERSINFO); \ + tar cf - --exclude ".git*" --exclude H5Z-ZFP-$(H5Z_ZFP_VERSINFO) . | tar xf - -C H5Z-ZFP-$(H5Z_ZFP_VERSINFO); \ + tar cvf - H5Z-ZFP-$(H5Z_ZFP_VERSINFO) | gzip --best > H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz; \ + rm -rf H5Z-ZFP-$(H5Z_ZFP_VERSINFO); diff --git a/ZFP/H5Z-ZFP/README.md b/ZFP/H5Z-ZFP/README.md new file mode 100644 index 00000000..7cd68b7b --- /dev/null +++ b/ZFP/H5Z-ZFP/README.md @@ -0,0 +1,38 @@ +# H5Z-ZFP + +A highly flexible floating point and integer +compression plugin for the HDF5 library using ZFP compression. + +[![Build Status](https://travis-ci.com/LLNL/H5Z-ZFP.svg?branch=master)](https://travis-ci.com/LLNL/H5Z-ZFP) +[![Documentation Status](https://readthedocs.org/projects/h5z-zfp/badge/?version=latest)](http://h5z-zfp.readthedocs.io) +[![codecov](https://codecov.io/gh/LLNL/H5Z-ZFP/branch/master/graph/badge.svg)](https://codecov.io/gh/LLNL/H5Z-ZFP) + +For information about ZFP compression and the BSD-Licensed ZFP +library, see... + +- https://computing.llnl.gov/projects/zfp +- https://github.com/LLNL/zfp + +For information about HDF5 filter plugins, see... + +- https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters + +This H5Z-ZFP plugin supports ZFP versions 0.5.0 and newer. + +This plugin uses the [*registered*](https://portal.hdfgroup.org/documentation/hdf5-docs/registered_filter_plugins.html) +HDF5 plugin filter id 32013 + +The HDF5 filter plugin code here is also part of the Silo library. +However, we have made an effort to also support it as a stand-alone +package due to the likely broad appeal and utility of the ZFP +compression library. + +This plugin supports all modes of the ZFP compression library, *rate*, +*accuracy*, *precision*, *expert* and *reversible*. It supports 1, 2, 3 and +4 dimensional datasets (for ZFP version 0.5.5 and newer) of single and double +precision integer and floating point data. It can be applied to HDF5 datasets +of more than 3 dimensions (or 4 dimensions for ZFP versions 0.5.5 and newer) +as long as no more than 3 (or 4) dimensions of the HDF5 dataset *chunking* are +of size greater than 1. + +[**Full documentation**](http://h5z-zfp.readthedocs.io) diff --git a/ZFP/H5Z-ZFP/cmake/HDFMacros.cmake b/ZFP/H5Z-ZFP/cmake/HDFMacros.cmake new file mode 100644 index 00000000..e80c325b --- /dev/null +++ b/ZFP/H5Z-ZFP/cmake/HDFMacros.cmake @@ -0,0 +1,285 @@ +#------------------------------------------------------------------------------- +macro (DEFAULT_FOLDERS) + #----------------------------------------------------------------------------- + # Setup output Directories + #----------------------------------------------------------------------------- + if (NOT ${H5ZZFP_PACKAGE_NAME}_EXTERNALLY_CONFIGURED) + set (CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all Executables." + ) + set (CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all Libraries" + ) + set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all static libraries." + ) + set (CMAKE_Fortran_MODULE_DIRECTORY + ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all fortran modules." + ) + if(_isMultiConfig) + set (CMAKE_TEST_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}) + set (CMAKE_PDB_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/bin CACHE PATH "Single Directory for all pdb files." + ) + else () + set (CMAKE_TEST_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + endif () + else () + # if we are externally configured, but the project uses old cmake scripts + # this may not be set + if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) + endif () + endif () +endmacro () + +#------------------------------------------------------------------------------- +macro (HDF5_SUPPORT) + if (NOT H5Z-ZFP_HDF5_HEADER) + set (FIND_HDF_COMPONENTS C shared) + message(STATUS "HDF5 FORTRAN_INTERFACE ${FORTRAN_INTERFACE}" ) + if (FORTRAN_INTERFACE) + set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} Fortran) + endif () + message (STATUS "HDF5 find comps: ${FIND_HDF_COMPONENTS}") + set (SEARCH_PACKAGE_NAME "HDF5") + + find_package (HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS}) + if (HDF5_shared_C_FOUND) + set(_HDF5_SHARED_C_STATUS "1") + else() + set(_HDF5_SHARED_C_STATUS "0") + endif() + message (STATUS "HDF5 C libs: shared: ${_HDF5_SHARED_C_STATUS}") + if (FORTRAN_INTERFACE) + if (HDF5_shared_Fortran_FOUND) + set(_HDF5_SHARED_FORTRAN_STATUS "1") + else() + set(_HDF5_SHARED_FORTRAN_STATUS "0") + endif() + message (STATUS "HDF5 Fortran libs: shared: ${_HDF5_SHARED_FORTRAN_STATUS}") + endif() + if (HDF5_FOUND) + if (HDF5_shared_C_FOUND) + # Determine which tool naming convention to use by checking if targets exist + # Newer HDF5 (develop, 1.14.5+) uses h5dump, h5diff, h5repack (without -shared suffix) + # Older HDF5 versions used h5dump-shared, h5diff-shared, h5repack-shared + + if (TARGET ${HDF5_NAMESPACE}h5dump-shared) + set (HDF5_DUMP_EXECUTABLE $) + set (_HDF5_TOOL_SUFFIX "-shared") + elseif (TARGET ${HDF5_NAMESPACE}h5dump) + set (HDF5_DUMP_EXECUTABLE $) + set (_HDF5_TOOL_SUFFIX "") + else () + # No target exists, create imported target and set its location + # Prefer h5dump-shared for older HDF5, but will set actual path later + add_executable (${HDF5_NAMESPACE}h5dump-shared IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5dump-shared PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5dump-shared") + set (HDF5_DUMP_EXECUTABLE $) + set (_HDF5_TOOL_SUFFIX "-shared") + endif () + + if (TARGET ${HDF5_NAMESPACE}h5diff-shared) + set (HDF5_DIFF_EXECUTABLE $) + elseif (TARGET ${HDF5_NAMESPACE}h5diff) + set (HDF5_DIFF_EXECUTABLE $) + else () + # No target exists, create imported target and set its location + add_executable (${HDF5_NAMESPACE}h5diff-shared IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5diff-shared PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5diff-shared") + set (HDF5_DIFF_EXECUTABLE $) + endif () + + if (TARGET ${HDF5_NAMESPACE}h5repack-shared) + set (HDF5_REPACK_EXECUTABLE $) + elseif (TARGET ${HDF5_NAMESPACE}h5repack) + set (HDF5_REPACK_EXECUTABLE $) + else () + # No target exists, create imported target and set its location + add_executable (${HDF5_NAMESPACE}h5repack-shared IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5repack-shared PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5repack-shared") + set (HDF5_REPACK_EXECUTABLE $) + endif () + + message (STATUS "HDF5 Tools configured (h5dump${_HDF5_TOOL_SUFFIX}, h5diff${_HDF5_TOOL_SUFFIX}, h5repack${_HDF5_TOOL_SUFFIX})") + else () + if (NOT TARGET ${HDF5_NAMESPACE}h5dump) + add_executable (${HDF5_NAMESPACE}h5dump IMPORTED) + endif () + set (HDF5_DUMP_EXECUTABLE $) + + if (NOT TARGET ${HDF5_NAMESPACE}h5diff) + add_executable (${HDF5_NAMESPACE}h5diff IMPORTED) + endif () + set (HDF5_DIFF_EXECUTABLE $) + + if (NOT TARGET ${HDF5_NAMESPACE}h5repack) + add_executable (${HDF5_NAMESPACE}h5repack IMPORTED) + endif () + set (HDF5_REPACK_EXECUTABLE $) + message (STATUS "HDF5 static Tools found - ${HDF5_DUMP_EXECUTABLE}") + endif() + + if (NOT HDF5_static_C_FOUND AND NOT HDF5_shared_C_FOUND) + #find library from non-dual-binary package + set (FIND_HDF_COMPONENTS C) + if (FORTRAN_INTERFACE) + set (FIND_HDF_COMPONENTS ${FIND_HDF_COMPONENTS} Fortran) + endif () + message (STATUS "HDF5 find comps: ${FIND_HDF_COMPONENTS}") + + find_package (HDF5 NAMES ${SEARCH_PACKAGE_NAME} COMPONENTS ${FIND_HDF_COMPONENTS}) + message (STATUS "HDF5 libs:${HDF5_FOUND} C:${HDF5_C_FOUND} Fortran:${HDF5_Fortran_FOUND}") + if (HDF5_BUILD_SHARED_LIBS) + add_definitions (-DH5_BUILT_AS_DYNAMIC_LIB) + else () + add_definitions (-DH5_BUILT_AS_STATIC_LIB) + endif () + if (FORTRAN_INTERFACE AND HDF5_BUILD_FORTRAN) + if (HDF5_shared_Fortran_FOUND) + set (HDF5_FORTRAN_INCLUDE_DIRS ${HDF5_INCLUDE_DIR_FORTRAN}) + set (HDF5_FORTRAN_LIBRARIES ${HDF5_FORTRAN_SHARED_LIBRARY}) + else () + set (FORTRAN_INTERFACE OFF CACHE BOOL "Build FORTRAN support" FORCE) + message (STATUS "HDF5 Fortran libs not found - disable build of Fortran support") + endif () + endif () + if (WIN32) + set_property (TARGET ${HDF5_NAMESPACE}h5dump PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5dumpdll") + set_property (TARGET ${HDF5_NAMESPACE}h5diff PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5diffdll") + set_property (TARGET ${HDF5_NAMESPACE}h5repack PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5repackdll") + endif () + set (HDF5_DUMP_EXECUTABLE $) + set (HDF5_DIFF_EXECUTABLE $) + set (HDF5_REPACK_EXECUTABLE $) + message (STATUS "HDF5 windows Tools found - ${HDF5_DUMP_EXECUTABLE}") + else () + if (HDF5_shared_C_FOUND) + set (HDF5_LIBRARIES ${HDF5_C_SHARED_LIBRARY}) + set (HDF5_LIBRARY_PATH ${PACKAGE_PREFIX_DIR}/lib) + else () + set (HDF5_FOUND 0) + endif () + if (FORTRAN_INTERFACE AND HDF5_BUILD_FORTRAN) + if (HDF5_shared_Fortran_FOUND) + set (HDF5_FORTRAN_INCLUDE_DIRS ${HDF5_INCLUDE_DIR_FORTRAN}) + set (HDF5_FORTRAN_LIBRARIES ${HDF5_FORTRAN_SHARED_LIBRARY}) + else () + set (FORTRAN_INTERFACE OFF CACHE BOOL "Build FORTRAN support" FORCE) + message (STATUS "HDF5 Fortran libs not found - disable build of Fortran support") + endif () + else () + set (FORTRAN_INTERFACE OFF CACHE BOOL "Build FORTRAN support" FORCE) + message (STATUS "HDF5 Fortran libs not found - disable build of Fortran support") + endif () + message (STATUS "HDF5 Tools imported location - ${HDF5_TOOLS_DIR}") + endif () + else () + if (FORTRAN_INTERFACE) + set(FORTRAN_COMP "Fortran") + endif() + find_package (HDF5 COMPONENTS ${FORTRAN_COMP}) # Legacy find + if (FORTRAN_INTERFACE AND NOT HDF5_Fortran_FOUND) + set (FORTRAN_INTERFACE OFF CACHE BOOL "Build FORTRAN support" FORCE) + message (STATUS "HDF5 Fortran libs not found - disable build of Fortran support") + endif () + #Legacy find_package does not set HDF5_TOOLS_DIR, so we set it here + get_filename_component(HDF5_BIN_DIR ${HDF5_DIFF_EXECUTABLE} DIRECTORY) + set(HDF5_TOOLS_DIR ${HDF5_BIN_DIR}) + if (NOT TARGET hdf5::h5dump) + add_executable (${HDF5_NAMESPACE}h5dump IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5dump PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5dump") + set (HDF5_DUMP_EXECUTABLE $) + endif () + + if (NOT TARGET hdf5::h5diff) + add_executable (${HDF5_NAMESPACE}h5diff IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5diff PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5diff") + set (HDF5_DIFF_EXECUTABLE $) + endif () + + if (NOT TARGET hdf5::h5repack) + add_executable (${HDF5_NAMESPACE}h5repack IMPORTED) + set_property (TARGET ${HDF5_NAMESPACE}h5repack PROPERTY IMPORTED_LOCATION "${HDF5_TOOLS_DIR}/h5repack") + set (HDF5_REPACK_EXECUTABLE $) + endif () + message (STATUS "HDF5 legacy Tools found - ${HDF5_DUMP_EXECUTABLE}") + endif () + + set (HDF5_PACKAGE_NAME ${SEARCH_PACKAGE_NAME}) + + if (HDF5_FOUND) + set (HDF5_HAVE_H5PUBCONF_H 1) + set (HDF5_HAVE_HDF5 1) + set (H5Z-ZFP_HDF5_HEADER "h5pubconf.h") + set (HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) + message (STATUS "HDF5-${HDF5_VERSION_STRING} found: INC=${HDF5_INCLUDE_DIR} TOOLS=${HDF5_TOOLS_DIR}") + else () + message (FATAL_ERROR " HDF5 shared is required for H5Z-ZFP") + endif () + else () + # This project is being called from within another and HDF5 is already configured + set (HDF5_HAVE_H5PUBCONF_H 1) + set (HDF5_HAVE_HDF5 1) + set (HDF5_LIBRARIES ${HDF5_LINK_LIBS}) + set (HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) + endif () + set (HDF5_LIBRARY_PATH ${PACKAGE_PREFIX_DIR}/lib) + if (FORTRAN_INTERFACE) + message (STATUS "HDF5 Fortran libs: include:${HDF5_FORTRAN_INCLUDE_DIRS} and shared:${HDF5_FORTRAN_LIBRARIES}") + endif () + message (STATUS "HDF5 link libs: ${HDF5_LIBRARIES} Includes: ${HDF5_INCLUDE_DIRS}") +endmacro () + +#------------------------------------------------------------------------------- +macro (SET_HDF_BUILD_TYPE) + if (_isMultiConfig) + # HDF_CFG_BUILD_TYPE is used in the Fortran install commands for the build location of the .mod files + set (HDF_CFG_BUILD_TYPE \${CMAKE_INSTALL_CONFIG_NAME}) + if (CMAKE_BUILD_TYPE) + # set the default to the specified command line define + set (HDF_CFG_NAME ${CMAKE_BUILD_TYPE}) + else () + # set the default to the MultiConfig variable + set (HDF_CFG_NAME "$") + endif () + else () + set (HDF_CFG_BUILD_TYPE ".") + if (CMAKE_BUILD_TYPE) + set (HDF_CFG_NAME ${CMAKE_BUILD_TYPE}) + else () + set (HDF_CFG_NAME "Release") + endif () + endif () + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "Setting build type to 'RelWithDebInfo' as none was specified.") + endif() + set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" + "MinSizeRel" "RelWithDebInfo") + endif() +endmacro () + +#------------------------------------------------------------------------------- +macro (TARGET_C_PROPERTIES wintarget libtype) + target_compile_options(${wintarget} PRIVATE + "$<$:${WIN_COMPILE_FLAGS}>" + "$<$:${WIN_COMPILE_FLAGS}>" + ) + if(MSVC) + set_property(TARGET ${wintarget} APPEND PROPERTY LINK_FLAGS "${WIN_LINK_FLAGS}") + endif() +endmacro () + +macro (HDFTEST_COPY_FILE src dest target) + add_custom_command( + OUTPUT "${dest}" + COMMAND "${CMAKE_COMMAND}" + ARGS -E copy_if_different "${src}" "${dest}" + DEPENDS "${src}" + ) + list (APPEND ${target}_list "${dest}") +endmacro () diff --git a/ZFP/H5Z-ZFP/cmake/h5z_zfp-config-version.cmake.in b/ZFP/H5Z-ZFP/cmake/h5z_zfp-config-version.cmake.in new file mode 100644 index 00000000..d32ef969 --- /dev/null +++ b/ZFP/H5Z-ZFP/cmake/h5z_zfp-config-version.cmake.in @@ -0,0 +1,15 @@ +set(PACKAGE_VERSION_MAJOR @PROJECT_VERSION_MAJOR@) +set(PACKAGE_VERSION_MINOR @PROJECT_VERSION_MINOR@) +set(PACKAGE_VERSION_PATCH @PROJECT_VERSION_PATCH@) +set(PACKAGE_VERSION @PROJECT_VERSION@) + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION OR + PACKAGE_VERSION_MAJOR GREATER PACKAGE_FIND_VERSION_MAJOR) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/ZFP/H5Z-ZFP/cmake/h5z_zfp-config.cmake.in b/ZFP/H5Z-ZFP/cmake/h5z_zfp-config.cmake.in new file mode 100644 index 00000000..0bf8b52b --- /dev/null +++ b/ZFP/H5Z-ZFP/cmake/h5z_zfp-config.cmake.in @@ -0,0 +1,59 @@ +# h5z_zfp-config.cmake +# -------------------- +# +# Finds the H5Z_ZFP library, specify the starting search path in H5Z_ZFP_ROOT +# +# Static vs. shared +# ----------------- +# To make use of the static library instead of the shared one, one needs +# to set the variable H5Z_ZFP_USE_STATIC_LIBS to ON before calling find_package. +# Example: +# set(H5Z_ZFP_USE_STATIC_LIBS ON) +# find_package(H5Z_ZFP REQUIRED CONFIG) +# +# This will define the following variables: +# +# H5Z_ZFP_FOUND - True if the system has the H5Z_ZFP library. +# H5Z_ZFP_WITH_OPENMP - True if the zfp library has been built with OpenMP support. +# +# and the following imported targets: +# +# h5z_zfp::h5z_zfp - The H5Z_ZFP library. + +find_path(H5Z_ZFP_INCLUDE_DIR NAMES H5Zzfp.h DOC "H5Z_ZFP include directory") +if(H5Z_ZFP_USE_STATIC_LIBS) + find_library(H5Z_ZFP_LIBRARY NAMES libh5zzfp.a DOC "H5Z_ZFP library") +else() + find_library(H5Z_ZFP_LIBRARY NAMES libh5zzfp.so HINTS $ENV{H5Z_ZFP_ROOT}/plugin DOC "H5Z_ZFP library") +endif() + +include(FindPackageHandleStandardArgs) +set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG "${CMAKE_CURRENT_LIST_FILE}") +find_package_handle_standard_args(H5Z_ZFP + FOUND_VAR H5Z_ZFP_FOUND + REQUIRED_VARS H5Z_ZFP_LIBRARY H5Z_ZFP_INCLUDE_DIR + CONFIG_MODE +) + +if(H5Z_ZFP_FOUND) + set(HDF5_USE_STATIC_LIBRARIES ${H5Z_ZFP_USE_STATIC_LIBS}) + find_package(HDF5 MODULE REQUIRED COMPONENTS C) + find_package(ZFP REQUIRED CONFIG) + if(H5Z_ZFP_USE_STATIC_LIBS) + add_library(h5z_zfp::h5z_zfp STATIC IMPORTED) + else() + add_library(h5z_zfp::h5z_zfp SHARED IMPORTED) + endif() + set_target_properties(h5z_zfp::h5z_zfp PROPERTIES + IMPORTED_LOCATION "${H5Z_ZFP_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${H5Z_ZFP_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "zfp::zfp;${HDF5_LIBRARIES}" + LINK_LIBRARIES "zfp::zfp;${HDF5_LIBRARIES}" + ) + set(H5Z_ZFP_WITH_OPENMP ${ZFP_WITH_OPENMP}) +endif() + +mark_as_advanced( + H5Z_ZFP_INCLUDE_DIR + H5Z_ZFP_LIBRARY +) diff --git a/ZFP/config.make b/ZFP/H5Z-ZFP/config.make similarity index 79% rename from ZFP/config.make rename to ZFP/H5Z-ZFP/config.make index 43112c31..7e10c81f 100644 --- a/ZFP/config.make +++ b/ZFP/H5Z-ZFP/config.make @@ -1,25 +1,40 @@ export SHELL = /bin/bash -ifeq ($(HDF5_HOME),) - $(warning WARNING: HDF5_HOME not specified) -endif - -ifeq ($(ZFP_HOME),) - $(warning WARNING: ZFP_HOME not specified) -endif - -# Construct version variable depending on what dir we're in +#ifeq ($(HDF5_HOME),) +# $(warning WARNING: HDF5_HOME not specified) +#endif +# +#ifeq ($(ZFP_HOME),) +# $(warning WARNING: ZFP_HOME not specified) +#endif + +# disallow relative paths in HOME variables +HOME_WORDS := $(subst /, ,$(HDF5_HOME)) +FIRST_WORD := $(firstword $(HOME_WORDS)) +ifeq ($(FIRST_WORD),.) + $(error Please use absolute path for HDF5_HOME) +else ifeq ($(FIRST_WORD),..) + $(error Please use absolute path for HDF5_HOME) +endif +HOME_WORDS := $(subst /, ,$(ZFP_HOME)) +FIRST_WORD := $(firstword $(HOME_WORDS)) +ifeq ($(FIRST_WORD),.) + $(error Please use absolute path for ZFP_HOME) +else ifeq ($(FIRST_WORD),..) + $(error Please use absolute path for ZFP_HOME) +endif + +# Construct H5Z_ZFP_BASE variable depending on what dir this config.cmake is being included from PWD_BASE = $(shell basename $$(pwd)) -ifeq ($(PWD_BASE),src) - H5Z_ZFP_BASE := . -else ifeq ($(PWD_BASE),test) - H5Z_ZFP_BASE := ../src -else ifeq ($(PWD_BASE),H5Z-ZFP) +ifneq ($(wildcard config.make),) # we're in top-level dir H5Z_ZFP_BASE := ./src +else ifneq ($(wildcard test_write.c),) # we're in test dir + H5Z_ZFP_BASE := ../src +else ifneq ($(wildcard H5Zzfp.c),) # we're in src dir + H5Z_ZFP_BASE := . endif H5Z_ZFP_PLUGIN := $(H5Z_ZFP_BASE)/plugin -H5Z_ZFP_VERSINFO := $(shell grep '^\#define H5Z_FILTER_ZFP_VERSION_[MP]' $(H5Z_ZFP_BASE)/H5Zzfp_plugin.h | cut -d' ' -f3 | tr '\n' '.' | cut -d'.' -f-3 2>/dev/null) ZFP_HAS_REVERSIBLE := ifneq ($(ZFP_HOME),) ZFP_HAS_REVERSIBLE := $(shell grep zfp_stream_set_reversible $(ZFP_HOME)/include/zfp.h 2>/dev/null) @@ -34,14 +49,14 @@ ifeq ($(ZFP_LIB_VERSION),) ZFP_LIB_VERSION := $(shell grep '^\#define ZFP_VERSION_[MRPT]' $(ZFP_HOME)/inc/zfp.h 2>/dev/null | tr ' ' '\n' | grep '[0-9]' | tr -d '\n' 2>/dev/null) endif ifeq ($(ZFP_LIB_VERSION),) - $(warning WARNING: ZFP lib version not detected by make -- some tests may run) + $(warning WARNING: ZFP lib version not detected by make -- some tests may be skipped) endif # Detect system type PROCESSOR := $(shell uname -p | tr '[:upper:]' '[:lower:]') OSNAME := $(shell uname -s | tr '[:upper:]' '[:lower:]') OSTYPE := $(shell env | grep OSTYPE | cut -d'=' -f2- | tr '[:upper:]' '[:lower:]') -# LLNL specific enviornment variable +# LLNL specific environment variable SYS_TYPE := $(shell env | grep SYS_TYPE | cut -d'=' -f2- | tr '[:upper:]' '[:lower:]') # Common C compilers @@ -51,6 +66,7 @@ HAS_ICC := $(shell basename $$(which icc 2>/dev/null) 2>/dev/null) HAS_PGCC := $(shell basename $$(which pgcc 2>/dev/null) 2>/dev/null) HAS_XLCR := $(shell basename $$(which xlc_r 2>/dev/null) 2>/dev/null) HAS_BGXLCR := $(shell basename $$(which bgxlc_r 2>/dev/null) 2>/dev/null) +HAS_CC := $(shell basename $$(which cc 2>/dev/null) 2>/dev/null) # Common Fortran compilers HAS_GFORTRAN := $(shell basename $$(which gfortran 2>/dev/null) 2>/dev/null) @@ -65,6 +81,8 @@ ifeq ($(CC),) CC = $(HAS_CLANG) else ifneq ($(strip $(HAS_GCC)),) CC = $(HAS_GCC) + else ifneq ($(strip $(HAS_CC)),) + CC = $(HAS_CC) endif else ifneq ($(findstring ppc, $(PROCESSOR),),) ifneq ($(strip $(HAS_BGXLCR)),) @@ -77,6 +95,8 @@ ifeq ($(CC),) else ifneq ($(strip $(HAS_GCC)),) CC = $(HAS_GCC) + else ifneq ($(strip $(HAS_CLANG)),) + CC = $(HAS_CLANG) else ifneq ($(strip $(HAS_ICC)),) CC = $(HAS_ICC) else ifneq ($(strip $(HAS_PGCC)),) @@ -101,7 +121,7 @@ ifneq ($(findstring gcc, $(CC)),) else ifneq ($(findstring clang, $(CC)),) SOEXT ?= dylib SHFLAG ?= -dynamiclib - PREPATH = -L + PREPATH = -Wl,-rpath, else ifneq ($(findstring icc, $(CC)),) CFLAGS += -fpic SOEXT ?= so @@ -112,6 +132,11 @@ else ifneq ($(findstring pgcc, $(CC)),) SOEXT ?= so SHFLAG ?= -shared PREPATH = -Wl,-rpath, +else ifneq ($(findstring cc, $(CC)),) + CFLAGS += -fPIC + SOEXT ?= so + SHFLAG ?= -shared + PREPATH = -Wl,-rpath, else ifneq ($(findstring xlc_r, $(CC)),) CFLAGS += -qpic SOEXT ?= so @@ -145,7 +170,7 @@ else ifneq ($(wildcard $(ZFP_HOME)/inc),) ZFP_INC = $(ZFP_HOME)/inc endif ifeq ($(wildcard $(ZFP_INC)/zfp.h),) # no header file -$(error "zfp.h not found") +$(warning "zfp.h not found") endif ifeq ($(wildcard $(ZFP_HOME)/lib),) @@ -188,6 +213,11 @@ else MAKEVARS = HDF5_HOME=$(HDF5_HOME) endif +HDF5_HAS_WRITE_CHUNK = 1 +ifeq ($(shell grep H5Dwrite_chunk $(HDF5_INC)/*.h),) + HDF5_HAS_WRITE_CHUNK = 0 +endif + ifeq ($(PREFIX),) PREFIX := $(shell pwd)/install endif diff --git a/ZFP/docs/Makefile b/ZFP/H5Z-ZFP/docs/Makefile similarity index 100% rename from ZFP/docs/Makefile rename to ZFP/H5Z-ZFP/docs/Makefile diff --git a/ZFP/H5Z-ZFP/docs/cd_vals.rst b/ZFP/H5Z-ZFP/docs/cd_vals.rst new file mode 100644 index 00000000..d96f0aef --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/cd_vals.rst @@ -0,0 +1,40 @@ +======================================= +H5Z-ZFP and the HDF5 filter's cd_values +======================================= + +.. note:: + The details described here are likely relevant only to *developers* of the H5Z-ZFP_ filter. + If you just want to *use* the filter, you can ignore this material. + +The HDF5_ library uses an array of values, named ``cd_values`` in formal arguments documenting various API functions, for managing *auxiliary data* for a filter. +Instances of this ``cd_values`` array are used in two subtly different ways within HDF5. + +The first use is in *passing* auxiliary data for a filter from the caller to the library when initially creating a dataset. +This happens *directly* in an ``H5Pset_filter()`` (`see here `_) call. + +The second use is in *persisting* auxiliary data for a filter to the dataset's object *header* in a file. +This happens *indirectly* as part of an ``H5Dcreate()`` call. + +When a dataset creation property list includes a filter, the filter's ``set_local()`` method is called (see `H5Zregister() `_) as part of the ``H5Dcreate`` call. +In the filter's ``set_local()`` method, the ``cd_values`` that were *passed* by the caller (in ``H5Pset_filter()``) are often modified (via ``H5Pmodify_filter()`` (`see here `__) before they are *persisted* to the dataset's object header in a file. + +Among other things, this design allows a filter to be generally configured for *any* dataset in a file and then adjusted as necessary to handle such things as data type and/or dimensions when it is applied to a specific dataset. +Long story short, the data stored in ``cd_values`` of the dataset object's header in the file are often not the same values passed by the caller when the dataset was created. + +To make matters a tad more complex, the ``cd_values`` data is treated by HDF5_ as an array of C typed, 4-byte, ``unsigned integer`` values. +Furthermore, regardless of `endianness `__ of the data producer, the persisted values are always stored in little-endian format in the dataset object header in the file. +Nonetheless, if the persisted ``cd_values`` data is ever retrieved (e.g. via ``H5Pget_filter_by_id()`` (`see here `__), the HDF5_ library ensures the data is returned to callers with proper endianness. +When command-line tools like ``h5ls`` and ``h5dump`` print ``cd_values``, the data will be displayed correctly. + +Handling double precision auxiliary data via ``cd_values`` is still more complicated because a single double precision value will span multiple entries in ``cd_values`` in almost all cases. +Setting aside the possibility of differing floating point formats between the producer and consumers, any endianness handling the HDF5_ library does for the 4-byte entries in ``cd_values`` will certainly not ensure proper endianness handling of larger values. +It is impossible for command-line tools like ``h5ls`` and ``h5dump`` to display such data correctly. + +Fortunately, the ZFP_ library has already been designed to handle these issues as part of the ZFP_'s *native* stream header. +But, the ZFP_ library handles these issues in an endian-agnostic way. +Consequently, the H5Z-ZFP_ filter uses the ``cd_values`` that is persisted to a dataset's object header to store ZFP_'s stream header. +ZFP_'s stream header is stored starting at ``&cd_values[1]``. +``cd_values[0]`` is used to stored H5Z-ZFP_ filter and ZFP_ library and ZFP_ encoder version information. + +This also means that H5Z-ZFP_ avoids the overhead of duplicating the ZFP_ stream header in each dataset chunk. +For larger chunks, these savings are probably not too terribly significant. diff --git a/ZFP/docs/conf.py b/ZFP/H5Z-ZFP/docs/conf.py similarity index 95% rename from ZFP/docs/conf.py rename to ZFP/H5Z-ZFP/docs/conf.py index 1103b22c..b589b084 100644 --- a/ZFP/docs/conf.py +++ b/ZFP/H5Z-ZFP/docs/conf.py @@ -30,6 +30,10 @@ # ones. extensions = [] +# sphinx_rtd_theme is now installed via requirements.txt +import sphinx_rtd_theme +extensions.append('sphinx_rtd_theme') + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -47,10 +51,11 @@ copyright = u'2016, LLNL-CODE-707197' rst_epilog = """ -.. _ZFP: https://computation.llnl.gov/projects/floating-point-compression -.. _HDF5: https://support.hdfgroup.org/HDF5/doc/index.html +.. _ZFP: https://computing.llnl.gov/projects/zfp +.. _HDF5: https://docs.hdfgroup.org/hdf5/develop/ .. _H5Z-ZFP: https://github.com/LLNL/H5Z-ZFP .. _Spack: https://spack.io +.. _CMake: https://cmake.org/cmake/help/latest/ """ # The version info for the project you're documenting, acts as replacement for @@ -58,9 +63,9 @@ # built documents. # # The short X.Y version. -version = '0.6' +version = '1.1' # The full version, including alpha/beta/rc tags. -release = '0.6.0' +release = '1.1.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -105,7 +110,8 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "sphinx_rtd_theme" +#html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/ZFP/docs/h5repack.rst b/ZFP/H5Z-ZFP/docs/direct.rst similarity index 84% rename from ZFP/docs/h5repack.rst rename to ZFP/H5Z-ZFP/docs/direct.rst index 8c46f6a6..1ea44e4d 100644 --- a/ZFP/docs/h5repack.rst +++ b/ZFP/H5Z-ZFP/docs/direct.rst @@ -22,14 +22,15 @@ code that does this, have a look at... In particular, look for the line using ``H5Dchunk_write`` in place of ``H5Dwrite``. In all other respects, the code looks the same. + The test case for this code writes uncompressed data as a dataset named ``zfparr_original``, the compressed dataset named ``zfparr_compressed`` using the filter and then the compressed -data a second time named ``zfparr_direct`` using a direct write. Then, the ``h5diff`` tool -is used to compare the data in the original and direct datasets. +data a second time named ``zfparr_direct`` using a direct_ write. Then, the ``h5diff`` tool +is used to compare the data in the original and the direct_ write datasets. Note that in order for consumers to work as normal, the producer must set dataset *creation* properties as it ordinarily would using the H5Z-ZFP_ filter. In the call to ``H5Dchunk_write``, the caller indicates to the HDF5 library not to invoke the filter via the ``filters`` mask argument. -.. _direct: https://support.hdfgroup.org/documentation/hdf5/latest/group___h5_d.html#ga416ccd200929b11386a10e9024977109 +.. _direct: https://docs.hdfgroup.org/hdf5/develop/group___h5_d.html#title38 diff --git a/ZFP/H5Z-ZFP/docs/endian_issues.rst b/ZFP/H5Z-ZFP/docs/endian_issues.rst new file mode 100644 index 00000000..b7aeeba0 --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/endian_issues.rst @@ -0,0 +1,26 @@ +.. _endian-issues: + +============= +Endian Issues +============= + +This section describes some issues related to `endianness `__ of producers and consumers of the data processed by H5Z-ZFP_. +This is likely less of an issue than it once was because almost all modern CPUs are `little-endian `__. + +That being said, the ZFP_ library writes an endian-independent stream. + +There is an unavoidable inefficiency when reading ZFP_ compressed data on a machine with a different endianness than the writer (e.g. a *mixed* endian context). Upon reading data from storage and decompressing the read stream with ZFP_, the correct endianness is returned in the result from ZFP_ before the buffer is handed back to HDF5_ from the decompression filter. +This happens regardless of reader and writer endianness incompatibility. +However, the HDF5_ library expects to get from H5Z-ZFP_ the endianness of the data as it was stored to the file on the writer machine and expects to have to byte-swap that buffer before returning to it an endian-incompatible caller. + +This means that in the H5Z-ZFP_ plugin, we wind up having to un-byte-swap an already correct result read in a cross-endian context. +That way, when HDF5_ gets the data and byte-swaps it as it is expecting to, it will produce the correct final result. +There is an endianness test in the Makefile and two ZFP_ compressed example datasets for big-endian and little-endian machines to test that cross-endian reads/writes work correctly. + +Again, because most CPUs are now little-endian and because ZFP_ became available only after the industry mostly moved away from big-endian, it is highly unlikely that this inefficiency will be triggered. + +Finally, *endian-targeting*, which is setting the file datatype for an endianness that is possibly different than the native endianness of the writer, is explicitly disallowed. +For example, data may be produced on a big-endian system, but most consumers will be little-endian. +Therefore, to alleviate downstream consumers from having to always byte-swap, it is desirable to byte-swap to little-endian when the data is written. +However, the juxtaposition of HDF5_'s type conversion and filter operations in a pipeline makes this impractical for the H5Z-ZFP_ filter. +The H5Z-ZFP_ filter will explicitly catch this condition, fail the compression and issue an error message. diff --git a/ZFP/H5Z-ZFP/docs/h5repack.rst b/ZFP/H5Z-ZFP/docs/h5repack.rst new file mode 100644 index 00000000..5171ee18 --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/h5repack.rst @@ -0,0 +1,104 @@ +================================== +Using H5Z-ZFP Plugin with H5Repack +================================== +A convenient way to use and play with the ZFP_ filter is as a *plugin* with the HDF5_ `h5repack `__ utility using the ``-f`` command-line argument to apply ZFP to existing data in a file. + +----------------- +Patching h5repack +----------------- + +.. warning:: + + Versions of HDF5_'s ``h5repack`` utility prior to 1.10.4 contain a bug that prevents proper parsing of the ``-f`` argument's option. + In order to use ``h5repack`` with ``-f`` argument as described here, you need to apply the patch from `h5repack_parse.patch `_. + To do so, after you've downloaded and untar'd HDF5_ but before you've built it, do something like the following using HDF5-1.8.14 as an example:: + + gunzip < hdf5-1.8.14.tar.gz | tar xvf - + cd hdf5-1.8.14 + patch ./tools/h5repack/h5repack_parse.c /h5repack_parse.patch + +------------------------------------- +Constructing an HDF5_ cd_values array +------------------------------------- +HDF5_'s ``h5repack`` utility uses only the *generic* interface to HDF5_ filters. +Another challenge in using ``h5repack`` as described here is constructing the set ``unsigned int cd_values`` as is used in `H5Pset_filter() `__ required by the *generic* HDF5_ filter interface, especially because of the type-punning (doubles as unsigned int) which may be involved. + +.. note:: + + Querying an existing dataset using ``h5dump`` or ``h5ls`` to obtain the ``cd_values`` *stored* with a ZFP_ compressed dataset will not provide the correct ``cd_values`` needed to invoke the filter. + This is because the ``cd_values`` stored in the file are different from those needed in the *generic* interface to invoke the ZFP_ filter. + +To facilitate constructing a valid ``-f`` argument to ``h5repack``, there is a utility program, ``print_h5repack_farg``, which is presently in the ``test`` directory and is built when tests are built. +This program was originally written simply to facilitate testing of H5Z-ZFP filter. +It should eventually be made a first class *tool* installed with H5Z-ZFP. +However, it is presently made only as part of *testing* H5Z-ZFP. + +The ``print_h5repack_farg`` utility can be used to read a command-line consisting of ZFP_ filter parameters you wish to use and output part of the command-line needed for the ``-f`` argument to ``h5repack``. + +-------- +Examples +-------- + +.. note:: + + The examples below assume H5Z-ZFP has been configured to run tests by either a preceding ``make check`` (if using a vanilla ``gmake`` build) or ``make test`` (if using a ``cmake`` build). + +In the examples below, we use ``h5repack`` with the example data file, ``mesh.h5`` in the tests directory. + +To use ZFP_ filter in *rate* mode with a rate of ``4.5`` bits per value, first, use the ``print_h5repack_farg``:: + + % ./print_h5repack_farg zfpmode=1 rate=4.5 + + Print cdvals for set of ZFP compression parameters... + zfpmode=1 set zfp mode (1=rate,2=prec,3=acc,4=expert,5=rev) + rate=4.5 set rate for rate mode of filter + acc=0 set accuracy for accuracy mode of filter + prec=0 set precision for precision mode of zfp filter + minbits=0 set minbits for expert mode of zfp filter + maxbits=0 set maxbits for expert mode of zfp filter + maxprec=0 set maxprec for expert mode of zfp filter + minexp=0 set minexp for expert mode of zfp filter + help=0 this help message + + h5repack -f argument... + -f UD=32013,0,4,1,0,0,1074921472 + +Next, cut-n-paste the ``-f UD=32013,0,4,1,0,0,1074921472`` in a command to ``h5repack`` like so:: + + env LD_LIBRARY_PATH=:$(LD_LIBRARY_PATH) \ + HDF5_PLUGIN_PATH= \ + $(HDF5_BIN)/h5repack -f UD=32013,0,4,1,0,0,1074921472 \ + -l Pressure,Pressure2,Pressure3:CHUNK=10x20x5 \ + -l Velocity,Velocity2,Velocity3,VelocityZ,VelocityZ2,VelocityZ3:CHUNK=11x21x1x1 \ + -l VelocityX_2D:CHUNK=21x31 \ + mesh.h5 mesh_repack.h5 + +where the ``-l`` arguments indicate the dataset(s) to be re-packed as well as their (new) chunking. + +To use ZFP_ filter in *accuracy* mode with an accuracy of ``0.075``, first, use the ``print_h5repack_farg``:: + + % ./print_h5repack_farg zfpmode=3 acc=0.075 + + Print cdvals for set of ZFP compression parameters... + zfpmode=3 set zfp mode (1=rate,2=prec,3=acc,4=expert,5=rev) + rate=3.5 set rate for rate mode of filter + acc=0.075 set accuracy for accuracy mode of filter + prec=0 set precision for precision mode of zfp filter + minbits=0 set minbits for expert mode of zfp filter + maxbits=0 set maxbits for expert mode of zfp filter + maxprec=0 set maxprec for expert mode of zfp filter + minexp=0 set minexp for expert mode of zfp filter + help=0 this help message + + h5repack -f argument... + -f UD=32013,0,4,3,0,858993459,1068708659 + +Next, cut-n-paste the ``-f UD=32013,0,4,3,0,858993459,1068708659`` in a command to ``h5repack`` like so:: + + env LD_LIBRARY_PATH=:$(LD_LIBRARY_PATH) \ + HDF5_PLUGIN_PATH= \ + $(HDF5_BIN)/h5repack -f UD=32013,0,4,3,0,858993459,1068708659 \ + -l Pressure,Pressure2,Pressure3:CHUNK=10x20x5 \ + -l Velocity,Velocity2,Velocity3,VelocityZ,VelocityZ2,VelocityZ3:CHUNK=11x21x1x1 \ + -l VelocityX_2D:CHUNK=21x31 \ + mesh.h5 mesh_repack.h5 diff --git a/ZFP/H5Z-ZFP/docs/hdf5_chunking.rst b/ZFP/H5Z-ZFP/docs/hdf5_chunking.rst new file mode 100644 index 00000000..1120414d --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/hdf5_chunking.rst @@ -0,0 +1,155 @@ +.. _hdf5_chunking: + +============== +HDF5_ Chunking +============== + +HDF5_'s dataset `chunking`_ feature is a way to optimize data layout on disk to support partial dataset reads by downstream consumers. +This is all the more important when compression filters are applied to datasets as it frees a consumer from suffering the UNcompression of an entire dataset only to read a portion. + +------------- +ZFP Chunklets +------------- + +When using HDF5_ `chunking`_ with ZFP_ compression, it is important to account for the fact that ZFP_ does its work in tiny 4\ :sup:`d` chunklets of its own where `d` is the dataset dimension (*rank* in HDF5_ parlance). +This means that whenever possible, the `chunking`_ dimensions you select in HDF5_ should be multiples of 4. +When a chunk_ dimension is not a multiple of 4, ZFP_ will wind up with partial chunklets, which will be padded with useless data, reducing the results' overall time and space efficiency. + +The degree to which this may degrade performance depends on the percentage of a chunk_ that is padded. +Suppose we have a 2D chunk of dimensions 27 x 101. +ZFP_ will have to treat it as 28 x 104 by padding out each dimension to the next closest multiple of 4. +The fraction of space that will wind up being wasted due to ZFP_ chunklet padding will be (28x104-27x101) / (28x104), which is about 6.4%. +On the other hand, consider a 3D chunk that is 1024 x 1024 x 2. +ZFP_ will have to treat it as a 1024 x 1024 x 4 resulting in 50% waste. + +The latter example is potentially very relevant when applying ZFP_ to compress data along the *time* dimension in a large, 3D, simulation. +Ordinarily, a simulation advances one time step at a time and so needs to store in memory only the *current* timestep. +However, in order to give ZFP_ enough *width* in the time dimension to satisfy the minimum chunklet dimension size of 4, the simulation +needs to keep in memory 4 timesteps. +This is demonstrated in the example below. + +-------------------- +Partial I/O Requests +-------------------- + +In any given H5Dwrite_ call, the caller has the option of writing (or reading) only a portion of the data in the dataset. +This is a *partial I/O* request. +This is handled by the ``mem_space_id`` and ``file_space_id`` arguments in an H5Dwrite_ call. + +An HDF5_ producer or consumer can issue partial I/O requests on *any* HDF5 dataset regardless of whether the dataset is compressed or not or whether the dataset has ``H5D_CONTIGUOUS`` layout. +When combining partial I/O with compression, chunk size and shape in relation to partial I/O request size and shape will have an impact on performance. + +This is particularly important in *writer* scenarios if an I/O request winds up overlapping chunks only partially. +Suppose the partially overlapped chunks exist in the file (from a previous write, for example). In that case, the HDF5_ library may wind up having to engage in *read-modify-write* operations for those chunks. + +If the partially overlapped chunks do not exist in the file, the HDF5_ library will wind up *fill-value* padding the chunks before they are written. +HDF5_'s default fill value is zero (as defined by the associated datatype). +Data producers can choose the desired fill value (see `H5Pset_fill_value `__) for a dataset, but this fill value can impact the space-performance of the compression filter. +On the other hand, if the partial chunks in one I/O request wind up getting fully filled in another, any fill value impacts on compressor performance are resolved. + +Finally, HDF5_ manages a `chunk cache `__ and `data sieving buffer `__ to help alleviate some of the I/O performance issues that can be encountered in these situations. + +----------------------------- +More Than 3 (or 4) Dimensions +----------------------------- + +Versions of ZFP_ 0.5.3 and older support compression in only 1,2 or 3 +dimensions. Versions of ZFP_ 0.5.4 and newer also support 4 dimensions. + +What if you have a dataset with more dimensions than ZFP_ can compress? +You can still use the H5Z-ZFP_ filter. But, in order to do so, you +are *required* to chunk_ the dataset [1]_ . Furthermore, you must select a +chunk_ size such that no more than 3 (or 4 for ZFP_ 0.5.4 and newer) +dimensions are non-unitary (e.g. of size one). + +For example, what if you are using ZFP_ 0.5.3 and have a 4D HDF5 dataset +you want to compress? To do this, you will need to chunk_ the dataset and +when you define the chunk_ size and shape, you will need to select which +of the 4 dimensions of the chunk you do *not* intend to have ZFP_ perform +compression along by setting the size of the chunk_ in that dimension to +unity (1). When you do this, as HDF5 processes writes and reads, it will +organize the data so that all the H5Z-ZFP_ filter *sees* are chunks +which have *extent* only in the non-unity dimensions of the chunk_. + +In the example below, we have a 4D array of shape ``int dims[] = {256,128,32,16};`` +that we have intentionally constructed to be *smooth* in only 2 of its 4 dimensions +(e.g. correlation is high in those dimensions). Because of that, we expect ZFP_ +compression to do well along those dimensions, and we do not want ZFP_ to compress +along the other 2 dimensions. The *uncorrelated* dimensions here are dimensions +with indices ``1`` (``128`` in ``dims[]``) and ``3`` (``16`` in ``dims[]``). +Thus, our chunk_ size and shape are chosen to set the size for those dimension +indices to ``1``, ``hsize_t hchunk[] = {256,1,32,1};`` + +.. literalinclude:: ../test/test_write.c + :language: c + :linenos: + :start-after: Test high dimensional (>3D) array + :end-before: End of high dimensional test + +What analysis process should you use to select the chunk_ shape? Depending +on what you expect in the way of access patterns in downstream consumers, +this can be a challenging question to answer. There are potentially two +competing interests. One is optimizing the chunk_ size and shape for access +patterns anticipated by downstream consumers. The other is optimizing the chunk_ +size and shape for compression. These two interests may not be compatible +and you may have to compromise between them. We illustrate the issues and +trade-offs using an example. + +--------------------------------------------------- +Compression *Along* the *State Iteration* Dimension +--------------------------------------------------- + +By *state iteration* dimension, we refer to the data producer's main iteration +loop(s). For example, the main iteration dimension for many +PDE-based simulations is *time*. But, for some *outer loop* methods, the +main iteration dimension(s) might be some kind of parameter study including +multiple parameters. + +The challenge here is to manage the data to meet ZFP_'s +chunklet size and shape *minimum* requirements. In any H5Dwrite_ at least 4 +*samples* along a ZFP_ compression dimension are needed, or there will +be wasted space due to padding. This means that data must be *buffered* +along those dimensions *before* H5Dwrite_'s can be issued. + +For example, suppose you have a tensor-valued field (e.g. a 3x3 matrix +at every *point*) over a 4D (3 spatial dimensions and 1 time dimension), +regularly sampled domain? Conceptually, this is a 6 dimensional dataset +in HDF5_ with one of the dimensions (the *time* dimension) *extendable*. +So, you are free to define this as a 6 dimensional dataset in HDF5_. But, you +will also have to chunk_ the dataset. You can select any chunk_ shape +you want, except that no more than 3 (or 4 for ZFP_ versions 0.5.4 and +newer) dimensions of the chunk_ can be non-unity. + +In the code snippet below, we demonstrate this case. A key issue to deal +with is that because we will use ZFP_ to compress along the time dimension, +this forces us to keep in memory a sufficient number of timesteps to match +ZFP_'s chunklet size of 4. + +The code below iterates over 9 timesteps. Each of the first two groups of 4 +timesteps are buffered in memory in ``tbuf``. Once 4 timesteps have been buffered, we +can issue an H5Dwrite_ call doing +`hyperslab `__ +can issue an H5Dwrite_ +call doing `hyperslab `__ +partial I/O on the 6D, `extendable `__ +dataset. But, notice that the chunk_ dimensions (line 10) are such that only 4 of the +6 dimensions are non-unity. This means ZFP_ will only ever see something to +compress that is essentially 4D. + +On the last iteration, we have only one *new* timestep. So, when we write this +to ZFP_ 75% of that write will be *wasted* due to ZFP_ chunklet padding. However, +if the application were to *restart* from this time and continue forward, this +*waste* would ultimately get overwritten with new timesteps. + +.. literalinclude:: ../test/test_write.c + :language: c + :linenos: + :start-after: 6D Example + :end-before: End of 6D Example + +.. _chunking: https://portal.hdfgroup.org/display/HDF5/Chunking+in+HDF5 +.. _chunk: https://portal.hdfgroup.org/display/HDF5/Chunking+in+HDF5 +.. _H5Dwrite: https://docs.hdfgroup.org/hdf5/v1_14/group___h5_d.html#title37 +.. [1] The HDF5_ library currently requires dataset chunking anyways for + any dataset that has any kind of filter applied. + diff --git a/ZFP/H5Z-ZFP/docs/index.rst b/ZFP/H5Z-ZFP/docs/index.rst new file mode 100644 index 00000000..57bd6fee --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/index.rst @@ -0,0 +1,23 @@ +================== +Welcome to H5Z-ZFP +================== + +H5Z-ZFP_ is a compression filter for HDF5_ using the ZFP_ compression library, supporting *lossy* and *lossless* compression of floating point and integer data to meet `bitrate `_, `accuracy `_, and/or `precision `_ targets. +The filter uses the `registered ` +* With :ref:`CMake ` +* With :ref:`Spack ` + +For both generic make and CMake_, you are responsible for also installing (or knowing where the installations are) the dependencies, ZFP_ and HDF5_. +For Spack_ installations, Spack_ will handle installation of dependencies as well. + +.. _gnumake: + +--------------------------------- +Installing via Generic (GNU) Make +--------------------------------- + +H5Z-ZFP_ installation supports both vanilla (`GNU `__) Make (described below) as well as :ref:`CMake `. + +^^^^^^^^^^^^^ +Prerequisites +^^^^^^^^^^^^^ + +* `ZFP Library `_ (or from `Github `_) +* `HDF5 Library `_ +* `H5Z-ZFP filter plugin `_ + +.. _zfp-config: + +^^^^^^^^^^^^^^ +Compiling ZFP_ +^^^^^^^^^^^^^^ + +* There is a ``Config`` file in top-level directory of the ZFP_ distribution that holds ``make`` variables the ZFP_ Makefiles use. By default, this file is setup for a vanilla GNU compiler. + If this is not the appropriate compiler, edit ``Config`` as necessary to adjust the compiler and compilation flags. +* An important flag you **will** need to adjust in order to use the ZFP_ library with this HDF5_ filter is the ``BIT_STREAM_WORD_TYPE`` CPP flag. + To use ZFP_ with H5Z-ZFP_, the ZFP_ library **must** be compiled with ``BIT_STREAM_WORD_TYPE`` of ``uint8``. + Typically, this is achieved by including a line in ``Config`` of the form ``DEFS += -DBIT_STREAM_WORD_TYPE=uint8``. + If you attempt to use this filter with a ZFP_ library compiled differently from this, the filter's ``can_apply`` method will always return false. + This will result in silently ignoring an HDF5_ client's request to compress data with ZFP_. + Also, be sure to see :ref:`endian-issues`. +* After you have setup ``Config``, simply run ``make`` and it will build the ZFP_ library placing the library in a ``lib`` sub-directory and the necessary include files in ``inc[lude]`` sub-directory. +* For more information and details, please see the `ZFP README `_. + +^^^^^^^^^^^^^^^ +Compiling HDF5_ +^^^^^^^^^^^^^^^ + +* If you want to be able to run the fortran tests for this filter, HDF5_ must be configured with *both* the ``--enable-fortran`` and ``--enable-fortran2003`` configuration switches. + Otherwise, any vanilla installation of HDF5_ is acceptable. + +* The Fortran interface to this filter *requires* a Fortran 2003 compiler because it uses `ISO_C_BINDING `_ to define the Fortran interface. + +* If you are using HDF5-1.12 and wish to use the filter as a *library* (see :ref:`plugin-vs-library`), you may need configure HDF5 with ``--disable-memory-alloc-sanity-check`` to work around a memory management issue in HDF5. + +^^^^^^^^^^^^^^^^^ +Compiling H5Z-ZFP +^^^^^^^^^^^^^^^^^ + +H5Z-ZFP_ is designed to be compiled both as a standalone HDF5_ *plugin* and as a separate *library* an application can explicitly link. See :ref:`plugin-vs-library`. + +Once you have installed the prerequisites, you can compile H5Z-ZFP_ using a command-line... + +:: + + make [FC=] CC= \ + ZFP_HOME= HDF5_HOME= \ + PREFIX= + +where ```` is a directory containing ZFP_ ``inc[lude]`` and ``lib`` dirs and ```` is a directory containing HDF5_ ``include`` and ``lib`` dirs. +If you don't specify a C compiler, it will try to guess one from your path. +Fortran compilation is optional. +If you do not specify a Fortran compiler, it will not attempt to build the Fortran interface. +However, if the variable ``FC`` is already defined in your environment (as in Spack_ for example), then H5Z-ZFP_ will attempt to build Fortran. +If this is not desired, the solution is to pass an *empty* ``FC`` on the make command line as in... + +:: + + make FC= CC= \ + ZFP_HOME= HDF5_HOME= \ + PREFIX= + + +The Makefile uses GNU Make syntax and is designed to work on OSX and Linux. The filter has been tested on gcc, clang, xlc, icc and pgcc compilers and checked with valgrind. + +The command ``make help`` will print useful information about various make targets and variables. ``make check`` will compile everything and run a handful of tests. + +If you don't specify a ``PREFIX``, it will install to ``./install``. +The installed package will look like... + +:: + + $(PREFIX)/include/{H5Zzfp.h,H5Zzfp_plugin.h,H5Zzfp_props.h,H5Zzfp_lib.h} + $(PREFIX)/plugin/libh5zzfp.{so,dylib} + $(PREFIX)/lib/libh5zzfp.a + +where ``$(PREFIX)`` resolves to whatever the full path of the installation is. + +To use the installed filter as an HDF5_ *plugin*, you would specify, for example, +``setenv HDF5_PLUGIN_PATH $(PREFIX)/plugin`` + +.. _ceemake: + +-------------------- +Installing via CMake +-------------------- + +It is possible to build the H5Z-ZFP_ filter using the CMake_ build system. +To use CMake_ for H5Z-ZFP_, it is necessary to have also built ZFP_ with CMake. +This is necessary to get the correct dependencies from ZFP_. +For example, it is possible to build ZFP_ with OpenMP support. +The resulting CMake_ config files of ZFP_ build will make sure that this OpenMP dependency is correctly propagated to the build of H5Z-ZFP_ filter. +However, for HDF5_ it is not necessary to build it with its CMake_ build system but it is strongly recommended. + +ZFP_ must have been :ref:`configured ` with ``BIT_STREAM_WORD_TYPE`` of ``uint8`` as described above. + +Similar as for the Makefile installation, the CMake_ build system is designed such it compiles both the standalone HDF5_ *plugin* and a separate *library* an application can explicitly link. See :ref:`plugin-vs-library` + +Once both HDF5_ and ZFP_ have been installed, H5Z-ZFP_ can be compiled using a command=line... + +:: + + export HDF5_DIR= + export ZFP_DIR= + CC= FC= cmake -DCMAKE_INSTALL_PREFIX= + +where ```` is a directory containing ``zfp-config.cmake`` and ```` is a directory containing HDF5_ ``include`` and ``lib`` directories. +Furthermore, ``src-dir`` is the directory where the H5Z-ZFP_ source is located and ``path-to-install`` is the directory in which the resulting *plugin* and *library* will be installed. +Once ``cmake`` has finished successfully, you can build and install the filter using the command... + +:: + + make install + +This ``cmake`` and ``make`` combination builds both the C and Fortran interface. +In the case you want to specify the ```` and ``>`` via command-line to CMake_, the command looks like this... + +:: + + CC= FC= cmake -DCMAKE_INSTALL_PREFIX= + -DCMAKE_PREFIX_PATH=";" + +.. note:: + + The double quotes in the CMAKE_PREFIX_PATH expression are necessary to make sure that semicolon is interpreted as a semicolon instead of a new command. + +It is possible to build the filter without the Fortran interface. This is done as follows... + +:: + + export HDF5_DIR= + export ZFP_DIR= + CC= cmake -DCMAKE_INSTALL_PREFIX= -DFORTRAN_INTERFACE:BOOL=OFF + +followed by the same make command... + +:: + + make install + +------------------------------------------- +Including H5Z-ZFP filter in a CMake project +------------------------------------------- + +Suppose you have built the H5Z-ZFP_ filter using the CMake_ build system and installed it in ````. +To include it in another CMake_ project is done using the following steps. First edit the ``CMakeLists.txt`` +by adding the following two lines... + +:: + + cmake_policy(SET CMP0028 NEW) # Double colon in target name means ALIAS or IMPORTED target. + ... + set(H5Z_ZFP_USE_STATIC_LIBS OFF) + find_package(H5Z_ZFP 1.0.1 CONFIG) + ... + target_link_libraries( h5z_zfp::h5z_zfp) + ... + +where ```` in the target within the CMake_ project. +This could be, for example, an executable or library. +Furthermore, check if the ``cmake`` version is equal or greater than 3.9. +Next, you need to make sure that the filter can be found by CMake_, followed by ``cmake`` itself and ``make``... + +:: + + export H5Z_ZFP_DIR= + CC= cmake -DCMAKE_INSTALL_PREFIX= + make install + +The ``cmake`` command itself could be different depending on the CMake_ project you have created. +If you want to make use of the H5Z-ZFP_ *library* instead of the plugin, change cmake variable ``H5Z_ZFP_USE_STATIC_LIBS`` to ``ON`` and build the project. + +.. _spack2: + +--------------------- +Installing via Spack_ +--------------------- +If you already have experience with Spack_, one way to install H5Z-ZFP_ is to use the command ``spack install h5z-zfp``. +If you do not have Spack_ installed, it is easy to install. +Assuming you are working in a Bash shell...:: + + git clone https://github.com/llnl/spack.git + cd spack + git checkout releases/v0.20 + . ./share/spack/setup-env.sh + spack install h5z-zfp + +.. note:: + + It is important to work from a *released* branch of Spack_. + The command ``git checkout releases/v0.20`` ensures this. + If a newer release of Spack_ is available, by all means feel free to use it. + Just change the ``v0.20`` to indicate the release of the Spack_ you want. + The command ``git branch -r | grep releases`` will produce a list of the available release branches. + +If you are using a version of Spack_ very much older than the release of H5Z-ZFP_ you intend to use, you may have to *pin* various versions of H5Z-ZFP_, ZFP_ and/or HDF5_. +This is done by using Spack_'s ``@`` modifier to specify versions. +For example, to *pin* the version of the ZFP_ library to 0.5.5, the Spack_ command would look like:: + + spack install h5z-zfp ^zfp@0.5.5 + +To use the ``develop`` version of H5Z-ZFP_ with version 1.10.6 of HDF5_ :: + + spack install h5z-zfp@develop ^hdf5@1.10.6 + +By default, H5Z-ZFP_ will attempt to build with Fortran support which requires a Fortran compiler. +If you wish to exclude support for Fortran, use the command:: + + spack install h5z-zfp~fortran + +Spack_ packages can sometimes favor the use of dependencies you may not need. +For example, the HDF5_ package favors the use of MPI. +Since H5Z-ZFP_ depends on HDF5_, this behavior will then create a dependency of H5Z-ZFP_ on MPI. +To avoid this, you can force Spack_ to use a version of HDF5_ *without* MPI. +In the example command below, we force Spack_ to not use MPI with HDF5_ and to not use OpenMP with ZFP_:: + + spack install h5z-zfp~fortran ^hdf5~mpi~fortran ^zfp~openmp + +This can have the effect of substantially reducing the number of dependencies Spack_ winds up having to build (from 35 in one case to 10) in order to install H5Z-ZFP_ which, in turn, speeds up the install process. + +.. note:: + + Spack_ will build H5Z-ZFP_ **and** all of its dependencies including the HDF5_ library *as well as a number of other dependencies you may not initially expect*. + Be patient and let the build complete. + It may take as much as an hour. + +In addition, by default, Spack_ installs packages to directory *hashes within* the cloned Spack_ repository's directory tree, ``$spack/opt/spack``. +You can find the resulting installed HDF5_ library with the command ``spack find -vp hdf5`` and the resulting H5Z-ZFP_ plugin installation with the command ``spack find -vp h5z-zfp``. +If you wish to exercise more control over how and where Spack_ installs, have a look at +`configuring Spack `_ + +-------------------------------- +H5Z-ZFP Source Code Organization +-------------------------------- + +The source code is in two separate directories + + * ``src`` includes the ZFP_ filter and a few header files + + * ``H5Zzfp_plugin.h`` is an optional header file applications *may* wish to include because it contains several convenient macros for easily controlling various compression modes of the ZFP_ library (*rate*, *precision*, *accuracy*, *expert*) via the :ref:`generic-interface`. + * ``H5Zzfp_props.h`` is a header file that contains functions to control the filter using *temporary* :ref:`properties-interface`. + Fortran callers are *required* to use this interface. + * ``H5Zzfp_lib.h`` is a header file for applications that wish to use the filter explicitly as a library rather than a plugin. + * ``H5Zzfp.h`` is an *all-of-the-above* header file for applications that don't care too much about separating out the above functionalities. + + * ``test`` includes various tests. In particular ``test_write.c`` includes examples of using both the :ref:`generic-interface` and :ref:`properties-interface`. + In addition, there is an example of how to use the filter from Fortran in ``test_rw_fortran.F90``. + +---------------- +Silo Integration +---------------- + +This filter (``H5Zzfp.c``) is also built-in to the `Silo library `_. +In particular, the ZFP_ library itself is also embedded in Silo but is protected from appearing in Silo's global namespace through a struct of function pointers (see `Namespaces in C `_). +If you happen to examine the source code here for H5Z-ZFP_, you will see some logic here that is specific to using this plugin within Silo and dealing with ZFP_ as an embedded library using this struct of function pointers wrapper. +In the source code for H5Z-ZFP_ this manifests as something like what is shown in the code snippet below... + +.. literalinclude:: ../src/H5Zzfp.c + :language: c + :linenos: + :start-after: /* set up dummy zfp field to compute meta header */ + :end-before: if (!dummy_field) + +In the code snippet above, note the funny ``Z`` in front of calls to various methods in the ZFP_ library. +When compiling H5Z-ZFP_ normally, that ``Z`` normally resolves to the empty string. +But, when the code is compiled with ``-DAS_SILO_BUILTIN`` (which is supported and should be done *only* when ``H5Zzfp.c`` is being compiled *within* the Silo library and *next to* a version of ZFP_ that is embedded in Silo) that ``Z`` resolves to the name of a struct and struct-member dereferencing operator as in ``zfp.``. +There is a similar ``B`` used for a similar purpose ahead of calls to ZFP_'s bitstream library. +This is something to be aware of and to adhere to if you plan to contribute any code changes here. diff --git a/ZFP/H5Z-ZFP/docs/interfaces.rst b/ZFP/H5Z-ZFP/docs/interfaces.rst new file mode 100644 index 00000000..0bd8736e --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/interfaces.rst @@ -0,0 +1,141 @@ +========== +Interfaces +========== + +There are two interfaces to control the filter. +One uses HDF5_'s *generic* interface via an array of ``unsigned int cd_values`` as is used in `H5Pset_filter() `__. +The other uses HDF5_ `property lists `__ added to the `dataset creation property list `__ used when the dataset to be compressed is being created. +You can find examples of writing HDF5_ data using both the `generic `_ and `properties `__ interfaces in `test_write.c `_. + +The filter itself supports either interface. The filter also supports all of the standard ZFP_ controls for affecting compression including *rate*, *precision*, *accuracy*, *expert* and *reversible* modes. +For more information and details about these modes of controlling ZFP_ compression, please see the `ZFP README `_. + +Finally, you should *not* attempt to combine the ZFP_ filter with any other *byte order altering* filter such as, for example, HDF5_'s shuffle filter. +Space-performance will be ruined. +This is in contrast to HDF5_'s `deflate `__ filter which often performs *better* when used in conjunction with the `shuffle `__ filter. +To understand why, see the description of :ref:`endian issues `. + +.. _generic-interface: + +----------------- +Generic Interface +----------------- + +The generic interface is the only means of controlling the H5Z-ZFP_ filter when it is used as a `dynamically loaded HDF5 plugin `_. + +For the generic interface, the following CPP macros are defined in the ``H5Zzfp_plugin.h`` header file:: + + H5Pset_zfp_rate_cdata(double rate, size_t cd_nelmts, unsigned int *cd_vals); + H5Pset_zfp_precision_cdata(unsigned int prec, size_t cd_nelmts, unsigned int *cd_vals); + H5Pset_zfp_accuracy_cdata(double acc, size_t cd_nelmts, unsigned int *cd_vals); + H5Pset_zfp_expert_cdata(unsigned int minbits, unsigned int maxbits, + unsigned int maxprec, int minexp, + size_t cd_nelmts, unsigned int *cd_vals); + H5Pset_zfp_reversible_cdata(size_t cd_nelmts, unsigned int *cd_vals); + +These macros utilize *type punning* to store the relevant ZFP_ parameters into a sufficiently large array (>=6) of ``unsigned int cd_values``. +It is up to the caller to then call `H5Pset_filter() `__ with the array of cd_values constructed by one of these macros. + +Here is example code from `test_write.c `_... + +.. literalinclude:: ../test/test_write.c + :language: c + :linenos: + :start-after: setup zfp filter via generic (cd_values) interface + :end-before: #else + +However, these macros are only a convenience. +You do not **need** the ``H5Zzfp_plugin.h`` header file if you want to avoid using it. +But, you are then responsible for setting up the ``cd_values`` array correctly for the filter. +For reference, the ``cd_values`` array for this ZFP_ filter is defined like so... + ++-----------+---------------------------------------------------------+ +| | cd_values index | ++-----------+--------+--------+---------+---------+---------+---------+ +| ZFP mode | 0 | 1 | 2 | 3 | 4 | 5 | ++-----------+--------+--------+---------+---------+---------+---------+ +| rate | 1 | unused | rateA | rateB | unused | unused | ++-----------+--------+--------+---------+---------+---------+---------+ +| precision | 2 | unused | prec | unused | unused | unused | ++-----------+--------+--------+---------+---------+---------+---------+ +| accuracy | 3 | unused | accA | accB | unused | unused | ++-----------+--------+--------+---------+---------+---------+---------+ +| expert | 4 | unused | minbits| maxbits| maxprec| minexp | ++-----------+--------+--------+---------+---------+---------+---------+ +| reversible| 5 | unused | unused | unused | unused | unused | ++-----------+--------+--------+---------+---------+---------+---------+ + +A/B are high/low 32-bit words of a double. + +Note that the cd_values used in the generic interface to ``H5Pset_filter()`` are **not the same** cd_values ultimately stored to the HDF5_ dataset header for a compressed dataset. +The values are transformed in the set_local method to use ZFP_'s internal routines for 'meta' and 'mode' data. +So, don't make the mistake of examining the values you find in a file and think you can use those same values, for example, in an invocation of h5repack. + +.. _properties-interface: + +-------------------- +Properties Interface +-------------------- + +For the properties interface, the following functions are defined in the ``H5Zzfp_props.h`` header file:: + + herr_t H5Pset_zfp_rate(hid_t dcpl_id, double rate); + herr_t H5Pset_zfp_precision(hid_t dcpl_id, unsigned int prec); + herr_t H5Pset_zfp_accuracy(hid_t dcpl_id, double acc); + herr_t H5Pset_zfp_expert(hid_t dcpl_id, + unsigned int minbits, unsigned int maxbits, + unsigned int maxprec, int minexp); + herr_t H5Pset_zfp_reversible(hid_t dcpl_id); + +These functions take a dataset creation property list, ``hid_t dcp_lid`` and create temporary HDF5_ property list entries to control the ZFP_ filter. +Calling any of these functions removes the effects of any previous call to any one of these functions. +In addition, calling any one of these functions also has the effect of adding the filter to the pipeline. + +Here is example code from `test_write.c `_... + +.. literalinclude:: ../test/test_write.c + :language: c + :linenos: + :start-after: When filter is used as a library, we need to init it + :end-before: #endif + +The properties interface is more type-safe than the generic interface. +However, there is no way for the implementation of the properties interface to reside within the filter plugin itself. +The properties interface requires that the caller link with with the filter as a *library*, ``libh5zzfp.a``. +The generic interface does not require this. + +Note that either interface can be used whether the filter is used as a plugin or as a library. +The difference is whether the application calls ``H5Z_zfp_initialize()`` or not. + +----------------- +Fortran Interface +----------------- + +Fortran equivalents for both the properties and generic interfaces, described above, has been added by Scot Breitenfeld of the HDF5_ group. +The code that implements the Fortran interfaces is in the file ``H5Zzfp_props_f.F90``. +An example of its use is in ``test/test_rw_fortran.F90``. + +.. _plugin-vs-library: + +---------------------------- +Plugin vs. Library Operation +---------------------------- + +The filter is designed to be compiled for use as both a standalone HDF5_ `dynamically loaded HDF5 plugin `_ and as an explicitly linked *library*. +When it is used as a plugin, it is a best practice to link the ZFP_ library into the plugin dynamic/shared object as a *static* library. +Why? In so doing, we ensure that all ZFP_ public namespace symbols remain *confined* to the plugin so as not to interfere with any application that may be directly explicitly linking to the ZFP_ library for other reasons. + +All HDF5_ applications are *required* to *find* the plugin dynamic library (named ``lib*.{so,dylib}``) in a directory specified by the environment variable, ``HDF5_PLUGIN_PATH``. +Currently, the HDF5 library offers no mechanism for applications themselves to have pre-programmed paths in which to search for a plugin. +Applications are then always vulnerable to an incorrectly specified or unspecified ``HDF5_PLUGIN_PATH`` environment variable. + +However, the plugin can also be used explicitly as a *library*. +In this case, **do** **not** specify the ``HDF5_PLUGIN_PATH`` environment variable and instead have the application link to ``libH5Zzfp.a`` in the ``lib`` dir of the installation. +Instead two initialization and finalization routines are defined:: + + int H5Z_zfp_initialize(void); + int H5Z_zfp_finalize(void); + +These functions are defined in the ``H5Zzfp_lib.h`` header file. +Any applications that wish to use the filter as a *library* are required to call the initialization routine, ``H5Z_zfp_initialize()`` before the filter can be referenced. +In addition, to free up resources used by the filter, applications may call ``H5Z_zfp_finalize()`` when they are done using the filter. diff --git a/ZFP/H5Z-ZFP/docs/requirements.txt b/ZFP/H5Z-ZFP/docs/requirements.txt new file mode 100644 index 00000000..49a29be2 --- /dev/null +++ b/ZFP/H5Z-ZFP/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx>=7.0,<9.0 +sphinx_rtd_theme>=2.0 diff --git a/ZFP/docs/tests.rst b/ZFP/H5Z-ZFP/docs/tests.rst similarity index 97% rename from ZFP/docs/tests.rst rename to ZFP/H5Z-ZFP/docs/tests.rst index 0b766bb1..ddb4d406 100644 --- a/ZFP/docs/tests.rst +++ b/ZFP/H5Z-ZFP/docs/tests.rst @@ -13,7 +13,7 @@ of the filter as an explicitly linked library. By default, these test a simple 1D array with and without ZFP_ compression using either the :ref:`generic-interface` (for plugin) or the :ref:`properties-interface` (for library). You can use the code there as an example of using the ZFP_ filter either as a plugin or as a library. However, these -also include some advanced usages for 4D and 6D, time-varying (e.g. *extendible*) +also include some advanced usages for 4D and 6D, time-varying (e.g. *extendable*) datasets. The command ``test_write_lib help`` or ``test_write_plugin help`` will print a list of the example's options and how to use them. @@ -34,7 +34,7 @@ Write Test Options chunk=256 set chunk size for 1D dataset doint=0 also do integer 1D data - ZFP compression paramaters... + ZFP compression parameters... zfpmode=3 (1=rate,2=prec,3=acc,4=expert,5=reversible) rate=4 set rate for rate mode of filter acc=0 set accuracy for accuracy mode of filter @@ -56,7 +56,7 @@ on a 4D dataset where two of the 4 dimensions are not correlated. This tests the plugin's ability to properly set chunking for HDF5 such that chunks span **only** correlated dimensions and have non-unity sizes in 3 or fewer dimensions. The ``sixd`` -test runs a test on a 6D, extendible dataset representing an +test runs a test on a 6D, extendable dataset representing an example of using ZFP_ for compression along the *time* axis. There is a companion, `test_read.c `_ diff --git a/ZFP/H5Z-ZFP/src/CMakeLists.txt b/ZFP/H5Z-ZFP/src/CMakeLists.txt new file mode 100644 index 00000000..efeab5fc --- /dev/null +++ b/ZFP/H5Z-ZFP/src/CMakeLists.txt @@ -0,0 +1,75 @@ +# Define headers. +set(h5z_zfp_headers + H5Zzfp.h H5Zzfp_lib.h H5Zzfp_plugin.h H5Zzfp_props.h H5Zzfp_version.h) + +#------------------------------------------------------------------------------# +# Static library +#------------------------------------------------------------------------------# +# Define source +set(h5z_zfp_lib_source + ${h5z_zfp_headers} + H5Zzfp_props_private.h + H5Zzfp.c H5Zzfp_props.c) + +if (FORTRAN_INTERFACE) + list(APPEND h5z_zfp_lib_source H5Zzfp_props_f.F90) +endif () + +add_library(h5z_zfp_static STATIC ${h5z_zfp_lib_source}) +target_compile_definitions(h5z_zfp_static PRIVATE H5Z_ZFP_AS_LIB) +target_include_directories(h5z_zfp_static + PUBLIC + "$" + "$" + "$" + ${HDF5_INCLUDE_DIRS} + "$<$:${HDF5_FORTRAN_INCLUDE_DIRS}>" +) +target_link_libraries(h5z_zfp_static PUBLIC zfp::zfp ${HDF5_LIBRARIES} $<$:${HDF5_FORTRAN_LIBRARIES}>) +set_target_properties(h5z_zfp_static PROPERTIES POSITION_INDEPENDENT_CODE 1) +set_target_properties(h5z_zfp_static PROPERTIES + OUTPUT_NAME h5zzfp + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) +install(TARGETS h5z_zfp_static + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +#------------------------------------------------------------------------------# +# Shared library +#------------------------------------------------------------------------------# +# Define source +set(h5z_zfp_plugin_source + ${h5z_zfp_headers} + H5Zzfp.c) + +add_library(h5z_zfp_shared SHARED ${h5z_zfp_plugin_source}) +target_include_directories(h5z_zfp_shared + PUBLIC + $ + $ + $ + ${HDF5_INCLUDE_DIRS}) +target_link_libraries(h5z_zfp_shared PUBLIC zfp::zfp ${HDF5_LIBRARIES}) +set_target_properties(h5z_zfp_shared PROPERTIES + OUTPUT_NAME h5zzfp + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin) +install(TARGETS h5z_zfp_shared + RUNTIME DESTINATION plugin + ARCHIVE DESTINATION plugin + LIBRARY DESTINATION plugin) + +#------------------------------------------------------------------------------# +# Install header and module files. +#------------------------------------------------------------------------------# +install(FILES ${h5z_zfp_headers} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +if (FORTRAN_INTERFACE) + install(FILES ${CMAKE_BINARY_DIR}/bin/h5zzfp_props_f.mod + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endif () diff --git a/ZFP/src/H5Zzfp.c b/ZFP/H5Z-ZFP/src/H5Zzfp.c similarity index 56% rename from ZFP/src/H5Zzfp.c rename to ZFP/H5Z-ZFP/src/H5Zzfp.c index 0734343c..28a76e85 100644 --- a/ZFP/src/H5Zzfp.c +++ b/ZFP/H5Z-ZFP/src/H5Zzfp.c @@ -1,9 +1,10 @@ #include #include + /* This code was based heavily on one of the HDF5 library's internal -filter, H5Zszip.c. The intention in so doing wasn't so much to -plagerize HDF5 developers as it was to produce a code that, if +filter, H5Zszip.c. The intention in so doing wasn't so much to +plagiarize HDF5 developers as it was to produce a code that, if The HDF Group ever decided to in the future, could be easily integrated with the existing HDF5 library code base. @@ -13,48 +14,13 @@ part of the Silo library but also supported as a stand-alone package. In Silo, the ZFP library is embedded inside a C struct to avoid pollution of the global namespace as well as collision with any other implementation of ZFP a Silo executable may be -linked with. Calls to ZFP lib methods are preface with 'Z ' +linked with. Calls to ZFP lib methods are preface with 'Z ' and calls to bitstream methods with 'B ' as in Z zfp_stream_open(...); B stream_open(...); */ -#include "zfp_config.h" -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef STDC_HEADERS -#include -#include -#else -#ifdef HAVE_STDLIB_H -#include -#endif -#endif -#ifdef HAVE_STRING_H -#if !defined STDC_HEADERS && defined HAVE_MEMORY_H -#include -#endif -#include -#endif -#ifdef HAVE_STRINGS_H -#include -#endif -#ifdef HAVE_INTTYPES_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - #ifdef Z #undef Z #endif @@ -74,31 +40,30 @@ and calls to bitstream methods with 'B ' as in #include "H5Spublic.h" #include "zfp.h" #define Z -#define B +#define B #endif /* ] AS_SILO_BUILTIN */ #include "H5Zzfp_plugin.h" #include "H5Zzfp_props_private.h" /* Convenient CPP logic to capture ZFP lib version numbers as compile time hex number */ -#define ZFP_VERSION_NO__(Maj, Min, Pat, Twk) (0x##Maj##Min##Pat##Twk) -#define ZFP_VERSION_NO_(Maj, Min, Pat, Twk) ZFP_VERSION_NO__(Maj, Min, Pat, Twk) +#define ZFP_VERSION_NO__(Maj,Min,Pat,Twk) (0x ## Maj ## Min ## Pat ## Twk) +#define ZFP_VERSION_NO_(Maj,Min,Pat,Twk) ZFP_VERSION_NO__(Maj,Min,Pat,Twk) #if defined(ZFP_VERSION_TWEAK) -#define ZFP_VERSION_NO \ - ZFP_VERSION_NO_(ZFP_VERSION_MAJOR, ZFP_VERSION_MINOR, ZFP_VERSION_PATCH, ZFP_VERSION_TWEAK) +#define ZFP_VERSION_NO ZFP_VERSION_NO_(ZFP_VERSION_MAJOR,ZFP_VERSION_MINOR,ZFP_VERSION_PATCH,ZFP_VERSION_TWEAK) #elif defined(ZFP_VERSION_RELEASE) -#define ZFP_VERSION_NO ZFP_VERSION_NO_(ZFP_VERSION_MAJOR, ZFP_VERSION_MINOR, ZFP_VERSION_RELEASE, 0) +#define ZFP_VERSION_NO ZFP_VERSION_NO_(ZFP_VERSION_MAJOR,ZFP_VERSION_MINOR,ZFP_VERSION_RELEASE,0) #elif defined(ZFP_VERSION_PATCH) -#define ZFP_VERSION_NO ZFP_VERSION_NO_(ZFP_VERSION_MAJOR, ZFP_VERSION_MINOR, ZFP_VERSION_PATCH, 0) +#define ZFP_VERSION_NO ZFP_VERSION_NO_(ZFP_VERSION_MAJOR,ZFP_VERSION_MINOR,ZFP_VERSION_PATCH,0) #else #error ZFP LIBRARY VERSION NOT DETECTED #endif /* Older versions of ZFP don't define this */ #ifndef ZFP_VERSION_STRING -#define ZFP_VERSION_STR__(Maj, Min, Rel) #Maj "." #Min "." #Rel -#define ZFP_VERSION_STR_(Maj, Min, Rel) ZFP_VERSION_STR__(Maj, Min, Rel) -#define ZFP_VERSION_STRING ZFP_VERSION_STR_(ZFP_VERSION_MAJOR, ZFP_VERSION_MINOR, ZFP_VERSION_RELEASE) +#define ZFP_VERSION_STR__(Maj,Min,Rel) #Maj "." #Min "." #Rel +#define ZFP_VERSION_STR_(Maj,Min,Rel) ZFP_VERSION_STR__(Maj,Min,Rel) +#define ZFP_VERSION_STRING ZFP_VERSION_STR_(ZFP_VERSION_MAJOR,ZFP_VERSION_MINOR,ZFP_VERSION_RELEASE) #endif /* Older versions of ZFP don't define this publicly */ @@ -107,107 +72,93 @@ and calls to bitstream methods with 'B ' as in #endif /* Convenient CPP logic to capture H5Z_ZFP Filter version numbers as string and hex number */ -#define H5Z_FILTER_ZFP_VERSION_STR__(Maj, Min, Pat) #Maj "." #Min "." #Pat -#define H5Z_FILTER_ZFP_VERSION_STR_(Maj, Min, Pat) H5Z_FILTER_ZFP_VERSION_STR__(Maj, Min, Pat) -#define H5Z_FILTER_ZFP_VERSION_STR \ - H5Z_FILTER_ZFP_VERSION_STR_(H5Z_FILTER_ZFP_VERSION_MAJOR, H5Z_FILTER_ZFP_VERSION_MINOR, \ - H5Z_FILTER_ZFP_VERSION_PATCH) - -#define H5Z_FILTER_ZFP_VERSION_NO__(Maj, Min, Pat) (0x0##Maj##Min##Pat) -#define H5Z_FILTER_ZFP_VERSION_NO_(Maj, Min, Pat) H5Z_FILTER_ZFP_VERSION_NO__(Maj, Min, Pat) -#define H5Z_FILTER_ZFP_VERSION_NO \ - H5Z_FILTER_ZFP_VERSION_NO_(H5Z_FILTER_ZFP_VERSION_MAJOR, H5Z_FILTER_ZFP_VERSION_MINOR, \ - H5Z_FILTER_ZFP_VERSION_PATCH) - -#define H5Z_ZFP_PUSH_AND_GOTO(MAJ, MIN, RET, MSG) \ - do { \ - H5Epush(H5E_DEFAULT, __FILE__, _funcname_, __LINE__, H5E_ERR_CLS, MAJ, MIN, MSG); \ - retval = RET; \ - goto done; \ - } while (0) +#define H5Z_FILTER_ZFP_VERSION_STR__(Maj,Min,Pat) #Maj "." #Min "." #Pat +#define H5Z_FILTER_ZFP_VERSION_STR_(Maj,Min,Pat) H5Z_FILTER_ZFP_VERSION_STR__(Maj,Min,Pat) +#define H5Z_FILTER_ZFP_VERSION_STR H5Z_FILTER_ZFP_VERSION_STR_(H5Z_FILTER_ZFP_VERSION_MAJOR,H5Z_FILTER_ZFP_VERSION_MINOR,H5Z_FILTER_ZFP_VERSION_PATCH) + +#define H5Z_FILTER_ZFP_VERSION_NO__(Maj,Min,Pat) (0x0 ## Maj ## Min ## Pat) +#define H5Z_FILTER_ZFP_VERSION_NO_(Maj,Min,Pat) H5Z_FILTER_ZFP_VERSION_NO__(Maj,Min,Pat) +#define H5Z_FILTER_ZFP_VERSION_NO H5Z_FILTER_ZFP_VERSION_NO_(H5Z_FILTER_ZFP_VERSION_MAJOR,H5Z_FILTER_ZFP_VERSION_MINOR,H5Z_FILTER_ZFP_VERSION_PATCH) + +#define H5Z_ZFP_PUSH_AND_GOTO(MAJ, MIN, RET, MSG) \ +do \ +{ \ + H5Epush(H5E_DEFAULT,__FILE__,_funcname_,__LINE__, \ + H5E_ERR_CLS,MAJ,MIN,MSG); \ + retval = RET; \ + goto done; \ +} while(0) static int h5z_zfp_was_registered = 0; -static size_t H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], - size_t nbytes, size_t *buf_size, void **buf); +static size_t H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[], + size_t nbytes, size_t *buf_size, void **buf); static htri_t H5Z_zfp_can_apply(hid_t dcpl_id, hid_t type_id, hid_t space_id); static herr_t H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t space_id); const H5Z_class2_t H5Z_ZFP[1] = {{ - H5Z_CLASS_T_VERS, /* H5Z_class_t version */ - (H5Z_filter_t)(H5Z_FILTER_ZFP), /* Filter id number */ -#ifdef FILTER_DECODE_ONLY - 0, /* encoder_present flag (false is not available) */ -#else - 1, /* encoder_present flag (set to true) */ -#endif - 1, /* decoder_present flag */ - "H5Z-ZFP" /* Filter name for debugging */ - "-" H5Z_FILTER_ZFP_VERSION_STR " (ZFP-" ZFP_VERSION_STRING ") " - "github.com/LLNL/H5Z-ZFP", - (H5Z_can_apply_func_t)(H5Z_zfp_can_apply), /* The "can apply" callback */ - (H5Z_set_local_func_t)(H5Z_zfp_set_local), /* The "set local" callback */ - (H5Z_func_t)(H5Z_filter_zfp), /* The actual filter function */ + H5Z_CLASS_T_VERS, /* H5Z_class_t version */ + H5Z_FILTER_ZFP, /* Filter id number */ + 1, /* encoder_present flag */ + 1, /* decoder_present flag */ + "H5Z-ZFP" /* Filter name for debugging */ + "-" H5Z_FILTER_ZFP_VERSION_STR + " (ZFP-" ZFP_VERSION_STRING ")", + H5Z_zfp_can_apply, /* The "can apply" callback */ + H5Z_zfp_set_local, /* The "set local" callback */ + H5Z_filter_zfp, /* The actual filter function */ }}; #ifdef H5Z_ZFP_AS_LIB -int -H5Z_zfp_initialize(void) +int H5Z_zfp_initialize(void) { if (H5Zfilter_avail(H5Z_FILTER_ZFP)) return 1; - if (H5Zregister(H5Z_ZFP) < 0) + if (H5Zregister(H5Z_ZFP)<0) return -1; h5z_zfp_was_registered = 1; return 1; } #else -H5PL_type_t -H5PLget_plugin_type(void) -{ - return H5PL_TYPE_FILTER; -} -const void * -H5PLget_plugin_info(void) -{ - return H5Z_ZFP; -} +H5PL_type_t H5PLget_plugin_type(void) {return H5PL_TYPE_FILTER;} +const void *H5PLget_plugin_info(void) {return H5Z_ZFP;} #endif #ifndef H5Z_ZFP_AS_LIB static #endif - int - H5Z_zfp_finalize(void) +int H5Z_zfp_finalize(void) { herr_t ret2 = 0; if (h5z_zfp_was_registered) ret2 = H5Zunregister(H5Z_FILTER_ZFP); h5z_zfp_was_registered = 0; - if (ret2 < 0) - return -1; + if (ret2 < 0) return -1; return 1; } static htri_t H5Z_zfp_can_apply(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) -{ +{ static char const *_funcname_ = "H5Z_zfp_can_apply"; - int const max_ndims = (ZFP_VERSION_NO <= 0x0053) ? 3 : 4; - int ndims, ndims_used = 0; - size_t i, dsize; - htri_t retval = 0; - hsize_t dims[H5S_MAX_RANK]; - H5T_class_t dclass; - hid_t native_type_id; + int const max_ndims = (ZFP_VERSION_NO <= 0x0053) ? 3 : 4; + int ndims, ndims_used = 0; + size_t i, dsize; + htri_t retval = 0; + hsize_t dims[H5S_MAX_RANK]; + H5T_class_t dclass; + hid_t native_type_id; + + (void)dcpl_id; /* currently not used */ /* Disable the ZFP filter entirely if it looks like the ZFP library hasn't been compiled for 8-bit stream word size */ - if ((int)B stream_word_bits != 8) + if ((int) B stream_word_bits != 8) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTINIT, -1, - "ZFP lib not compiled with -DBIT_STREAM_WORD_TYPE=uint8"); + "ZFP lib not compiled with -DBIT_STREAM_WORD_TYPE=uint8"); /* get datatype class, size and space dimensions */ if (H5T_NO_CLASS == (dclass = H5Tget_class(type_id))) @@ -219,39 +170,42 @@ H5Z_zfp_can_apply(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) if (0 > (ndims = H5Sget_simple_extent_dims(chunk_space_id, dims, 0))) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, -1, "bad chunk data space"); - /* confirm ZFP library can handle this data */ + /* confirm ZFP library can handle this data */ #if ZFP_VERSION_NO < 0x0510 if (!(dclass == H5T_FLOAT)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, "requires datatype class of H5T_FLOAT"); + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, + "requires datatype class of H5T_FLOAT"); #else if (!(dclass == H5T_FLOAT || dclass == H5T_INTEGER)) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, - "requires datatype class of H5T_FLOAT or H5T_INTEGER"); + "requires datatype class of H5T_FLOAT or H5T_INTEGER"); #endif if (!(dsize == 4 || dsize == 8)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, "requires datatype size of 4 or 8"); + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, + "requires datatype size of 4 or 8"); /* check for *USED* dimensions of the chunk */ - for (i = 0; i < ndims; i++) { - if (dims[i] <= 1) - continue; + for (i = 0; i < (size_t) ndims; i++) + { + if (dims[i] <= 1) continue; ndims_used++; } -#if ZFP_VERSION_NO < 0x0530 if (ndims_used == 0 || ndims_used > max_ndims) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "chunk must have only 1...3 non-unity dimensions"); +#if ZFP_VERSION_NO < 0x0530 + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, + "chunk must have only 1...3 non-unity dimensions"); #else - if (ndims_used == 0 || ndims_used > max_ndims) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "chunk must have only 1...4 non-unity dimensions"); + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, + "chunk must have only 1...4 non-unity dimensions"); #endif - /* if caller is doing "endian targetting", disallow that */ + /* if caller is doing "endian targeting", disallow that */ native_type_id = H5Tget_native_type(type_id, H5T_DIR_ASCEND); if (H5Tget_order(type_id) != H5Tget_order(native_type_id)) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, - "endian targetting non-sensical in conjunction with ZFP filter"); + "endian targeting non-sensical in conjunction with ZFP filter"); retval = 1; @@ -262,23 +216,23 @@ H5Z_zfp_can_apply(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) static herr_t H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) -{ +{ static char const *_funcname_ = "H5Z_zfp_set_local"; - int i, ndims, ndims_used = 0; - size_t dsize, hdr_bits, hdr_bytes; - size_t mem_cd_nelmts = H5Z_ZFP_CD_NELMTS_MEM; - unsigned int mem_cd_values[H5Z_ZFP_CD_NELMTS_MEM]; - size_t hdr_cd_nelmts = H5Z_ZFP_CD_NELMTS_MAX; - unsigned int hdr_cd_values[H5Z_ZFP_CD_NELMTS_MAX]; - unsigned int flags = 0; - herr_t retval = 0; - hsize_t dims[H5S_MAX_RANK], dims_used[H5S_MAX_RANK]; - H5T_class_t dclass; - zfp_type zt; - zfp_field *dummy_field = 0; - bitstream *dummy_bstr = 0; - zfp_stream *dummy_zstr = 0; - int have_zfp_controls = 0; + int i, ndims, ndims_used = 0; + size_t dsize, hdr_bits, hdr_bytes; + size_t mem_cd_nelmts = H5Z_ZFP_CD_NELMTS_MEM; + unsigned int mem_cd_values[H5Z_ZFP_CD_NELMTS_MEM]; + size_t hdr_cd_nelmts = H5Z_ZFP_CD_NELMTS_MAX; + unsigned int hdr_cd_values[H5Z_ZFP_CD_NELMTS_MAX]; + unsigned int flags = 0; + herr_t retval = 0; + hsize_t dims[H5S_MAX_RANK], dims_used[H5S_MAX_RANK]; + H5T_class_t dclass; + zfp_type zt; + zfp_field *dummy_field = 0; + bitstream *dummy_bstr = 0; + zfp_stream *dummy_zstr = 0; + int have_zfp_controls = 0; h5z_zfp_controls_t ctrls; if (0 > (dclass = H5Tget_class(type_id))) @@ -291,7 +245,8 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADTYPE, -1, "not a data space"); /* setup zfp data type for meta header */ - if (dclass == H5T_FLOAT) { + if (dclass == H5T_FLOAT) + { if (dsize == sizeof(float)) zt = zfp_type_float; else if (dsize == sizeof(double)) @@ -299,7 +254,8 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) else H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADTYPE, -1, "invalid datatype size"); } - else if (dclass == H5T_INTEGER) { + else if (dclass == H5T_INTEGER) + { if (dsize == sizeof(int32)) zt = zfp_type_int32; else if (dsize == sizeof(int64)) @@ -307,53 +263,50 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) else H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADTYPE, -1, "invalid datatype size"); } - else { - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, "datatype class must be H5T_FLOAT or H5T_INTEGER"); + else + { + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, + "datatype class must be H5T_FLOAT or H5T_INTEGER"); } /* computed used (e.g. non-unity) dimensions in chunk */ - for (i = 0; i < ndims; i++) { - if (dims[i] <= 1) - continue; + for (i = 0; i < ndims; i++) + { + if (dims[i] <= 1) continue; dims_used[ndims_used] = dims[i]; ndims_used++; } /* set up dummy zfp field to compute meta header */ - switch (ndims_used) { - case 1: - dummy_field = Z zfp_field_1d(0, zt, dims_used[0]); - break; - case 2: - dummy_field = Z zfp_field_2d(0, zt, dims_used[1], dims_used[0]); - break; - case 3: - dummy_field = Z zfp_field_3d(0, zt, dims_used[2], dims_used[1], dims_used[0]); - break; + switch (ndims_used) + { + case 1: dummy_field = Z zfp_field_1d(0, zt, dims_used[0]); break; + case 2: dummy_field = Z zfp_field_2d(0, zt, dims_used[1], dims_used[0]); break; + case 3: dummy_field = Z zfp_field_3d(0, zt, dims_used[2], dims_used[1], dims_used[0]); break; #if ZFP_VERSION_NO >= 0x0540 - case 4: - dummy_field = Z zfp_field_4d(0, zt, dims_used[3], dims_used[2], dims_used[1], dims_used[0]); - break; + case 4: dummy_field = Z zfp_field_4d(0, zt, dims_used[3], dims_used[2], dims_used[1], dims_used[0]); break; #endif - default: #if ZFP_VERSION_NO < 0x0530 - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "chunks may have only 1...3 non-unity dims"); + default: H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, + "chunks may have only 1...3 non-unity dims"); #else - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "chunks may have only 1...4 non-unity dims"); + default: H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, + "chunks may have only 1...4 non-unity dims"); #endif } if (!dummy_field) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "zfp_field_Xd() failed"); /* get current cd_values and re-map to new cd_value set */ - if (0 > - H5Pget_filter_by_id(dcpl_id, H5Z_FILTER_ZFP, &flags, &mem_cd_nelmts, mem_cd_values, 0, NULL, NULL)) + if (0 > H5Pget_filter_by_id(dcpl_id, H5Z_FILTER_ZFP, &flags, &mem_cd_nelmts, mem_cd_values, 0, NULL, NULL)) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTGET, 0, "unable to get current ZFP cd_values"); /* Handle default case when no cd_values are passed by using ZFP library defaults. */ - if (mem_cd_nelmts == 0) { - /* check for filter controls in the properites */ - if (0 < H5Pexist(dcpl_id, "zfp_controls")) { + if (mem_cd_nelmts == 0) + { + /* check for filter controls in the properties */ + if (0 < H5Pexist(dcpl_id, "zfp_controls")) + { if (0 > H5Pget(dcpl_id, "zfp_controls", &ctrls)) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTGET, 0, "unable to get ZFP controls"); have_zfp_controls = 1; @@ -361,14 +314,13 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) else /* just use ZFP library defaults */ { mem_cd_nelmts = H5Z_ZFP_CD_NELMTS_MEM; - H5Pset_zfp_expert_cdata(ZFP_MIN_BITS, ZFP_MAX_BITS, ZFP_MAX_PREC, ZFP_MIN_EXP, mem_cd_nelmts, - mem_cd_values); + H5Pset_zfp_expert_cdata(ZFP_MIN_BITS, ZFP_MAX_BITS, ZFP_MAX_PREC, ZFP_MIN_EXP, mem_cd_nelmts, mem_cd_values); } } - + /* Into hdr_cd_values, we encode ZFP library and H5Z-ZFP plugin version info at entry 0 and use remaining entries as a tiny buffer to write ZFP native header. */ - hdr_cd_values[0] = (unsigned int)((ZFP_VERSION_NO << 16) | (ZFP_CODEC << 12) | H5Z_FILTER_ZFP_VERSION_NO); + hdr_cd_values[0] = (unsigned int) ((ZFP_VERSION_NO<<16) | (ZFP_CODEC<<12) | H5Z_FILTER_ZFP_VERSION_NO); if (0 == (dummy_bstr = B stream_open(&hdr_cd_values[1], sizeof(hdr_cd_values)))) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "stream_open() failed"); @@ -376,8 +328,10 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "zfp_stream_open() failed"); /* Set the ZFP stream mode from zfp_control properties or mem_cd_values[0] */ - if (have_zfp_controls) { - switch (ctrls.mode) { + if (have_zfp_controls) + { + switch (ctrls.mode) + { case H5Z_ZFP_MODE_RATE: Z zfp_stream_set_rate(dummy_zstr, ctrls.details.rate, zt, ndims_used, 0); break; @@ -397,8 +351,8 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) break; case H5Z_ZFP_MODE_EXPERT: Z zfp_stream_set_params(dummy_zstr, ctrls.details.expert.minbits, - ctrls.details.expert.maxbits, ctrls.details.expert.maxprec, - ctrls.details.expert.minexp); + ctrls.details.expert.maxbits, ctrls.details.expert.maxprec, + ctrls.details.expert.minexp); break; #if ZFP_VERSION_NO >= 0x0550 case H5Z_ZFP_MODE_REVERSIBLE: @@ -409,10 +363,12 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "invalid ZFP mode"); } } - else { - switch (mem_cd_values[0]) { + else + { + switch (mem_cd_values[0]) + { case H5Z_ZFP_MODE_RATE: - Z zfp_stream_set_rate(dummy_zstr, *((double *)&mem_cd_values[2]), zt, ndims_used, 0); + Z zfp_stream_set_rate(dummy_zstr, *((double*) &mem_cd_values[2]), zt, ndims_used, 0); break; case H5Z_ZFP_MODE_PRECISION: #if ZFP_VERSION_NO < 0x0510 @@ -423,14 +379,14 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) break; case H5Z_ZFP_MODE_ACCURACY: #if ZFP_VERSION_NO < 0x0510 - Z zfp_stream_set_accuracy(dummy_zstr, *((double *)&mem_cd_values[2]), zt); + Z zfp_stream_set_accuracy(dummy_zstr, *((double*) &mem_cd_values[2]), zt); #else - Z zfp_stream_set_accuracy(dummy_zstr, *((double *)&mem_cd_values[2])); + Z zfp_stream_set_accuracy(dummy_zstr, *((double*) &mem_cd_values[2])); #endif break; case H5Z_ZFP_MODE_EXPERT: - Z zfp_stream_set_params(dummy_zstr, mem_cd_values[2], mem_cd_values[3], mem_cd_values[4], - (int)mem_cd_values[5]); + Z zfp_stream_set_params(dummy_zstr, mem_cd_values[2], mem_cd_values[3], + mem_cd_values[4], (int) mem_cd_values[5]); break; #if ZFP_VERSION_NO >= 0x0550 case H5Z_ZFP_MODE_REVERSIBLE: @@ -450,7 +406,7 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) Z zfp_stream_flush(dummy_zstr); /* compute necessary hdr_cd_values size */ - hdr_bytes = 1 + ((hdr_bits - 1) / 8); + hdr_bytes = 1 + ((hdr_bits - 1) / 8); hdr_cd_nelmts = 1 + ((hdr_bytes - 1) / sizeof(hdr_cd_values[0])); hdr_cd_nelmts++; /* for slot 0 holding version info */ @@ -459,39 +415,34 @@ H5Z_zfp_set_local(hid_t dcpl_id, hid_t type_id, hid_t chunk_space_id) /* Now, update cd_values for the filter */ if (0 > H5Pmodify_filter(dcpl_id, H5Z_FILTER_ZFP, flags, hdr_cd_nelmts, hdr_cd_values)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "failed to modify cd_values"); + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, + "failed to modify cd_values"); /* cleanup the dummy ZFP stuff we used to generate the header */ - Z zfp_field_free(dummy_field); - dummy_field = 0; - Z zfp_stream_close(dummy_zstr); - dummy_zstr = 0; - B stream_close(dummy_bstr); - dummy_bstr = 0; + Z zfp_field_free(dummy_field); dummy_field = 0; + Z zfp_stream_close(dummy_zstr); dummy_zstr = 0; + B stream_close(dummy_bstr); dummy_bstr = 0; retval = 1; done: - if (dummy_field) - Z zfp_field_free(dummy_field); - if (dummy_zstr) - Z zfp_stream_close(dummy_zstr); - if (dummy_bstr) - B stream_close(dummy_bstr); + if (dummy_field) Z zfp_field_free(dummy_field); + if (dummy_zstr) Z zfp_stream_close(dummy_zstr); + if (dummy_bstr) B stream_close(dummy_bstr); return retval; } static int -get_zfp_info_from_cd_values(size_t cd_nelmts, unsigned int const *cd_values, uint64 *zfp_mode, - uint64 *zfp_meta, H5T_order_t *swap) +get_zfp_info_from_cd_values(size_t cd_nelmts, unsigned int const *cd_values, + uint64 *zfp_mode, uint64 *zfp_meta, H5T_order_t *swap) { static char const *_funcname_ = "get_zfp_info_from_cd_values"; - unsigned int cd_values_copy[H5Z_ZFP_CD_NELMTS_MAX]; - int retval = 0; - bitstream *bstr = 0; - zfp_stream *zstr = 0; - zfp_field *zfld = 0; + unsigned int cd_values_copy[H5Z_ZFP_CD_NELMTS_MAX]; + int retval = 0; + bitstream *bstr = 0; + zfp_stream *zstr = 0; + zfp_field *zfld = 0; if (cd_nelmts > H5Z_ZFP_CD_NELMTS_MAX) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_OVERFLOW, 0, "cd_nelmts exceeds max"); @@ -511,7 +462,8 @@ get_zfp_info_from_cd_values(size_t cd_nelmts, unsigned int const *cd_values, uin H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "allocating field failed"); /* Do a read of *just* magic to detect possible codec version mismatch */ - if (0 == (Z zfp_read_header(zstr, zfld, ZFP_HEADER_MAGIC))) { + if (0 == (Z zfp_read_header(zstr, zfld, ZFP_HEADER_MAGIC))) + { herr_t conv; /* The read may have failed due to difference in endian-ness between @@ -538,21 +490,15 @@ get_zfp_info_from_cd_values(size_t cd_nelmts, unsigned int const *cd_values, uin *zfp_meta = Z zfp_field_metadata(zfld); /* cleanup */ - Z zfp_field_free(zfld); - zfld = 0; - Z zfp_stream_close(zstr); - zstr = 0; - B stream_close(bstr); - bstr = 0; + Z zfp_field_free(zfld); zfld = 0; + Z zfp_stream_close(zstr); zstr = 0; + B stream_close(bstr); bstr = 0; retval = 1; done: - if (zfld) - Z zfp_field_free(zfld); - if (zstr) - Z zfp_stream_close(zstr); - if (bstr) - B stream_close(bstr); + if (zfld) Z zfp_field_free(zfld); + if (zstr) Z zfp_stream_close(zstr); + if (bstr) B stream_close(bstr); return retval; } @@ -573,21 +519,23 @@ version was incrimented. */ static int -zfp_codec_version_mismatch(unsigned int h5zfpver_from_cd_val_data_in_file, - unsigned int zfpver_from_cd_val_data_in_file, - unsigned int zfpcodec_from_cd_val_data_in_file) +zfp_codec_version_mismatch( + unsigned int h5zfpver_from_cd_val_data_in_file, + unsigned int zfpver_from_cd_val_data_in_file, + unsigned int zfpcodec_from_cd_val_data_in_file) { int writer_codec; int reader_codec; - if (h5zfpver_from_cd_val_data_in_file < 0x0110) { + if (h5zfpver_from_cd_val_data_in_file < 0x0110) + { /* for data written with older versions of the filter, we infer codec from ZFP library version stored in the file. */ zfpver_from_cd_val_data_in_file <<= 4; if (zfpver_from_cd_val_data_in_file < 0x0500) writer_codec = 4; else if (zfpver_from_cd_val_data_in_file < 0x1000) - writer_codec = (zfpver_from_cd_val_data_in_file & 0x0F00) >> 8; + writer_codec = (zfpver_from_cd_val_data_in_file & 0x0F00)>>8; else if (zfpver_from_cd_val_data_in_file == 0x1000) writer_codec = 5; else @@ -608,28 +556,31 @@ zfp_codec_version_mismatch(unsigned int h5zfpver_from_cd_val_data_in_file, } static size_t -H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, - size_t *buf_size, void **buf) +H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, + const unsigned int cd_values[], size_t nbytes, + size_t *buf_size, void **buf) { - static char const *_funcname_ = "H5Z_filter_zfp"; - void *newbuf = 0; - size_t retval = 0; - unsigned int cd_vals_h5zzfpver = cd_values[0] & 0x00000FFF; - unsigned int cd_vals_zfpcodec = (cd_values[0] >> 12) & 0x0000000F; - unsigned int cd_vals_zfpver = (cd_values[0] >> 16) & 0x0000FFFF; - H5T_order_t swap = H5T_ORDER_NONE; - uint64 zfp_mode, zfp_meta; - bitstream *bstr = 0; - zfp_stream *zstr = 0; - zfp_field *zfld = 0; + static char const *_funcname_ = "H5Z_filter_zfp"; + void *newbuf = 0; + size_t retval = 0; + unsigned int cd_vals_h5zzfpver = cd_values[0]&0x00000FFF; + unsigned int cd_vals_zfpcodec = (cd_values[0]>>12)&0x0000000F; + unsigned int cd_vals_zfpver = (cd_values[0]>>16)&0x0000FFFF; + H5T_order_t swap = H5T_ORDER_NONE; + uint64 zfp_mode, zfp_meta; + bitstream *bstr = 0; + zfp_stream *zstr = 0; + zfp_field *zfld = 0; + + (void)nbytes; /* currently not used */ /* Pass &cd_values[1] here to strip off first entry holding version info */ - if (0 == get_zfp_info_from_cd_values(cd_nelmts - 1, &cd_values[1], &zfp_mode, &zfp_meta, &swap)) + if (0 == get_zfp_info_from_cd_values(cd_nelmts-1, &cd_values[1], &zfp_mode, &zfp_meta, &swap)) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTGET, 0, "can't get ZFP mode/meta"); if (flags & H5Z_FLAG_REVERSE) /* decompression */ { - int status; + int status; size_t bsize, dsize; /* Worry about zfp version mismatch only for decompression */ @@ -643,27 +594,19 @@ H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value Z zfp_field_set_metadata(zfld, zfp_meta); bsize = Z zfp_field_size(zfld, 0); - switch (Z zfp_field_type(zfld)) { - case zfp_type_int32: - dsize = sizeof(int32); - break; - case zfp_type_int64: - dsize = sizeof(int64); - break; - case zfp_type_float: - dsize = sizeof(float); - break; - case zfp_type_double: - dsize = sizeof(double); - break; - default: - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, "invalid datatype"); + switch (Z zfp_field_type(zfld)) + { + case zfp_type_int32: dsize = sizeof(int32); break; + case zfp_type_int64: dsize = sizeof(int64); break; + case zfp_type_float: dsize = sizeof(float); break; + case zfp_type_double: dsize = sizeof(double); break; + default: H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADTYPE, 0, "invalid datatype"); } bsize *= dsize; if (NULL == (newbuf = malloc(bsize))) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, - "memory allocation failed for ZFP decompression"); + "memory allocation failed for ZFP decompression"); Z zfp_field_set_pointer(zfld, newbuf); @@ -680,36 +623,34 @@ H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value status = Z zfp_decompress(zstr, zfld); /* clean up */ - Z zfp_field_free(zfld); - zfld = 0; - Z zfp_stream_close(zstr); - zstr = 0; - B stream_close(bstr); - bstr = 0; + Z zfp_field_free(zfld); zfld = 0; + Z zfp_stream_close(zstr); zstr = 0; + B stream_close(bstr); bstr = 0; if (!status) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTFILTER, 0, "decompression failed"); - /* ZFP is an endian-independent format. It will produce correct endian-ness - during decompress regardless of endian-ness differences between reader - and writer. However, the HDF5 library will not be expecting that. So, - we need to undue the correct endian-ness here. We use HDF5's built-in - byte-swapping here. Because we know we need only to endian-swap, - we treat the data as unsigned. */ - if (swap != H5T_ORDER_NONE) { - hid_t src = dsize == 4 ? H5T_STD_U32BE : H5T_STD_U64BE; + /* ZFP is an endian-independent format. It will produce correct endian-ness + during decompress regardless of endian-ness differences between reader + and writer. However, the HDF5 library will not be expecting that. So, + we need to undue the correct endian-ness here. We use HDF5's built-in + byte-swapping here. Because we know we need only to endian-swap, + we treat the data as unsigned. */ + if (swap != H5T_ORDER_NONE) + { + hid_t src = dsize == 4 ? H5T_STD_U32BE : H5T_STD_U64BE; hid_t dst = dsize == 4 ? H5T_NATIVE_UINT32 : H5T_NATIVE_UINT64; if (swap == H5T_ORDER_BE) - src = dsize == 4 ? H5T_STD_U32LE : H5T_STD_U64LE; - if (H5Tconvert(src, dst, bsize / dsize, newbuf, 0, H5P_DEFAULT) < 0) + src = dsize == 4 ? H5T_STD_U32LE : H5T_STD_U64LE; + if (H5Tconvert(src, dst, bsize/dsize, newbuf, 0, H5P_DEFAULT) < 0) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, 0, "endian-UN-swap failed"); } free(*buf); - *buf = newbuf; - newbuf = 0; - *buf_size = bsize; - retval = bsize; + *buf = newbuf; + newbuf = 0; + *buf_size = bsize; + retval = bsize; } else /* compression */ { @@ -726,13 +667,13 @@ H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value if (0 == (zstr = Z zfp_stream_open(0))) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "zfp stream open failed"); - Z zfp_stream_set_mode(zstr, zfp_mode); + Z zfp_stream_set_mode(zstr, zfp_mode); msize = Z zfp_stream_maximum_size(zstr, zfld); /* Set up the bitstream object */ if (NULL == (newbuf = malloc(msize))) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, - "memory allocation failed for ZFP compression"); + "memory allocation failed for ZFP compression"); if (0 == (bstr = B stream_open(newbuf, msize))) H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, 0, "bitstream open failed"); @@ -743,12 +684,9 @@ H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value zsize = Z zfp_compress(zstr, zfld); /* clean up */ - Z zfp_field_free(zfld); - zfld = 0; - Z zfp_stream_close(zstr); - zstr = 0; - B stream_close(bstr); - bstr = 0; + Z zfp_field_free(zfld); zfld = 0; + Z zfp_stream_close(zstr); zstr = 0; + B stream_close(bstr); bstr = 0; if (zsize == 0) H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_CANTFILTER, 0, "compression failed"); @@ -757,22 +695,18 @@ H5Z_filter_zfp(unsigned int flags, size_t cd_nelmts, const unsigned int cd_value H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_OVERFLOW, 0, "uncompressed buffer overrun"); free(*buf); - *buf = newbuf; - newbuf = 0; + *buf = newbuf; + newbuf = 0; *buf_size = zsize; - retval = zsize; + retval = zsize; } done: - if (zfld) - Z zfp_field_free(zfld); - if (zstr) - Z zfp_stream_close(zstr); - if (bstr) - B stream_close(bstr); - if (newbuf) - free(newbuf); - return retval; + if (zfld) Z zfp_field_free(zfld); + if (zstr) Z zfp_stream_close(zstr); + if (bstr) B stream_close(bstr); + if (newbuf) free(newbuf); + return retval ; } #undef Z diff --git a/ZFP/src/H5Zzfp.h b/ZFP/H5Z-ZFP/src/H5Zzfp.h similarity index 100% rename from ZFP/src/H5Zzfp.h rename to ZFP/H5Z-ZFP/src/H5Zzfp.h diff --git a/ZFP/src/H5Zzfp_lib.h b/ZFP/H5Z-ZFP/src/H5Zzfp_lib.h similarity index 100% rename from ZFP/src/H5Zzfp_lib.h rename to ZFP/H5Z-ZFP/src/H5Zzfp_lib.h diff --git a/ZFP/H5Z-ZFP/src/H5Zzfp_plugin.h b/ZFP/H5Z-ZFP/src/H5Zzfp_plugin.h new file mode 100644 index 00000000..dd893c08 --- /dev/null +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_plugin.h @@ -0,0 +1,70 @@ +#ifndef H5Z_ZFP_PLUGIN_H +#define H5Z_ZFP_PLUGIN_H + +#include "H5Zzfp_version.h" + +/* HDF5 generic cd_vals[] memory layout (6 unsigned ints) for + controlling H5Z-ZFP behavior as a plugin. NOTE: These cd_vals + used to pass properties in-memory from caller to filter via HDF5 + generic interface are NOT THE SAME AS the cd_vals[] that + ultimately get stored to the file for the filter "header" data. + +cd_vals 0 1 2 3 4 5 +---------------------------------------------------------------- +rate: 1 unused rateA rateB unused unused +precision: 2 unused prec unused unused unused +accuracy: 3 unused accA accB unused unused +expert: 4 unused minbits maxbits maxprec minexp + +A/B are high/low words of a double. +*/ + +#define H5Pset_zfp_rate_cdata(R, N, CD) \ +do { if (N>=4) {double *p = (double *) &CD[2]; \ +CD[0]=CD[1]=CD[2]=CD[3]=0; \ +CD[0]=H5Z_ZFP_MODE_RATE; *p=R; N=4;}} while(0) + +#define H5Pget_zfp_rate_cdata(N, CD) \ +((double)(((N>=4)&&(CD[0]==H5Z_ZFP_MODE_RATE))?*((double *) &CD[2]):0)) + +#define H5Pset_zfp_precision_cdata(P, N, CD) \ +do { if (N>=3) {CD[0]=H5Z_ZFP_MODE_PRECISION; \ +CD[1]=0; CD[2]=P; N=3;}} while(0) + +#define H5Pget_zfp_precision_cdata(N, CD) \ +((double)(((N>=3)&&(CD[0]==H5Z_ZFP_MODE_PRECISION))?CD[2]:0)) + +#define H5Pset_zfp_accuracy_cdata(A, N, CD) \ +do { if (N>=4) {double *p = (double *) &CD[2]; \ +CD[0]=CD[1]=CD[2]=CD[3]=0; \ +CD[0]=H5Z_ZFP_MODE_ACCURACY; *p=A; N=4;}} while(0) + +#define H5Pget_zfp_accuracy_cdata(N, CD) \ +((double)(((N>=4)&&(CD[0]==H5Z_ZFP_MODE_ACCURACY))?*((double *) &CD[2]):0)) + +#define H5Pset_zfp_expert_cdata(MiB, MaB, MaP, MiE, N, CD) \ +do { if (N>=6) { CD[0]=CD[1]=CD[2]=CD[3]=CD[4]=CD[5]=0; \ +CD[0]=H5Z_ZFP_MODE_EXPERT; \ +CD[2]=MiB; CD[3]=MaB; CD[4]=MaP; \ +CD[5]=(unsigned int)MiE; N=6;}} while(0) + +#define H5Pget_zfp_expert_cdata(N, CD, MiB, MaB, MaP, MiE) \ +do { \ + if ((N>=6)&&(CD[0] == H5Z_ZFP_MODE_EXPERT)) \ + { \ + unsigned int *p; int *q; \ + p = &MiB; *p = CD[2]; \ + p = &MaB; *p = CD[3]; \ + p = &MaP; *p = CD[4]; \ + q = &MiE; *q = (int) CD[5]; \ + } \ +} while(0) + +#define H5Pset_zfp_reversible_cdata(N, CD) \ +do { if (N>=1) { \ +CD[0]=H5Z_ZFP_MODE_REVERSIBLE; N=1;}} while(0) + +#define H5Pget_zfp_reversible_cdata(N, CD) \ +((int)(((N>=1)&&(CD[0]==H5Z_ZFP_MODE_REVERSIBLE))?1:0)) + +#endif diff --git a/ZFP/H5Z-ZFP/src/H5Zzfp_props.c b/ZFP/H5Z-ZFP/src/H5Zzfp_props.c new file mode 100644 index 00000000..8cb9b288 --- /dev/null +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_props.c @@ -0,0 +1,177 @@ +#include "H5Zzfp_plugin.h" +#include "H5Zzfp_props_private.h" + +#include "hdf5.h" + +#include +#include +#include + +#define H5Z_ZFP_PUSH_AND_GOTO(MAJ, MIN, RET, MSG) \ +do \ +{ \ + H5Epush(H5E_DEFAULT,__FILE__,_funcname_,__LINE__, \ + H5E_ERR_CLS_g,MAJ,MIN,MSG); \ + retval = RET; \ + goto done; \ +} while(0) + +static herr_t H5Pset_zfp(hid_t plist, int mode, ...) +{ + static char const *_funcname_ = "H5Pset_zfp"; + static size_t const ctrls_sz = sizeof(h5z_zfp_controls_t); + unsigned int flags; + size_t cd_nelmts = 0; + unsigned int cd_values[1]; + h5z_zfp_controls_t *ctrls_p = 0; + int i; + va_list ap; + herr_t retval = 0; + + if (0 >= H5Pisa_class(plist, H5P_DATASET_CREATE)) + H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADTYPE, -1, "not a dataset creation property list class"); + + ctrls_p = (h5z_zfp_controls_t *) malloc(ctrls_sz); + if (0 == ctrls_p) + H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, -1, "allocation failed for ZFP controls"); + + va_start(ap, mode); + ctrls_p->mode = mode; + switch (mode) + { + case H5Z_ZFP_MODE_RATE: + { + ctrls_p->details.rate = va_arg(ap, double); + if (0 > ctrls_p->details.rate) + H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "rate out of range."); + break; + } + case H5Z_ZFP_MODE_ACCURACY: + { + ctrls_p->details.acc = va_arg(ap, double); + if (0 > ctrls_p->details.acc) + H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "accuracy out of range."); + break; + } + case H5Z_ZFP_MODE_PRECISION: + { + ctrls_p->details.prec = va_arg(ap, unsigned int); + break; + } + case H5Z_ZFP_MODE_EXPERT: + { + ctrls_p->details.expert.minbits = va_arg(ap, unsigned int); + ctrls_p->details.expert.maxbits = va_arg(ap, unsigned int); + ctrls_p->details.expert.maxprec = va_arg(ap, unsigned int); + ctrls_p->details.expert.minexp = va_arg(ap, int); + break; + } + case H5Z_ZFP_MODE_REVERSIBLE: + { + break; + } + default: + { + H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "bad ZFP mode."); + break; + } + } + va_end(ap); + + for (i = 0; i < H5Pget_nfilters(plist); i++) + { + H5Z_filter_t fid; + if (0 <= (fid = H5Pget_filter(plist, i, &flags, &cd_nelmts, cd_values, 0, 0, 0)) + && fid == H5Z_FILTER_ZFP) + { + if (0 > H5Premove_filter(plist, H5Z_FILTER_ZFP)) + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, -1, "Unable to remove old ZFP filter from pipeline."); + break; + } + } + + if (0 > H5Pset_filter(plist, H5Z_FILTER_ZFP, H5Z_FLAG_MANDATORY, 0, 0)) + H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, -1, "Unable to put ZFP filter in pipeline."); + + if (0 == H5Pexist(plist, "zfp_controls")) + { + retval = H5Pinsert2(plist, "zfp_controls", ctrls_sz, ctrls_p, 0, 0, 0, 0, 0, 0); + } + else + { + retval = H5Pset(plist, "zfp_controls", ctrls_p); + } + + /* HDF5 copies the memory we gave it */ + free(ctrls_p); + + return retval; + +done: + + if (ctrls_p) + free(ctrls_p); + + return retval; +} + +herr_t H5Pset_zfp_rate(hid_t plist, double rate) +{ + return H5Pset_zfp(plist, H5Z_ZFP_MODE_RATE, rate); +} + +herr_t H5Pset_zfp_precision(hid_t plist, unsigned int prec) +{ + return H5Pset_zfp(plist, H5Z_ZFP_MODE_PRECISION, prec); +} + +herr_t H5Pset_zfp_accuracy(hid_t plist, double acc) +{ + return H5Pset_zfp(plist, H5Z_ZFP_MODE_ACCURACY, acc); +} + +herr_t H5Pset_zfp_expert(hid_t plist, unsigned int minbits, unsigned int maxbits, + unsigned int maxprec, int minexp) +{ + return H5Pset_zfp(plist, H5Z_ZFP_MODE_EXPERT, minbits, maxbits, maxprec, minexp); +} + +herr_t H5Pset_zfp_reversible(hid_t plist) +{ + return H5Pset_zfp(plist, H5Z_ZFP_MODE_REVERSIBLE); +} + + +/* Used only for Fortran wrappers */ + +void H5Pset_zfp_rate_cdata_f(double rate, size_t *cd_nelmts_f, unsigned int *cd_values) { + size_t cd_nelmts = *cd_nelmts_f; + H5Pset_zfp_rate_cdata(rate, cd_nelmts, cd_values); + *cd_nelmts_f = cd_nelmts; +} + +void H5Pset_zfp_precision_cdata_f(unsigned int prec, size_t *cd_nelmts_f, unsigned int *cd_values) { + size_t cd_nelmts = *cd_nelmts_f; + H5Pset_zfp_precision_cdata(prec, cd_nelmts, cd_values); + *cd_nelmts_f = cd_nelmts; +} + +void H5Pset_zfp_accuracy_cdata_f(double acc, size_t *cd_nelmts_f, unsigned int *cd_values) { + size_t cd_nelmts = *cd_nelmts_f; + H5Pset_zfp_accuracy_cdata(acc, cd_nelmts, cd_values); + *cd_nelmts_f = cd_nelmts; +} + +void H5Pset_zfp_expert_cdata_f(unsigned int minbits, unsigned int maxbits, unsigned int maxprec, + int minexp, size_t *cd_nelmts_f, unsigned int *cd_values) { + size_t cd_nelmts = *cd_nelmts_f; + H5Pset_zfp_expert_cdata(minbits, maxbits, maxprec, minexp, cd_nelmts, cd_values); + *cd_nelmts_f = cd_nelmts; +} + +void H5Pset_zfp_reversible_cdata_f(size_t *cd_nelmts_f, unsigned int *cd_values) { + size_t cd_nelmts = *cd_nelmts_f; + H5Pset_zfp_reversible_cdata(cd_nelmts, cd_values); + *cd_nelmts_f = cd_nelmts; +} + diff --git a/ZFP/src/H5Zzfp_props.h b/ZFP/H5Z-ZFP/src/H5Zzfp_props.h similarity index 74% rename from ZFP/src/H5Zzfp_props.h rename to ZFP/H5Z-ZFP/src/H5Zzfp_props.h index f3631842..1e3dffec 100644 --- a/ZFP/src/H5Zzfp_props.h +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_props.h @@ -1,18 +1,16 @@ #ifndef H5Z_ZFP_PROPS_H #define H5Z_ZFP_PROPS_H -#include "hdf5.h" - #ifdef __cplusplus extern "C" { #endif -extern herr_t H5Pset_zfp_rate(hid_t plist, double rate); -extern herr_t H5Pset_zfp_precision(hid_t plist, unsigned int prec); -extern herr_t H5Pset_zfp_accuracy(hid_t plist, double acc); -extern herr_t H5Pset_zfp_expert(hid_t plist, unsigned int minbits, unsigned int maxbits, unsigned int maxprec, - int minexp); -extern herr_t H5Pset_zfp_reversible(hid_t plist); +extern herr_t H5Pset_zfp_rate(hid_t plist, double rate); +extern herr_t H5Pset_zfp_precision(hid_t plist, unsigned int prec); +extern herr_t H5Pset_zfp_accuracy(hid_t plist, double acc); +extern herr_t H5Pset_zfp_expert(hid_t plist, unsigned int minbits, unsigned int maxbits, + unsigned int maxprec, int minexp); +extern herr_t H5Pset_zfp_reversible(hid_t plist); extern void H5Pset_zfp_rate_cdata_f(double rate, size_t *cd_nelmts, unsigned int *cd_values); extern void H5Pset_zfp_precision_cdata_f(unsigned int prec, size_t *cd_nelmts, unsigned int *cd_values); diff --git a/ZFP/H5Z-ZFP/src/H5Zzfp_props_f.F90 b/ZFP/H5Z-ZFP/src/H5Zzfp_props_f.F90 new file mode 100644 index 00000000..e9bfa937 --- /dev/null +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_props_f.F90 @@ -0,0 +1,147 @@ +MODULE h5zzfp_props_f + +#include "H5Zzfp_version.h" + + USE ISO_C_BINDING + USE HDF5 + IMPLICIT NONE + + ! First, create _F equivalent parameters for all the C interface's CPP symbols and + ! capture the original C interface's CPP values. + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_F=H5Z_FILTER_ZFP + + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_MAJOR_F=H5Z_FILTER_ZFP_VERSION_MAJOR + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_MINOR_F=H5Z_FILTER_ZFP_VERSION_MINOR + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_PATCH_F=H5Z_FILTER_ZFP_VERSION_PATCH + + INTEGER(C_SIZE_T), PARAMETER :: H5Z_ZFP_CD_NELMTS_MEM_F=H5Z_ZFP_CD_NELMTS_MEM + INTEGER(C_SIZE_T), PARAMETER :: H5Z_ZFP_CD_NELMTS_MAX_F=H5Z_ZFP_CD_NELMTS_MAX + + INTEGER, PARAMETER :: H5Z_ZFP_MODE_RATE_F = H5Z_ZFP_MODE_RATE + INTEGER, PARAMETER :: H5Z_ZFP_MODE_PRECISION_F = H5Z_ZFP_MODE_PRECISION + INTEGER, PARAMETER :: H5Z_ZFP_MODE_ACCURACY_F = H5Z_ZFP_MODE_ACCURACY + INTEGER, PARAMETER :: H5Z_ZFP_MODE_EXPERT_F = H5Z_ZFP_MODE_EXPERT + INTEGER, PARAMETER :: H5Z_ZFP_MODE_REVERSIBLE_F = H5Z_ZFP_MODE_REVERSIBLE + + ! Next, undef all the C interface's CPP symbols so we can declare Fortran parameters + ! with the identical names +#undef H5Z_FILTER_ZFP +#undef H5Z_FILTER_ZFP_VERSION_MAJOR +#undef H5Z_FILTER_ZFP_VERSION_MINOR +#undef H5Z_FILTER_ZFP_VERSION_PATCH +#undef H5Z_ZFP_CD_NELMTS_MEM +#undef H5Z_ZFP_CD_NELMTS_MAX +#undef H5Z_ZFP_MODE_RATE +#undef H5Z_ZFP_MODE_PRECISION +#undef H5Z_ZFP_MODE_ACCURACY +#undef H5Z_ZFP_MODE_EXPERT +#undef H5Z_ZFP_MODE_REVERSIBLE + + ! Define Fortran parameters using the original _F values captured above. + INTEGER, PARAMETER :: H5Z_FILTER_ZFP=H5Z_FILTER_ZFP_F + + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_MAJOR=H5Z_FILTER_ZFP_VERSION_MAJOR_F + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_MINOR=H5Z_FILTER_ZFP_VERSION_MINOR_F + INTEGER, PARAMETER :: H5Z_FILTER_ZFP_VERSION_PATCH=H5Z_FILTER_ZFP_VERSION_PATCH_F + + INTEGER(C_SIZE_T), PARAMETER :: H5Z_ZFP_CD_NELMTS_MEM=H5Z_ZFP_CD_NELMTS_MEM_F + INTEGER(C_SIZE_T), PARAMETER :: H5Z_ZFP_CD_NELMTS_MAX=H5Z_ZFP_CD_NELMTS_MAX_F + + INTEGER, PARAMETER :: H5Z_ZFP_MODE_RATE = H5Z_ZFP_MODE_RATE_F + INTEGER, PARAMETER :: H5Z_ZFP_MODE_PRECISION = H5Z_ZFP_MODE_PRECISION_F + INTEGER, PARAMETER :: H5Z_ZFP_MODE_ACCURACY = H5Z_ZFP_MODE_ACCURACY_F + INTEGER, PARAMETER :: H5Z_ZFP_MODE_EXPERT = H5Z_ZFP_MODE_EXPERT_F + INTEGER, PARAMETER :: H5Z_ZFP_MODE_REVERSIBLE = H5Z_ZFP_MODE_REVERSIBLE_F + + INTERFACE + INTEGER(C_INT) FUNCTION H5Z_zfp_initialize() BIND(C, NAME='H5Z_zfp_initialize') + IMPORT :: C_INT + IMPLICIT NONE + END FUNCTION H5Z_zfp_initialize + + INTEGER(C_INT) FUNCTION H5Z_zfp_finalize() BIND(C, NAME='H5Z_zfp_finalize') + IMPORT :: C_INT + IMPLICIT NONE + END FUNCTION H5Z_zfp_finalize + + INTEGER(C_INT) FUNCTION H5Pset_zfp_rate(plist, rate) BIND(C, NAME='H5Pset_zfp_rate') + IMPORT :: C_INT, C_DOUBLE, HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: plist + REAL(C_DOUBLE), VALUE :: rate + END FUNCTION H5Pset_zfp_rate + + INTEGER(C_INT) FUNCTION H5Pset_zfp_precision(plist, prec) BIND(C, NAME='H5Pset_zfp_precision') + IMPORT :: C_INT, HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: plist + INTEGER(C_INT), VALUE :: prec + END FUNCTION H5Pset_zfp_precision + + INTEGER(C_INT) FUNCTION H5Pset_zfp_accuracy(plist, acc) BIND(C, NAME='H5Pset_zfp_accuracy') + IMPORT :: C_INT, C_DOUBLE, HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: plist + REAL(C_DOUBLE), VALUE :: acc + END FUNCTION H5Pset_zfp_accuracy + + INTEGER(C_INT) FUNCTION H5Pset_zfp_expert(plist, minbits, maxbits, maxprec, minexp) & + BIND(C, NAME='H5Pset_zfp_expert') + IMPORT :: C_INT, HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: plist + INTEGER(C_INT), VALUE :: minbits + INTEGER(C_INT), VALUE :: maxbits + INTEGER(C_INT), VALUE :: maxprec + INTEGER(C_INT), VALUE :: minexp + END FUNCTION H5Pset_zfp_expert + + INTEGER(C_INT) FUNCTION H5Pset_zfp_reversible(plist) BIND(C, NAME='H5Pset_zfp_reversible') + IMPORT :: C_INT, HID_T + IMPLICIT NONE + INTEGER(HID_T), VALUE :: plist + END FUNCTION H5Pset_zfp_reversible + + SUBROUTINE H5Pset_zfp_rate_cdata(rate, cd_nelmts, cd_values) BIND(C, NAME='H5Pset_zfp_rate_cdata_f') + IMPORT :: C_DOUBLE, C_INT, C_SIZE_T + IMPLICIT NONE + REAL(C_DOUBLE), VALUE :: rate + INTEGER(C_SIZE_T) :: cd_nelmts + INTEGER(C_INT), DIMENSION(*) :: cd_values + END SUBROUTINE H5Pset_zfp_rate_cdata + + SUBROUTINE H5Pset_zfp_accuracy_cdata(acc, cd_nelmts, cd_values) BIND(C, NAME='H5Pset_zfp_accuracy_cdata_f') + IMPORT :: C_DOUBLE, C_INT, C_SIZE_T + IMPLICIT NONE + REAL(C_DOUBLE), VALUE :: acc + INTEGER(C_SIZE_T) :: cd_nelmts + INTEGER(C_INT), DIMENSION(*) :: cd_values + END SUBROUTINE H5Pset_zfp_accuracy_cdata + + SUBROUTINE H5Pset_zfp_precision_cdata(prec, cd_nelmts, cd_values) BIND(C, NAME='H5Pset_zfp_precision_cdata_f') + IMPORT :: C_INT, C_SIZE_T + IMPLICIT NONE + INTEGER(C_INT), VALUE :: prec + INTEGER(C_SIZE_T) :: cd_nelmts + INTEGER(C_INT), DIMENSION(*) :: cd_values + END SUBROUTINE H5Pset_zfp_precision_cdata + + SUBROUTINE H5Pset_zfp_expert_cdata(minbits, maxbits, maxprec, minexp, cd_nelmts, cd_values) & + BIND(C, NAME='H5Pset_zfp_expert_cdata_f') + IMPORT :: C_INT, C_SIZE_T + IMPLICIT NONE + INTEGER(C_INT), VALUE :: minbits, maxbits, maxprec, minexp + INTEGER(C_SIZE_T) :: cd_nelmts + INTEGER(C_INT), DIMENSION(*) :: cd_values + END SUBROUTINE H5Pset_zfp_expert_cdata + + SUBROUTINE H5Pset_zfp_reversible_cdata(cd_nelmts, cd_values) BIND(C, NAME='H5Pset_zfp_reversible_cdata_f') + IMPORT :: C_INT, C_SIZE_T + IMPLICIT NONE + INTEGER(C_SIZE_T) :: cd_nelmts + INTEGER(C_INT), DIMENSION(*) :: cd_values + END SUBROUTINE H5Pset_zfp_reversible_cdata + + END INTERFACE + +END MODULE H5Zzfp_props_f diff --git a/ZFP/src/H5Zzfp_props_private.h b/ZFP/H5Z-ZFP/src/H5Zzfp_props_private.h similarity index 80% rename from ZFP/src/H5Zzfp_props_private.h rename to ZFP/H5Z-ZFP/src/H5Zzfp_props_private.h index b6115d91..c738d191 100644 --- a/ZFP/src/H5Zzfp_props_private.h +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_props_private.h @@ -4,14 +4,14 @@ typedef struct _h5z_zfp_controls_t { unsigned int mode; union { - double rate; - double acc; + double rate; + double acc; unsigned int prec; struct expert_ { unsigned int minbits; unsigned int maxbits; unsigned int maxprec; - int minexp; + int minexp; } expert; } details; } h5z_zfp_controls_t; diff --git a/ZFP/src/H5Zzfp_version.h b/ZFP/H5Z-ZFP/src/H5Zzfp_version.h similarity index 69% rename from ZFP/src/H5Zzfp_version.h rename to ZFP/H5Z-ZFP/src/H5Zzfp_version.h index ce4823f2..a79179ca 100644 --- a/ZFP/src/H5Zzfp_version.h +++ b/ZFP/H5Z-ZFP/src/H5Zzfp_version.h @@ -7,10 +7,10 @@ #define H5Z_FILTER_ZFP_VERSION_MINOR 1 #define H5Z_FILTER_ZFP_VERSION_PATCH 1 -#define H5Z_ZFP_MODE_RATE 1 -#define H5Z_ZFP_MODE_PRECISION 2 -#define H5Z_ZFP_MODE_ACCURACY 3 -#define H5Z_ZFP_MODE_EXPERT 4 +#define H5Z_ZFP_MODE_RATE 1 +#define H5Z_ZFP_MODE_PRECISION 2 +#define H5Z_ZFP_MODE_ACCURACY 3 +#define H5Z_ZFP_MODE_EXPERT 4 #define H5Z_ZFP_MODE_REVERSIBLE 5 #define H5Z_ZFP_CD_NELMTS_MEM 6 diff --git a/ZFP/H5Z-ZFP/src/Makefile b/ZFP/H5Z-ZFP/src/Makefile new file mode 100644 index 00000000..35cb6d21 --- /dev/null +++ b/ZFP/H5Z-ZFP/src/Makefile @@ -0,0 +1,68 @@ +ifneq ($(strip $(MAKECMDGOALS)),clean) + include ../config.make +endif + +.PHONY: all lib clean + +# The filter compiled to be used as a plugin +H5Zzfp_plugin.o: H5Zzfp.c + $(CC) -c $< -o $@ $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +# The filter compiled to be used as a library +H5Zzfp_lib.o: H5Zzfp.c + $(CC) -c $< -o $@ -DH5Z_ZFP_AS_LIB $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +# The plugin shared lib (HDF5 expects it to be named "lib*.{so,dylib}" +plugin/libh5zzfp.$(SOEXT): H5Zzfp_plugin.o + rm -rf plugin + mkdir plugin + $(CC) $< $(SHFLAG) -o plugin/libh5zzfp.$(SOEXT) \ + $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) \ + -L$(ZFP_LIB) -L$(HDF5_LIB) -lhdf5 -lzfp $(LDFLAGS) + +# Alias target for filter plugin +plugin: plugin/libh5zzfp.$(SOEXT) + +# C language properties interface +H5Zzfp_props.o: H5Zzfp_props.c + $(CC) -c $< -o $@ $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +# Fortran language properties interface +H5Zzfp_props_f.o H5Zzfp_props_f.mod: H5Zzfp_props_f.F90 + $(FC) -c $< -o $@ $(FCFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +# The filter member of the filter library +libh5zzfp.a(H5Zzfp_lib.o): H5Zzfp_lib.o + $(AR) cr libh5zzfp.a $< + +# The C properties interface member of the filter library +libh5zzfp.a(H5Zzfp_props.o): H5Zzfp_props.o + $(AR) cr libh5zzfp.a $< + +# The Fortran properties interface member of the filter library +libh5zzfp.a(H5Zzfp_props_f.o): H5Zzfp_props_f.o + $(AR) cr libh5zzfp.a $< + +# Alias target for filter library, conditionally includes Fortran +LIBOBJ = libh5zzfp.a(H5Zzfp_lib.o) libh5zzfp.a(H5Zzfp_props.o) +ifneq ($(FC),) +LIBOBJ += libh5zzfp.a(H5Zzfp_props_f.o) +endif +lib: $(LIBOBJ) + +all: lib plugin + +install: all + $(INSTALL) -d $(DESTDIR)$(PREFIX)/{plugin,include,lib} + $(INSTALL) plugin/libh5zzfp.$(SOEXT) $(DESTDIR)$(PREFIX)/plugin + $(INSTALL) libh5zzfp.a $(DESTDIR)$(PREFIX)/lib + $(INSTALL) -m 644 H5Zzfp.h H5Zzfp_lib.h H5Zzfp_plugin.h H5Zzfp_version.h H5Zzfp_props.h $(DESTDIR)$(PREFIX)/include +ifneq ($(FC),) + $(INSTALL) -m 644 *.[mM][oO][dD] $(DESTDIR)$(PREFIX)/include +endif + +clean: + rm -rf plugin + rm -f libh5zzfp.a *.o *.[mM][oO][dD] + rm -f *.gcno *.gcda *.gcov + rm -f H5Zzfp_props_f.mod diff --git a/ZFP/H5Z-ZFP/test/CMakeLists.txt b/ZFP/H5Z-ZFP/test/CMakeLists.txt new file mode 100644 index 00000000..f871c38f --- /dev/null +++ b/ZFP/H5Z-ZFP/test/CMakeLists.txt @@ -0,0 +1,973 @@ +set(ZFP_LIB_VERSION ${ZFP_VERSION_MAJOR}${ZFP_VERSION_MINOR}${ZFP_VERSION_PATCH}) +if (ZFP_VERSION VERSION_GREATER_EQUAL 1.0.0) + set(ZFP_LIB_VERSION ${ZFP_LIB_VERSION}${ZFP_VERSION_TWEAK}) +endif () +set(ZFP_HAS_CFP 0) +if (ZFP_CFP_ENABLED) + set(ZFP_HAS_CFP 1) +endif() + +# HDF5 docs say H5Dwrite_chunk was introduced in 1.10.2 +set(HDF5_HAS_WRITE_CHUNK 0) +if ("${HDF5_VERSION}" VERSION_GREATER_EQUAL "1.10.2") + set(HDF5_HAS_WRITE_CHUNK 1) +endif() + +#------------------------------------------------------------------------------# +# Setup HDF5_PLUGIN_PATH +#------------------------------------------------------------------------------# +get_target_property(HDF5_PLUGIN_PATH h5z_zfp_shared RUNTIME_OUTPUT_DIRECTORY) +if (_isMultiConfig) + set(HDF5_PLUGIN_PATH "${HDF5_PLUGIN_PATH}/${HDF_CFG_NAME}") +endif () + +#------------------------------------------------------------------------------# +# Plugin and library write & read tests (No check implemented) +#------------------------------------------------------------------------------# +add_executable(test_write_plugin test_write.c) +target_compile_definitions(test_write_plugin PRIVATE H5Z_ZFP_USE_PLUGIN) +target_compile_definitions(test_write_plugin PRIVATE ZFP_LIB_VERSION=0x${ZFP_LIB_VERSION}) +target_link_libraries(test_write_plugin h5z_zfp_shared) +if (NOT WIN32) + target_link_libraries(test_write_plugin m) +endif () + +add_executable(test_read_plugin test_read.c) +target_compile_definitions(test_read_plugin PRIVATE H5Z_ZFP_USE_PLUGIN) +target_link_libraries(test_read_plugin h5z_zfp_shared) +if (NOT WIN32) + target_link_libraries(test_read_plugin m) +endif () + +add_executable(test_write_lib test_write.c) +target_compile_definitions(test_write_lib PRIVATE ZFP_LIB_VERSION=0x${ZFP_LIB_VERSION}) +target_compile_definitions(test_write_lib PRIVATE HDF5_HAS_WRITE_CHUNK=${HDF5_HAS_WRITE_CHUNK}) +target_compile_definitions(test_write_lib PRIVATE ZFP_HAS_CFP=${ZFP_HAS_CFP}) +target_link_libraries(test_write_lib h5z_zfp_static) +if (ZFP_CFP_ENABLED) + target_link_libraries(test_write_lib zfp::cfp) +endif () +if (NOT WIN32) + target_link_libraries(test_write_lib m) +endif () + +add_executable(test_read_lib test_read.c) +target_link_libraries(test_read_lib h5z_zfp_static) +if (NOT WIN32) + target_link_libraries(test_read_lib m) +endif () + +if (FORTRAN_INTERFACE) + add_executable(test_rw_fortran test_rw_fortran.F90) + target_link_libraries(test_rw_fortran h5z_zfp_static) + set_target_properties (test_rw_fortran PROPERTIES LINKER_LANGUAGE Fortran) +endif () + +#------------------------------------------------------------------------------# +# Tests +#------------------------------------------------------------------------------# + +if (MSVC) + string(REPLACE ";" "\\;" ESCAPED_PATH "$ENV{PATH}") +endif () + +# Rate +set(RATE_RATE 32 16 8 4) +if (MSVC) + set(RATE_DIFF 3e-7 0.008 2.0 45) +else () + set(RATE_DIFF 1e-7 0.003 0.4 33) +endif () +list(LENGTH RATE_RATE NRATES) +math(EXPR NRATES "${NRATES} - 1") +foreach (IRATE RANGE ${NRATES}) + list(GET RATE_RATE ${IRATE} RATE) + list(GET RATE_DIFF ${IRATE} DIFF) + + add_test( + NAME + test-rate-write-${RATE} + COMMAND + $ zfpmode=1 rate=${RATE} ofile=test_zfp-rate-${RATE}.h5 + ) + set_property( + TEST + test-rate-write-${RATE} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-rate-write-${RATE} + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + + add_test( + NAME + test-rate-read-${RATE} + COMMAND + $ max_absdiff=${DIFF} max_reldiff=${DIFF} ifile=test_zfp-rate-${RATE}.h5 + ) + set_property( + TEST + test-rate-read-${RATE} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-rate-read-${RATE} + APPEND + PROPERTY + ENVIRONMENT "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-rate-read-${RATE} PROPERTIES DEPENDS test-rate-write-${RATE}) + + add_test( + NAME + test-rate-cleanup-${RATE} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-rate-${RATE}.h5 + ) + set_tests_properties (test-rate-cleanup-${RATE} PROPERTIES DEPENDS test-rate-read-${RATE}) + + set_tests_properties(test-rate-write-${RATE} PROPERTIES FIXTURES_SETUP "rate-read-${RATE};rate-cleanup-${RATE}") + set_tests_properties(test-rate-write-${RATE} PROPERTIES FIXTURES_REQUIRED "rate-write-${RATE}") + set_tests_properties(test-rate-read-${RATE} PROPERTIES FIXTURES_REQUIRED "rate-read-${RATE}") + set_tests_properties(test-rate-cleanup-${RATE} PROPERTIES FIXTURES_REQUIRED "rate-cleanup-${RATE}") + set_tests_properties(test-rate-cleanup-${RATE} PROPERTIES FIXTURES_CLEANUP "rate-write-${RATE};rate-read-${RATE}") + + add_test( + NAME + test-lib-rate-write-${RATE} + COMMAND + $ zfpmode=1 rate=${RATE} ofile=test_zfp-lib-rate-${RATE}.h5 + ) + + add_test( + NAME + test-lib-rate-read-${RATE} + COMMAND + $ max_absdiff=${DIFF} max_reldiff=${DIFF} ifile=test_zfp-lib-rate-${RATE}.h5 + ) + set_tests_properties (test-lib-rate-read-${RATE} PROPERTIES DEPENDS test-lib-rate-write-${RATE}) + + add_test( + NAME + test-lib-rate-cleanup-${RATE} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-lib-rate-${RATE}.h5 + ) + set_tests_properties (test-lib-rate-cleanup-${RATE} PROPERTIES DEPENDS test-lib-rate-read-${RATE}) + + set_tests_properties(test-lib-rate-write-${RATE} PROPERTIES FIXTURES_SETUP "lib-rate-read-${RATE};lib-rate-cleanup-${RATE}") + set_tests_properties(test-lib-rate-write-${RATE} PROPERTIES FIXTURES_REQUIRED "lib-rate-write-${RATE}") + set_tests_properties(test-lib-rate-read-${RATE} PROPERTIES FIXTURES_REQUIRED "lib-rate-read-${RATE}") + set_tests_properties(test-lib-rate-cleanup-${RATE} PROPERTIES FIXTURES_REQUIRED "lib-rate-cleanup-${RATE}") + set_tests_properties(test-lib-rate-cleanup-${RATE} PROPERTIES FIXTURES_CLEANUP "lib-rate-write-${RATE};lib-rate-read-${RATE}") + + if (NOT MSVC AND FORTRAN_INTERFACE) + add_test( + NAME + test-rate-write-${RATE}-f + COMMAND + $ zfpmode 1 rate ${RATE} ofile test_zfp_fortran-rate-${RATE}.h5 + ) + + add_test( + NAME + test-rate-info1-${RATE}-f + COMMAND + "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=${HDF5_DUMP_EXECUTABLE}" + -D "TEST_FILE=test_zfp_fortran-rate-${RATE}.h5" + -D "TEST_DSET=compressed" + -D "TEST_RATE=${RATE}" + -D "RATE_START=64" + -P "${CMAKE_CURRENT_SOURCE_DIR}/h5dump-rate.cmake" + ) + set_tests_properties (test-rate-info1-${RATE}-f PROPERTIES DEPENDS test-rate-write-${RATE}-f) + + add_test( + NAME + test-rate-info2-${RATE}-f + COMMAND + "${CMAKE_COMMAND}" + -D "TEST_PROGRAM=${HDF5_DUMP_EXECUTABLE}" + -D "TEST_FILE=test_zfp_fortran-rate-${RATE}.h5" + -D "TEST_DSET=compressed-plugin" + -D "TEST_RATE=${RATE}" + -D "RATE_START=64" + -P "${CMAKE_CURRENT_SOURCE_DIR}/h5dump-rate.cmake" + ) + set_tests_properties (test-rate-info2-${RATE}-f PROPERTIES DEPENDS test-rate-info1-${RATE}-f) + + add_test( + NAME + test-rate-cleanup-${RATE}-f + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp_fortran-rate-${RATE}.h5 + ) + set_tests_properties (test-rate-cleanup-${RATE}-f PROPERTIES DEPENDS test-rate-info2-${RATE}-f) + + set_tests_properties(test-rate-write-${RATE}-f PROPERTIES FIXTURES_SETUP "rate-info1-${RATE}-f;rate-info1-${RATE}-f;rate-cleanup-${RATE}-f") + set_tests_properties(test-rate-write-${RATE}-f PROPERTIES FIXTURES_REQUIRED "rate-write-${RATE}-f") + set_tests_properties(test-rate-info1-${RATE}-f PROPERTIES FIXTURES_REQUIRED "rate-info1-${RATE}-f") + set_tests_properties(test-rate-info2-${RATE}-f PROPERTIES FIXTURES_REQUIRED "rate-info2-${RATE}-f") + set_tests_properties(test-rate-cleanup-${RATE}-f PROPERTIES FIXTURES_REQUIRED "rate-cleanup-${RATE}-f") + set_tests_properties(test-rate-cleanup-${RATE}-f PROPERTIES FIXTURES_CLEANUP "rate-write-${RATE}-f;rate-info1-${RATE}-f;rate-info1-${RATE}-f") + endif () +endforeach () + +# Accuracy +set(ACC_NO 1 2 3 4) +set(ACC_ACC 0.1 0.01 0.001 0.0001) +set(ACC_DIFF 0.025 0.004 0.0006 4e-5) +list(LENGTH ACC_NO NACCS) +math(EXPR NACCS "${NACCS} - 1") +foreach (IACC RANGE ${NACCS}) + list(GET ACC_NO ${IACC} NUMBER) + list(GET ACC_ACC ${IACC} ACC) + list(GET ACC_DIFF ${IACC} DIFF) + + add_test( + NAME + test-accuracy-write-${NUMBER} + COMMAND + $ zfpmode=3 acc=${ACC} ofile=test_zfp-acc-${NUMBER}.h5 + ) + set_property( + TEST + test-accuracy-write-${NUMBER} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-accuracy-write-${NUMBER} + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + + add_test( + NAME + test-accuracy-read-${NUMBER} + COMMAND + $ ret=1 max_absdiff=${DIFF} ifile=test_zfp-acc-${NUMBER}.h5 + ) + set_property( + TEST + test-accuracy-read-${NUMBER} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-accuracy-read-${NUMBER} + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-accuracy-read-${NUMBER} PROPERTIES DEPENDS test-accuracy-write-${NUMBER}) + + add_test( + NAME + test-accuracy-cleanup-${NUMBER} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-acc-${NUMBER}.h5 + ) + set_tests_properties (test-accuracy-cleanup-${NUMBER} PROPERTIES DEPENDS test-accuracy-read-${NUMBER}) + + set_tests_properties(test-accuracy-write-${NUMBER} PROPERTIES FIXTURES_SETUP "accuracy-read-${NUMBER};accuracy-cleanup-${NUMBER}") + set_tests_properties(test-accuracy-write-${NUMBER} PROPERTIES FIXTURES_REQUIRED "accuracy-write-${NUMBER}") + set_tests_properties(test-accuracy-read-${NUMBER} PROPERTIES FIXTURES_REQUIRED "accuracy-read-${NUMBER}") + set_tests_properties(test-accuracy-cleanup-${NUMBER} PROPERTIES FIXTURES_REQUIRED "accuracy-cleanup-${NUMBER}") + set_tests_properties(test-accuracy-cleanup-${NUMBER} PROPERTIES FIXTURES_CLEANUP "accuracy-write-${NUMBER};accuracy-read-${NUMBER}") + + add_test( + NAME + test-lib-accuracy-write-${NUMBER} + COMMAND + $ zfpmode=3 acc=${ACC} ofile=test_zfp-lib-acc-${NUMBER}.h5 + ) + + add_test( + NAME + test-lib-accuracy-read-${NUMBER} + COMMAND + $ ret=1 max_absdiff=${DIFF} ifile=test_zfp-lib-acc-${NUMBER}.h5 + ) + set_tests_properties (test-lib-accuracy-read-${NUMBER} PROPERTIES DEPENDS test-lib-accuracy-write-${NUMBER}) + + add_test( + NAME + test-lib-accuracy-cleanup-${NUMBER} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-lib-acc-${NUMBER}.h5 + ) + set_tests_properties (test-lib-accuracy-cleanup-${NUMBER} PROPERTIES DEPENDS test-lib-accuracy-read-${NUMBER}) + + set_tests_properties(test-lib-accuracy-write-${NUMBER} PROPERTIES FIXTURES_SETUP "lib-accuracy-read-${NUMBER};lib-accuracy-cleanup-${NUMBER}") + set_tests_properties(test-lib-accuracy-write-${NUMBER} PROPERTIES FIXTURES_REQUIRED "lib-accuracy-write-${NUMBER}") + set_tests_properties(test-lib-accuracy-read-${NUMBER} PROPERTIES FIXTURES_REQUIRED "lib-accuracy-read-${NUMBER}") + set_tests_properties(test-lib-accuracy-cleanup-${NUMBER} PROPERTIES FIXTURES_REQUIRED "lib-accuracy-cleanup-${NUMBER}") + set_tests_properties(test-lib-accuracy-cleanup-${NUMBER} PROPERTIES FIXTURES_CLEANUP "lib-accuracy-write-${NUMBER};lib-accuracy-read-${NUMBER}") + + if (FORTRAN_INTERFACE) + add_test( + NAME + test-accuracy-write-${NUMBER}-f + COMMAND + $ zfpmode 3 acc ${ACC} ofile test_zfp_fortran-acc-${NUMBER}.h5 write + ) + + add_test( + NAME + test-accuracy-diff1-${NUMBER}-f + COMMAND + ${HDF5_DIFF_EXECUTABLE} -v -d ${ACC} test_zfp_fortran-acc-${NUMBER}.h5 test_zfp_fortran-acc-${NUMBER}.h5 compressed original + ) + set_property( + TEST + test-accuracy-diff1-${NUMBER}-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-accuracy-diff1-${NUMBER}-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-accuracy-diff1-${NUMBER}-f PROPERTIES DEPENDS test-accuracy-write-${NUMBER}-f) + + add_test( + NAME + test-accuracy-diff2-${NUMBER}-f + COMMAND + ${HDF5_DIFF_EXECUTABLE} -v -d ${ACC} test_zfp_fortran-acc-${NUMBER}.h5 test_zfp_fortran-acc-${NUMBER}.h5 compressed-plugin original + ) + set_property( + TEST + test-accuracy-diff2-${NUMBER}-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-accuracy-diff2-${NUMBER}-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-accuracy-diff2-${NUMBER}-f PROPERTIES DEPENDS test-accuracy-diff1-${NUMBER}-f) + + add_test( + NAME + test-accuracy-cleanup-${NUMBER}-f + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp_fortran-acc-${NUMBER}.h5 + ) + set_tests_properties (test-accuracy-cleanup-${NUMBER}-f PROPERTIES DEPENDS test-accuracy-diff2-${NUMBER}-f) + + set_tests_properties(test-accuracy-write-${NUMBER}-f PROPERTIES FIXTURES_SETUP "accuracy-diff1-${NUMBER}-f;accuracy-diff2-${NUMBER}-f;accuracy-cleanup-${NUMBER}-f") + set_tests_properties(test-accuracy-write-${NUMBER}-f PROPERTIES FIXTURES_REQUIRED "accuracy-write-${NUMBER}-f") + set_tests_properties(test-accuracy-diff1-${NUMBER}-f PROPERTIES FIXTURES_REQUIRED "accuracy-diff1-${NUMBER}-f") + set_tests_properties(test-accuracy-diff2-${NUMBER}-f PROPERTIES FIXTURES_REQUIRED "accuracy-diff2-${NUMBER}-f") + set_tests_properties(test-accuracy-cleanup-${NUMBER}-f PROPERTIES FIXTURES_REQUIRED "accuracy-cleanup-${NUMBER}-f") + set_tests_properties(test-accuracy-cleanup-${NUMBER}-f PROPERTIES FIXTURES_CLEANUP "accuracy-write-${NUMBER}-f;accuracy-diff1-${NUMBER}-f;accuracy-diff2-${NUMBER}-f") + endif () +endforeach () + +# Precision +set(PREC_PREC 12 16 20 24) + +if (MSVC) + set(PREC_DIFF 0.06 0.003 7e-4 5e-5) +else () + set(PREC_DIFF 0.02 0.0005 5e-5 1e-6) +endif () +list(LENGTH PREC_PREC NPRECS) +math(EXPR NPRECS "${NPRECS} - 1") +foreach (IPREC RANGE ${NPRECS}) + list(GET PREC_PREC ${IPREC} PREC) + list(GET PREC_DIFF ${IPREC} DIFF) + + add_test( + NAME + test-precision-write-${PREC} + COMMAND + $ zfpmode=2 prec=${PREC} ofile=test_zfp-prec-${PREC}.h5 + ) + set_property( + TEST + test-precision-write-${PREC} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-precision-write-${PREC} + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + + add_test( + NAME + test-precision-read-${PREC} + COMMAND + $ ret=2 max_reldiff=${DIFF} ifile=test_zfp-prec-${PREC}.h5 + ) + set_property( + TEST + test-precision-read-${PREC} + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-precision-read-${PREC} + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-precision-read-${PREC} PROPERTIES DEPENDS test-precision-write-${PREC}) + + add_test( + NAME + test-precision-cleanup-${PREC} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-prec-${PREC}.h5 + ) + set_tests_properties (test-precision-cleanup-${PREC} PROPERTIES DEPENDS test-precision-read-${PREC}) + + set_tests_properties(test-precision-write-${PREC} PROPERTIES FIXTURES_SETUP "precision-read-${PREC};precision-cleanup-${PREC}") + set_tests_properties(test-precision-write-${PREC} PROPERTIES FIXTURES_REQUIRED "precision-write-${PREC}") + set_tests_properties(test-precision-read-${PREC} PROPERTIES FIXTURES_REQUIRED "precision-read-${PREC}") + set_tests_properties(test-precision-cleanup-${PREC} PROPERTIES FIXTURES_REQUIRED "precision-cleanup-${PREC}") + set_tests_properties(test-precision-cleanup-${PREC} PROPERTIES FIXTURES_CLEANUP "precision-write-${PREC};precision-read-${PREC}") + + add_test( + NAME + test-lib-precision-write-${PREC} + COMMAND + $ zfpmode=2 prec=${PREC} ofile=test_zfp-lib-prec-${PREC}.h5 + ) + + add_test( + NAME + test-lib-precision-read-${PREC} + COMMAND + $ ret=2 max_reldiff=${DIFF} ifile=test_zfp-lib-prec-${PREC}.h5 + ) + set_tests_properties (test-lib-precision-read-${PREC} PROPERTIES DEPENDS test-lib-precision-write-${PREC}) + + add_test( + NAME + test-lib-precision-cleanup-${PREC} + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-lib-prec-${PREC}.h5 + ) + set_tests_properties (test-lib-precision-cleanup-${PREC} PROPERTIES DEPENDS test-lib-precision-read-${PREC}) + + set_tests_properties(test-lib-precision-write-${PREC} PROPERTIES FIXTURES_SETUP "lib-precision-read-${PREC};lib-precision-cleanup-${PREC}") + set_tests_properties(test-lib-precision-write-${PREC} PROPERTIES FIXTURES_REQUIRED "lib-precision-write-${PREC}") + set_tests_properties(test-lib-precision-read-${PREC} PROPERTIES FIXTURES_REQUIRED "lib-precision-read-${PREC}") + set_tests_properties(test-lib-precision-cleanup-${PREC} PROPERTIES FIXTURES_REQUIRED "lib-precision-cleanup-${PREC}") + set_tests_properties(test-lib-precision-cleanup-${PREC} PROPERTIES FIXTURES_CLEANUP "lib-precision-write-${PREC};lib-precision-read-${PREC}") + + if (FORTRAN_INTERFACE) + add_test( + NAME + test-precision-write-${PREC}-f + COMMAND + $ zfpmode 2 prec ${PREC} ofile test_zfp_fortran-prec-${PREC}.h5 write + ) + + # FIXME: Currently, replaced the difference tests because the relative difference between the two datasets is tricky in this case. + add_test( + NAME + test-precision-diff1-${PREC}-f + COMMAND + echo ${HDF5_DIFF_EXECUTABLE} -v -p 0.00001 test_zfp_fortran-prec-${PREC}.h5 test_zfp_fortran-prec-${PREC}.h5 compressed original + ) + set_property( + TEST + test-precision-diff1-${PREC}-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-precision-diff1-${PREC}-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-precision-diff1-${PREC}-f PROPERTIES DEPENDS test-precision-write-${PREC}-f) + + add_test( + NAME + test-precision-diff2-${PREC}-f + COMMAND + echo ${HDF5_DIFF_EXECUTABLE} -v -p 0.00001 test_zfp_fortran-prec-${PREC}.h5 test_zfp_fortran-prec-${PREC}.h5 compressed-plugin original + ) + set_property( + TEST + test-precision-diff2-${PREC}-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-precision-diff2-${PREC}-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-precision-diff2-${PREC}-f PROPERTIES DEPENDS test-precision-diff1-${PREC}-f) + + add_test( + NAME + test-precision-cleanup-${PREC}-f + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp_fortran-prec-${PREC}.h5 + ) + set_tests_properties (test-precision-cleanup-${PREC}-f PROPERTIES DEPENDS test-precision-diff2-${PREC}-f) + + set_tests_properties(test-precision-write-${PREC}-f PROPERTIES FIXTURES_SETUP "precision-diff1-${PREC}-f;precision-diff2-${PREC}-f;precision-cleanup-${PREC}-f") + set_tests_properties(test-precision-write-${PREC}-f PROPERTIES FIXTURES_REQUIRED "precision-write-${PREC}-f") + set_tests_properties(test-precision-diff1-${PREC}-f PROPERTIES FIXTURES_REQUIRED "precision-diff1-${PREC}-f") + set_tests_properties(test-precision-diff2-${PREC}-f PROPERTIES FIXTURES_REQUIRED "precision-diff2-${PREC}-f") + set_tests_properties(test-precision-cleanup-${PREC}-f PROPERTIES FIXTURES_REQUIRED "precision-cleanup-${PREC}-f") + set_tests_properties(test-precision-cleanup-${PREC}-f PROPERTIES FIXTURES_CLEANUP "precision-write-${PREC}-f;precision-diff1-${PREC}-f;precision-diff2-${PREC}-f") + endif () +endforeach () + +# Reversible +add_test( + NAME + test-reversible + COMMAND + $ zfpmode=5 ofile=test_zfp-reversible.h5 +) +set_property( + TEST + test-reversible + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" +) +if (MSVC) + set_property( + TEST + test-reversible + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) +endif () + +add_test( + NAME + test-reversible-diff + COMMAND + $ ret=1 max_absdiff=0 ifile=test_zfp-reversible.h5 +) +set_property( + TEST + test-reversible-diff + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" +) +if (MSVC) + set_property( + TEST + test-reversible-diff + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) +endif () +set_tests_properties (test-reversible-diff PROPERTIES DEPENDS test-reversible) + +add_test( + NAME + test-reversible-cleanup + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-reversible.h5 +) +set_tests_properties (test-reversible-cleanup PROPERTIES DEPENDS test-reversible-diff) + +set_tests_properties(test-reversible PROPERTIES FIXTURES_SETUP "reversible-diff;reversible-cleanup") +set_tests_properties(test-reversible PROPERTIES FIXTURES_REQUIRED "reversible") +set_tests_properties(test-reversible-diff PROPERTIES FIXTURES_REQUIRED "reversible-diff") +set_tests_properties(test-reversible-cleanup PROPERTIES FIXTURES_REQUIRED "reversible-cleanup") +set_tests_properties(test-reversible-cleanup PROPERTIES FIXTURES_CLEANUP "reversible;reversible-diff") + +add_test( + NAME + test-lib-reversible + COMMAND + $ zfpmode=5 ofile=test_zfp-lib-reversible.h5 +) + +add_test( + NAME + test-lib-reversible-diff + COMMAND + $ ret=1 max_absdiff=0 ifile=test_zfp-lib-reversible.h5 +) +set_tests_properties (test-lib-reversible-diff PROPERTIES DEPENDS test-lib-reversible) + +add_test( + NAME + test-lib-reversible-cleanup + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp-lib-reversible.h5 +) +set_tests_properties (test-lib-reversible-cleanup PROPERTIES DEPENDS test-lib-reversible-diff) + +set_tests_properties(test-lib-reversible PROPERTIES FIXTURES_SETUP "lib-reversible-diff;lib-reversible-cleanup") +set_tests_properties(test-lib-reversible PROPERTIES FIXTURES_REQUIRED "lib-reversible") +set_tests_properties(test-lib-reversible-diff PROPERTIES FIXTURES_REQUIRED "lib-reversible-diff") +set_tests_properties(test-lib-reversible-cleanup PROPERTIES FIXTURES_REQUIRED "lib-reversible-cleanup") +set_tests_properties(test-lib-reversible-cleanup PROPERTIES FIXTURES_CLEANUP "lib-reversible;lib-reversible-diff") + +if (FORTRAN_INTERFACE) + add_test( + NAME + test-reversible-write-f + COMMAND + $ zfpmode 5 ofile test_zfp_fortran-reversible.h5 write + ) + + add_test( + NAME + test-reversible-diff1-f + COMMAND + ${HDF5_DIFF_EXECUTABLE} -v -p 0.00001 test_zfp_fortran-reversible.h5 test_zfp_fortran-reversible.h5 compressed original + ) + set_property( + TEST + test-reversible-diff1-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-reversible-diff1-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-reversible-diff1-f PROPERTIES DEPENDS test-reversible-write-f) + + add_test( + NAME + test-reversible-diff2-f + COMMAND + ${HDF5_DIFF_EXECUTABLE} -v -p 0.00001 test_zfp_fortran-reversible.h5 test_zfp_fortran-reversible.h5 compressed-plugin original + ) + set_property( + TEST + test-reversible-diff2-f + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-reversible-diff2-f + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-reversible-diff2-f PROPERTIES DEPENDS test-reversible-diff1-f) + + add_test( + NAME + test-reversible-cleanup-f + COMMAND + "${CMAKE_COMMAND}" -E remove test_zfp_fortran-reversible.h5 + ) + set_tests_properties (test-reversible-cleanup-f PROPERTIES DEPENDS test-reversible-diff2-f) + + set_tests_properties(test-reversible-write-f PROPERTIES FIXTURES_SETUP "reversible-diff1-f;reversible-diff2-f;reversible-cleanup-f") + set_tests_properties(test-reversible-write-f PROPERTIES FIXTURES_REQUIRED "reversible-write-f") + set_tests_properties(test-reversible-diff1-f PROPERTIES FIXTURES_REQUIRED "reversible-diff1-f") + set_tests_properties(test-reversible-diff2-f PROPERTIES FIXTURES_REQUIRED "reversible-diff2-f") + set_tests_properties(test-reversible-cleanup-f PROPERTIES FIXTURES_REQUIRED "reversible-cleanup-f") + set_tests_properties(test-reversible-cleanup-f PROPERTIES FIXTURES_CLEANUP "reversible-write-f;reversible-diff1-f;reversible-diff2-f") +endif () + +#------------------------------------------------------------------------------# +# Misc tests +#------------------------------------------------------------------------------# +# Integer +add_test(NAME test-lib-int-write COMMAND $ zfpmode=3 doint=1 ofile=test_zfp-int.h5) +add_test(NAME test-lib-int-read COMMAND $ ret=1 max_absdiff=2 ifile=test_zfp-int.h5) +set_tests_properties (test-lib-int-read PROPERTIES DEPENDS test-lib-int-write) +add_test(NAME test-lib-int-cleanup COMMAND "${CMAKE_COMMAND}" -E remove test_zfp-int.h5) +set_tests_properties (test-lib-int-cleanup PROPERTIES DEPENDS test-lib-int-read) + +set_tests_properties(test-lib-int-write PROPERTIES FIXTURES_SETUP "lib-int-read;lib-int-cleanup") +set_tests_properties(test-lib-int-write PROPERTIES FIXTURES_REQUIRED "lib-int-write") +set_tests_properties(test-lib-int-read PROPERTIES FIXTURES_REQUIRED "lib-int-read") +set_tests_properties(test-lib-int-cleanup PROPERTIES FIXTURES_REQUIRED "lib-int-cleanup") +set_tests_properties(test-lib-int-cleanup PROPERTIES FIXTURES_CLEANUP "lib-int-write;lib-int-read") + +# Highd +add_test(NAME test-lib-highd COMMAND $ highd=1 ofile=test_zfp-highd.h5) +add_test(NAME test-lib-highd-cleanup COMMAND "${CMAKE_COMMAND}" -E remove test_zfp-highd.h5) +set_tests_properties (test-lib-highd-cleanup PROPERTIES DEPENDS test-lib-highd) + +set_tests_properties(test-lib-highd PROPERTIES FIXTURES_SETUP "lib-highd-cleanup") +set_tests_properties(test-lib-highd PROPERTIES FIXTURES_REQUIRED "lib-highd") +set_tests_properties(test-lib-highd-cleanup PROPERTIES FIXTURES_REQUIRED "lib-highd-cleanup") +set_tests_properties(test-lib-highd-cleanup PROPERTIES FIXTURES_CLEANUP "lib-highd") + +# Sixd +add_test(NAME test-lib-sixd COMMAND $ sixd=1 ofile=test_zfp-sixd.h5) +add_test(NAME test-lib-sixd-cleanup COMMAND "${CMAKE_COMMAND}" -E remove test_zfp-sixd.h5) +set_tests_properties (test-lib-sixd-cleanup PROPERTIES DEPENDS test-lib-sixd) + +set_tests_properties(test-lib-sixd PROPERTIES FIXTURES_SETUP "lib-sixd-cleanup") +set_tests_properties(test-lib-sixd PROPERTIES FIXTURES_REQUIRED "lib-sixd") +set_tests_properties(test-lib-sixd-cleanup PROPERTIES FIXTURES_REQUIRED "lib-sixd-cleanup") +set_tests_properties(test-lib-sixd-cleanup PROPERTIES FIXTURES_CLEANUP "lib-sixd") + +if (ZFP_CFP_ENABLED) + # zfparr + add_test( + NAME + test-zfparr + COMMAND + $ zfparr=1 rate=10 + ) + + add_test( + NAME + test-zfparr-diff + COMMAND + ${HDF5_DIFF_EXECUTABLE} -v -d 0.01 test_zfp.h5 test_zfp.h5 zfparr_original zfparr_direct + ) + set_property( + TEST + test-zfparr-diff + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-zfparr-diff + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + set_tests_properties (test-zfparr-diff PROPERTIES DEPENDS test-zfparr) + + set_tests_properties(test-zfparr PROPERTIES FIXTURES_SETUP "zfparr-diff") + set_tests_properties(test-zfparr-diff PROPERTIES FIXTURES_REQUIRED "zfparr-diff") +endif () + +# Endian +# FIXME: fails due to datatype difference -> return code 2 +#add_test( +# NAME +# test-endian +# COMMAND +# ${HDF5_DIFF_EXECUTABLE} -v -d 0.00001 ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_le.h5 ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_be.h5 compressed compressed +#) +#set_property( +# TEST +# test-endian +# APPEND +# PROPERTY +# ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" +#) +#if (MSVC) +# set_property( +# TEST +# test-endian +# APPEND +# PROPERTY +# ENVIRONMENT +# "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" +# ) +#endif () + +#------------------------------------------------------------------------------# +# Errors tests +#------------------------------------------------------------------------------# +add_executable(test_error test_error.c) +target_compile_definitions(test_write_lib PRIVATE ZFP_LIB_VERSION=0x${ZFP_LIB_VERSION}) +target_link_libraries(test_error h5z_zfp_static) +if (NOT WIN32) + target_link_libraries(test_error m) +endif () + +add_test(NAME test-error COMMAND $) +add_test(NAME test-error-cleanup COMMAND "${CMAKE_COMMAND}" -E remove test_zfp_errors.h5) +set_tests_properties (test-error-cleanup PROPERTIES DEPENDS test-error) + +set_tests_properties(test-error PROPERTIES FIXTURES_SETUP "error-cleanup") +set_tests_properties(test-error PROPERTIES FIXTURES_REQUIRED "error") +set_tests_properties(test-error-cleanup PROPERTIES FIXTURES_REQUIRED "error-cleanup") +set_tests_properties(test-error-cleanup PROPERTIES FIXTURES_CLEANUP "error") + +#------------------------------------------------------------------------------# +# H5repack tests +#------------------------------------------------------------------------------# +add_executable(print_h5repack_farg print_h5repack_farg.c) +target_link_libraries(print_h5repack_farg h5z_zfp_shared) + +if (NOT MSVC) + add_test( + NAME + test-h5repack + COMMAND + ${HDF5_REPACK_EXECUTABLE} -f UD=32013,0,4,3,0,3539053052,1062232653 + -l X,Y,Z,Indexes:CHUNK=217 + -l Indexes2:CHUNK=1517 + -l Pressure,Pressure2,Pressure3:CHUNK=10x20x5 + -l Pressure_2D:CHUNK=10x20 + -l Stress,Velocity,Stress2,Velocity2,Stress3,Velocity3,VelocityZ,VelocityZ2,VelocityZ3:CHUNK=11x21x1x1 + -l VelocityX_2D:CHUNK=21x31 + -l XY:CHUNK=651x1 + -l XYZ:CHUNK=217x1 + -l XYZ2:CHUNK=1617x1 + -l XYZ3:CHUNK=33x1 + ${CMAKE_CURRENT_SOURCE_DIR}/mesh.h5 mesh_repack.h5 + ) + set_property( + TEST + test-h5repack + APPEND + PROPERTY + ENVIRONMENT "HDF5_PLUGIN_PATH=${HDF5_PLUGIN_PATH}" + ) + if (MSVC) + set_property( + TEST + test-h5repack + APPEND + PROPERTY + ENVIRONMENT + "PATH=${ESCAPED_PATH}\\;${HDF5_PLUGIN_PATH}" + ) + endif () + + add_test( + NAME + test-h5repack-filesizes + COMMAND + "${CMAKE_COMMAND}" + -D "FILE_ORIGINAL=${CMAKE_CURRENT_SOURCE_DIR}/mesh.h5" + -D "FILE_REPACK=mesh_repack.h5" + -D "RATIO_LIMIT=200" + -P "${CMAKE_CURRENT_SOURCE_DIR}/h5repack-filesizes.cmake" + ) + set_tests_properties (test-h5repack-filesizes PROPERTIES DEPENDS test-h5repack) + + add_test( + NAME + test-h5repack-cleanup + COMMAND + "${CMAKE_COMMAND}" -E rm mesh_repack.h5 + ) + set_tests_properties (test-h5repack-cleanup PROPERTIES DEPENDS test-h5repack-filesizes) + + set_tests_properties(test-h5repack PROPERTIES FIXTURES_SETUP "h5repack-filesizes;h5repack-cleanup") + set_tests_properties(test-h5repack PROPERTIES FIXTURES_REQUIRED "h5repack") + set_tests_properties(test-h5repack-filesizes PROPERTIES FIXTURES_REQUIRED "h5repack-filesizes") + set_tests_properties(test-h5repack-cleanup PROPERTIES FIXTURES_REQUIRED "h5repack-cleanup") + set_tests_properties(test-h5repack-cleanup PROPERTIES FIXTURES_CLEANUP "h5repack;h5repack-filesizes") +endif () + +#------------------------------------------------------------------------------# +# Version compatibility tests +#------------------------------------------------------------------------------# +set(H5FILES ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_030040.h5 ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_030235.h5 ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_110050.h5 ${CMAKE_CURRENT_SOURCE_DIR}/test_zfp_110xxx.h5) +set(RETSTAT FALSE FALSE FALSE TRUE) +list(LENGTH H5FILES NH5FILES) +math(EXPR NH5FILES "${NH5FILES} - 1") +foreach (IFILE RANGE ${NH5FILES}) + list(GET H5FILES ${IFILE} H5FILE) + list(GET RETSTAT ${IFILE} STATUS) + + math(EXPR VERSION_NO "${IFILE} + 1") + add_test(NAME test-version-${VERSION_NO} COMMAND $ ifile=${H5FILE} max_reldiff=0.025 ret=2) + set_tests_properties(test-version-${VERSION_NO} PROPERTIES WILL_FAIL ${STATUS}) +endforeach () + +if (FORTRAN_INTERFACE) + set(H5FILE test_zfp_fortran_version.h5) + math(EXPR VERSION_NO "${NH5FILES} + 2") + add_test(NAME test-version-${VERSION_NO}-input COMMAND $ write dim 1024 zfpmode 1 rate 16 ofile ${H5FILE}) + add_test(NAME test-version-${VERSION_NO} COMMAND $ ifile=${H5FILE} max_reldiff=0.025 ret=2) + add_test(NAME test-version-${VERSION_NO}-cleanup COMMAND "${CMAKE_COMMAND}" -E rm ${H5FILE}) + set_tests_properties(test-version-${VERSION_NO}-input PROPERTIES FIXTURES_SETUP "version;version-cleanup") + set_tests_properties(test-version-${VERSION_NO}-input PROPERTIES FIXTURES_REQUIRED "version-input") + set_tests_properties(test-version-${VERSION_NO} PROPERTIES FIXTURES_REQUIRED "version") + set_tests_properties(test-version-${VERSION_NO}-cleanup PROPERTIES FIXTURES_REQUIRED "version-cleanup") + set_tests_properties(test-version-${VERSION_NO}-cleanup PROPERTIES FIXTURES_CLEANUP "version-input;version") +endif () diff --git a/ZFP/H5Z-ZFP/test/Makefile b/ZFP/H5Z-ZFP/test/Makefile new file mode 100644 index 00000000..09a87319 --- /dev/null +++ b/ZFP/H5Z-ZFP/test/Makefile @@ -0,0 +1,747 @@ +# Include config.make only if we're not making this tool +ifneq ($(strip $(MAKECMDGOALS)),print_h5repack_farg) + ifneq ($(strip $(MAKECMDGOALS)),clean) + include ../config.make + endif +endif + +# printf symbols for output of test results +NO_COLOR=\033[0m +OK_COLOR=\033[32;01m +ERROR_COLOR=\033[31;01m +SKIP_COLOR=\033[0;34m +padlimit=60 +padlength=60 + +ZFP_LIBS = -lzfp +ifeq ($(ZFP_HAS_CFP),1) + ZFP_LIBS += -lcfp -lstdc++ +endif + +.PHONY: lib plugin check patch clean + +patch: + @echo "If using HDF5-1.8, make sure you have patched repack" + +plugin: + cd ../src; $(MAKE) $(MAKEVARS) $@ + +lib: + cd ../src; $(MAKE) $(MAKEVARS) $@ + +test_write_plugin.o: test_write.c + $(CC) -c $< -o $@ -DH5Z_ZFP_USE_PLUGIN -DZFP_LIB_VERSION=0x$(ZFP_LIB_VERSION) $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +test_write_lib.o: test_write.c + $(CC) -c $< -o $@ $(CFLAGS) -DZFP_HAS_CFP=$(ZFP_HAS_CFP) -DHDF5_HAS_WRITE_CHUNK=$(HDF5_HAS_WRITE_CHUNK) -DZFP_LIB_VERSION=0x$(ZFP_LIB_VERSION) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +test_write_plugin: test_write_plugin.o plugin + $(CC) $< -o $@ $(CFLAGS) $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L$(HDF5_LIB) -L$(ZFP_LIB) -lhdf5 $(ZFP_LIBS) -lm $(LDFLAGS) + +test_write_lib: test_write_lib.o lib + $(CC) $< -o $@ $(CFLAGS) $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L../src -L$(HDF5_LIB) -L$(ZFP_LIB) -lh5zzfp -lhdf5 $(ZFP_LIBS) -lm $(LDFLAGS) + +test_read_plugin.o: test_read.c + $(CC) -c $< -o $@ -DH5Z_ZFP_USE_PLUGIN $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +test_read_lib.o: test_read.c + $(CC) -c $< -o $@ $(CFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +test_read_plugin: test_read_plugin.o plugin + $(CC) $< -o $@ $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L$(HDF5_LIB) -L$(ZFP_LIB) -lhdf5 $(ZFP_LIBS) -lm $(LDFLAGS) + +test_read_lib: test_read_lib.o lib + $(CC) $< -o $@ $(CFLAGS) $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L../src -L$(HDF5_LIB) -L$(ZFP_LIB) -lh5zzfp -lhdf5 $(ZFP_LIBS) -lm $(LDFLAGS) + +test_error.o: test_error.c + $(CC) -c $< -o $@ $(CFLAGS) -DZFP_LIB_VERSION=0x$(ZFP_LIB_VERSION) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + +test_error: test_error.o lib + $(CC) $< -o $@ $(CFLAGS) $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L../src -L$(HDF5_LIB) -L$(ZFP_LIB) -lh5zzfp -lhdf5 $(ZFP_LIBS) -lm $(LDFLAGS) + +print_h5repack_farg: print_h5repack_farg.o + $(CC) $< -o $@ $(LDFLAGS) + +print_h5repack_farg.o: print_h5repack_farg.c + $(CC) -c $< -o $@ $(CFLAGS) -I../src + +ifneq ($(FC),) # Fortran Tests [ + +test_rw_fortran: test_rw_fortran.o lib + $(FC) $(FCFLAGS) -o $@ $< $(PREPATH)$(HDF5_LIB) $(PREPATH)$(ZFP_LIB) -L../src -L$(HDF5_LIB) -L$(ZFP_LIB) -lh5zzfp -lhdf5_fortran -lhdf5 $(ZFP_LIBS) $(LDFLAGS) + +%.o:%.F90 + $(FC) -o $@ -c $< $(FCFLAGS) -I$(H5Z_ZFP_BASE) -I$(ZFP_INC) -I$(HDF5_INC) + + +# Note: The write-half of all the Fortran tests utilize the default and properties +# interface library to control the filter. The read-half uses the plugin. + +test-default : test_rw_fortran + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_rw_fortran"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + +# Decrease bit rate and confirm compression ratio increases +test-rate-f: plugin test_rw_fortran + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for r in 32 16 8 4; do\ + x="./test_rw_fortran zfpmode 1 rate $$r"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + expected_ratio=$$(expr 64 \/ $$r); \ + $$x >/dev/null 2>/dev/null; \ + status=$$?; \ + if [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + actual_ratio=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5dump -H -d compressed -p test_zfp_fortran.h5 | grep COMPRESSION | cut -d':' -f1 | cut -d'(' -f2 | cut -d'.' -f1); \ + if [[ $$expected_ratio -ne $$actual_ratio ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DUMP*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + actual_ratio=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5dump -H -d compressed-plugin -p test_zfp_fortran.h5 | grep COMPRESSION | cut -d':' -f1 | cut -d'(' -f2 | cut -d'.' -f1); \ + if [[ $$expected_ratio -ne $$actual_ratio ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DUMP*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + +# Increase accuracy and test absolute error tolerance is within accuracy +test-accuracy-f: plugin test_rw_fortran + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for a in 0.1 0.01 0.001 0.0001; do\ + x="./test_rw_fortran zfpmode 3 acc $$a write"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x >/dev/null 2>/dev/null; \ + status=$$?; \ + if [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -d $$a test_zfp_fortran.h5 test_zfp_fortran.h5 compressed original 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -d $$a test_zfp_fortran.h5 test_zfp_fortran.h5 compressed-plugin original 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + +# Increase precision and confirm diff count for given tolerance drops +test-precision-f: plugin test_rw_fortran + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for p in 12 16 20 24; do\ + x="./test_rw_fortran zfpmode 2 prec $$p write"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x >/dev/null 2>/dev/null; \ + status=$$?; \ + if [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp_fortran.h5 test_zfp_fortran.h5 compressed original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$ldiffcnt -ne 0 ]] && [[ $$diffcnt -gt $$ldiffcnt ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp_fortran.h5 test_zfp_fortran.h5 compressed-plugin original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$ldiffcnt -ne 0 ]] && [[ $$diffcnt -gt $$ldiffcnt ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + +# Ensure reversible gives bit-for-bit identical results +test-reversible-f: plugin test_rw_fortran + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_rw_fortran zfpmode 5 write"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x >/dev/null 2>/dev/null; \ + status=$$?; \ + if [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp_fortran.h5 test_zfp_fortran.h5 compressed original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$diffcnt -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp_fortran.h5 test_zfp_fortran.h5 compressed-plugin original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$diffcnt -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED *H5DIFF*$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n\n"; \ + +endif # ] ifneq ($(FC),) + +# Decrease bit rate and confirm compression ratio increases +test-rate: plugin test_write_plugin + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for r in 32 16 8 4; do \ + expected_ratio=$$(expr 64 \/ $$r); \ + x="./test_write_plugin zfpmode=1 rate=$$r"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + env HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + actual_ratio=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5dump -H -d compressed -p test_zfp.h5 | grep COMPRESSION | cut -d':' -f1 | cut -d'(' -f2 | cut -d'.' -f1); \ + if [[ $$expected_ratio -ne $$actual_ratio ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Plugin rate tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Increase accuracy and test absolute error tolerance is within accuracy +test-accuracy: plugin test_write_plugin + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for a in 0.1 0.01 0.001 0.0001; do\ + x="./test_write_plugin zfpmode=3 acc=$$a"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + env HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -d $$a test_zfp.h5 test_zfp.h5 compressed original 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + echo "Plugin accuracy test failed for accuracy=$$a"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Plugin accuracy tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Increase precision and confirm diff count for given tolerance drops +test-precision: plugin test_write_plugin + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + ldiffcnt=0; \ + for p in 12 16 20 24; do\ + x="./test_write_plugin zfpmode=2 prec=$$p"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + env HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp.h5 test_zfp.h5 compressed original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$ldiffcnt -ne 0 ]] && [[ $$diffcnt -gt $$ldiffcnt ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + ldiffcnt=$$diffcnt; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Plugin precision tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Ensure reversible mode works +test-reversible: plugin test_write_plugin + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_plugin zfpmode=5"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + env HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + diffcnt=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -p 0.00001 test_zfp.h5 test_zfp.h5 compressed original | grep 'differences found' | cut -d' ' -f1); \ + if [[ $$diffcnt -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# +# Uses h5repack to test ZFP filter on float and int datasets in +# 1,2,3 and 4 dimensions. Note: need to specify raw cd_values on +# command-line to h5repack. We can get these from an invocation +# of print_h5repack_farg. The values here are for accuracy mode +# and tolerance of 0.001. +# +# A bug-fix patch to h5repack_parse.c is required for this test on +# older HDF5 versions (like <= 1.8.10). +# +# Note use h5repack `-n` option to ensure machine native format +# used when copying datasets to output file. Also, use filter flag +# of 0 in h5repack's UD argument to make the filter mandatory. +# +test-h5repack: plugin mesh.h5 patch print_h5repack_farg + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + rparg=$$(./print_h5repack_farg zfpmode=3 acc=0.001 | grep '^. *-f'); \ + x="h5repack -n $$rparg"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/$$x \ + -l X,Y,Z,Indexes:CHUNK=217 \ + -l Indexes2:CHUNK=1517 \ + -l Pressure,Pressure2,Pressure3:CHUNK=10x20x5 \ + -l Pressure_2D:CHUNK=10x20 \ + -l Stress,Velocity,Stress2,Velocity2,Stress3,Velocity3,VelocityZ,VelocityZ2,VelocityZ3:CHUNK=11x21x1x1 \ + -l VelocityX_2D:CHUNK=21x31 \ + -l XY:CHUNK=651x1 \ + -l XYZ:CHUNK=217x1 \ + -l XYZ2:CHUNK=1617x1 \ + -l XYZ3:CHUNK=33x1 \ + mesh.h5 mesh_repack.h5 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + orig_size=$$(ls -l mesh.h5 | tr -s ' ' | cut -d' ' -f5); \ + new_size=$$(ls -l mesh_repack.h5 | tr -s ' ' | cut -d' ' -f5); \ + ratio=$$(perl -e "printf int($$orig_size*100/$$new_size)"); \ + if [[ $$ratio -lt 200 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (size ratio) $(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Diff ZFP compressed data from little endian and big endian machines +# There is a bug in h5diff that causes it to return 0 when it can't find plugin. +# We protect against that by additional check of output error text +# We should test return code but h5diff's return code has been unreliable across +# versions and so am not relying on it here. +test-endian: plugin test_zfp_le.h5 test_zfp_be.h5 + @echo " "; \ + padlimit=80; \ + padlength=80; \ + pad=$$(printf '%*s' "$${padlimit}"); \ + pad=$${pad// /.}; \ + x="h5diff -v -d 0.00001 test_zfp_le.h5 test_zfp_be.h5 compressed compressed"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($${padlength} - $${#x} )) "$$pad"; \ + outerr=$$(env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/$$x 2>&1); \ + if [[ -z "$$(echo $$outerr | grep '0 differences found')" ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Test dumping a file generated on a big endian machine +# The file was generated with: +# yes 12345 | head -n 5000 | h5import /dev/stdin -dims 5000 -type TEXTIN -size 32 -o unpacked.h5 +# h5repack -f UD=32013,0,4,1,0,0,1074921472 unpacked.h5 bigendian.h5 +test-endian1: plugin bigendian.h5 + @echo " "; \ + padlimit=80; \ + padlength=80; \ + pad=$$(printf '%*s' "$${padlimit}"); \ + pad=$${pad// /.}; \ + x="h5dump bigendian.h5"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($${padlength} - $${#x} )) "$$pad"; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/$$x | grep -q '12345, 12345, 12345, 12345,' ; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +# Test the filter as a library rather than as a plugin +test-lib-rate: test_write_lib test_read_lib + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for t in 32:1e-07 16:0.003 8:0.4; do\ + r=$$(echo $$t | cut -d':' -f1); \ + d=$$(echo $$t | cut -d':' -f2); \ + x="./test_write_lib rate=$$r zfpmode=1"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + ./test_read_lib max_absdiff=$$d max_reldiff=$$d 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (readback)$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Library rate tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-lib-accuracy: test_write_lib test_read_lib + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for v in 0.1:0.025 0.01:0.004 0.001:0.0006 0.0001:4e-5; do\ + a=$$(echo $$v | cut -d':' -f1); \ + d=$$(echo $$v | cut -d':' -f2); \ + x="./test_write_lib acc=$$a zfpmode=3"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + ./test_read_lib ret=1 max_absdiff=$$d 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (readback)$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Library accuracy tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-lib-precision: test_write_lib test_read_lib + @failed=0; \ + echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + for v in 12:0.02 16:0.0005 20:5e-5 24:1e-6; do\ + p=$$(echo $$v | cut -d':' -f1); \ + d=$$(echo $$v | cut -d':' -f2); \ + x="./test_write_lib prec=$$p zfpmode=2"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + ./test_read_lib ret=2 max_reldiff=$$d 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (readback)$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Library precision tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-lib-reversible: test_write_lib test_read_lib + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_lib zfpmode=5"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + ./test_read_lib ret=1 max_absdiff=0 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (readback)$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-int: test_write_lib test_read_lib + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_lib zfpmode=3 doint=1"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + status=$$?; \ + if [[ $$status -eq 1 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + elif [[ $$status -eq 2 ]]; then \ + printf " [$(SKIP_COLOR)SKIPPED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + ./test_read_lib ret=1 max_absdiff=2 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (readback)$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-highd: test_write_lib + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_lib highd=1"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-sixd: test_write_lib + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_lib sixd=1"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + status=$$?; \ + if [[ $$status -eq 2 ]]; then \ + printf " [$(SKIP_COLOR)SKIPPED$(NO_COLOR)]\n"; \ + exit 0; \ + elif [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-error: test_error + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_error"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-zfparr: test_write_lib + @echo " "; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + x="./test_write_lib zfparr=1 rate=10"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x 2>&1 1>/dev/null; \ + status=$$?; \ + if [[ $$status -eq 2 ]]; then \ + printf " [$(SKIP_COLOR)SKIPPED$(NO_COLOR)]\n"; \ + exit 0; \ + elif [[ $$status -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + env LD_LIBRARY_PATH=$(HDF5_LIB):$(LD_LIBRARY_PATH) HDF5_PLUGIN_PATH=$(H5Z_ZFP_PLUGIN) $(HDF5_BIN)/h5diff -v -d 0.01 test_zfp.h5 test_zfp.h5 zfparr_original zfparr_direct 2>&1 1>/dev/null; \ + if [[ $$? -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED (h5diff) $(NO_COLOR)]\n"; \ + touch check-failed; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +test-version-compatibility: test_read_lib + @echo " "; \ + failed=0; \ + pad=$$(printf '%*s' "$(padlimit)"); \ + pad=$${pad// /.}; \ + files="test_zfp_030040.h5:0 test_zfp_030235.h5:0 test_zfp_110050.h5:0 test_zfp_110xxx.h5:1"; \ + if [[ -x ./test_rw_fortran ]]; then \ + ./test_rw_fortran write dim 1024 zfpmode 1 rate 16 2>&1 1>/dev/null; \ + if [[ $$? -eq 0 ]]; then \ + files="$$files test_zfp_fortran.h5:0"; \ + fi; \ + fi; \ + for f in $$files; do \ + fname=$$(echo $$f | cut -d':' -f1); \ + xstat=$$(echo $$f | cut -d':' -f2); \ + x="./test_read_lib ifile=$$fname max_reldiff=0.025"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + $$x ret=2 2>/dev/null 1>/dev/null; \ + if [[ $$? -ne $$xstat ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + failed=1; \ + touch check-failed; \ + continue; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n"; \ + done; \ + x="Version compatibility tests"; \ + printf "$$x"; \ + printf ' %*.*s' 0 $$(($(padlength) - $${#x} )) "$$pad"; \ + if [[ $$failed -ne 0 ]]; then \ + printf " [$(ERROR_COLOR)FAILED$(NO_COLOR)]\n"; \ + exit 0; \ + fi; \ + printf " [$(OK_COLOR)PASSED$(NO_COLOR)] \n" + +check-start: + @rm -f check-failed + +check-end: + @if [[ -e check-failed ]]; then \ + exit 1; \ + fi + +SPECIAL_CHECK = test-version-compatibility test-int test-highd test-sixd test-zfparr + +FORTRAN_CHECK = test-default test-rate-f test-accuracy-f test-precision-f +ifneq ($(ZFP_HAS_REVERSIBLE),) + FORTRAN_CHECK += test-reversible-f +endif + +LIB_CHECK = test-lib-rate test-lib-accuracy test-lib-precision test-error +ifneq ($(ZFP_HAS_REVERSIBLE),) + LIB_CHECK += test-lib-reversible +endif + +PLUGIN_CHECK = test-rate test-accuracy test-precision test-h5repack +ifneq ($(ZFP_HAS_REVERSIBLE),) + PLUGIN_CHECK += test-reversible +endif +PLUGIN_CHECK += test-endian test-endian1 + +CHECK = $(LIB_CHECK) $(PLUGIN_CHECK) +ifneq ($(FC),) + CHECK += $(FORTRAN_CHECK) +endif +CHECK += $(SPECIAL_CHECK) + +check: check-start $(CHECK) check-end + +clean: + rm -f test_write_plugin.o test_write_lib.o test_read_plugin.o test_read_lib.o test_rw_fortran.o test_error.o + rm -f test_write_plugin test_write_lib test_read_plugin test_read_lib test_rw_fortran test_error + rm -f test_zfp.h5 test_zfp_fortran.h5 mesh_repack.h5 test_zfp_errors.h5 + rm -f print_h5repack_farg.o print_h5repack_farg check-failed + rm -f *.gcno *.gcda *.gcov diff --git a/ZFP/H5Z-ZFP/test/bigendian.h5 b/ZFP/H5Z-ZFP/test/bigendian.h5 new file mode 100644 index 0000000000000000000000000000000000000000..2f12c1de63ca430463577706d55cbcc94b218869 GIT binary patch literal 22048 zcmeIxu};G<5P;!xQjn>HRA51!GBRdmf=W%*si0C-9a|NifIa|Yc@rLmSKw*d*mox( zHpGyD-%)+e*>RfF=lAJ&a^4^ICAAo(Cxbln?qIE2YR2zcd_values[j++]=atoi(stype); + r=0; ++ } + q=0; +- u++; /* skip ',' */ +- } +- c = str[u]; +- if (!isdigit(c) && l==-1) +- { +- if (obj_list) HDfree(obj_list); +- error_msg("filter number parameter is not a digit in <%s>\n",str); +- HDexit(EXIT_FAILURE); +- } +- stype[q]=c; +- if (l==0 && p==0) +- { +- if (r==0) +- filt->cd_values[j++]=atoi(stype); ++ } else { ++ c = str[u]; ++ if (!isdigit(c) && l==-1) ++ { ++ if (obj_list) HDfree(obj_list); ++ error_msg("filter number parameter is not a digit in <%s>\n",str); ++ HDexit(EXIT_FAILURE); ++ } ++ stype[q++]=c; + } + + } /* u */ diff --git a/ZFP/H5Z-ZFP/test/mesh.h5 b/ZFP/H5Z-ZFP/test/mesh.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b4840728b62ad8aa4685b329ab6c940d88362d0b GIT binary patch literal 1151188 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 z?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV z=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@ zf$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a z9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv z-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=! z&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{) z1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~- zJJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixT zx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(e zpgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p z2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~v zcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRw zbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{ zKzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I z4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T z?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV z=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@ zf$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a z9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv z-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=! z&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{) z1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~- zJJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixT zx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(e zpgVASc3|0Tv)M9^XZT_^+jO?Ypc`$p(ePyB+4jS?w_35|Y?I;0R?N2BVz%9p=)j=6u7m<-2Y)eji_LonN09zxeU{pS0&} zcF^$cv+9fgyT|h3_qII0O?&WrTQ*xh{1%su9shLU`S19YKkubZn!m-#hs?ic{^h^^ zd5@ZY_u1}eRFB_mJ^!Pe(qoGoZ#6tR;g-`s8NX-(9Xce8>Ld*9VMW?|s<8_dNK1v)LX;?D3F29y*)NzrD-w zZGNKt=0E*x{AFebjNjgG|GDMsU52;Y|A1Zj+TX|cX8-*5@J5sGAKp0M_V?+}`_FHW zKj5F=9)Ez}_UHH8{``L1pMT#65N0-;f4$52^{%s<-*5GSM;v&#U;D#{_bGnvgU0tC zf1Q5a0xfW67U;)Kr|09Q`H%VM|6CU4M$7hW&;Il1_@2@Ci+PB4XovjW@Xy!6-1_%L zI}8PS5A#E4hj!>r4*v|%e~#!sNA#Z~=5yE%?a)2!9(D)11Kok{KzE=!&>iRwbO*Wv z-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=! z&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{) z1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~- zJJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixT zx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(e zpgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p z2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~v zcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRw zbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{ zKzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I z4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T z?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV z=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@ zf$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a z9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv z-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{)1Kok{KzE=! z&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~-JJ22I4s-{) z1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixTx&z&T?m%~- zJJ22I4s-{)1Kok{KzE=!&>iRwbO*Wv-GS~vcc44a9q0~p2f72@f$l(epgYhV=nixT zx&x z`*5MKL%49bNVsUYSlBVF2p12R2$u|(3YQL-36~8!h0BG@hbx3DhAV|DhpU90!&SpB zVb^fAaP@GFaLsV7aP4rNaNTgdaQ$$Duv=INyN4Tw8-+c>jl)gCO~cK?&BHCiEyK#N zXV@$39rg*g3bzjXhTDYOhTDbPhyB9-;ec?5aK~_`aOZHBuqxa&+%4QatPTf;dxU$2 zgTle#Ug6&1KH0@X_$G@bU18@X2s|I3av0d^&t4d^UV8 zd_H_3oET0DUkqOgUk+ahUkzUiUk~31-wfXh8^X84cfxnW$>Dq9`{4)Shv7%z$Kfa8 zr{QPe=iwLOm*H38*Wowex8Zl;_u&uWkKs?@&*3lOuitr9WE0t8+Hnp3zrX92v-bO3RezS2|I_YhF!w0;cDUP;TqwZ;acI^;X2{E z;dq() z|8Q71JUk#gFgz$cI2;ik5*`{J79JiR5gr+i42$7WVJSR1tO<_^Yr|v1QQ>jn@!<*K ziQ!4%$>AyC=3~vf=4sQu>4Q~r?5AO)ag?EN`g?ESdg!hK`h4+W` z;RE4=;X~oW;UnRr;bY#uua%DTrg}GwhtEyJA?~|i-e1Yi-jG-ig598iEznqsc`9VnQ+;#Q@C8X ze7HimVz^Sca=1#^Ib1dD5_Sz&3s(=<2-ghP3fB(T3D*tR3)c@f2)l)auzR>+xKY?6 z+&J7M+%()Q+&tVO+%l{TdxpKj-eI3`t8nYEZ@5jkZMa>yeb_JT9}Wn22zLy33U>~7 z39G_g!`;H&!|HHgxJS5WI4B$(?iKDG?i21C?iUUThlcxy!@}X=0pWq+LE*vSi13i` z(D1PE@bHN6$Z%v>437#+;n87DcuZIu9vhAdj|-0vPY6#8PYO>CPYFkdr-rA6r-x^R zXNG5mXNTv6=Z5En=Z6=B7ls#w7l(D>CE=Lx((tnI^6-lA%J8c2>hPNI+Hh=mU3h(X zLwI9&Q+RWDOL%K|TX=hTM>sCLGrTLjJG>{nH@q*rKdcWQ2p zxKP+3TsT}LTr^xP>=;&ri-${uONL8@ONYyZ%Z8o8<-+B|6~Yz6mBN+7Rl?5Us$rL~ zYq(mtdbmcoX1G?kcDPQsZn$2!ez-x{Ei8oH!wtiY!XDwq;U?jx;b!6H;TGYRVP)7e z>=pJ7`-EGCTZetaZNhEC?ZWNDeqsM`K)6G=W4KeebGS=b7491D7VaKahXcbs!ac)5 z;oxwuaPM%RaNlsha7Z{b+&>%^4i66q4-5|q4-Q9!hlGcQhlPiSM}$X)Bg0~NR9Fg+ z4r{_=!rJiIa8!6)czk$5cw%@`cyf43I66EvJS{vuJR>|aJS#jqJSRLiJTE*yydb%$wu8^fEzo5NeeTf^JJ+rvA; zap9feUE$r~J>k9Kec}CKefU85VE9n@aQI00X!uz8c=$y4WH>&Y5Iz+?9X=C28$K64 zAHEPy3@3#zhA)LLhp&XMhOdRMhi`;$hHr%p;oIRm;k)7F@V)T;@PqKf@T2hK@RRV< z@U!sq@Qd)v@T>6a@SE`4@VoH)@Q3in@Tc(S@R#t{@VD^y@Q*OtB=7%Wqp)$tr9WE0t8+Hnp3zrX92v-bO3RezS2|I_YhF!w0;cDUP;TqwZ;acI^;X2{E z;dq() z|8Q71JUk#gFgz$cI2;ik5*`{J79JiR5gr+i42$7WVJSR1tO<_^Yr|v1QQ>jn@!<*K ziQ!4%$>AyC=3~vf=4sQu>4Q~r?5AO)ag?EN`g?ESdg!hK`h4+W` z;RE4=;X~oW;UnRr;bY<< z^M~bOtFU#rK-ea18!i~O3)_bag&o3$!$rbH!^OgmVMVxjxJ0;QxKy}wxJ>REdb_u(NtA(qFYlLftYlUlv>xAou>xJuw8-(4$LfAdrFx)8Y z5pEoA5^fr97H%GH5pEe)hCRbxVeha{xK+4y*f-oJ+&0`U+&=6V_74YyJA^xiJB2%k zyM$HYuHkOs?qPK}Fx(^DGaM8S4)+T84)+Q74fhL&ghRvq!(rj@@PP2Z@SyPEa71`W zcxZT7czAe3cw{&-EQUvgrSRymCOjsr4UY{+g~x@*hbM$5h9`w5ho^+2!&Af4!qdYu z!ZX9O!n4D3!gIs(!t=um!VANT!i&SY@RD#$cxiZ9czJk5cx8B1cy)M9cx^Z~ye_;x zydk_XyeYgnyd}Ifye+&vydxYJ-WlE%-W}c(-W%Q*-XGS74}=ef4}}khkA#ngkA;ti zPlQi~^7YP>)7YjRv72)FH65*2JQsL6!GU2jer*OG&`EZ4B#c-u?<#3g-bGT~Q zCF~lm7Oozy5w01o6|Nnw6RsPs7p@;}5Oxa-VfS#uaHFtCxN*2ixM{dqxOuomxMf%w z_6&Q4y~94?R^irR-*B67+i<&Z`>|z~hP#Ekht=W0aF1}$ za8Nin+$-EW+$Y>O+%Fsw4h{DYhlRt#1HuEtgTjNu5#b@>q2XcS;o%YCk>SX&7#3|KmEl$4)!{Yawc*(Cy72n&hVaJlrts$Qmhjf_w($1w zj&NLfXLwh5cX&^DZ+KsLe^?(r5Iz__6h0h25O`eYjBAAzV0IBwRFHEbJIo zgo}qugiD4?g-eIagv*AV!sWu{!xh36!!6 zG~7QN77h;&2oDSo3J(rPgolKOhKGfRhew1*h9kpbcvM&lj}B|XW5U|-*l<*MTzGtV zLU>|$Qh0KBN;o<^H9RdmJv<{kGdwFiJ3J>mH#{#qKfEBkFuW+dIIIgV3CDz&hL?qx zhgXDGhF67Ghu4JHhGWC)!t28u!W+Yz!kfce!dt`J!rQ|;!g1l9;a%a~;XUEK;eFx# zVSV^O_+a=@_;C10_-Oc8_;~n4_+&UfoDe=0J{>+2J{vw4J|DgiP7Ei7FNQCLFNd#$ zuZFLMuZM4hZ-#G$4dL72JK?+G+qZK z+wi;a`|yYG$MC1{=kS;C*YLOS_wbLvC-|3zjl#xZldx&nENmXO2RCF~ro8g>c0hO33EhiimuhHHguhwFsvhU=AApZW3-9ZWeAHZV_%7R)#&pUSaRBPq3`Cx$15Cx@qmqr+3f)56ok zGr}{&v%<5(bHa1O^TPAP3&IP-i^7Y;y6}>4On7N{S$KJPMR;X+Rd{uHO?YiMHoPvp zKD;5kF}x|fIlLvjHM}jnJ-j0v7v34(72X}*6W$x%7v3M%hYy4gh7W}ghmVAhhL44h zhfjo0hU3Et;Zxz$;WOd0;d9~h;S1r!a8meU_)_?C_)7R{_*(dS_(u3<_*U2uz8$_3 zz8g*s-wWRlKL|ezKMFq%KM6k#KMOw(zX-n!zY4z&zX`t$zYD()e+YjJ{~t^D6az|@ zMFF(?*|u%lwr$(CZQHhO+qP}nZ&oK$$@;FZo!nHNv+s9)@RMKs<_~}QZ@A}Q0uYcu z1SSYU2}W>25Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{afwHK5|EHYBqj+-Nk(!~ zkdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8DMoQhP?A!VrVM2% zM|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee(2`cPrVVXrM|(QZkxq1` z3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E)$9N_%kx5Ku3R9WJbY?J< zS-EM^HyS;lf!u##1*W({ju$9gufkxgu73tQR7c6P9nUF>ELd)dc+ z4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8EzTioUjce%%X9`KMyJmv{c zdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBA2)?_UBCkU#_`2tf%(a6%B0 zP=qE7VF^cgA`p>CL?#MRiAHo{5R+KMCJu3lM|={HkVGUV2}wyta#E0zRHP;iX-P+V zGLVr>WF`w)$wqc^kds{GCJ%YZM}7)WkU|uu2t_GIaY|5Y(34*D zrVoATM}Gz|kUW_xyE&FaFbiy<_>qc$9*2~kVib`2~T;(b6)V0SG?v8 zZ+XXiKJbxGeC7*Z`NnsC@RMKs<_~}QZ>aZQ0uYcu1SSYU2}W>25Ry=YCJbQ-M|dI- zkw`=)3Q>thbYc*bSi~j{afwHK5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ3t7oV zc5;xDT;wJXdC5n93Q&+j6s8D8DMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$PTGXZv zb*V>v8qknNG^PnnX-0Ee(2`cPrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk1~8C8 z3}y&J8OCr%Fp^P>W(;E)$9N_%kx5Ku3R9WJbY?J-EM^HyS;lf! zu##1*W({ju$9gufkxgu73tQR7c6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD;<_u>! z$9XPrkxN|W3Rk(tb#8EzTioUjce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW) z3t#!hcYg4bU;O3|fBA2q|6c+SkU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MRiAHo{ z5R+KMCJu3lM|={HkVGUV2}wyta#E0zRHP;iX-P+VGLVr>WF`w)$wqc^kds{GCJ%YZ zM}7)WkU|uu2t_GIaY|5Y(34*DrVoATM}Gz|kUW_ zxyE&FaFbiy<_>qc$9*2~kVib`2~T;(b6)V0SG?v8Z+XXiKJbxGeC7*Z`NnsC@RMKs z<_~}QZ<*&`0uYcu1SSYU2}W>25Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{afwHK z5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8 zDMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee(2`cP zrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E)$9N_% zkx5Ku3R9WJbY?J-EM^HyS;lf!u##1*W({ju$9gufkxgu73tQR7 zc6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8EzTioUj zce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBA2b?_UBC zkU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MRiAHo{5R+KMCJu3lM|={HkVGUV2}wyt za#E0zRHP;iX-P+VGLVr>WF`w)$wqc^kds{GCJ%YZM}7)WkU|uu2t_GIaY|5Y(34*DrVoATM}Gz|kUW_xyE&FaFbiy<_>qc$9*2~kVib` z2~T;(b6)V0SG?v8Z+XXiKJbxGeC7*Z`NnsC@RMKs<_~}QZ;AI`0uYcu1SSYU2}W>2 z5Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{afwHK5|EHYBqj+-Nk(!~kdjoSCJkvx zM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8DMoQhP?A!VrVM2%M|mnxkxEpi z3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee(2`cPrVVXrM|(QZkxq1`3tj0(cY4s1 zUi799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E)$9N_%kx5Ku3R9WJbY?J-EM^HyS;lf!u##1*W({ju$9gufkxgu73tQR7c6P9nUF>ELd)dc+4seh|9Oei| zImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8EzTioUjce%%X9`KMyJmv{cdB$^I@RC=& z<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBA2L|6c+SkU#_`2tf%(a6%B0P=qE7VF^cg zA`p>CL?#MRiAHo{5R+KMCJu3lM|={HkVGUV2}wyta#E0zRHP;iX-P+VGLVr>WF`w) z$wqc^kds{GCJ%YZM}7)WkU|uu2t_GIaY|5Y(34*DrVoATM}Gz| zkUW_xyE&FaFbiy<_>qc$9*2~kVib`2~T;(b6)V0SG?v8Z+XXiKJbxG zeC7*Z`NnsC@RMKs<_~}Que{@50uYcu1SSYU2}W>25Ry=YCJbQ-M|dI-kw`=)3Q>th zbYc*bSi~j{afwHK5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJX zdC5n93Q&+j6s8D8DMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknN zG^PnnX-0Ee(2`cPrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr% zFp^P>W(;E)$9N_%kx5Ku3R9WJbY?J-EM^HyS;lf!u##1*W({ju z$9gufkxgu73tQR7c6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W z3Rk(tb#8EzTioUjce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4b zU;O3|fBCPt=U)O4kU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MRiAHo{5R+KMCJu3l zM|={HkVGUV2}wyta#E0zRHP;iX-P+VGLVr>WF`w)$wqc^kds{GCJ%YZM}7)WkU|uu z2t_GIaY|5Y(34*DrVoATM}Gz|kUW_xyE&FaFbiy z<_>qc$9*2~kVib`2~T;(b6)V0SG?v8Z+XXiKJbxGeC7*Z`NnsC@RMKs<_~}Que9r5 z0uYcu1SSYU2}W>25Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{afwHK5|EHYBqj+- zNk(!~kdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8DMoQhP?A!V zrVM2%M|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee(2`cPrVVXrM|(QZ zkxq1`3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E)$9N_%kx5Ku3R9WJ zbY?J-EM^HyS;lf!u##1*W({ju$9gufkxgu73tQR7c6P9nUF>EL zd)dc+4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8EzTioUjce%%X9`KMy zJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBCPl?_UBCkU#_`2tf%( za6%B0P=qE7VF^cgA`p>CL?#MRiAHo{5R+KMCJu3lM|={HkVGUV2}wyta#E0zRHP;i zX-P+VGLVr>WF`w)$wqc^kds{GCJ%YZM}7)WkU|uu2t_GIaY|5Y z(34*DrVoATM}Gz|kUW_xyE&FaFbiy<_>qc$9*2~kVib`2~T;(b6)V0 zSG?v8Z+XXiKJbxGeC7*Z`NnsC@RMKs<_~}QudMT50uYcu1SSYU2}W>25Ry=YCJbQ- zM|dI-kw`=)3Q>thbYc*bSi~j{afwHK5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ z3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8DMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$P zTGXZvb*V>v8qknNG^PnnX-0Ee(2`cPrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk z1~8C83}y&J8OCr%Fp^P>W(;E)$9N_%kx5Ku3R9WJbY?J-EM^Hy zS;lf!u##1*W({ju$9gufkxgu73tQR7c6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD; z<_u>!$9XPrkxN|W3Rk(tb#8EzTioUjce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2T zkxzW)3t#!hcYg4bU;O3|fBCPd_g?}KkU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MR ziAHo{5R+KMCJu3lM|={HkVGUV2}wyta#E0zRHP;iX-P+VGLVr>WF`w)$wqc^kds{G zCJ%YZM}7)WkU|uu2t_GIaY|5Y(34*DrVoATM}Gz|kUW_xyE&FaFbiy<_>qc$9*2~kVib`2~T;(b6)V0SG?v8Z+XXiKJbxGeC7*Z`NnsC z@RMKs<_~}QucZ550uYcu1SSYU2}W>25Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{ zafwHK5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j z6s8D8DMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee z(2`cPrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E) z$9N_%kx5Ku3R9WJbY?J-EM^HyS;lf!u##1*W({ju$9gufkxgu7 z3tQR7c6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8Ez zTioUjce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBCPV z|6c+SkU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MRiAHo{5R+KMCJu3lM|={HkVGUV z2}wyta#E0zRHP;iX-P+VGLVr>WF`w)$wqc^kds{GCJ%YZM}7)WkU|uu2t_GIaY|5< zQk13)WhqB_Do~M1RHh15sYZ2bP?K8JrVe$fM|~R5kVZ772~BB6b6U`nRY(34*DrVoATM}Gz|kUW_xyE&FaFbiy<_>qc$9*2~ zkVib`2~T;(b6)V0SG?v8Z+XXiKJbxGeC7*Z`NnsC@RMKs<_~}Q?{bcR2|z#s5ttwZ zB^bd8K}bRonlOYV9N~#TL?RKHC`2V1(TPD!ViB7-#3df_NkBppk(eYTB^k*{K}u4Q znlz*(9qGwHMlz9^EMz4c*~vjpa*>-nMQr5Vj>K}%ZEnl`kh9qs8rM>^4&E_9_E z-RVJ3deNIc^ravD8NfgWF_<9?Wf;R5!AM3inlX%J9OIe5L?$trDNJP=)0x3cW-*&N z%w-<)S-?UTv6v++Wf{v^!Ae%Knl-Ft9qZY^MmDjTEo@~Q+u6ZRcCnj1>}4POIlw^< zahM|<fMJ{ofD_rFo*SWz>ZgHDC+~pqkdB8&+@t7w({N=xkdHy8;0SQE4f)JEo1SbR`2}Nka z5SDO+Cjt?PL}a26m1smK1~G|6Y~m1?c*G|G2}wj^l8}^SBqs$aNkwYXkd}0$Cj%MD zL}s#(m26}u2RX?_Zt{?qeB`G91t~;ficpkd6sH6wDMe|@P?mC(rveqJL}jW_m1+=(3WeG#AU83dBtnq@RoPH z=K~-4#Am+nm2Z6K2S546Z~pL?|1RbFmjDDL5P=CoP=XPh5QHQYp$S7+!V#VbL?jZC zi9%GO5uF&sBo?uWLtNq!p9CZ%5s67cQj(FJ6r>~-sYydx(vhAFWF!-r$wF4Lk)0gm zBp12KLtgTcp8^!55QQm1QHoKV5|pGAr71&M%2A#QRHPD>sX|q%QJospq!zWQLtW}o zp9VCf5shg=Q<~A77PO=lt!YDB+R>g4bfgoV=|We!(VZUjq!+#ELtpyQp8*VH5Q7=Q zP=+y_5sYLMqZz|k#xb4=Ok@(1nZi`2F`XIAWEQiT!(8Sup9L&r5sO*EQkJot6|7_x zt69TZ*0G)qY-AIg*}_(~v7H_4WEZ>H!(R5Wp937^5QjO!QI2t(6P)A}r#Zt}&T*a# zT;vj$xx!Vhah)67Oe|NOrS=%4>r0{rv;)xdxLzasF@|3?M?`TxkkKmY%A z@X!B0A^h|Iqr^Y|y)G89i9=lC5uXGkBoT>8LQ;~EoD`%a6{$%>TGEl83}hq|naM&{ zvXPw}F`or2WD$#5!cvy8 zoE5BO6{}gpTGp|i4Qyl+o7uuvwy~WZ>|__a*~4D;v7ZARg5|8*KAR&oJOcIikjO3&sC8HNAm8eV=s#1;W)SxD{s7)Q}QjhvHpdpQD zOcR>YjOMhUC9P;p8`{#2_H>{lo#;##y3&pA^q?ob=uIE`(vSWOU?77S%n*h$jNy!6 zB%>J37{)S=@l0SMlbFmDrZSD`%wQ(7n9UsKGLQKzU?GcG%o3KejODCgC97D?8rHIo z^=x1xo7l`2wz7@w>|iIm*v%gHvXA{7;2?)M%n^=qjN_c(B&Rsd8P0N!^IYH}m$=Lo zu5yj*+~6j+xXm5za*z8w;31EA%oCpSjOV=IC9inR8{YDc_k7?ZpZLrdzVeOl{NN|Q z_{|^w@=pNyCjbEnL|}ptlwbrW1R)7UXu=SdaD*oU5s5@(q7ap6L?;F@iA8MU5SMtw zCjkjbL}HSVlw>3)1u02IYSNIFbfhN(8OcOuvXGT*WG4qX$whARke7VqrvL>hL}7|h zlwuU81SKg&Y06NRa+Ie66{$pJs!)|`RHp_tsYPw-P?vhtrvVLVL}QxJlx8%i1ubbs zYueD3cC@Dh9qB}8y3mzwbf*VB=|yk)(3gJnX8;2k#9)Rnlwk~K1S1*6XvQ#>ag1jI z6Pd(hrZAOhOlJl&nZ<18Fqe7EX8{XY#A24Plw~Yu1uI#_YSyrpb*yIt8`;EWwy>3L zY-a~M*~M=5u$O)8=Ku#e#9@wblw%y{1SdJgY0hw#bDZY_7rDe`u5guWT;~Qixy5bn zaF=`B=K&9S#ABZDlxIBW1uuEUYu@mdcf98VANj;*zVMZAeCG#0`NePk@R$D%{r?hx zfCM5iK?q7Pf)j#}gd#Ly2unD^6M=|CA~I2kN;IMqgP6o3HgSkcJmQmpgd`#{Nk~dE zl9Pgzq#`wGNJ~1>lYxw6A~RXYN;a~SgPi0dH+jfQKJrt5f)t`KMJP%!ic^A;l%h0c zC`&oYQ-O+9qB2#eN;RregPPQ$Hg%{=J?hhdhBTrvO=wCpn$v=ow4ya_XiGcV(}9k3 zqBC9SN;kUGgP!!FH+|?!Kl(F(fed0WLm0|1hBJbZjAArn7|S@uGl7XrVlq>h$~2}k zgPF`?HglNEJm#~2g)Cw*OIXS>ma~GDtYS55Sj#%rvw@9lVl!LV$~LyMgPrVRH+$I2 zKK65fgB;>8M>xtcj&p*OoZ>WRILkTCbAgLo;xbpb$~CTYgPYvqHg~woJ?`^>hdkmj zPk72Rp7Vm2yy7))c*{H9^MQ|i;xk|P$~V6AgP;83H-GrcKY`?*00blufeAuTf)Sh$ zgd`N92}4-I5uOM{BodK{LR6v=ofyO<7O{y#T;dU*1SBL8iAh3Il98Mgq$CxoNkdxF zk)8}>Bomp*LRPYoogCyO7rDtpUhrl%y1;DMMMxQJxA^q!N{> zLRG3!of_1n7PYBEUFuPv1~jA*jcGztn$esVw4@cSX+vAu(Vh-;q!XR#LRY%cogVb0 z7rp62U;5FX0SsgigBik5hB2HGjARs}8N*n{F`fxbWD=8^!c?X)of*tz7PFbdT;?&K z1uSF{i&?@_ma&`_tYj6dS;Jb^v7QZVWD}d&!dAAiogM6C7rWWRUiPt{103WKhdIJg zj&Yn5oa7XzIm21bah?lYUG8z82R!5vk9opVp7ER)yyO+H zdBa=Y@tzNS{7OcbILjp)Q6Cb5W39O4p>_#_}9iAYQml9G(%q#z}!NKG2jl8*FbAS0Q`Oct_| zjqKzgC%MQ?9`cfp{1l)dg(yrBic*Z?l%OP~C`}p4QjYRepdyv1Ockn9jq22(Cbg(d z9qLk#`ZS;+jc800n$nEsw4f!eXiXd1(vJ3Ypd+2=Oc%P+jqdcIC%x!RANtad{tRFs zgBZ*ZhBA!dj9?_A7|j^QGLG>~U?P*4%oL_Fjp@u_CbO8$9Og2Q`7B@|i&)GOma>fH ztY9UpSj`&NvX1p^U?ZE@%oet?jqU7UC%f3q9`>@2{T$#Rhd9g;j&h9SoZuv;3J>- z%oo1$jqm*6C%^d3AO7-B5cwwn0SQE4f)JEo1SbR`2}Nka5SDO+Cjt?PL}a26m1smK z1~G|6Y~m1?c*G|G2}wj^l8}^SBqs$aNkwYXkd}0$Cj%MDL}s#(m26}u2RX?_Zt{?q zeB`G91t~;ficpkd6sH6wDMe|@P?mC(rveqJL}jW_m1+=(3WeG#AU8< zm1|t*1~<9IZSHWFd)(&%4|&96p74}sJm&>3dBtnq@RoPH=K~-4#Am+nm2Z6K2S546 zZ~pL?e}c+C0SHJS0uzLw1S2>h2uUbH6Na#aBRmm^NF*W?g{VX$Ix&bzEMgOfxWpqq z2}npH5|f0aBqKQ~NJ%PElZLdUBRv_&NG39qg{)*FJ2}WnE^?EHyyPQ41t>@%3R8rl z6r(sLC`l}a> z$Rs8+g{e$qIy0EbEM_x@xy)le3s}e^7PEw-V?7(#$R;+kg{^F3 zJ3H9PE_Snrz3gK@2RO(f4s(Q~9OF1AILRqabB42=<2)C*$R#dwg{xfSIybnKt?i=nJi=_8`;T0PI8f(Jme)G`6)m_3Q?FM6r~u&DM3j}QJON8 zr5xp{Kt(E1nJQGJ8r7*mO=?k_I@F~e^=Uvu8qt_0G^H8MX+cX`(V8~2r5)|*Ku0>! znJ#pt8{O$aPkPatKJ=v@{TaYO1~Hf+3}qO@8NoS|UJKW_S_j$lW9`Tqb zJmneBdBICw@tQZh>it7{Lia zNJ0^sFoY!>;fX**A`zJ=L?s&0i9t+a5t}%~B_8ofKtd9cm?R`68OcdON>Y)UG^8aR z>B&GwGLe}qWF;Hf$w5wXk()f^B_H`IKtT#om?9LV7{w_;NlH=yOIp#IHngQ3?dd>AI?r62tnz(58um>~>h7{eLCNJcT5F^pv#;I&HLPVF>)F6YHnEv4Y-JnU*}+bBv70^YWgq)Fz(Edim?IqJ z7{@umNltN^Go0ld=efW|E^(PFT;&?qxxr0tahp5bh{PlzDalAq3R04a)TALT=}1ooGLnhRWFafr z$W9J&l8fBrAusvJPXP*2h{6=1D8(pF2})9m(v+brs7?)PQj6Nu zp)U2PPXij#h{iObDa~k33tG~O*0iB5?PyO2I?{>GbfGKV=uQuM(u>~op)dXD&j1E8 zh`|hDD8m@e2u3oB(Trg%;~38bCNhc1Okpb1n9dAlGK<;FVJ`ES&jJ>*h{Y^nDa%;S z3Rbd;)vRGH>sZeQHnNG$Y+)*>T;VF$xXul3a*NyC;V$>M&jTLvh{rtPDbIM$3tsYy*Sz5^?|9D#KJtmr zeBmqK_|6Z0@{8a6;V=IU_5Mo$0uqS81R*HF2u=t>5{l4-AuQntPXrvz-t?g_{pimC1~Q1j3}Gn47|sYr zGK$fRVJzbq&jcniiOEc1D$|(G3}!Nm+00=s^O(;97P5%NEMY0jSk4MovWnHLVJ+)e z&jvQKiOp25Ry=YCJbQ-M|dI-kw`=)3Q>thbYc*bSi~j{afwHK z5|EHYBqj+-Nk(!~kdjoSCJkvxM|v`lkxXPJ3t7oVc5;xDT;wJXdC5n93Q&+j6s8D8 zDMoQhP?A!VrVM2%M|mnxkxEpi3RS5_b!t$PTGXZvb*V>v8qknNG^PnnX-0Ee(2`cP zrVVXrM|(QZkxq1`3tj0(cY4s1Ui799ed$Mk1~8C83}y&J8OCr%Fp^P>W(;E)$9N_% zkx5Ku3R9WJbY?J-EM^HyS;lf!u##1*W({ju$9gufkxgu73tQR7 zc6P9nUF>ELd)dc+4seh|9Oei|ImU5LaFSD;<_u>!$9XPrkxN|W3Rk(tb#8EzTioUj zce%%X9`KMyJmv{cdB$^I@RC=&<_&Lo$9q2TkxzW)3t#!hcYg4bU;O3|fBA2j=U)O4 zkU#_`2tf%(a6%B0P=qE7VF^cgA`p>CL?#MRiAMDQRd5dpfEWM}1e3LG+qP}nwr$(C zZQHhO+qO5ALp`C7GsGY!v4~9^;u4SeBp@M)NK6uvl8oe}ASJ0tO&ZdYj`U<8Bbmrd z7P69!?BpOPxyVf(@{*7I6rdo5C`=KGQjFr1pd_UzO&Q8kj`CEXB9*926{=E=>eQen zwWv)U>QayTG@v1kXiO8D(v0S`pe3znO&i+Mj`nn*Bc13>7rN4o?)0E1z35FJ`qGd7 z3}7IG7|alcGK}GjU?ig$%^1cqj`2)jB9oZR6s9tb>C9jzvzW~s<}#1@EMOsvSj-ZZ zvW(@dU?r)hZbx46w6?sAX&Jm4XZc+3-?@{H%a;3cnk%^TkGj`w`v zBcJ%p7rye1@BH8=zxd4`{_;;4{S$zI1R^j&2ud)56M~S0A~azLOE|(4frvyRGEs<1 zG@=uOn8YGBafnMi;*)@cBqA|MNJ=u2lY*3_A~k79OFGh%fsAA#Gg-(=HnNk0oa7=m zdB{sX@>76<6rwOiC`vJkQ-YF|qBLbFOF7C@fr?b3GF7NbHL6pCn$)5;b*M`{>eGOR zG@>z0Xi77h(}I??qBU)3OFP=rfsS;dGhOIPH@eeEMhTBSjsY%vx1eZVl``6 z%R1JxfsJfpGh5ioHny{ao$O*ad)Ui9_H%%P9O5uXILa}ObApqc;xuPC%Q?<-fs0(? zGFQ0DHLi1mo800yceu+v?(=|$JmN7=c*--L^MaSW;x%u0%RAolfscIRGhg`1H@@?O zpZwxCfB4J)Bi?@rKtKW!m>>it7{LiaNJ0^sFoY!>;fX**A`zJ=L?s&0i9t+a5t}%~ zB_8ofKtd9cm?R`68OcdON>Y)UG^8aR>B&GwGLe}qWF;Hf$w5wXk()f^B_H`IKtT#o zm?9LV7{w_;NlH=y zOIp#IHngQ3?dd>AI?r62tnz(58um>~>h7{eLCNJcT5F^pv# z;I&HLPVF>)F6YHnEv4 zY-JnU*}+bBv70^YWgq)Fz(Edim?IqJ7{@umNltN^Go0ld=efW|E^(PFT;&?qxxr0t zahp5b3)1u02IYSNIFbfhN(8OcOuvXGT*WG4qX$whARke7VqrvL>hL}7|hlwuU81SKg& zY06NRa+Ie66{$pJs!)|`RHp_tsYPw-P?vhtrvVLVL}QxJlx8%i1ubbsYueD3cC@Dh z9qB}8y3mzwbf*VB=|yk)(3gJnX8;2k#9)Rnlwk~K1S1*6XvQ#>ag1jI6Pd(hrZAOh zOlJl&nZ<18Fqe7EX8{XY#A24Plw~Yu1uI#_YSyrpb*yIt8`;EWwy>3LY-a~M*~M=5 zu$O)8=Ku#e#9@wblw%y{1SdJgY0hw#bDZY_7rDe`u5guWT;~Qixy5bnaF=`B=K&9S z#ABZDlxIBW1uuEUYu@mdcf98VANj;*zVMZAeCG#0`NePk@R$G3JN_jA0SQE4f)JEo z1SbR`2}Nka5SDO+Cjt?PL}a26m1smK1~G|6Y~m1?c*G|G2}wj^l8}^SBqs$aNkwYX zkd}0$Cj%MDL}s#(m26}u2RX?_Zt{?qeB`G91t~;ficpkd6sH6wDMe|@P?mC(rveqJ zL}jW_m1+=(3WeG#AU83 zdBtnq@RoPH=K~-4#Am+nm2Z6K2S546Z~pL?eBomp* zLRPYoogCyO7rDtpUhrl%y1;DMMMxQJxA^q!N{>LRG3!of_1n z7PYBEUFuPv1~jA*jcGztn$esVw4@cSX+vAu(Vh-;q!XR#LRY%cogVb07rp62U;5FX z0SsgigBik5hB2HGjARs}8N*n{F`fxbWD=8^!c?X)of*tz7PFbdT;?&K1uSF{i&?@_ zma&`_tYj6dS;Jb^v7QZVWD}d&!dAAiogM6C7rWWRUiPt{103WKhdIJgj&Yn5oa7Xz zIm21bah?lYUG8z82R!5vk9opVp7ER)yyO+HdBa=Y@tzO- E2Ve%JZU6uP literal 0 HcmV?d00001 diff --git a/ZFP/H5Z-ZFP/test/print_h5repack_farg.c b/ZFP/H5Z-ZFP/test/print_h5repack_farg.c new file mode 100644 index 00000000..8467ddd3 --- /dev/null +++ b/ZFP/H5Z-ZFP/test/print_h5repack_farg.c @@ -0,0 +1,116 @@ +/* +Copyright (c) 2016, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory +Written by Mark C. Miller, miller86@llnl.gov +LLNL-CODE-707197. All rights reserved. + +This file is part of H5Z-ZFP. Please also read the BSD license +https://raw.githubusercontent.com/LLNL/H5Z-ZFP/master/LICENSE +*/ + +#include +#include +#include +#include +#if defined(_WIN32) || defined(_WIN64) +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +typedef unsigned int uint; + +#include "H5Zzfp_plugin.h" + +#define NAME_LEN 256 + +/* convenience macro to handle command-line args and help */ +#define HANDLE_SEP(SEPSTR) \ +{ \ + char tmpstr[64]; \ + int len = snprintf(tmpstr, sizeof(tmpstr), "\n%s...", #SEPSTR);\ + printf(" %*s\n",60-len,tmpstr); \ +} + +#define HANDLE_ARG(A,PARSEA,PRINTA,HELPSTR) \ +{ \ + int i; \ + char tmpstr[64]; \ + int len; \ + int len2 = strlen(#A)+1; \ + for (i = 0; i < argc; i++) \ + { \ + if (!strncmp(argv[i], #A"=", len2)) \ + { \ + A = PARSEA; \ + break; \ + } \ + else if (!strncasecmp(argv[i], "help", 4)) \ + { \ + return 0; \ + } \ + } \ + len = snprintf(tmpstr, sizeof(tmpstr), "%s=" PRINTA, #A, A);\ + printf(" %s%*s\n",tmpstr,60-len,#HELPSTR); \ +} + +static void print_cdvals(int zfpmode, double rate, double acc, uint prec, + uint minbits, uint maxbits, uint maxprec, int minexp) +{ + unsigned int cd_values[10] = {0,0,0,0,0,0,0,0,0,0}; + int i, cd_nelmts = 10; + + /* setup zfp filter via generic (cd_values) interface */ + if (zfpmode == H5Z_ZFP_MODE_RATE) + H5Pset_zfp_rate_cdata(rate, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_PRECISION) + H5Pset_zfp_precision_cdata(prec, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_ACCURACY) + H5Pset_zfp_accuracy_cdata(acc, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_EXPERT) + H5Pset_zfp_expert_cdata(minbits, maxbits, maxprec, minexp, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_REVERSIBLE) + H5Pset_zfp_reversible_cdata(cd_nelmts, cd_values); + else + return; + + /* h5repack -f argument format... + + h5repack -f UD=32013,0,6,3,0,3539053052,1062232653,0,0 + */ + printf("\nh5repack -f argument...\n"); + printf(" -f UD=%u,0,%u", H5Z_FILTER_ZFP, cd_nelmts); + for (i = 0; i < cd_nelmts; i++) + printf(",%u", cd_values[i]); + printf("\n"); +} + +int main(int argc, char **argv) +{ + /* compression parameters (defaults taken from ZFP header) */ + int zfpmode = 1; + double rate = 3.5; + double acc = 0; + uint prec = 0; + uint minbits = 0; + uint maxbits = 0; + uint maxprec = 0; + int minexp = 0; + int help = 0; + + /* ZFP filter arguments */ + HANDLE_SEP(Print cdvals for set of ZFP compression parameters) + HANDLE_ARG(zfpmode,(int) strtol(argv[i]+len2,0,10),"%d",set zfp mode (1=rate,2=prec,3=acc,4=expert,5=rev)); + HANDLE_ARG(rate,(double) strtod(argv[i]+len2,0),"%g",set rate for rate mode of filter); + HANDLE_ARG(acc,(double) strtod(argv[i]+len2,0),"%g",set accuracy for accuracy mode of filter); + HANDLE_ARG(prec,(uint) strtol(argv[i]+len2,0,10),"%u",set precision for precision mode of zfp filter); + HANDLE_ARG(minbits,(uint) strtol(argv[i]+len2,0,10),"%u",set minbits for expert mode of zfp filter); + HANDLE_ARG(maxbits,(uint) strtol(argv[i]+len2,0,10),"%u",set maxbits for expert mode of zfp filter); + HANDLE_ARG(maxprec,(uint) strtol(argv[i]+len2,0,10),"%u",set maxprec for expert mode of zfp filter); + HANDLE_ARG(minexp,(int) strtol(argv[i]+len2,0,10),"%d",set minexp for expert mode of zfp filter); + HANDLE_ARG(help,(int)strtol(argv[i]+len2,0,10),"%d",this help message); /* must be last */ + + if (!help) + print_cdvals(zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + return 0; +} diff --git a/ZFP/H5Z-ZFP/test/test_common.h b/ZFP/H5Z-ZFP/test/test_common.h new file mode 100644 index 00000000..d791bd5f --- /dev/null +++ b/ZFP/H5Z-ZFP/test/test_common.h @@ -0,0 +1,145 @@ +/* +Copyright (c) 2016, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory +Written by Mark C. Miller, miller86@llnl.gov +LLNL-CODE-707197. All rights reserved. + +This file is part of H5Z-ZFP. Please also read the BSD license +https://raw.githubusercontent.com/LLNL/H5Z-ZFP/master/LICENSE +*/ + +#ifndef test_common_H +#define test_common_H + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* ahead of ALL headers to take proper effect */ +#endif + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_DEPRECATE +#define _USE_MATH_DEFINES +#include +#define j0 _j0 +#include +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#include +#pragma comment(lib, "Shlwapi.lib") +#define strcasestr StrStrIA +#define srandom(X) srand(X) +#define random rand +#define read _read +#define open _open +#define close _close +// strndup() is not available on Windows +char *strndup( const char *s1, size_t n) +{ + size_t len = strlen(s1); + size_t copy_len = len < n ? len : n; + char *copy = (char*)malloc(copy_len + 1); + memcpy(copy, s1, copy_len); + copy[copy_len] = 0; + return copy; +}; +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include "hdf5.h" + +#define NAME_LEN 256 + +/* convenience macro to handle command-line args and help */ +#define HANDLE_SEP(SEPSTR) \ +{ \ + char tmpstr[64]; \ + int len = snprintf(tmpstr, sizeof(tmpstr), "\n%s...", #SEPSTR);\ + printf(" %*s\n",60-len,tmpstr); \ +} + +#define HANDLE_ARG(A,PARSEA,PRINTA,HELPSTR) \ +{ \ + int i; \ + char tmpstr[64]; \ + int len; \ + int len2 = strlen(#A)+1; \ + for (i = 0; i < argc; i++) \ + { \ + if (!strncasecmp(#A,"help",4) && strstr(argv[i],"help"))\ + { \ + return 0; \ + } \ + else if (!strncmp(argv[i], #A"=", len2)) \ + { \ + A = PARSEA; \ + break; \ + } \ + } \ + len = snprintf(tmpstr, sizeof(tmpstr), "%s=" PRINTA, #A, A);\ + printf(" %s%*s\n",tmpstr,60-len,#HELPSTR); \ +} + + +/* convenience macro to handle errors */ +#ifdef _MSC_VER + +#define SET_ERROR(FNAME) \ +do { \ + size_t errmsglen = 94; \ + char errmsg[errmsglen]; \ + strerror_s(errmsg, errmsglen, errno); \ + fprintf(stderr, #FNAME " failed at line %d, errno=%d (%s)\n", \ + __LINE__, errno, errno?errmsg:"ok"); \ + return 1; \ +} while(0) + +#else + +#define SET_ERROR(FNAME) \ +do { \ + int _errno = errno; \ + fprintf(stderr, #FNAME " failed at line %d, errno=%d (%s)\n", \ + __LINE__, _errno, _errno?strerror(_errno):"ok"); \ + return 1; \ +} while(0) + +#endif + +/* Generate a simple, 1D sinusioidal data array with some noise */ +#define TYPINT 1 +#define TYPDBL 2 +static int gen_data(size_t npoints, double noise, double amp, void **_buf, int typ) +{ + size_t i; + double *pdbl = 0; + int *pint = 0; + + /* create data buffer to write */ + if (typ == TYPINT) + pint = (int *) malloc(npoints * sizeof(int)); + else + pdbl = (double *) malloc(npoints * sizeof(double)); + srandom(0xDeadBeef); + for (i = 0; i < npoints; i++) + { + double x = 2 * M_PI * (double) i / (double) (npoints-1); + double n = noise * ((double) random() / ((double)(1<<31)-1) - 0.5); + if (typ == TYPINT) + pint[i] = (int) (amp * (1 + sin(x)) + n); + else + pdbl[i] = (double) (amp * (1 + sin(x)) + n); + } + if (typ == TYPINT) + *_buf = pint; + else + *_buf = pdbl; + return 0; +} +#endif /* test_common_H */ diff --git a/ZFP/H5Z-ZFP/test/test_error.c b/ZFP/H5Z-ZFP/test/test_error.c new file mode 100644 index 00000000..d358fc2f --- /dev/null +++ b/ZFP/H5Z-ZFP/test/test_error.c @@ -0,0 +1,203 @@ +/* +Copyright (c) 2016, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory +Written by Mark C. Miller, miller86@llnl.gov +LLNL-CODE-707197. All rights reserved. + +This file is part of H5Z-ZFP. Please also read the BSD license +https://raw.githubusercontent.com/LLNL/H5Z-ZFP/master/LICENSE +*/ + +#include "test_common.h" + +#ifdef H5Z_ZFP_USE_PLUGIN +#include "H5Zzfp_plugin.h" +#else +#include "H5Zzfp_lib.h" +#include "H5Zzfp_props.h" +#endif + +static hid_t setup_filter(int n, hsize_t *chunk, int zfpmode, + double rate, double acc, unsigned int prec, + unsigned int minbits, unsigned int maxbits, unsigned int maxprec, int minexp) +{ + hid_t cpid; + + /* setup dataset creation properties */ + if (0 > (cpid = H5Pcreate(H5P_DATASET_CREATE))) SET_ERROR(H5Pcreate); + if (0 > H5Pset_chunk(cpid, n, chunk)) SET_ERROR(H5Pset_chunk); + + /* When filter is used as a library, we need to init it */ + H5Z_zfp_initialize(); + + /* Setup the filter using properties interface. These calls also add + the filter to the pipeline */ + if (zfpmode == H5Z_ZFP_MODE_RATE) + H5Pset_zfp_rate(cpid, rate); + else if (zfpmode == H5Z_ZFP_MODE_PRECISION) + H5Pset_zfp_precision(cpid, prec); + else if (zfpmode == H5Z_ZFP_MODE_ACCURACY) + H5Pset_zfp_accuracy(cpid, acc); + else if (zfpmode == H5Z_ZFP_MODE_EXPERT) + H5Pset_zfp_expert(cpid, minbits, maxbits, maxprec, minexp); + else if (zfpmode == H5Z_ZFP_MODE_REVERSIBLE) + H5Pset_zfp_reversible(cpid); + + return cpid; +} + +typedef struct client_data {char const *str; int has_str;} client_data_t; + +static int walk_hdf5_error_stack_cb(unsigned int n, H5E_error_t const *err_desc, void *_cd) +{ + client_data_t *cd = (client_data_t *) _cd; + if (n > 0) return 0; + cd->has_str = strcasestr(err_desc->desc, cd->str) != 0; + return 0; +} + +static int check_hdf5_error_stack_for_string(char const *str) +{ + client_data_t cd = {str, 0}; + H5Ewalk(H5E_DEFAULT, H5E_WALK_UPWARD, walk_hdf5_error_stack_cb, &cd); + return cd.has_str; +} + +#define DSIZE 2048 +#define FNAME "test_zfp_errors.h5" + +int main(int argc, char **argv) +{ + int i, ndiffs; + unsigned corrupt[4] = {0xDeadBeef,0xBabeFace, 0xDeadBabe, 0xBeefFace}; + double d = 1.0, *buf = 0, rbuf[DSIZE]; + hsize_t chunk[] = {DSIZE,16,16,16,16}; + haddr_t off; + hsize_t siz; + + /* HDF5 related variables */ + hid_t fid, tid, dsid, sid, cpid; + + int help = 0; + + /* compression parameters (defaults taken from ZFP header) */ + int zfpmode = H5Z_ZFP_MODE_ACCURACY; + double rate = 4; + double acc = 0.1; + unsigned int prec = 11; + unsigned int minbits = 0; + unsigned int maxbits = 4171; + unsigned int maxprec = 64; + int minexp = -1074; + + /* ZFP filter arguments */ + HANDLE_SEP(Usage: test_error [opt1=value1 opt2=value2]) + HANDLE_ARG(zfpmode,(int) strtol(argv[i]+len2,0,10),"%d", (1=rate,2=prec,3=acc,4=expert,5=reversible)); + HANDLE_ARG(rate,(double) strtod(argv[i]+len2,0),"%g",set rate for rate mode); + HANDLE_ARG(acc,(double) strtod(argv[i]+len2,0),"%g",set accuracy for accuracy mode); + HANDLE_ARG(prec,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set precision for precision mode); + HANDLE_ARG(minbits,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set minbits for expert mode); + HANDLE_ARG(maxbits,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set maxbits for expert mode); + HANDLE_ARG(maxprec,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set maxprec for expert mode); + HANDLE_ARG(minexp,(int) strtol(argv[i]+len2,0,10),"%d",set minexp for expert mode); + + cpid = setup_filter(1, chunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + /* Put this after setup_filter to permit printing of otherwise hard to + construct cd_values to facilitate manual invocation of h5repack */ + HANDLE_ARG(help,(int)strtol(argv[i]+len2,0,10),"%d",this help message); /* must be last for help to work */ + + gen_data(DSIZE, 0.01, 10, (void**)&buf, TYPDBL); + + H5Eset_auto(H5E_DEFAULT, 0, 0); + + /* setup the 1D data space */ + if (0 > (sid = H5Screate_simple(1, chunk, 0))) SET_ERROR(H5Screate_simple); + + /* create HDF5 file */ + if (0 > (fid = H5Fcreate(FNAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Fcreate); + + /* test incorrect data type */ + tid = H5Tcreate(H5T_STRING, 8); + if (0 <= (dsid = H5Dcreate(fid, "bad_type", tid, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION<=0x052 + assert(check_hdf5_error_stack_for_string("requires datatype class of H5T_FLOAT")); +#else + assert(check_hdf5_error_stack_for_string("requires datatype class of H5T_FLOAT or H5T_INTEGER")); +#endif + H5Tclose(tid); + + /* test invalid size of data type */ + tid = H5Tcopy(H5T_NATIVE_DOUBLE); + H5Tset_size(tid, 9); + if (0 <= (dsid = H5Dcreate(fid, "bad_type_size", tid, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + assert(check_hdf5_error_stack_for_string("requires datatype size of 4 or 8")); + H5Tclose(tid); + + /* test invalid chunking on highd data */ + cpid = setup_filter(5, chunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + if (0 <= (dsid = H5Dcreate(fid, "bad_chunking", H5T_NATIVE_FLOAT, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION<=0x053 + assert(check_hdf5_error_stack_for_string("chunk must have only 1...3 non-unity dimensions")); +#else + assert(check_hdf5_error_stack_for_string("chunk must have only 1...4 non-unity dimensions")); +#endif + H5Pclose(cpid); + + /* write a compressed dataset to be corrupted later */ + cpid = setup_filter(1, chunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + if (0 > (dsid = H5Dcreate(fid, "corrupted_data", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + off = 3496; // H5Dget_offset(dsid); + siz = H5Dget_storage_size(dsid); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + if (0 > H5Pclose(cpid)) SET_ERROR(H5Pclose); + + /* write a compressed dataset with some nans and infs */ + cpid = setup_filter(1, chunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + if (0 > (dsid = H5Dcreate(fid, "nans_and_infs", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + memcpy(rbuf, buf, sizeof(rbuf)); + for (i = 7; i < 7+4; i++) + rbuf[i] = d/(d-1.0); + rbuf[42] = sqrt((double)-1.0); + rbuf[42+1] = sqrt((double)-1.0); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + if (0 > H5Pclose(cpid)) SET_ERROR(H5Pclose); + if (0 > H5Fclose(fid)) SET_ERROR(H5Fclose); + + /* Use raw file I/O to corrupt the dataset named corrupted_data */ + FILE *fp; + fp = fopen(FNAME, "rb+"); + if(fp == NULL) SET_ERROR(fopen); + fseek(fp, (off_t) off + (off_t) siz / 3, SEEK_SET); + fwrite(corrupt, 1 , sizeof(corrupt), fp); + fclose(fp); + + /* Now, open the file with the nans_and_infs and corrupted datasets and try to read them */ + if (0 > (fid = H5Fopen(FNAME, H5F_ACC_RDONLY, H5P_DEFAULT))) SET_ERROR(H5Fopen); + if (0 > (dsid = H5Dopen(fid, "nans_and_infs", H5P_DEFAULT))) SET_ERROR(H5Dopen); + if (0 > H5Dread(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf)) SET_ERROR(H5Dread); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + for (i = 0, ndiffs = 0; i < DSIZE; i++) + { + double d = fabs(rbuf[i] - buf[i]); + if (d > acc) ndiffs++; + } + assert(ndiffs == 10); + if (0 > (dsid = H5Dopen(fid, "corrupted_data", H5P_DEFAULT))) SET_ERROR(H5Dopen); + if (0 > H5Dread(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf)) SET_ERROR(H5Dread); + for (i = 0, ndiffs = 0; i < DSIZE; i++) + { + double d = fabs(rbuf[i] - buf[i]); + if (d > acc) ndiffs++; + } + assert(ndiffs == 1408); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + free(buf); + if (0 > H5Fclose(fid)) SET_ERROR(H5Fclose); + H5close(); + + return 0; +} diff --git a/ZFP/H5Z-ZFP/test/test_read.c b/ZFP/H5Z-ZFP/test/test_read.c new file mode 100644 index 00000000..136c13d7 --- /dev/null +++ b/ZFP/H5Z-ZFP/test/test_read.c @@ -0,0 +1,166 @@ +/* + Copyright (c) 2016, Lawrence Livermore National Security, LLC. + Produced at the Lawrence Livermore National Laboratory + Written by Mark C. Miller, miller86@llnl.gov + LLNL-CODE-707197 All rights reserved. + +This file is part of H5Z-ZFP. For details, see +https://github.com/LLNL/H5Z-ZFP. Please also read the Additional +BSD Notice. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the disclaimer below. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the disclaimer (as noted below) + in the documentation and/or other materials provided with the + distribution. + +* Neither the name of the LLNS/LLNL nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE +LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Additional BSD Notice + +1. This notice is required to be provided under our contract with the +U.S. Department of Energy (DOE). This work was produced at Lawrence +Livermore National Laboratory under Contract No. DE-AC52-07NA27344 +with the DOE. + +2. Neither the United States Government nor Lawrence Livermore +National Security, LLC nor any of their employees, makes any warranty, +express or implied, or assumes any liability or responsibility for the +accuracy, completeness, or usefulness of any information, apparatus, +product, or process disclosed, or represents that its use would not +infringe privately-owned rights. + +3. Also, reference herein to any specific commercial products, +process, or services by trade name, trademark, manufacturer or +otherwise does not necessarily constitute or imply its endorsement, +recommendation, or favoring by the United States Government or +Lawrence Livermore National Security, LLC. The views and opinions of +authors expressed herein do not necessarily state or reflect those of +the United States Government or Lawrence Livermore National Security, +LLC, and shall not be used for advertising or product endorsement +purposes. +*/ + +#include "test_common.h" + +#ifndef H5Z_ZFP_USE_PLUGIN +#include "H5Zzfp_lib.h" +#endif + +int main(int argc, char **argv) +{ + int i, help=0; + double *obuf, *cbuf; + + /* filename variables */ + char *ifile = (char *) calloc(NAME_LEN,sizeof(char)); + + /* HDF5 dataset info */ + hid_t fid, dsid, space_id; + hsize_t npoints; + + /* absolute and relative differencing thresholds */ + double max_absdiff = 0; + double max_reldiff = 0; + + /* actual absolute and relative differences observed */ + double actual_max_absdiff = 0; + double actual_max_reldiff = 0; + int num_absdiffs = 0; + int num_reldiffs = 0; + int doint = 0; + int ret = 0; + + /* file arguments */ + strcpy(ifile, "test_zfp.h5"); + HANDLE_SEP(Usage: test_read [opt1=value1 opt2=value2]) + HANDLE_ARG(ifile,strndup(argv[i]+len2,NAME_LEN), "\"%s\"",set input filename); + HANDLE_ARG(max_absdiff,strtod(argv[i]+len2,0),"%g",set maximum absolute diff); + HANDLE_ARG(max_reldiff,strtod(argv[i]+len2,0),"%g",set maximum relative diff); + HANDLE_ARG(doint,(int) strtol(argv[i]+len2,0,10),"%d",check integer datasets instead); + HANDLE_ARG(ret,(int) strtol(argv[i]+len2,0,10),"%d",return 1 if diffs (0=all,1=abs,2=rel)); + HANDLE_ARG(help,(int)strtol(argv[i]+len2,0,10),"%d",this help message); + +#ifndef H5Z_ZFP_USE_PLUGIN + H5Z_zfp_initialize(); +#endif + + /* open the HDF5 file */ + if (0 > (fid = H5Fopen(ifile, H5F_ACC_RDONLY, H5P_DEFAULT))) SET_ERROR(H5Fopen); + + /* read the original dataset */ + if (0 > (dsid = H5Dopen(fid, doint?"int_original":"original", H5P_DEFAULT))) SET_ERROR(H5Dopen); + if (0 > (space_id = H5Dget_space(dsid))) SET_ERROR(H5Dget_space); + if (0 == (npoints = H5Sget_simple_extent_npoints(space_id))) SET_ERROR(H5Sget_simple_extent_npoints); + if (0 > H5Sclose(space_id)) SET_ERROR(H5Sclose); + if (0 == (obuf = (double *) malloc(npoints * sizeof(double)))) SET_ERROR(malloc); + if (0 > H5Dread(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, obuf)) SET_ERROR(H5Dread); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* read the compressed dataset */ + if (0 > (dsid = H5Dopen(fid, doint?"int_compressed":"compressed", H5P_DEFAULT))) SET_ERROR(H5Dopen); + if (0 == (cbuf = (double *) malloc(npoints * sizeof(double)))) SET_ERROR(malloc); + if (0 > H5Dread(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, cbuf)) SET_ERROR(H5Dread); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* clean up */ + if (0 > H5Fclose(fid)) SET_ERROR(H5Fclose); + + /* compare original to compressed */ + for (i = 0; i < (int) npoints; i++) + { + double absdiff = obuf[i] - cbuf[i]; + if (absdiff < 0) absdiff = -absdiff; + if (absdiff > 0) + { + double reldiff = 0; + if (obuf[i] != 0) reldiff = absdiff / obuf[i]; + + if (absdiff > actual_max_absdiff) actual_max_absdiff = absdiff; + if (reldiff > actual_max_reldiff) actual_max_reldiff = reldiff; + if (absdiff > max_absdiff) + num_absdiffs++; + if (reldiff > max_reldiff) + num_reldiffs++; + } + } + printf("Absolute Diffs: %d values are different; actual-max-absdiff = %g\n", + num_absdiffs, actual_max_absdiff); + printf("Relative Diffs: %d values are different; actual-max-reldiff = %g\n", + num_reldiffs, actual_max_reldiff); + +#ifndef H5Z_ZFP_USE_PLUGIN + /* When filter is used as a library, we need to finalize it */ + H5Z_zfp_finalize(); +#endif + + free(obuf); + free(cbuf); + free(ifile); + + if (ret == 0) return (num_absdiffs+num_reldiffs)>0; + if (ret == 1) return num_absdiffs>0; + if (ret == 2) return num_reldiffs>0; + return 0; +} diff --git a/ZFP/H5Z-ZFP/test/test_rw_fortran.F90 b/ZFP/H5Z-ZFP/test/test_rw_fortran.F90 new file mode 100644 index 00000000..313cd944 --- /dev/null +++ b/ZFP/H5Z-ZFP/test/test_rw_fortran.F90 @@ -0,0 +1,465 @@ +PROGRAM main + + USE ISO_C_BINDING + USE ISO_FORTRAN_ENV, ONLY: ERROR_UNIT, OUTPUT_UNIT + USE HDF5 + USE h5zzfp_props_f + IMPLICIT NONE + + INTEGER, PARAMETER :: dp = C_DOUBLE + + INTEGER, PARAMETER :: NAME_LEN=256 + INTEGER, PARAMETER :: DIM0=32 + INTEGER, PARAMETER :: DIM1=64 + INTEGER, PARAMETER :: CHUNK0=4 + INTEGER, PARAMETER :: CHUNK1=8 + + INTEGER :: i + INTEGER(hsize_t) :: j + + ! sinusoid data generation variables + INTEGER(hsize_t) :: npoints + + ! compression parameters (defaults taken from ZFP header) + INTEGER(C_INT) :: zfpmode = 3 !1=rate, 2=prec, 3=acc, 4=expert + REAL(dp) :: rate = 4_c_double + REAL(dp) :: acc = 0_c_double + INTEGER(C_INT) :: prec = 11 + INTEGER(C_INT) :: dim = 0 + INTEGER(C_INT), PARAMETER :: minbits = 0 + INTEGER(C_INT), PARAMETER :: maxbits = 4171 + INTEGER(C_INT), PARAMETER :: maxprec = 64 + INTEGER(C_INT), PARAMETER :: minexp = -1074 + + ! HDF5 related variables + INTEGER(hid_t) fid, dsid, sid, cpid, dcpl_id, space_id + INTEGER(C_INT), DIMENSION(1:H5Z_ZFP_CD_NELMTS_MEM) :: cd_values + INTEGER(C_SIZE_T) :: cd_nelmts = H5Z_ZFP_CD_NELMTS_MEM + + ! compressed/uncompressed difference stat variables + REAL(dp) :: max_absdiff = 1.e-8_dp + REAL(dp) :: max_reldiff = 1.e-8_dp + INTEGER(C_INT) :: num_diffs = 0 + + REAL(dp) :: noise = 0.001 + REAL(dp) :: amp = 17.7 + + REAL(dp), DIMENSION(1:DIM0,1:DIM1), TARGET :: wdata + INTEGER(hsize_t), DIMENSION(1:2) :: dims = (/DIM0, DIM1/) + INTEGER(hsize_t), DIMENSION(1:2) :: dims1; + INTEGER(hsize_t), DIMENSION(1:2) :: chunk2 = (/CHUNK0, CHUNK1/) + INTEGER(hsize_t), DIMENSION(1:1) :: chunk256 = (/256/) + REAL(dp), DIMENSION(:), ALLOCATABLE, TARGET :: obuf, cbuf, cbuf1, cbuf2 + CHARACTER(LEN=180) :: ofile="test_zfp_fortran.h5" + + INTEGER :: status + TYPE(C_PTR) :: f_ptr + INTEGER, PARAMETER :: H5Z_FLAG_MANDATORY = INT(Z'00000000') + REAL(dp) :: absdiff, reldiff + + INTERFACE + LOGICAL FUNCTION real_eq(a,b,ulp) + USE ISO_C_BINDING + IMPLICIT NONE + REAL(C_DOUBLE), INTENT (in):: a,b + REAL(C_DOUBLE) :: Rel + INTEGER, OPTIONAL, INTENT( IN ) :: ulp + END FUNCTION real_eq + END INTERFACE + + CHARACTER(LEN=180) :: arg + INTEGER :: len + LOGICAL :: write_only = .FALSE., avail + INTEGER :: config_flag = 0 ! for h5zget_filter_info_f + INTEGER :: config_flag_both = 0 ! for h5zget_filter_info_f + INTEGER :: nerr = 0 + + DO i = 1, COMMAND_ARGUMENT_COUNT() + CALL GET_COMMAND_ARGUMENT(i,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + IF(arg(1:len).EQ.'zfpmode') THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) zfpmode + ELSE IF (arg(1:len).EQ.'rate')THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) rate + ELSE IF (arg(1:len).EQ.'acc')THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) acc + ELSE IF (arg(1:len).EQ.'dim')THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) dim + ELSE IF (arg(1:len).EQ.'prec')THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) prec + ELSE IF (arg(1:len).EQ.'ofile')THEN + CALL GET_COMMAND_ARGUMENT(i+1,arg,len,status) + IF (status .NE. 0) THEN + WRITE (ERROR_UNIT,*) 'get_command_argument failed: status = ', status, ' arg = ', i + STOP 1 + END IF + READ(arg(1:len), *) ofile + ELSE IF (arg(1:len).EQ.'write')THEN + write_only = .TRUE. + + ELSE IF (INDEX(arg(1:len),'help').NE.0)THEN + PRINT*," *** USAGE *** " + PRINT*,"zfpmode - 1=rate,2=prec,3=acc,4=expert,5=reversible" + PRINT*,"rate - set rate for rate mode of filter" + PRINT*,"acc - set accuracy for accuracy mode of filter" + PRINT*,"prec - set PRECISION for PRECISION mode of zfp filter" + PRINT*,"dim - set size of 1D dataset used" + PRINT*,"ofile - set the output file" + PRINT*,"write - only write the file" + STOP 1 + ENDIF + + END DO + + ! create data to write if we're not reading from an existing file + + IF (dim .EQ. 0) THEN + CALL gen_data(INT(dim1*dim0, c_size_t), noise, amp, wdata) + ELSE + CALL gen_data(INT(dim, c_size_t), noise, amp, wdata) + END IF + + CALL h5open_f(status) + CALL check("h5open_f", status, nerr) + + ! initialize the ZFP filter + status = H5Z_zfp_initialize() + CALL check("H5Z_zfp_initialize", status, nerr) + + ! create HDF5 file + CALL h5fcreate_f(ofile, H5F_ACC_TRUNC_F, fid, status) + CALL check("h5fcreate_f", status, nerr) + + ! setup dataset compression via cd_values + + CALL h5pcreate_f(H5P_DATASET_CREATE_F, cpid, status) + CALL check("h5pcreate_f", status, nerr) + IF (dim .EQ. 0) THEN + CALL h5pset_chunk_f(cpid, 2, chunk2, status) + CALL check("h5pset_chunk_f", status, nerr) + ELSE + CALL h5pset_chunk_f(cpid, 1, chunk256, status) + CALL check("h5pset_chunk_f", status, nerr) + END IF + + ! + ! Check that filter is registered with the library now. + ! If it is registered, retrieve filter's configuration. + ! + CALL H5Zfilter_avail_f(H5Z_FILTER_ZFP, avail, status) + CALL check("H5Zfilter_avail_f", status, nerr) + + IF (avail) THEN + CALL h5zget_filter_info_f(H5Z_FILTER_ZFP, config_flag, status) + CALL check("h5zget_filter_info_f", status, nerr) + ! + ! Make sure h5zget_filter_info_f returns the right flag + ! + config_flag_both=IOR(H5Z_FILTER_ENCODE_ENABLED_F,H5Z_FILTER_DECODE_ENABLED_F) + IF (config_flag .NE. config_flag_both) THEN + IF(config_flag .NE. H5Z_FILTER_DECODE_ENABLED_F) THEN + PRINT*,'h5zget_filter_info_f config_flag failed' + ENDIF + ENDIF + ENDIF + + ! setup the 2D data space + IF (dim .EQ. 0) THEN + CALL h5screate_simple_f(2, dims, sid, status) + CALL check("h5screate_simple_f", status, nerr) + ELSE + dims1 = (/dim, 1/) + CALL h5screate_simple_f(1, dims1, sid, status) + CALL check("h5screate_simple_f", status, nerr) + END IF + + ! write the data WITHOUT compression + CALL h5dcreate_f(fid, "original", H5T_NATIVE_DOUBLE, sid, dsid, status) + CALL check("h5dcreate_f", status, nerr) + f_ptr = C_LOC(wdata(1,1)) + CALL h5dwrite_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("h5dwrite_f", status, nerr) + CALL h5dclose_f(dsid,status) + CALL check("h5dclose_f", status, nerr) + + ! write data using default parameters + cd_nelmts = 0 + CALL H5Pset_filter_f(cpid, H5Z_FILTER_ZFP, H5Z_FLAG_MANDATORY, cd_nelmts, cd_values, status) + CALL check("H5Pset_filter_f", status, nerr) + + CALL h5dcreate_f(fid, "compressed-default", H5T_NATIVE_DOUBLE, sid, dsid, status, dcpl_id=cpid) + CALL check("h5dcreate_f", status, nerr) + f_ptr = C_LOC(wdata(1,1)) + CALL h5dwrite_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("h5dwrite_f", status, nerr) + IF(status.NE.0) PRINT*,"h5dwrite_f failed" + CALL h5dclose_f(dsid,status) + CALL check("h5dclose_f", status, nerr) + + ! write the data using properties + CALL H5Premove_filter_f(cpid, H5Z_FILTER_ZFP, status) + IF (zfpmode .EQ. H5Z_ZFP_MODE_RATE) THEN + status = H5Pset_zfp_rate(cpid, rate) + CALL check("H5Pset_zfp_rate", status, nerr) + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_PRECISION) THEN + status = H5Pset_zfp_precision(cpid, prec) + CALL check("H5Pset_zfp_precision", status, nerr) + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_ACCURACY)THEN + status = H5Pset_zfp_accuracy(cpid, acc) + CALL check("H5Pset_zfp_accuracy", status, nerr) + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_EXPERT) THEN + status = H5Pset_zfp_expert(cpid, minbits, maxbits, maxprec, minexp) + CALL check("H5Pset_zfp_expert", status, nerr) + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_REVERSIBLE) THEN + status = H5Pset_zfp_reversible(cpid) + CALL check("H5Pset_zfp_reversible", status, nerr) + ENDIF + CALL check("H5Pset_filter_f", status, nerr) + CALL h5dcreate_f(fid, "compressed", H5T_NATIVE_DOUBLE, sid, dsid, status, dcpl_id=cpid) + CALL check("h5dcreate_f", status, nerr) + f_ptr = C_LOC(wdata(1,1)) + CALL h5dwrite_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("h5dwrite_f", status, nerr) + CALL h5dclose_f(dsid,status) + CALL check("h5dclose_f", status, nerr) + + ! write the data using plug-in + CALL H5Premove_filter_f(cpid, H5Z_FILTER_ZFP, status) + cd_values = 0 + cd_nelmts = H5Z_ZFP_CD_NELMTS_MEM + IF (zfpmode .EQ. H5Z_ZFP_MODE_RATE) THEN + CALL H5Pset_zfp_rate_cdata(rate, cd_nelmts, cd_values) + IF(cd_values(1).NE.1 .OR. cd_nelmts.NE.4)THEN + PRINT*,'H5Pset_zfp_rate_cdata failed' + STOP 1 + ENDIF + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_PRECISION) THEN + CALL H5Pset_zfp_precision_cdata(prec, cd_nelmts, cd_values) + IF(cd_values(1).NE.2 .OR. cd_nelmts.NE.3)THEN + PRINT*,'H5Pset_zfp_precision_cdata failed' + STOP 1 + ENDIF + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_ACCURACY)THEN + CALL H5Pset_zfp_accuracy_cdata(0._dp, cd_nelmts, cd_values) + IF(cd_values(1).NE.3 .OR. cd_nelmts.NE.4)THEN + PRINT*,'H5Pset_zfp_accuracy_cdata failed' + STOP 1 + ENDIF + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_EXPERT) THEN + CALL H5Pset_zfp_expert_cdata(minbits, maxbits, maxprec, minexp, cd_nelmts, cd_values) + IF(cd_values(1).NE.4 .OR. cd_nelmts.NE.6)THEN + PRINT*,'H5Pset_zfp_expert_cdata failed' + STOP 1 + ENDIF + ELSE IF (zfpmode .EQ. H5Z_ZFP_MODE_REVERSIBLE) THEN + CALL H5Pset_zfp_reversible_cdata(cd_nelmts, cd_values) + IF(cd_values(1).NE.5 .OR. cd_nelmts.NE.1)THEN + PRINT*,'H5Pset_zfp_reversible_cdata failed' + STOP 1 + ENDIF + ENDIF + + CALL H5Pset_filter_f(cpid, H5Z_FILTER_ZFP, H5Z_FLAG_MANDATORY, cd_nelmts, cd_values, status) + CALL check("H5Pset_filter_f", status, nerr) + + CALL h5dcreate_f(fid, "compressed-plugin", H5T_NATIVE_DOUBLE, sid, dsid, status, dcpl_id=cpid) + CALL check("h5dcreate_f", status, nerr) + f_ptr = C_LOC(wdata(1,1)) + CALL h5dwrite_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("h5dwrite_f", status, nerr) + CALL h5dclose_f(dsid,status) + CALL check("h5dclose_f", status, nerr) + + ! clean up + CALL h5pclose_f(cpid, status) + CALL check("", status, nerr) + CALL h5sclose_f(sid, status) + CALL check("", status, nerr) + CALL h5fclose_f(fid, status) + CALL check("", status, nerr) + + IF(write_only) STOP + + CALL h5fopen_f(ofile, H5F_ACC_RDONLY_F, fid, status) + CALL check("h5fopen_f", status, nerr) + + ! read the original dataset + CALL h5dopen_f (fid, "original", dsid, status) + CALL check("h5dopen_f", status, nerr) + + CALL h5dget_space_f(dsid, space_id,status) + CALL check("h5dget_space_f", status, nerr) + CALL H5Sget_simple_extent_npoints_f(space_id, npoints, status) + CALL check("H5Sget_simple_extent_npoints_f", status, nerr) + CALL H5Sclose_f(space_id, status) + CALL check("H5Sclose_f", status, nerr) + ALLOCATE(obuf(1:npoints)) + f_ptr = C_LOC(obuf(1)) + CALL H5Dread_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("H5Dread_f", status, nerr) + CALL H5Dclose_f(dsid, status) + CALL check("H5Dclose_f", status, nerr) + + ! read the compressed dataset + CALL h5dopen_f (fid, "compressed-default", dsid, status) + CALL check("", status, nerr) + CALL H5Dget_create_plist_f(dsid, dcpl_id, status ) + CALL check("", status, nerr) + ALLOCATE(cbuf(1:npoints)) + f_ptr = C_LOC(cbuf(1)) + CALL H5Dread_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("H5Dread_f", status, nerr) + CALL H5Dclose_f(dsid, status) + CALL check("H5Dclose_f", status, nerr) + + ! read the compressed dataset + CALL h5dopen_f (fid, "compressed", dsid, status) + CALL check("", status, nerr) + CALL H5Dget_create_plist_f(dsid, dcpl_id, status ) + CALL check("", status, nerr) + ALLOCATE(cbuf1(1:npoints)) + f_ptr = C_LOC(cbuf1(1)) + CALL H5Dread_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("H5Dread_f", status, nerr) + CALL H5Dclose_f(dsid, status) + CALL check("H5Dclose_f", status, nerr) + + ! read the compressed dataset (plugin) + CALL h5dopen_f (fid, "compressed-plugin", dsid, status) + CALL check("", status, nerr) + CALL H5Dget_create_plist_f(dsid, dcpl_id, status ) + CALL check("", status, nerr) + ALLOCATE(cbuf2(1:npoints)) + f_ptr = C_LOC(cbuf2(1)) + CALL H5Dread_f(dsid, H5T_NATIVE_DOUBLE, f_ptr, status) + CALL check("H5Dread_f", status, nerr) + CALL H5Dclose_f(dsid, status) + CALL check("H5Dclose_f", status, nerr) + + ! clean up + CALL H5Pclose_f(dcpl_id, status) + CALL check("H5Pclose_f", status, nerr) + CALL H5Fclose_f(fid, status) + CALL check("H5Fclose_f", status, nerr) + + ! compare to generated data + DO j = 1, npoints + absdiff = obuf(j) - cbuf(j) + if(absdiff < 0) absdiff = -absdiff + IF(absdiff > max_absdiff) THEN + reldiff = 0 + IF (obuf(j) .NE. 0) reldiff = absdiff / obuf(j) + + IF (absdiff > max_absdiff) max_absdiff = absdiff + IF (reldiff > max_reldiff) max_reldiff = reldiff + IF( .NOT.real_eq(obuf(j), cbuf(j), 100) ) THEN + num_diffs = num_diffs + 1 + ENDIF + ENDIF + ENDDO + + IF(num_diffs.NE.0)THEN + WRITE(ERROR_UNIT,'(A)') "Fortran read/write test Failed" + WRITE(ERROR_UNIT,'(I0," values are different; max-absdiff = ",E15.8,", max-reldiff = ",E15.8)') & + num_diffs,max_absdiff, max_reldiff + STOP 1 + ELSE IF(nerr.NE.0)THEN + WRITE(ERROR_UNIT,'(A)') "Fortran read/write test Failed" + STOP 1 + ELSE + WRITE(OUTPUT_UNIT,'(A)') "Fortran read/write test Passed" + ENDIF + + DEALLOCATE(obuf, cbuf, cbuf1, cbuf2) + + ! initialize the ZFP filter + status = H5Z_zfp_finalize() + CALL check("H5Z_zfp_finalize", status, nerr) + + CALL H5close_f(status) + + CALL EXIT(0) + +END PROGRAM main + +! Generate a simple, 1D sinusioidal data array with some noise +SUBROUTINE gen_data(npoints, noise, amp, buf) + USE ISO_C_BINDING + IMPLICIT NONE + INTEGER(C_SIZE_T) :: npoints + REAL(C_DOUBLE) :: noise + REAL(C_DOUBLE) :: amp + REAL(C_DOUBLE), DIMENSION(1:npoints) :: buf + + REAL(C_DOUBLE), PARAMETER :: PI = 3.1415926535897932384626433832795028841971_C_DOUBLE + + INTEGER :: size + INTEGER, DIMENSION(:), ALLOCATABLE :: seed + INTEGER(C_SIZE_T) :: i + REAL(C_DOUBLE) :: x + REAL(C_DOUBLE) :: rand + + ! Fixed random seed. + CALL RANDOM_SEED(SIZE=size) + ALLOCATE(seed(size)) + seed = 123456789 + CALL RANDOM_SEED(PUT=seed) + + DO i = 1, npoints + rand = REAL(i, C_DOUBLE) + CALL RANDOM_NUMBER(rand) + x = 2_c_double * PI * REAL(i-1, C_DOUBLE) / REAL(npoints-1, C_DOUBLE) + buf(i) = amp*( 1.0_C_DOUBLE + SIN(x)) + (rand - 0.5_C_DOUBLE)*noise + ENDDO + + IF (ALLOCATED(seed)) DEALLOCATE(seed) +END SUBROUTINE gen_data + +LOGICAL FUNCTION real_eq(a,b,ulp) + USE ISO_C_BINDING + IMPLICIT NONE + REAL(C_DOUBLE), INTENT (in):: a,b + REAL(C_DOUBLE) :: Rel = 1.0_C_DOUBLE + INTEGER, OPTIONAL, INTENT( IN ) :: ulp + IF ( PRESENT( ulp ) ) Rel = REAL( ABS(ulp), C_DOUBLE) + real_eq = ABS( a - b ) < ( Rel * SPACING( MAX(ABS(a),ABS(b)) ) ) +END FUNCTION real_eq + +SUBROUTINE check(string,error,total_error) + USE ISO_FORTRAN_ENV, ONLY: ERROR_UNIT + CHARACTER(LEN=*) :: string + INTEGER :: error, total_error + IF (error .LT. 0) THEN + total_error=total_error+1 + WRITE(ERROR_UNIT,*) string, " FAILED" + ENDIF + RETURN +END SUBROUTINE check diff --git a/ZFP/H5Z-ZFP/test/test_write.c b/ZFP/H5Z-ZFP/test/test_write.c new file mode 100644 index 00000000..a0bca47c --- /dev/null +++ b/ZFP/H5Z-ZFP/test/test_write.c @@ -0,0 +1,602 @@ +/* +Copyright (c) 2016, Lawrence Livermore National Security, LLC. +Produced at the Lawrence Livermore National Laboratory +Written by Mark C. Miller, miller86@llnl.gov +LLNL-CODE-707197. All rights reserved. + +This file is part of H5Z-ZFP. Please also read the BSD license +https://raw.githubusercontent.com/LLNL/H5Z-ZFP/master/LICENSE +*/ + +#include "test_common.h" + +#ifdef H5Z_ZFP_USE_PLUGIN +#include "H5Zzfp_plugin.h" +#else +#include "H5Zzfp_lib.h" +#include "H5Zzfp_props.h" +#endif + +#if ZFP_HAS_CFP +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION>=0x1000 + #include "zfp/array.h" +#elif defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION>=0x053 + #include "cfparrays.h" +#else + #error GOT HERE +#endif +#endif + +#if 0 +/* Populate the hyper-dimensional array with samples of a radially symmetric + sinc() function but where certain sub-spaces are randomized through dimindx arrays */ +static void +hyper_smooth_radial(void *b, int typ, int n, int ndims, int const *dims, int const *m, + int const * const dimindx[10]) +{ + int i; + double hyper_radius = 0; + const double amp = 10000; + double val; + + for (i = ndims-1; i >= 0; i--) + { + int iar = n / m[i]; + iar = dimindx[i][iar]; /* allow for randomized shuffle of this axis */ + iar -= dims[i]/2; /* ensure centering in middle of the array */ + n = n % m[i]; + hyper_radius += iar*iar; + } + hyper_radius = sqrt(hyper_radius); + + if (hyper_radius < 1e-15) + val = amp; + else + val = amp * sin(0.4*hyper_radius) / (0.4*hyper_radius); + + if (typ == TYPINT) + { + int *pi = (int*) b; + *pi = (int) val; + } + else + { + double *pd = (double*) b; + *pd = val; + } +} +#endif + +static double func(int i, double arg) +{ + /* a random assortment of interesting, somewhat bounded, unary functions */ + double (*const funcs[])(double x) = {cos, j0, fabs, sin, cbrt, erf}; + int const nfuncs = sizeof(funcs)/sizeof(funcs[0]); + return funcs[i%nfuncs](arg); +} + +/* Populate the hyper-dimensional array with samples of set of separable functions + but where certain sub-spaces are randomized through dimindx arrays */ +static void +hyper_smooth_separable(void *b, int typ, int n, int ndims, int const *dims, int const *m, + int const * const dimindx[10]) +{ + int i; + double val = 1; + + for (i = ndims-1; i >= 0; i--) + { + int iar = n / m[i]; + iar = dimindx[i][iar]; /* allow for randomized shuffle of this axis */ + iar -= dims[i]/2; /* ensure centering in middle of the array */ + n = n % m[i]; + val *= func(i, (double) iar); + } + + if (typ == TYPINT) + { + int *pi = (int*) b; + *pi = (int) val; + } + else + { + double *pd = (double*) b; + *pd = val; + } +} + +/* Produce multi-dimensional array test data with the property that it is random + in the UNcorrelated dimensions but smooth in the correlated dimensions. This + is achieved by randomized shuffling of the array indices used in specific + dimensional axes of the array. */ +static void * +gen_random_correlated_array(int typ, int ndims, int const *dims, int nucdims, int const *ucdims) +{ + int i, n; + int nbyt = (int) (typ == TYPINT ? sizeof(int) : sizeof(double)); + unsigned char *buf, *buf0; + int m[10]; /* subspace multipliers */ + int *dimindx[10]; + + assert(ndims <= 10); + + /* Set up total size and sub-space multipliers */ + for (i=0, n=1; i < ndims; i++) + { + n *= dims[i]; + m[i] = i==0?1:m[i-1]*dims[i-1]; + } + + /* allocate buffer of suitable size (doubles or ints) */ + buf0 = buf = (unsigned char*) malloc(n * nbyt); + + /* set up dimension identity indexing (e.g. Idx[i]==i) so that + we can randomize those dimensions we wish to have UNcorrelated */ + for (i = 0; i < ndims; i++) + { + int j; + dimindx[i] = (int*) malloc(dims[i]*sizeof(int)); + for (j = 0; j < dims[i]; j++) + dimindx[i][j] = j; + } + + /* Randomize selected dimension indexing */ + srandom(0xDeadBeef); + for (i = 0; i < nucdims; i++) + { + int j, ucdimi = ucdims[i]; + for (j = 0; j < dims[ucdimi]-1; j++) + { + int tmp, k = random() % (dims[ucdimi]-j); + if (k == j) continue; + tmp = dimindx[ucdimi][j]; + dimindx[ucdimi][j] = k; + dimindx[ucdimi][k] = tmp; + } + } + + /* populate the array data */ + for (i = 0; i < n; i++) + { + hyper_smooth_separable(buf, typ, i, ndims, dims, m, (int const * const *) dimindx); + buf += nbyt; + } + + /* free dimension indexing */ + for (i = 0; i < ndims; i++) + free(dimindx[i]); + + return buf0; +} + +static void +modulate_by_time(void *data, int typ, int ndims, int const *dims, int t) +{ + int i, n; + + for (i = 0, n = 1; i < ndims; i++) + n *= dims[i]; + + if (typ == TYPINT) + { + int *p = (int *) data; + for (i = 0; i < n; i++, p++) + { + double val = *p; + val *= exp(0.1*t*sin(t/9.0*2*M_PI)); + *p = val; + } + } + else + { + double *p = (double *) data; + for (i = 0; i < n; i++, p++) + { + double val = *p; + val *= exp(0.1*t*sin(t/9.0*2*M_PI)); + *p = val; + } + } +} + +static void +buffer_time_step(void *tbuf, void *data, int typ, int ndims, int const *dims, int t) +{ + int i, n; + int k = t % 4; + int nbyt = (int) (typ == TYPINT ? sizeof(int) : sizeof(double)); + + for (i = 0, n = 1; i < ndims; i++) + n *= dims[i]; + + memcpy((char*)tbuf+k*n*nbyt, data, n*nbyt); +} + +static int read_data(char const *fname, size_t npoints, double **_buf) +{ + size_t const nbytes = npoints * sizeof(double); + int fd; + + if (0 > (fd = open(fname, O_RDONLY))) SET_ERROR(open); + if (0 == (*_buf = (double *) malloc(nbytes))) SET_ERROR(malloc); + if (nbytes != (size_t) read(fd, *_buf, nbytes)) SET_ERROR(read); + if (0 != close(fd)) SET_ERROR(close); + return 0; +} + +static hid_t setup_filter(int n, hsize_t *chunk, int zfpmode, + double rate, double acc, unsigned int prec, + unsigned int minbits, unsigned int maxbits, unsigned int maxprec, int minexp) +{ + hid_t cpid; + + /* setup dataset creation properties */ + if (0 > (cpid = H5Pcreate(H5P_DATASET_CREATE))) SET_ERROR(H5Pcreate); + if (0 > H5Pset_chunk(cpid, n, chunk)) SET_ERROR(H5Pset_chunk); + +#ifdef H5Z_ZFP_USE_PLUGIN + + int i; + unsigned int cd_values[10]; + size_t cd_nelmts = 10; + + /* setup zfp filter via generic (cd_values) interface */ + if (zfpmode == H5Z_ZFP_MODE_RATE) + H5Pset_zfp_rate_cdata(rate, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_PRECISION) + H5Pset_zfp_precision_cdata(prec, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_ACCURACY) + H5Pset_zfp_accuracy_cdata(acc, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_EXPERT) + H5Pset_zfp_expert_cdata(minbits, maxbits, maxprec, minexp, cd_nelmts, cd_values); + else if (zfpmode == H5Z_ZFP_MODE_REVERSIBLE) + H5Pset_zfp_reversible_cdata(cd_nelmts, cd_values); + else + cd_nelmts = 0; /* causes default behavior of ZFP library */ + + /* print cd-values array used for filter */ + printf("\n%d cd_values=", (int) cd_nelmts); + for (i = 0; i < (int) cd_nelmts; i++) + printf("%u%c", cd_values[i],((i==cd_nelmts-1)?'\0':',')); + printf("\n"); + + /* Add filter to the pipeline via generic interface */ + if (0 > H5Pset_filter(cpid, H5Z_FILTER_ZFP, H5Z_FLAG_MANDATORY, cd_nelmts, cd_values)) SET_ERROR(H5Pset_filter); + +#else + + /* When filter is used as a library, we need to init it */ + H5Z_zfp_initialize(); + + /* Setup the filter using properties interface. These calls also add + the filter to the pipeline */ + if (zfpmode == H5Z_ZFP_MODE_RATE) + H5Pset_zfp_rate(cpid, rate); + else if (zfpmode == H5Z_ZFP_MODE_PRECISION) + H5Pset_zfp_precision(cpid, prec); + else if (zfpmode == H5Z_ZFP_MODE_ACCURACY) + H5Pset_zfp_accuracy(cpid, acc); + else if (zfpmode == H5Z_ZFP_MODE_EXPERT) + H5Pset_zfp_expert(cpid, minbits, maxbits, maxprec, minexp); + else if (zfpmode == H5Z_ZFP_MODE_REVERSIBLE) + H5Pset_zfp_reversible(cpid); + +#endif + + return cpid; +} + + +int main(int argc, char **argv) +{ + int retval=0; + + /* filename variables */ + char *ifile = (char *) calloc(NAME_LEN,sizeof(char)); + char *ofile = (char *) calloc(NAME_LEN,sizeof(char)); + + /* sinusoid data generation variables */ + hsize_t npoints = 1024; + double noise = 0.001; + double amp = 17.7; + int doint = 0; + int highd = 0; + int sixd = 0; + int zfparr = 0; + int help = 0; + + /* compression parameters (defaults taken from ZFP header) */ + int zfpmode = H5Z_ZFP_MODE_RATE; + double rate = 4; + double acc = 0; + unsigned int prec = 11; + unsigned int minbits = 0; + unsigned int maxbits = 4171; + unsigned int maxprec = 64; + int minexp = -1074; + int *ibuf = 0; + double *buf = 0; + + /* HDF5 related variables */ + hsize_t chunk = 256; + hid_t fid, dsid, idsid, sid, cpid; + + /* file arguments */ + strcpy(ofile, "test_zfp.h5"); + HANDLE_SEP(Usage: test_write [opt1=value1 opt2=value2]) + HANDLE_ARG(ifile,strndup(argv[i]+len2,NAME_LEN), "\"%s\"",set input filename); + HANDLE_ARG(ofile,strndup(argv[i]+len2,NAME_LEN), "\"%s\"",set output filename); + + /* ZFP filter arguments */ + HANDLE_SEP(ZFP compression parameters) + HANDLE_ARG(zfpmode,(int) strtol(argv[i]+len2,0,10),"%d", (1=rate,2=prec,3=acc,4=expert,5=reversible)); + HANDLE_ARG(rate,(double) strtod(argv[i]+len2,0),"%g",set rate for rate mode); + HANDLE_ARG(acc,(double) strtod(argv[i]+len2,0),"%g",set accuracy for accuracy mode); + HANDLE_ARG(prec,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set precision for precision mode); + HANDLE_ARG(minbits,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set minbits for expert mode); + HANDLE_ARG(maxbits,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set maxbits for expert mode); + HANDLE_ARG(maxprec,(unsigned int) strtol(argv[i]+len2,0,10),"%u",set maxprec for expert mode); + HANDLE_ARG(minexp,(int) strtol(argv[i]+len2,0,10),"%d",set minexp for expert mode); + + /* 1D dataset arguments */ + HANDLE_SEP(1D dataset generation arguments) + HANDLE_ARG(npoints,(hsize_t) strtol(argv[i]+len2,0,10), "%llu",set number of points for 1D dataset); + HANDLE_ARG(noise,(double) strtod(argv[i]+len2,0),"%g",set amount of random noise in 1D dataset); + HANDLE_ARG(amp,(double) strtod(argv[i]+len2,0),"%g",set amplitude of sinusoid in 1D dataset); + HANDLE_ARG(chunk,(hsize_t) strtol(argv[i]+len2,0,10), "%llu",set chunk size for 1D dataset); +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION>=0x051 + HANDLE_ARG(doint,(int) strtol(argv[i]+len2,0,10),"%d",also do integer 1D data); +#else + HANDLE_ARG(doint,(int) strtol(argv[i]+len2,0,10),"%d",requires ZFP>=0.5.1); + if (doint) retval = 2; + doint = 0; +#endif + + /* Advanced cases */ + HANDLE_SEP(Advanced cases) + HANDLE_ARG(highd,(int) strtol(argv[i]+len2,0,10),"%d",4D w/2D chunk example); +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION>=0x054 + HANDLE_ARG(sixd,(int) strtol(argv[i]+len2,0,10),"%d",run 6D extendable example); +#else + HANDLE_ARG(sixd,(int) strtol(argv[i]+len2,0,10),"%d",requires ZFP>=0.5.4); + if (sixd) retval = 2; + sixd = 0; +#endif + +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION>=0x054 && ZFP_HAS_CFP>0 && HDF5_HAS_WRITE_CHUNK>0 + HANDLE_ARG(zfparr,(int) strtol(argv[i]+len2,0,10),"%d",run ZFP array case using H5Dwrite_chunk); +#else + HANDLE_ARG(zfparr,(int) strtol(argv[i]+len2,0,10),"%d",requires ZFP>=0.5.4 with CFP enabled); + if (zfparr) retval = 2; + zfparr = 0; +#endif + + cpid = setup_filter(1, &chunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + /* Put this after setup_filter to permit printing of otherwise hard to + construct cd_values to facilitate manual invocation of h5repack */ + HANDLE_ARG(help,(int)strtol(argv[i]+len2,0,10),"%d",this help message); /* must be last for help to work */ + + /* create double data to write if we're not reading from an existing file */ + if (ifile[0] == '\0') + gen_data((size_t) npoints, noise, amp, (void**)&buf, TYPDBL); + else + read_data(ifile, (size_t) npoints, &buf); + + /* create integer data to write */ + + if (doint) + gen_data((size_t) npoints, noise*100, amp*1000000, (void**)&ibuf, TYPINT); + + /* create HDF5 file */ + if (0 > (fid = H5Fcreate(ofile, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Fcreate); + + /* setup the 1D data space */ + if (0 > (sid = H5Screate_simple(1, &npoints, 0))) SET_ERROR(H5Screate_simple); + + /* write the data WITHOUT compression */ + if (0 > (dsid = H5Dcreate(fid, "original", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + if (doint) + { + if (0 > (idsid = H5Dcreate(fid, "int_original", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(idsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, ibuf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(idsid)) SET_ERROR(H5Dclose); + } + + /* write the data with requested compression */ + if (0 > (dsid = H5Dcreate(fid, "compressed", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + if (doint) + { + if (0 > (idsid = H5Dcreate(fid, "int_compressed", H5T_NATIVE_INT, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(idsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, ibuf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(idsid)) SET_ERROR(H5Dclose); + } + + /* clean up from simple tests */ + if (0 > H5Sclose(sid)) SET_ERROR(H5Sclose); + if (0 > H5Pclose(cpid)) SET_ERROR(H5Pclose); + free(buf); + if (ibuf) free(ibuf); + + /* Test high dimensional (>3D) array */ + if (highd) + { + /* dimension indices 0 1 2 3 */ + int dims[] = {256,128,32,16}; + int ucdims[]={1,3}; /* UNcorrleted dimensions indices */ + hsize_t hdims[] = {256,128,32,16}; + hsize_t hchunk[] = {256,1,32,1}; + + buf = gen_random_correlated_array(TYPDBL, 4, dims, 2, ucdims); + + cpid = setup_filter(4, hchunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + if (0 > (sid = H5Screate_simple(4, hdims, 0))) SET_ERROR(H5Screate_simple); + + /* write the data WITHOUT compression */ + if (0 > (dsid = H5Dcreate(fid, "highD_original", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* write the data with compression */ + if (0 > (dsid = H5Dcreate(fid, "highD_compressed", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* clean up from high dimensional test */ + if (0 > H5Sclose(sid)) SET_ERROR(H5Sclose); + if (0 > H5Pclose(cpid)) SET_ERROR(H5Pclose); + free(buf); + } + /* End of high dimensional test */ + + /* 6D Example */ + /* Test six dimensional, time varying array... + ...a 3x3 tensor valued variable + ...over a 3D+time domain. + Dimension sizes are chosen to miss perfect ZFP block alignment. + */ + if (sixd) + { + void *tbuf; + int t, dims[] = {31,31,31,3,3}; /* a single time instance */ + int ucdims[]={3,4}; /* indices of UNcorrleted dimensions in dims (tensor components) */ + hsize_t hdims[] = {31,31,31,3,3,H5S_UNLIMITED}; + hsize_t hchunk[] = {31,31,31,1,1,4}; /* 4 non-unity, requires >= ZFP 0.5.4 */ + hsize_t hwrite[] = {31,31,31,3,3,4}; /* size/shape of any given H5Dwrite */ + + /* Setup the filter properties and create the dataset */ + cpid = setup_filter(6, hchunk, zfpmode, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + /* Create the time-varying, 6D dataset */ + if (0 > (sid = H5Screate_simple(6, hwrite, hdims))) SET_ERROR(H5Screate_simple); + if (0 > (dsid = H5Dcreate(fid, "6D_extendible", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Sclose(sid)) SET_ERROR(H5Sclose); + if (0 > H5Pclose(cpid)) SET_ERROR(H5Pclose); + + /* Generate a single buffer which we'll modulate by a time-varying function + to represent each timestep */ + buf = gen_random_correlated_array(TYPDBL, 5, dims, 2, ucdims); + + /* Allocate the "time" buffer where we will buffer up each time step + until we have enough to span a width of 4 */ + tbuf = malloc(31*31*31*3*3*4*sizeof(double)); + + /* Iterate, writing 9 timesteps by buffering in time 4x. The last + write will contain just one timestep causing ZFP to wind up + padding all those blocks by 3x along the time dimension. */ + for (t = 1; t < 10; t++) + { + hid_t msid, fsid; + hsize_t hstart[] = {0,0,0,0,0,t-4}; /* size/shape of any given H5Dwrite */ + hsize_t hcount[] = {31,31,31,3,3,4}; /* size/shape of any given H5Dwrite */ + hsize_t hextend[] = {31,31,31,3,3,t}; /* size/shape of */ + + /* Update (e.g. modulate) the buf data for the current time step */ + modulate_by_time(buf, TYPDBL, 5, dims, t); + + /* Buffer this timestep in memory. Since chunk size in time dimension is 4, + we need to buffer up 4 time steps before we can issue any writes */ + buffer_time_step(tbuf, buf, TYPDBL, 5, dims, t); + + /* If the buffer isn't full, just continue updating it */ + if (t%4 && t!=9) continue; + + /* For last step, adjust time dim of this write down from 4 to just 1 */ + if (t == 9) + { + /* last timestep, write a partial buffer */ + hwrite[5] = 1; + hcount[5] = 1; + } + + /* extend the dataset in time */ + if (t > 4) + H5Dextend(dsid, hextend); + + /* Create the memory dataspace */ + if (0 > (msid = H5Screate_simple(6, hwrite, 0))) SET_ERROR(H5Screate_simple); + + /* Get the file dataspace to use for this H5Dwrite call */ + if (0 > (fsid = H5Dget_space(dsid))) SET_ERROR(H5Dget_space); + + /* Do a hyperslab selection on the file dataspace for this write*/ + if (0 > H5Sselect_hyperslab(fsid, H5S_SELECT_SET, hstart, 0, hcount, 0)) SET_ERROR(H5Sselect_hyperslab); + + /* Write this iteration to the dataset */ + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, msid, fsid, H5P_DEFAULT, tbuf)) SET_ERROR(H5Dwrite); + if (0 > H5Sclose(msid)) SET_ERROR(H5Sclose); + if (0 > H5Sclose(fsid)) SET_ERROR(H5Sclose); + } + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + free(buf); + free(tbuf); + } + /* End of 6D Example */ + +#if ZFP_HAS_CFP>0 && HDF5_HAS_WRITE_CHUNK>0 + /* ZFP Array Example */ + if (zfparr>0 && zfpmode==1 && rate>0) + { + int dims[] = {38, 128}; + hsize_t hdims[] = {38, 128}; + /*hsize_t hchunk_dims[] = {19, 34};*/ + hsize_t hchunk_dims[] = {38, 128}; + hsize_t hchunk_off[] = {0, 0}; +#if defined(ZFP_LIB_VERSION) && ZFP_LIB_VERSION<=0x055 + cfp_array2d *origarr; +#else + cfp_array2d origarr; +#endif + + /* Create the array data */ + buf = gen_random_correlated_array(TYPDBL, 2, dims, 0, 0); + + /* Instantiate a cfp array */ + origarr = cfp.array2d.ctor(dims[1], dims[0], rate, buf, 0); + cfp.array2d.flush_cache(origarr); + + cpid = setup_filter(2, hchunk_dims, 1, rate, acc, prec, minbits, maxbits, maxprec, minexp); + + if (0 > (sid = H5Screate_simple(2, hdims, 0))) SET_ERROR(H5Screate_simple); + + /* write the data WITHOUT compression */ + if (0 > (dsid = H5Dcreate(fid, "zfparr_original", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* write the data with compression via the filter */ + if (0 > (dsid = H5Dcreate(fid, "zfparr_compressed", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite(dsid, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)) SET_ERROR(H5Dwrite); + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + /* write the data direct from compressed array using H5Dwrite_chunk calls */ + if (0 > (dsid = H5Dcreate(fid, "zfparr_direct", H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT, cpid, H5P_DEFAULT))) SET_ERROR(H5Dcreate); + if (0 > H5Dwrite_chunk(dsid, H5P_DEFAULT, 0, hchunk_off, cfp.array2d.compressed_size(origarr), cfp.array2d.compressed_data(origarr))) SET_ERROR(H5Dwrite_chunk); + + if (0 > H5Dclose(dsid)) SET_ERROR(H5Dclose); + + free(buf); + cfp.array2d.dtor(origarr); + } + /* End of ZFP Array Example */ +#endif + + if (0 > H5Fclose(fid)) SET_ERROR(H5Fclose); + + free(ifile); + free(ofile); + +#ifndef H5Z_ZFP_USE_PLUGIN + /* When filter is used as a library, we need to finalize it */ + H5Z_zfp_finalize(); +#endif + + H5close(); + + return retval; +} diff --git a/ZFP/H5Z-ZFP/test/test_zfp_030040.h5 b/ZFP/H5Z-ZFP/test/test_zfp_030040.h5 new file mode 100644 index 0000000000000000000000000000000000000000..56a0628940980fbcce00292c5e501c188d588df0 GIT binary patch literal 24328 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�nx&g&`qZdGV+Ut-L;p$gScIA?h? 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 literal 0 HcmV?d00001 diff --git a/ZFP/H5Z-ZFP/test/test_zfp_052.h5 b/ZFP/H5Z-ZFP/test/test_zfp_052.h5 new file mode 100644 index 0000000000000000000000000000000000000000..69ca1b6d73c47cb45a9a814257ffd04707ce0d42 GIT binary patch literal 15064 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 literal 0 HcmV?d00001 diff --git a/ZFP/H5Z-ZFP/test/test_zfp_054.h5 b/ZFP/H5Z-ZFP/test/test_zfp_054.h5 new file mode 100644 index 0000000000000000000000000000000000000000..22dcccc495d5673fc9c6644b1063803b27a904a9 GIT binary patch literal 15064 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

ioD2yVMMZ%ce$GL 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 literal 0 HcmV?d00001 diff --git a/ZFP/H5Z-ZFP/test/test_zfp_be.h5 b/ZFP/H5Z-ZFP/test/test_zfp_be.h5 new file mode 100644 index 0000000000000000000000000000000000000000..cede86d48d3d1bf117819da2744f4c37945a2992 GIT binary patch literal 20280 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 literal 0 HcmV?d00001 diff --git a/ZFP/Makefile b/ZFP/Makefile deleted file mode 100644 index 32b59690..00000000 --- a/ZFP/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include config.make - -.PHONY: help all clean dist install - -help: - @echo "" - @echo "" - @echo "" - @echo " This is H5Z-ZFP version $(H5Z_ZFP_VERSINFO)." - @echo "See http://h5z-zfp.readthedocs.io/en/latest/ file for more info." - @echo "" - @echo "Typical make command is..." - @echo "" - @echo " make CC= HDF5_HOME= ZFP_HOME= PREFIX= all" - @echo "" - @echo "where is a dir whose children are include/lib/bin subdirs." - @echo "HDF5_HOME can also be specified by the HDF5 include directory," - @echo "library directory and bin directory separated by commas, i.e. HDF5_HOME=INC,LIB,BIN" - @echo "Standard make variables (e.g. CFLAGS, LD, etc.) can be set as usual." - @echo "Optionally, add FC= to include Fortran support and tests." - @echo "" - @echo "Available make targets are..." - @echo " all - build everything" - @echo " check - all + run tests" - @echo " install - install compiled components" - @echo " clean - clean away all derived targets" - @echo " dist - create distribution tarfile" - -all: - cd src; $(MAKE) $(MAKEVARS) $@ - -check: all install - cd test; $(MAKE) $(MAKEVARS) $@ - -install: - cd src; $(MAKE) $(MAKEVARS) $@ - -clean: - rm -f H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz - cd src; $(MAKE) $(MAKEVARS) $@ - cd test; $(MAKE) $(MAKEVARS) $@ - -dist: clean - rm -rf H5Z-ZFP-$(H5Z_ZFP_VERSINFO) H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz; \ - mkdir H5Z-ZFP-$(H5Z_ZFP_VERSINFO); \ - tar cf - --exclude ".git*" --exclude H5Z-ZFP-$(H5Z_ZFP_VERSINFO) . | tar xf - -C H5Z-ZFP-$(H5Z_ZFP_VERSINFO); \ - tar cvf - H5Z-ZFP-$(H5Z_ZFP_VERSINFO) | gzip --best > H5Z-ZFP-$(H5Z_ZFP_VERSINFO).tar.gz; \ - rm -rf H5Z-ZFP-$(H5Z_ZFP_VERSINFO); diff --git a/ZFP/Makefile.am b/ZFP/Makefile.am deleted file mode 100644 index c1031a5f..00000000 --- a/ZFP/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright by The HDF Group. All rights reserved. - -# This builds the main LZ4 directory. - -# Allen Byrne, Ed Hartnett 1/15/19 - -# This directory stores libtool macros, put there by aclocal. -ACLOCAL_AMFLAGS = -I m4 - -# Build these subdirectories. -SUBDIRS = src #example diff --git a/ZFP/README.md b/ZFP/README.md index ec4d2dae..a1de9752 100644 --- a/ZFP/README.md +++ b/ZFP/README.md @@ -1,38 +1,94 @@ -# H5Z-ZFP +# H5Z-ZFP Filter Plugin -A highly flexible floating point and integer -compression plugin for the HDF5 library using ZFP compression. +This directory integrates the H5Z-ZFP filter plugin from LLNL using **git subtree**. -[![Build Status](https://travis-ci.com/LLNL/H5Z-ZFP.svg?branch=master)](https://travis-ci.com/LLNL/H5Z-ZFP) -[![Documentation Status](https://readthedocs.org/projects/h5z-zfp/badge/?version=latest)](http://h5z-zfp.readthedocs.io) -[![codecov](https://codecov.io/gh/LLNL/H5Z-ZFP/branch/master/graph/badge.svg)](https://codecov.io/gh/LLNL/H5Z-ZFP) +## Upstream Source -For information about ZFP compression and the BSD-Licensed ZFP -library, see... +- **Repository**: https://github.com/LLNL/H5Z-ZFP +- **License**: BSD 3-Clause (see H5Z-ZFP/LICENSE) +- **Maintainer**: Mark C. Miller (LLNL) +- **Documentation**: https://h5z-zfp.readthedocs.io -- https://computation.llnl.gov/projects/floating-point-compression -- https://github.com/LLNL/zfp +## About H5Z-ZFP -For information about HDF5 filter plugins, see... +H5Z-ZFP is a highly flexible floating point and integer compression plugin for HDF5 using the ZFP compression library. It supports all modes of ZFP compression: +- **Rate**: Target a fixed compressed size +- **Accuracy**: Limit absolute error +- **Precision**: Limit relative error +- **Expert**: Fine-grained control +- **Lossless**: Reversible compression -- https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters +The filter supports 1-4 dimensional datasets of single and double precision integer and floating point data. -This H5Z-ZFP plugin supports ZFP versions 0.5.0 through 1.1.0. +## Building -This plugin uses the [*registered*](https://support.hdfgroup.org/services/filters.html#zfp) -HDF5 plugin filter id 32013 +### No Special Setup Required -The HDF5 filter plugin code here is also part of the Silo library. -However, we have made an effort to also support it as a stand-alone -package due to the likely broad appeal and utility of the ZFP -compression library. +The H5Z-ZFP source is included directly in this repository via git subtree. Simply clone and build: -This plugin supports all modes of the ZFP compression library, *rate*, -*accuracy*, *precision*, *expert* and *lossless*. It supports 1, 2, 3 and -4 dimensional datasets (for ZFP version 0.5.5 and newer) of single and double -precision integer and floating point data. It can be applied to HDF5 datasets -of more than 3 dimensions (or 4 dimensions for ZFP versions 0.5.5 and newer) -as long as no more than 3 (or 4) dimensions of the HDF5 dataset *chunking* are -of size greater than 1. +```bash +git clone https://github.com/HDFGroup/hdf5_plugins.git +# Everything is ready - no submodule initialization needed! +``` -[**Full documentation**](http://h5z-zfp.readthedocs.io) +### Build Requirements + +H5Z-ZFP requires: +1. **HDF5 library** - Set `HDF5_ROOT` environment variable +2. **ZFP compression library** - The parent build system will fetch this automatically + +### Building as Part of hdf5_plugins + +```bash +cd hdf5_plugins +export HDF5_ROOT=/path/to/hdf5 +mkdir build && cd build + +cmake -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_ZFP=ON \ + -DH5PL_ALLOW_EXTERNAL_SUPPORT=TGZ \ + -DH5PL_TGZPATH=../libs \ + .. + +cmake --build . +``` + +## Updating to Newer Versions (Maintainers Only) + +HDF Group maintainers can update to newer H5Z-ZFP versions using git subtree: + +```bash +# One-time: Add upstream remote (if not already done) +git remote add h5z-zfp https://github.com/LLNL/H5Z-ZFP.git + +# Update to latest master +git subtree pull --prefix=ZFP/H5Z-ZFP h5z-zfp master --squash + +# Or update to specific version +git subtree pull --prefix=ZFP/H5Z-ZFP h5z-zfp v1.1.1 --squash +``` + +**Important**: The `--squash` flag is recommended to avoid importing full upstream history into hdf5_plugins. + +## Reporting Issues + +### Filter Issues +Issues with the ZFP filter itself (bugs, feature requests, compression behavior) should be reported at: +**https://github.com/LLNL/H5Z-ZFP/issues** + +### Integration Issues +Issues with how H5Z-ZFP integrates with the hdf5_plugins build system should be reported at: +**https://github.com/HDFGroup/hdf5_plugins/issues** + +## Policy: Upstream-First Development + +HDF Group does not maintain a fork of H5Z-ZFP. This directory uses the upstream repository directly via git subtree. + +**Important**: Never modify files in `ZFP/H5Z-ZFP/` directly! + +If you need changes to the filter: +1. Open an issue at https://github.com/LLNL/H5Z-ZFP/issues +2. Submit a pull request to upstream +3. After upstream merges, use `git subtree pull` to update (see above) + +This ensures the HDF community benefits from improvements and the upstream maintainers remain authoritative. diff --git a/ZFP/UPDATING_ZFP_SUBTREE.md b/ZFP/UPDATING_ZFP_SUBTREE.md new file mode 100644 index 00000000..a9f4d940 --- /dev/null +++ b/ZFP/UPDATING_ZFP_SUBTREE.md @@ -0,0 +1,199 @@ +# Updating the ZFP Subtree + +This document explains how to update the H5Z-ZFP filter plugin to a newer upstream version. + +## Overview + +The ZFP filter is integrated using **git subtree**, which embeds the upstream LLNL/H5Z-ZFP repository directly into `ZFP/H5Z-ZFP/`. This allows users to clone and build without any additional setup while maintaining a clear connection to upstream. + +## Prerequisites + +Before updating, ensure: +1. You have a clean working tree: `git status` shows no uncommitted changes +2. You're on the appropriate branch (usually `master` or a feature branch) +3. You have push access to the hdf5_plugins repository + +## Step-by-Step Update Process + +### 1. Add Upstream Remote (One-Time Setup) + +If you haven't already added the upstream H5Z-ZFP remote: + +```bash +git remote add h5z-zfp https://github.com/LLNL/H5Z-ZFP.git +``` + +Verify the remote was added: + +```bash +git remote -v +``` + +You should see `h5z-zfp` pointing to the LLNL repository. + +### 2. Fetch Upstream Changes + +Before pulling, fetch the latest upstream changes: + +```bash +git fetch h5z-zfp +``` + +### 3. Check Available Versions + +List available upstream tags to see what versions are available: + +```bash +git ls-remote --tags h5z-zfp +``` + +### 4. Pull the Update + +#### Option A: Update to Latest Master + +To update to the latest development version: + +```bash +git subtree pull --prefix=ZFP/H5Z-ZFP h5z-zfp master --squash -m "Update H5Z-ZFP to latest upstream master" +``` + +#### Option B: Update to Specific Version Tag + +To update to a specific release (recommended for stability): + +```bash +git subtree pull --prefix=ZFP/H5Z-ZFP h5z-zfp v1.1.1 --squash -m "Update H5Z-ZFP to v1.1.1" +``` + +Replace `v1.1.1` with the desired version tag. + +### 5. Verify the Update + +After pulling, verify the update was successful: + +```bash +# Check that ZFP/H5Z-ZFP directory contains the new code +ls -la ZFP/H5Z-ZFP/ + +# View the commit created by subtree pull +git log -1 + +# Check git status +git status +``` + +### 6. Test the Build + +Before pushing, ensure the updated filter builds correctly: + +```bash +# Set HDF5_ROOT to your HDF5 installation +export HDF5_ROOT=/path/to/hdf5 + +# Create a clean build directory +rm -rf build +mkdir build && cd build + +# Configure with ZFP enabled +cmake -DCMAKE_BUILD_TYPE=Release \ + -DENABLE_ZFP=ON \ + -DH5PL_ALLOW_EXTERNAL_SUPPORT=TGZ \ + -DH5PL_TGZPATH=../libs \ + .. + +# Build +cmake --build . + +# Run tests +ctest -R ZFP +``` + +### 7. Commit and Push + +If the build and tests pass: + +```bash +# The subtree pull already created a commit, so just push +git push origin +``` + +## Understanding the --squash Flag + +The `--squash` flag is **recommended** for subtree updates. Here's why: + +- **Without --squash**: Imports the entire upstream commit history into hdf5_plugins + - Pro: Preserves full upstream history + - Con: Makes hdf5_plugins history cluttered with upstream commits + +- **With --squash**: Combines all upstream changes into a single commit + - Pro: Keeps hdf5_plugins history clean + - Con: Loses individual upstream commit details (but you can still view them in the upstream repo) + +**Recommendation**: Always use `--squash` unless you have a specific reason to preserve full upstream history. + +## Troubleshooting + +### Merge Conflicts + +If you encounter merge conflicts during `git subtree pull`: + +1. **Resolve conflicts**: Edit the conflicting files in `ZFP/H5Z-ZFP/` +2. **Stage resolved files**: `git add ZFP/H5Z-ZFP/` +3. **Complete the merge**: `git commit` + +**Note**: Conflicts are rare if you never modify files in `ZFP/H5Z-ZFP/` directly (which is the policy). + +### Checking Current Upstream Version + +To see what upstream commit the current subtree is based on: + +```bash +git log --grep="git-subtree-split" --format="%H %s" -1 +``` + +Look for the commit hash after `git-subtree-split:` in the commit message. + +### Reverting a Failed Update + +If an update fails or causes issues: + +```bash +# Find the commit hash before the subtree pull +git log --oneline -5 + +# Reset to before the update +git reset --hard +``` + +## Update Checklist + +Before pushing an H5Z-ZFP update to the main repository: + +- [ ] Upstream remote is configured correctly +- [ ] Fetched latest upstream changes +- [ ] Pulled the desired version using `--squash` +- [ ] Verified `ZFP/H5Z-ZFP/` contains expected changes +- [ ] Build succeeds with `-DENABLE_ZFP=ON` +- [ ] ZFP tests pass: `ctest -R ZFP` +- [ ] Commit message clearly indicates version/branch updated +- [ ] Ready to push to hdf5_plugins repository + +## Policy Reminder + +**Never modify files in `ZFP/H5Z-ZFP/` directly!** + +If you need changes to the H5Z-ZFP filter: +1. Open an issue at https://github.com/LLNL/H5Z-ZFP/issues +2. Submit a pull request to upstream +3. After upstream merges, use `git subtree pull` to update + +This ensures: +- The HDF community benefits from improvements +- Upstream maintainers remain authoritative +- Updates remain straightforward without merge conflicts + +## Additional Resources + +- H5Z-ZFP Documentation: https://h5z-zfp.readthedocs.io +- H5Z-ZFP Repository: https://github.com/LLNL/H5Z-ZFP +- Git Subtree Documentation: `man git-subtree` or https://git-scm.com/docs/git-subtree diff --git a/ZFP/config.h.in b/ZFP/config.h.in deleted file mode 100644 index 7637258e..00000000 --- a/ZFP/config.h.in +++ /dev/null @@ -1,86 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#undef HAVE_DOPRNT - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `hdf5' library (-lhdf5). */ -#undef HAVE_LIBHDF5 - -/* Define to 1 if you have the `zfp' library (-lzfp). */ -#undef HAVE_LIBZFP - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `vprintf' function. */ -#undef HAVE_VPRINTF - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `unsigned int' if does not define. */ -#undef size_t diff --git a/ZFP/configure.ac b/ZFP/configure.ac deleted file mode 100644 index 6a84c5d6..00000000 --- a/ZFP/configure.ac +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright by The HDF Group. All rights reserved. - -# This is the main configure file for the ZFP filter, a HDF5 plugin -# library that enables zfp compression/decompression as a HDF5 -# filter. This is part of the hdf5_plugin project. - -# Allen Byrne, Ed Hartnett 1/14/19 - -# Initialize autoconf. -AC_PREREQ(2.59) -## -*- Autoconf -*- -## Process this file with autoconf to produce a configure script. -## -## Copyright by The HDF Group. -## Copyright by the Board of Trustees of the University of Illinois. -## All rights reserved. -## -## This file is part of HDF5. The full HDF5 copyright notice, including -## terms governing use, modification, and redistribution, is contained in -## the files COPYING and Copyright.html. COPYING can be found at the root -## of the source code distribution tree; Copyright.html can be found at the -## root level of an installed copy of the electronic HDF5 document set and -## is linked from the top-level documents page. It can also be found at -## http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have -## access to either file, you may request a copy from help@hdfgroup.org. - -AC_PREREQ(2.59) -AC_INIT(H5ZFP, 0.1, help@hdfgroup.org) -AC_CONFIG_HEADER([zfp_config.h]) -AC_CONFIG_MACRO_DIR([m4]) - -# Initialize automake. -AM_INIT_AUTOMAKE([foreign]) - -# Checks for programs. -AC_PROG_CC -AC_PROG_INSTALL - -LT_INIT(dlopen) - -# If the env. variable HDF5_PLUGIN_DIR is set, or if -# --with-hdf5-plugin-dir=, use it as a place for the large -# (i.e. > 2 GiB) files created during the large file testing. -AC_MSG_CHECKING([where to put HDF5 plugins]) -HDF5_PLUGIN_DIR=${HDF5_PLUGIN_DIR-'/usr/local/hdf5/lib/plugin'} -AC_ARG_WITH([hdf5-plugin-dir], - [AS_HELP_STRING([--with-hdf5-plugin-dir=], - [specify HDF5 plugin directory (defaults to /usr/local/hdf5/lib/plugin, or value of HDF5_PLUGIN_DIR, if set)])], - [HDF5_PLUGIN_DIR=$with_hdf5_plugin_dir]) -AC_MSG_RESULT($HDF5_PLUGIN_DIR) -AC_SUBST([HDF5_PLUGIN_DIR]) - -# Is the zfp library present? -AC_CHECK_HEADERS([zfp.h], [], [AC_MSG_ERROR([zfp.h is required, set CPPFLAGS.])]) -AC_CHECK_LIB([zfp], [zfp_compress], [], [AC_MSG_ERROR([libzfp is required, set LDFLAGS.])]) - -# We need the math library -AC_CHECK_LIB([m], [floor], [], [AC_MSG_ERROR([Math library is required.])]) - -# We need the HDF5 headers and library. -AC_CHECK_HEADERS([hdf5.h], [], [AC_MSG_ERROR([hdf5.h is required, set CPPFLAGS.])]) -AC_SEARCH_LIBS([H5Fflush], [hdf5dll hdf5], [], [AC_MSG_ERROR([libhdf5 is required, set LDFLAGS.])]) - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_SIZE_T - -# Checks for library functions. -AC_FUNC_ERROR_AT_LINE -AC_FUNC_MEMCMP -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([memset]) - -# Check which plugins to build, if no environmental variables are set, build -# all. -if test ! "$PLUGIN_H5LZ4" -then - PLUGIN_H5LZ4=1 -fi -AM_CONDITIONAL(H5LZ4, test "$PLUGIN_H5LZ4") - -# These files will be generated by configure. -AC_CONFIG_FILES([Makefile - example/Makefile - src/Makefile]) - -# Output configure and all Makefile.in files. -AC_OUTPUT diff --git a/ZFP/docs/cmake.rst b/ZFP/docs/cmake.rst deleted file mode 100644 index 77c22a7f..00000000 --- a/ZFP/docs/cmake.rst +++ /dev/null @@ -1,93 +0,0 @@ -===== -CMake -===== - -It is possible to build the H5Z-ZFP filter using the CMake build system. If you decide to -do so, please build ZFP also with its CMake build system. This is necessary to get the -correct dependencies from ZFP. For example, it is possible to build ZFP with OpenMP support. -The resulting CMake config files of ZFP build will make sure that this OpenMP dependency is -correctly propagated to the build of H5Z-ZFP filter. However, for HDF5 it is not -necessary to build it with its CMake build system but it is strongly recommended. - ------------------ -Compiling H5Z-ZFP ------------------ - -Similar as for the Makefile installation, the CMake build system is designed such it -compiles both the standalone HDF5_ *plugin* and a separate *library* an application -can explicitly link. See :ref:`plugin-vs-library` - -Once you have installed both HDF5 and ZFP, you can compile H5Z-ZFP_ using a command=line... - -:: - - export HDF_DIR= - export ZFP_DIR= - CC= FC= cmake -DCMAKE_INSTALL_PREFIX= - -where ```` is a directory containing ZFP_ ``inc[lude]`` and ``lib`` directories and -```` is a directory containing HDF5_ ``include`` and ``lib`` directories. Furthermore, -``src-dir`` is the directory where the source is located and ``path-to-install`` is the directory in -which the resulting *plugin* and *library* will be installed. Once cmake has finished successfully, -you can build and install the filter using the command... - -:: - - make install - -This cmake and make combination builds both the C and Fortran interface. In the case you want to specify -the ```` and ``>`` via command-line to CMake, the command looks like this... - -:: - - CC= FC= cmake -DCMAKE_INSTALL_PREFIX= - -DCMAKE_PREFIX_PATH=";" - -Please, notice the double quotes in the CMAKE_PREFIX_PATH expression. These are needed to make sure that semicolon -is interpreted as a semicolon instead of a new command. - -It is possible to build the filter without the Fortran interface. This is done as follows... - -:: - - export HDF5_DIR= - export ZFP_DIR= - CC= cmake -DCMAKE_INSTALL_PREFIX= -DFORTRAN_INTERFACE:BOOL=OFF - -followed by the same make command... - -:: - - make install - -------------------------------------------- -Including H5Z-ZFP filter in a CMake project -------------------------------------------- - -Suppose you have built the H5Z-ZFP filter using the CMake build system and installed it in ````. -To include it in another CMake project is done using the following steps. First edit the ``CMakeLists.txt`` -by adding the following two lines... - -:: - - cmake_policy(SET CMP0028 NEW) # Double colon in target name means ALIAS or IMPORTED target. - ... - set(H5Z_ZFP_USE_STATIC_LIBS OFF) - find_package(H5Z_ZFP 1.0.1 CONFIG) - ... - target_link_libraries( h5z_zfp::h5z_zfp) - ... - -where ```` in the target within the CMake project. This could be, for example, a executable or library. -Furthermore, check if the cmake version is equal or greater than 3.9. Next, you need to make sure that the filter -can be found by CMake, followed CMake itself and make... - -:: - - export H5Z_ZFP_DIR= - CC= cmake -DCMAKE_INSTALL_PREFIX= - make install - -The cmake command itself could be different depending on the CMake project you have created. If you want -to make use of the H5Z_ZFP *library* instead of the plugin, change cmake variable H5Z_ZFP_USE_STATIC_LIBS -to ON and build the project. diff --git a/ZFP/docs/endian_issues.rst b/ZFP/docs/endian_issues.rst deleted file mode 100644 index 34b6b0e8..00000000 --- a/ZFP/docs/endian_issues.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. _endian-issues: - -============= -Endian Issues -============= - -The ZFP_ library writes an endian-independent stream. - -When reading ZFP_ compressed data on a machine with a different -endian-ness than the writer, there is an unnavoidable -inefficiency. Upon reading data from disk and decompressing the read -stream with ZFP_, the correct endian-ness is returned in the result from -ZFP_ before the buffer is handed back to HDF5_ from the decompression -filter. This happens regardless of -reader and writer endian-ness incompatability. However, the HDF5_ -library is expecting to get from the decompression filter the endian-ness -of the data as it was stored to to file (typically -that of the writer machine) and expects to have to byte-swap that -buffer before returning to any endian-incompatible caller. So, in the H5Z-ZFP_ plugin, we wind up having -to un-byte-swap an already correct result read in a cross-endian context. That way, when -HDF5_ gets the data and byte-swaps it, it will produce the correct result. -There is an endian-ness test in the Makefile and two ZFP_ compressed -example datasets for big-endian and little-endian machines to test -that cross-endian reads/writes work correctly. - -Finally, *endian-targetting*, that is setting the file datatype for an -endian-ness that is possibly different than the native endian-ness of -the writer (to, for example, alleviate down-stream consumers from having -to byte-swap due to endian incompatability between writer and reader) -is explicitly dis-allowed because it is not an operation that is currently -supported by the HDF5 library. diff --git a/ZFP/docs/hdf5_chunking.rst b/ZFP/docs/hdf5_chunking.rst deleted file mode 100644 index e5c0259b..00000000 --- a/ZFP/docs/hdf5_chunking.rst +++ /dev/null @@ -1,143 +0,0 @@ -.. _hdf5_chunking: - -============== -HDF5_ Chunking -============== - -HDF5_'s dataset `chunking`_ feature is a way to optimize data layout on disk -to support partial dataset reads by downstream consumers. This is all the more -important when compression filters are applied to datasets as it frees a consumer -from suffering the UNcompression of an entire dataset only to read a portion. - - -------------- -ZFP Chunklets -------------- - -When using HDF5_ `chunking`_ with ZFP_ compression, it is important to account -for the fact that ZFP_ does its work in tiny 4\ :sup:`d` chunklets of its -own where `d` is the dataset dimension (*rank* in HDF5_ parlance). This means -that that whenever possible `chunking`_ dimensions you select in HDF5_ should be -multiples of 4. When a chunk_ dimension is not a multiple of 4, ZFP_ will wind -up with partial chunklets which it will pad with useless data reducing overall -time and space efficiency of the results. - -The degree to which this may degrade performance depends on the percentage of a -chunk_ that is padded. Suppose we have 2D chunk of dimensions 27 x 101. ZFP_ will -have to treat it as 28 x 104 by padding out each dimension to the next closest -multiple of 4. The fraction of space that will wind up being wasted due to ZFP_ -chunklet padding will be (28x104-27x101) / (28x104) which is about 6.4%. On the -other hand, consider a 3D chunk that is 1024 x 1024 x 2. ZFP_ will have to treat -it as a 1024 x 1024 x 4 resulting in 50% waste. - -The latter example is potentialy very relevant when attemping to apply ZFP_ to -compress data long the *time* dimension in a large, 3D, simulation. Ordinarily, -a simulation advances one time step at a time and so needs to store in memory -only the *current* timestep. In order to give ZFP_ enough *width* in the time -dimension to satisfy the minimum chunklet dimension size of 4, the simulation -needs to keep in memory 4 timesteps. This is demonstrated in the example below. - ------------------------------ -More Than 3 (or 4) Dimensions ------------------------------ - -Versions of ZFP_ 0.5.3 and older support compression in only 1,2 or 3 -dimensions. Versions of ZFP_ 0.5.4 and newer also support 4 dimensions. - -What if you have a dataset with more dimensions than ZFP_ can compress? -You can still use the H5Z-ZFP_ filter. But, in order to do so you -are *required* to chunk_ the dataset [1]_ . Furthermore, you must select a -chunk_ size such that no more than 3 (or 4 for ZFP_ 0.5.4 and newer) -dimensions are non-unitary (e.g. of size one). - -For example, what if you are using ZFP_ 0.5.3 and have a 4D HDF5 dataset -you want to compress? To do this, you will need to chunk_ the dataset and -when you define the chunk_ size and shape, you will need to select which -of the 4 dimensions of the chunk you do *not* intend to have ZFP_ perform -compression along by setting the size of the chunk_ in that dimension to -unity (1). When you do this, as HDF5 processes writes and reads, it will -organize the data so that all the H5Z-ZFP_ filter *sees* are chunks -which have *extent* only in the non-unity dimensions of the chunk_. - -In the example below, we have a 4D array of shape ``int dims[] = {256,128,32,16};`` -that we have intentionally constructed to be *smooth* in only 2 of its 4 dimensions -(e.g. correlation is high in those dimensions). Because of that, we expect ZFP_ -compression to do well along those dimensions and we do no want ZFP_ to compress -along the other 2 dimensions. The *uncorrelated* dimensions here are dimensions -with indices ``1`` (``128`` in ``dims[]``) and ``3`` (``16`` in ``dims[]``). -Thus, our chunk_ size and shape is chosoen to set the size for those dimension -indices to ``1``, ``hsize_t hchunk[] = {256,1,32,1};`` - -.. literalinclude:: ../test/test_write.c - :language: c - :linenos: - :start-after: Test high dimensional (>3D) array - :end-before: End of high dimensional test - -What analysis process should you use to select the chunk_ shape? Depending -on what you expect in the way of access patters in downstream consumers, -this can be a challenging question to answer. There are potentially two -competing interests. One is optimizing the chunk_ size and shape for access -patterns anticipated by downstream consumers. The other is optimizing the chunk_ -size and shape for compression. These two interests may not be compatible -and you may have to compromise between them. We illustrate the issues and -tradeoffs using an example. - ---------------------------------------------------- -Compression *Along* the *State Iteration* Dimension ---------------------------------------------------- - -By *state iteration* dimension, we are referring to the main iteration -loop(s) of the data producer. For many PDE-based simulations, the main -iteration dimension is *time*. But, for some *outer loop* methods, the -main iteration dimension(s) might be some kind of parameter study including -multiple paramaters. - -The challenge here is to manage the data in a way that meets ZFP_'s -chunklet size and shape *minimum* requirements. In any H5Dwrite_ at least 4 -*samples* along a ZFP_ compression dimension are needed or there will -be wasted space due to padding. This means that data must be *buffered* -along those dimensions *before* H5Dwrite_'s can be issued. - -For example, suppose you have a tensor valued field (e.g. a 3x3 matrix -at every *point*) over a 4D (3 spatial dimensions and 1 time dimension), -regularly sampled domain? Conceptually, this is a 6 dimensional dataset -in HDF5_ with one of the dimensions (the *time* dimension) *extendible*. -You are free to define this as a 6 dimensional dataset in HDF5_. But, you -will also have to chunk_ the dataset. You can select any chunk_ shape -you want except that no more than 3 (or 4 for ZFP_ versions 0.5.4 and -newer) dimensions of the chunk_ can be non-unity. - -In the code snipit below, we demonstrate this case. A key issue to deal -with is that because we will use ZFP_ to compress along the time dimension, -this forces us to keep in memory a sufficient number of timesteps to match -ZFP_'s chunklet size of 4. - -The code below iterates over 9 timesteps. Each of the first two groups of 4 -timesteps are buffered in memory in ``tbuf``. Once 4 timesteps have been buffered, we -can issue an H5Dwrite_ call doing -`hyperslab `_ -can issue an `H5Dwrite `_ -call doing `hyperslab `_ -partial I/O on the 6D, `extendible `_ -dataset. But, notice that the chunk_ dimensions (line 10) are such that only 4 of the -6 dimensions are non-unity. This means ZFP_ will only ever see something to -compress that is essentially 4D. - -On the last iteration, we have only one *new* timestep. So, when we write this -to ZFP_ 75% of that write will be *wasted* due to ZFP_ chunklet padding. However, -if the application were to *restart* from this time and continue forward, this -*waste* will ulimately get overwritten with new timesteps. - -.. literalinclude:: ../test/test_write.c - :language: c - :linenos: - :start-after: 6D Example - :end-before: End of 6D Example - -.. _chunking: https://support.hdfgroup.org/HDF5/doc/Advanced/Chunking/index.html -.. _chunk: https://support.hdfgroup.org/HDF5/doc/Advanced/Chunking/index.html -.. _H5Dwrite: https://support.hdfgroup.org/HDF5/doc/RM/RM_H5D.html#Dataset-Write -.. [1] The HDF5_ library currently requires dataset chunking anyways for - any dataset that has any kind of filter applied. - diff --git a/ZFP/docs/index.rst b/ZFP/docs/index.rst deleted file mode 100644 index 8c83329c..00000000 --- a/ZFP/docs/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -================== -Welcome to H5Z-ZFP -================== - -H5Z-ZFP_ is a compression filter for HDF5_ using the -`ZFP compression library `_, -supporting *lossy* and *lossless* compression of floating point and integer data to meet -bitrate, accuracy, and/or precision targets. The filter uses the -`registered `_ HDF5_ filter ID, ``32013``. -It supports single and double precision floating point and integer data *chunked* in 1, 2 or -3 dimensions. The filter will function on datasets of more than 3 dimensions (or 4 -dimensions for ZFP versions 0.5.4 and newer), albeit at the -possible expense of compression performance, as long as no more than 3 -(or 4) dimensions of the HDF5 dataset chunking are of size greater than 1. - -Contents: - -.. toctree:: - :maxdepth: 1 - :glob: - - installation - interfaces - hdf5_chunking - direct - h5repack - endian_issues - tests - cmake diff --git a/ZFP/docs/installation.rst b/ZFP/docs/installation.rst deleted file mode 100644 index bb8a4dd6..00000000 --- a/ZFP/docs/installation.rst +++ /dev/null @@ -1,182 +0,0 @@ -============ -Installation -============ - ------------------------------------------- -Installing via `Spack `_ ------------------------------------------- -The HDF5_ and ZFP_ libraries and the H5Z-ZFP_ plugin are all now part of the -Spack_ package manager. If you already have Spack_ installed, the easiest way to -install H5Z-ZFP_ is to simply use the Spack_ command ``spack install h5z-zfp``. -If you do not have Spack_ installed, it is very easy to install. - -:: - - git clone https://github.com/llnl/spack.git - . spack/share/spack/setup-env.sh - spack install h5z-zfp - -By default, H5Z-ZFP_ will attempt to build with Fortran support which requires -a Fortran compiler. If you wish to exclude support for Fortran, use the command - -:: - - spack install h5z-zfp~fortran - -Note that these commands will build H5Z-ZFP_ **and** all of its dependencies including -the HDF5_ library (as well as a number of other dependencies you may not initially -expect. Be patient and let the build complete). In addition, by default, Spack_ installs -packages to directory *hashes* *within* the cloned Spack_ repository's directory tree, -``$spack/opt/spack``. You can find the resulting installed HDF5_ library with the command -``spack find -vp hdf5`` and your resulting H5Z-ZFP plugin installation with the command -``spack find -vp h5z-zfp``. If you wish to exercise more control over where Spack_ -installs things, have a look at -`configuring Spack `_ - -------------------- -Manual Installation -------------------- - -If Spack_ is not an option for you, information on *manually* installing is provided -here. - -^^^^^^^^^^^^^ -Prerequisites -^^^^^^^^^^^^^ - -* `ZFP Library `_ (or from `Github `_) -* `HDF5 Library `_ -* `H5Z-ZFP filter plugin `_ - -^^^^^^^^^^^^^ -Compiling ZFP -^^^^^^^^^^^^^ - -* There is a ``Config`` file in top-level directory of the ZFP_ distribution that holds ``make`` variables - the ZFP_ Makefiles use. By default, this file is setup for a vanilla GNU compiler. If this is not the - appropriate compiler, edit ``Config`` as necessary to adjust the compiler and compilation flags. -* An important flag you **will** need to adjust in order to use the ZFP_ library with this HDF5_ filter is - the ``BIT_STREAM_WORD_TYPE`` CPP flag. To use ZFP_ with H5Z-ZFP_, the ZFP_ library **must** be compiled - with ``BIT_STREAM_WORD_TYPE`` of ``uint8``. Typically, this is achieved by including a line in ``Config`` - of the form ``DEFS += -DBIT_STREAM_WORD_TYPE=uint8``. If you attempt to use this filter with a ZFP_ - library compiled differently from this, the filter's ``can_apply`` method will always return - false. This will result in silently ignoring an HDF5_ client's request to compress data with - ZFP_. Also, be sure to see :ref:`endian-issues`. -* After you have setup ``Config``, simply run ``make`` and it will build the ZFP_ library placing - the library in a ``lib`` sub-directory and the necessary include files in ``inc[lude]`` sub-directory. -* For more information and details, please see the `ZFP README `_. - -^^^^^^^^^^^^^^^ -Compiling HDF5_ -^^^^^^^^^^^^^^^ - -* If you want to be able to run the fortran tests for this filter, HDF5_ must be - configured with *both* the ``--enable-fortran`` and ``--enable-fortran2003`` - configuration switches. Otherwise, any vanilla installation of HDF5_ is acceptable. - -* The Fortran interface to this filter *requires* a Fortran 2003 compiler - because it uses - `ISO_C_BINDING `_ - to define the Fortran interface. - -* If you are using HDF5-1.12 and wish to use the filter as a *library* (see :ref:`plugin-vs-library`), - you may need configure HDF5 with ``--disable-memory-alloc-sanity-check`` to work - around a memory management issue in HDF5. - ------------------ -Compiling H5Z-ZFP ------------------ - -H5Z-ZFP_ is designed to be compiled both as a standalone HDF5_ *plugin* and as a separate -*library* an application can explicitly link. See :ref:`plugin-vs-library`. - -Once you have installed the prerequisites, you can compile H5Z-ZFP_ using a command-line... - -:: - - make [FC=] CC= \ - ZFP_HOME= HDF5_HOME= \ - PREFIX= - -where ```` is a directory containing ZFP_ ``inc[lude]`` and ``lib`` dirs and -```` is a directory containing HDF5_ ``include`` and ``lib`` dirs. -If you don't specify a C compiler, it will try to guess one from your path. Fortran -compilation is optional. If you do not specify a Fortran compiler, it will not attempt -to build the Fortran interface. However, if the variable ``FC`` is already defined in -your enviornment (as in Spack_ for example), then H5Z-ZFP_ will attempt to build Fortran. -If this is not desired, the solution is to pass an *empty* ``FC`` on the make command -line as in... - -:: - - make FC= CC= \ - ZFP_HOME= HDF5_HOME= \ - PREFIX= - - -The Makefile uses GNU Make syntax and is designed to work on OSX and -Linux. The filter has been tested on gcc, clang, xlc, icc and pgcc compilers -and checked with valgrind. - -The command ``make help`` will print useful information -about various make targets and variables. ``make check`` will compile everything -and run a handful of tests. - -If you don't specify a ``PREFIX``, it will install to ``./install``. The installed -package will look like... - -:: - - $(PREFIX)/include/{H5Zzfp.h,H5Zzfp_plugin.h,H5Zzfp_props.h,H5Zzfp_lib.h} - $(PREFIX)/plugin/libh5zzfp.{so,dylib} - $(PREFIX)/lib/libh5zzfp.a - -where ``$(PREFIX)`` resolves to whatever the full path of the installation is. - -To use the installed filter as an HDF5_ *plugin*, you would specify, for example, -``setenv HDF5_PLUGIN_PATH $(PREFIX)/plugin`` - --------------------------------- -H5Z-ZFP Source Code Organization --------------------------------- - -The source code is in two separate directories - - * ``src`` includes the ZFP_ filter and a few header files - - * ``H5Zzfp_plugin.h`` is an optional header file applications *may* wish - to include because it contains several convenient macros for easily - controlling various compression modes of the ZFP_ library (*rate*, - *precision*, *accuracy*, *expert*) via the :ref:`generic-interface`. - * ``H5Zzfp_props.h`` is a header file that contains functions to control the - filter using *temporary* :ref:`properties-interface`. Fortran callers are - *required* to use this interface. - * ``H5Zzfp_lib.h`` is a header file for applications that wish to use the filter - explicitly as a library rather than a plugin. - * ``H5Zzfp.h`` is an *all-of-the-above* header file for applications that don't - care too much about separating out the above functionalities. - - * ``test`` includes various tests. In particular ``test_write.c`` includes examples - of using both the :ref:`generic-interface` and :ref:`properties-interface`. In - addition, there is an example of how to use the filter from Fortran in ``test_rw_fortran.F90``. - ----------------- -Silo Integration ----------------- - -This filter (``H5Zzfp.c``) is also built-in to the `Silo library `_. -In particular, the ZFP_ library itself is also embedded in Silo but is protected from appearing in Silo's global namespace through a struct of function pointers (see `Namespaces in C `_). -If you happen to examine the source code here for H5Z-ZFP_, you will see some logic here that is specific to using this plugin within Silo and dealing with ZFP_ as an embedded library using this struct of function pointers wrapper. -In the source code for H5Z-ZFP_ this manifests as something like what is shown in the code snippet below... - -.. literalinclude:: ../src/H5Zzfp.c - :language: c - :linenos: - :start-after: /* set up dummy zfp field to compute meta header */ - :end-before: if (!dummy_field) - -In the code snippet above, note the funny ``Z`` in front of calls to various methods in the ZFP_ library. -When compiling H5Z-ZFP_ normally, that ``Z`` normally resolves to the empty string. -But, when the code is compiled with ``-DAS_SILO_BUILTIN`` (which is supported and should be done *only* when ``H5Zzfp.c`` is being compiled *within* the Silo library and *next to* a version of ZFP_ that is embedded in Silo) that ``Z`` resolves to the name of a struct and struct-member dereferncing operator as in ``zfp.``. -There is a similar ``B`` used for a similar purpose ahead of calls to ZFP_'s bitstream library. -This is something to be aware of and to adhere to if you plan to contribute any code changes here. diff --git a/ZFP/docs/interfaces.rst b/ZFP/docs/interfaces.rst deleted file mode 100644 index 0bf2ce3a..00000000 --- a/ZFP/docs/interfaces.rst +++ /dev/null @@ -1,188 +0,0 @@ -========== -Interfaces -========== - -There are two interfaces to control the filter. One uses HDF5_'s -*generic* interface via an array of ``unsigned int cd_values`` as is used -in `H5Pset_filter() `_. The other -uses HDF5_ `properties `_ -added to the `dataset creation property list `_ -used when the dataset to be compressed is being created. You can find examples of writing -HDF5_ data using both the -`generic `_ -and -`properties `__ -interfaces in -`test_write.c `_. - -The filter itself supports either interface. The filter also supports all of the -standard ZFP_ controls for affecting compression including *rate*, *precision*, -*accuracy*, *expert* and *reversible* modes. For more information and details about -these modes of controlling ZFP_ compression, please see the -`ZFP README `_. - -Finally, you should *not* attempt to combine the ZFP_ filter with any other -*byte order altering* filter such as, for example, HDF5_'s shuffle filter. -Space-performance will be ruined. This is in contrast to HDF5_'s -`deflate `_ -filter which often performs *better* when used in conjunction with the -`shuffle `_ -filter. - -.. _generic-interface: - ------------------ -Generic Interface ------------------ - -The generic interface is the only means of controlling the H5Z-ZFP_ filter when it -is used as a -`dynamically loaded HDF5 plugin `_. - -For the generic interface, the following CPP macros are defined in -the ``H5Zzfp_plugin.h`` header file:: - - H5Pset_zfp_rate_cdata(double rate, size_t cd_nelmts, unsigned int *cd_vals); - H5Pset_zfp_precision_cdata(unsigned int prec, size_t cd_nelmts, unsigned int *cd_vals); - H5Pset_zfp_accuracy_cdata(double acc, size_t cd_nelmts, unsigned int *cd_vals); - H5Pset_zfp_expert_cdata(unsigned int minbits, unsigned int maxbits, - unsigned int maxprec, int minexp, - size_t cd_nelmts, unsigned int *cd_vals); - H5Pset_zfp_reversible_cdata(size_t cd_nelmts, unsigned int *cd_vals); - -These macros utilize *type punning* to store the relevant ZFP_ parameters into a -sufficiently large array (>=6) of ``unsigned int cd_values``. It is up to -the caller to then call -`H5Pset_filter() `_ -with the array of cd_values constructed by one of these macros. - -Here is example code from -`test_write.c `_... - -.. literalinclude:: ../test/test_write.c - :language: c - :linenos: - :start-after: setup zfp filter via generic (cd_values) interface - :end-before: #else - -However, these macros are only a convenience. You do not **need** the -``H5Zzfp_plugin.h`` header file if you want to avoid using it. But, you are then -responsible for setting up the ``cd_values`` array correctly for the -filter. For reference, the ``cd_values`` array for this ZFP_ filter is -defined like so... - -+-----------+---------------------------------------------------------+ -| | cd_values index | -+-----------+--------+--------+---------+---------+---------+---------+ -| ZFP mode | 0 | 1 | 2 | 3 | 4 | 5 | -+-----------+--------+--------+---------+---------+---------+---------+ -| rate | 1 | unused | rateA | rateB | unused | unused | -+-----------+--------+--------+---------+---------+---------+---------+ -| precision | 2 | unused | prec | unused | unused | unused | -+-----------+--------+--------+---------+---------+---------+---------+ -| accuracy | 3 | unused | accA | accB | unused | unused | -+-----------+--------+--------+---------+---------+---------+---------+ -| expert | 4 | unused | minbits| maxbits| maxprec| minexp | -+-----------+--------+--------+---------+---------+---------+---------+ -| reversible| 5 | unused | unused | unused | unused | unsued | -+-----------+--------+--------+---------+---------+---------+---------+ - -A/B are high/low 32-bit words of a double. - -Note that the cd_values used in the generic interface to ``H5Pset_filter()`` -are **not the same** cd_values ultimately stored to the HDF5_ dataset header -for a compressed dataset. The values are transformed in the set_local -method to use ZFP_'s internal routines for 'meta' and 'mode' data. So, -don't make the mistake of examining the values you find in a file and -think you can use those same values, for example, in an invokation of -h5repack. - -.. _properties-interface: - --------------------- -Properties Interface --------------------- - -For the properties interface, the following functions are defined in -the ``H5Zzfp_props.h`` header file:: - - herr_t H5Pset_zfp_rate(hid_t dcpl_id, double rate); - herr_t H5Pset_zfp_precision(hid_t dcpl_id, unsigned int prec); - herr_t H5Pset_zfp_accuracy(hid_t dcpl_id, double acc); - herr_t H5Pset_zfp_expert(hid_t dcpl_id, - unsigned int minbits, unsigned int maxbits, - unsigned int maxprec, int minexp); - herr_t H5Pset_zfp_reversible(hid_t dcpl_id); - -These functions take a dataset creation property list, ``hid_t dcp_lid`` and -create temporary HDF5_ property -list entries to control the ZFP_ filter. Calling any of these functions -removes the effects of any previous call to any one of these functions. -In addition, calling any one of these functions also has the effect of -adding the filter to the pipeline. - -Here is example code from -`test_write.c `_... - -.. literalinclude:: ../test/test_write.c - :language: c - :linenos: - :start-after: When filter is used as a library, we need to init it - :end-before: #endif - -The properties interface is more type-safe than the generic interface. -However, there is no way for the implementation of the properties interface -to reside within the filter plugin itself. The properties interface requires that the caller link -with with the filter as a *library*, ``libh5zzfp.a``. The generic -interface does not require this. - -Note that either interface can be used whether the -filter is used as a plugin or as a library. The difference -is whether the application calls ``H5Z_zfp_initialize()`` or not. - ------------------ -Fortran Interface ------------------ - -Fortran equivalents for both the properties and generic interfaces, described above, -has been added by Scot Breitenfeld of the HDF5_ group. The code that -implements the Fortran interfaces is in the file ``H5Zzfp_props_f.F90``. -An example of its use is in ``test/test_rw_fortran.F90``. - -.. _plugin-vs-library: - ----------------------------- -Plugin vs. Library Operation ----------------------------- - -The filter is designed to be compiled for use as both a standalone HDF5_ -`dynamically loaded HDF5 plugin `_ -and as an explicitly linked *library*. -When it is used as a plugin, it is a best practice to link the ZFP_ library -into the plugin dynamic/shared object as a *static* library. Why? In so doing, -we ensure that all ZFP_ public namespace symbols remain *confined* to the plugin -so as not to interfere with any application that may be directly explicitly linking -to the ZFP_ library for other reasons. - -All HDF5_ applications are *required* -to *find* the plugin dynamic library (named ``lib*.{so,dylib}``) -in a directory specified by the enviornment -variable, ``HDF5_PLUGIN_PATH``. Currently, the HDF5 library offers -no mechanism for applications themselves to have pre-programmed -paths in which to search for a plugin. Applications are -then always vulnerable to an incorrectly specified or unspecified ``HDF5_PLUGIN_PATH`` -environment variable. - -However, the plugin can also be used explicitly as a *library*. In this case, -**do** **not** specify the ``HDF5_PLUGIN_PATH`` enviornment variable and instead -have the application link to ``libH5Zzfp.a`` in the ``lib`` dir of the installation. -Instead two initialization and finalization routines are defined:: - - int H5Z_zfp_initialize(void); - int H5Z_zfp_finalize(void); - -These functions are defined in the ``H5Zzfp_lib.h`` header file. -Any applications that wish to use the filter as a *library* are required to call -the initialization routine, ``H5Z_zfp_initialize()`` before the filter can be -referenced. In addition, to free up resources used by the filter, applications may -call ``H5Z_zfp_finalize()`` when they are done using the filter. diff --git a/ZFP/example/testfiles/h5ex_d_zfp.tst b/ZFP/example/testfiles/h5ex_d_zfp.tst index 8b95b6e2..b343a1e3 100644 --- a/ZFP/example/testfiles/h5ex_d_zfp.tst +++ b/ZFP/example/testfiles/h5ex_d_zfp.tst @@ -5,7 +5,7 @@ zfp filter is available for encoding and decoding. Filter info is available from the dataset creation property Filter identifier is 32013 Number of parameters is 6 with the value 269504785 - To find more about the filter check H5Z-ZFP-1.1.1 (ZFP-1.0.1) github.com/LLNL/H5Z-ZFP + To find more about the filter check H5Z-ZFP-1.1.1 (ZFP-1.0.1) ....Reading zfp compressed data ................ Maximum value in DS1 is 1890.0000 zfp filter is available now since H5Dread triggered loading of the filter. diff --git a/ZFP/src/CMakeLists.txt b/ZFP/src/CMakeLists.txt deleted file mode 100644 index 91dea30d..00000000 --- a/ZFP/src/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright by The HDF Group. -# All rights reserved. -# -# This file is part of HDF5. The full HDF5 copyright notice, including -# terms governing use, modification, and redistribution, is contained in -# the COPYING file, which can be found at the root of the source code -# distribution tree, or in https://www.hdfgroup.org/licenses. -# If you do not have access to either file, you may request a copy from -# help@hdfgroup.org. -# -cmake_minimum_required (VERSION 3.18) -project (H5ZFP_SRC C) - -#----------------------------------------------------------------------------- -# Apply Definitions to compiler in this directory and below -#----------------------------------------------------------------------------- -add_definitions (${HDF5_EXTRA_C_FLAGS}) - -#----------------------------------------------------------------------------- -# Setup include Directories -#----------------------------------------------------------------------------- -set (H5ZFP_INCLUDE_DIRS ${H5ZFP_INCLUDE_DIRS} - ${H5PL_HDF5_INCLUDE_DIRS} - ${H5ZFP_SRC_SOURCE_DIR} - ${H5ZFP_BINARY_DIR} - ${ZFP_INCLUDE_DIRS} -) -#----------------------------------------------------------------------------- -# Define H5ZFP Library -#----------------------------------------------------------------------------- -set (H5ZFP_HDRS - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp.h - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp_lib.h - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp_plugin.h - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp_props.h -) - -set (H5ZFP_SRCS - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp.c - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp_props_private.h - ${H5ZFP_SRC_SOURCE_DIR}/H5Zzfp_props.c -) - -add_library (${H5ZFP_LIB_TARGET} MODULE ${H5ZFP_SRCS} ${H5ZFP_HDRS}) -if (DISABLE_H5ZFP_ENCODER) - set_target_properties(${H5ZFP_LIB_TARGET} PROPERTIES COMPILE_DEFINITIONS "FILTER_DECODE_ONLY") -endif () -target_include_directories(${H5ZFP_LIB_TARGET} PRIVATE ${H5ZFP_INCLUDE_DIRS}) -target_link_libraries (${H5ZFP_LIB_TARGET} PRIVATE ${H5PL_LINK_LIBS}) -if (WIN32) - target_link_libraries (${H5ZFP_LIB_TARGET} PRIVATE "ws2_32.lib") -endif () -set_global_variable (H5ZFP_LIBRARIES_TO_EXPORT ${H5ZFP_LIB_TARGET}) -HDF_SET_LIB_VERSIONS ("H5ZFP" ${H5ZFP_LIB_TARGET} ${H5ZFP_LIB_NAME} MODULE) - -if (H5PL_BUILD_TESTING) - #----------------------------------------------------------------------------- - # Copy plugin library to a plugins folder - #----------------------------------------------------------------------------- - - # make plugins dir - file (MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/plugins") - add_custom_command ( - TARGET ${H5ZFP_LIB_TARGET} - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different - "$" - "${CMAKE_BINARY_DIR}/plugins/$" - ) -endif () - -#----------------------------------------------------------------------------- -# Add Target(s) to CMake Install for import into other projects -#----------------------------------------------------------------------------- -if (H5ZFP_EXPORTED_TARGETS) - install ( - TARGETS - ${H5ZFP_LIB_TARGET} - EXPORT - ${H5ZFP_EXPORTED_TARGETS} - LIBRARY DESTINATION ${H5ZFP_INSTALL_LIB_DIR} COMPONENT libraries - ARCHIVE DESTINATION ${H5ZFP_INSTALL_LIB_DIR} COMPONENT libraries - RUNTIME DESTINATION ${H5ZFP_INSTALL_BIN_DIR} COMPONENT libraries - ) -endif () diff --git a/ZFP/src/H5Zzfp_plugin.h b/ZFP/src/H5Zzfp_plugin.h deleted file mode 100644 index 3d694fe2..00000000 --- a/ZFP/src/H5Zzfp_plugin.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef H5Z_ZFP_PLUGIN_H -#define H5Z_ZFP_PLUGIN_H - -#include "H5Zzfp_version.h" - -/* HDF5 generic cd_vals[] memory layout (6 unsigned ints) for - controlling H5Z-ZFP behavior as a plugin. NOTE: These cd_vals - used to pass properties in-memory from caller to filter via HDF5 - generic interface are NOT THE SAME AS the cd_vals[] that - ultimately get stored to the file for the filter "header" data. - -cd_vals 0 1 2 3 4 5 ----------------------------------------------------------------- -rate: 1 unused rateA rateB unused unused -precision: 2 unused prec unused unused unused -accuracy: 3 unused accA accB unused unused -expert: 4 unused minbits maxbits maxprec minexp - -A/B are high/low words of a double. -*/ - -#define H5Pset_zfp_rate_cdata(R, N, CD) \ - do { \ - if (N >= 4) { \ - double *p = (double *)&CD[2]; \ - CD[0] = CD[1] = CD[2] = CD[3] = 0; \ - CD[0] = H5Z_ZFP_MODE_RATE; \ - *p = R; \ - N = 4; \ - } \ - } while (0) - -#define H5Pget_zfp_rate_cdata(N, CD) \ - ((double)(((N >= 4) && (CD[0] == H5Z_ZFP_MODE_RATE)) ? *((double *)&CD[2]) : -1)) - -#define H5Pset_zfp_precision_cdata(P, N, CD) \ - do { \ - if (N >= 3) { \ - CD[0] = H5Z_ZFP_MODE_PRECISION; \ - CD[1] = 0; \ - CD[2] = P; \ - N = 3; \ - } \ - } while (0) - -#define H5Pget_zfp_precision_cdata(N, CD) \ - ((double)(((N >= 3) && (CD[0] == H5Z_ZFP_MODE_PRECISION)) ? CD[2] : 0)) - -#define H5Pset_zfp_accuracy_cdata(A, N, CD) \ - do { \ - if (N >= 4) { \ - double *p = (double *)&CD[2]; \ - CD[0] = CD[1] = CD[2] = CD[3] = 0; \ - CD[0] = H5Z_ZFP_MODE_ACCURACY; \ - *p = A; \ - N = 4; \ - } \ - } while (0) - -#define H5Pget_zfp_accuracy_cdata(N, CD) \ - ((double)(((N >= 4) && (CD[0] == H5Z_ZFP_MODE_ACCURACY)) ? *((double *)&CD[2]) : 0)) - -#define H5Pset_zfp_expert_cdata(MiB, MaB, MaP, MiE, N, CD) \ - do { \ - if (N >= 6) { \ - CD[0] = CD[1] = CD[2] = CD[3] = CD[4] = CD[5] = 0; \ - CD[0] = H5Z_ZFP_MODE_EXPERT; \ - CD[2] = MiB; \ - CD[3] = MaB; \ - CD[4] = MaP; \ - CD[5] = (unsigned int)MiE; \ - N = 6; \ - } \ - } while (0) - -#define H5Pget_zfp_expert_cdata(N, CD, MiB, MaB, MaP, MiE) \ - do { \ - if ((N >= 6) && (CD[0] == H5Z_ZFP_MODE_EXPERT)) { \ - unsigned int *p; \ - int *q; \ - p = &MiB; \ - *p = CD[2]; \ - p = &MaB; \ - *p = CD[3]; \ - p = &MaP; \ - *p = CD[4]; \ - q = &MiE; \ - *q = (int)CD[5]; \ - } \ - } while (0) - -#define H5Pset_zfp_reversible_cdata(N, CD) \ - do { \ - if (N >= 1) { \ - CD[0] = H5Z_ZFP_MODE_REVERSIBLE; \ - N = 1; \ - } \ - } while (0) - -#define H5Pget_zfp_reversible_cdata(N, CD) ((int)(((N >= 1) && (CD[0] == H5Z_ZFP_MODE_REVERSIBLE)) ? 1 : 0)) - -#endif diff --git a/ZFP/src/H5Zzfp_props.c b/ZFP/src/H5Zzfp_props.c deleted file mode 100644 index 190b7ca9..00000000 --- a/ZFP/src/H5Zzfp_props.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "H5Zzfp_plugin.h" -#include "H5Zzfp_props_private.h" - -#include "hdf5.h" - -#include -#include - -#define H5Z_ZFP_PUSH_AND_GOTO(MAJ, MIN, RET, MSG) \ - do { \ - H5Epush(H5E_DEFAULT, __FILE__, _funcname_, __LINE__, H5E_ERR_CLS_g, MAJ, MIN, MSG); \ - retval = RET; \ - goto done; \ - } while (0) - -static herr_t -H5Pset_zfp(hid_t plist, int mode, ...) -{ - static char const *_funcname_ = "H5Pset_zfp"; - static size_t const ctrls_sz = sizeof(h5z_zfp_controls_t); - unsigned int flags; - size_t cd_nelmts = 0; - unsigned int cd_values[1]; - h5z_zfp_controls_t *ctrls_p = 0; - int i; - va_list ap; - herr_t retval = 0; - - if (0 >= H5Pisa_class(plist, H5P_DATASET_CREATE)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADTYPE, -1, "not a dataset creation property list class"); - - ctrls_p = (h5z_zfp_controls_t *)malloc(ctrls_sz); - if (0 == ctrls_p) - H5Z_ZFP_PUSH_AND_GOTO(H5E_RESOURCE, H5E_NOSPACE, -1, "allocation failed for ZFP controls"); - - va_start(ap, mode); - ctrls_p->mode = mode; - switch (mode) { - case H5Z_ZFP_MODE_RATE: { - ctrls_p->details.rate = va_arg(ap, double); - if (0 > ctrls_p->details.rate) - H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "rate out of range."); - break; - } - case H5Z_ZFP_MODE_ACCURACY: { - ctrls_p->details.acc = va_arg(ap, double); - if (0 > ctrls_p->details.acc) - H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "accuracy out of range."); - break; - } - case H5Z_ZFP_MODE_PRECISION: { - ctrls_p->details.prec = va_arg(ap, unsigned int); - break; - } - case H5Z_ZFP_MODE_EXPERT: { - ctrls_p->details.expert.minbits = va_arg(ap, unsigned int); - ctrls_p->details.expert.maxbits = va_arg(ap, unsigned int); - ctrls_p->details.expert.maxprec = va_arg(ap, unsigned int); - ctrls_p->details.expert.minexp = va_arg(ap, int); - break; - } - case H5Z_ZFP_MODE_REVERSIBLE: { - break; - } - default: { - H5Z_ZFP_PUSH_AND_GOTO(H5E_ARGS, H5E_BADVALUE, -1, "bad ZFP mode."); - break; - } - } - va_end(ap); - - for (i = 0; i < H5Pget_nfilters(plist); i++) { - H5Z_filter_t fid; - if (0 <= (fid = H5Pget_filter(plist, i, &flags, &cd_nelmts, cd_values, 0, 0, 0)) && - fid == H5Z_FILTER_ZFP) { - if (0 > H5Premove_filter(plist, H5Z_FILTER_ZFP)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, -1, - "Unable to remove old ZFP filter from pipeline."); - break; - } - } - - if (0 > H5Pset_filter(plist, H5Z_FILTER_ZFP, H5Z_FLAG_MANDATORY, 0, 0)) - H5Z_ZFP_PUSH_AND_GOTO(H5E_PLINE, H5E_BADVALUE, -1, "Unable to put ZFP filter in pipeline."); - - if (0 == H5Pexist(plist, "zfp_controls")) { - retval = H5Pinsert2(plist, "zfp_controls", ctrls_sz, ctrls_p, 0, 0, 0, 0, 0, 0); - } - else { - retval = H5Pset(plist, "zfp_controls", ctrls_p); - } - - /* HDF5 copies the memory we gave it */ - free(ctrls_p); - - return retval; - -done: - - if (ctrls_p) - free(ctrls_p); - - return retval; -} - -herr_t -H5Pset_zfp_rate(hid_t plist, double rate) -{ - return H5Pset_zfp(plist, H5Z_ZFP_MODE_RATE, rate); -} - -herr_t -H5Pset_zfp_precision(hid_t plist, unsigned int prec) -{ - return H5Pset_zfp(plist, H5Z_ZFP_MODE_PRECISION, prec); -} - -herr_t -H5Pset_zfp_accuracy(hid_t plist, double acc) -{ - return H5Pset_zfp(plist, H5Z_ZFP_MODE_ACCURACY, acc); -} - -herr_t -H5Pset_zfp_expert(hid_t plist, unsigned int minbits, unsigned int maxbits, unsigned int maxprec, int minexp) -{ - return H5Pset_zfp(plist, H5Z_ZFP_MODE_EXPERT, minbits, maxbits, maxprec, minexp); -} - -herr_t -H5Pset_zfp_reversible(hid_t plist) -{ - return H5Pset_zfp(plist, H5Z_ZFP_MODE_REVERSIBLE); -} diff --git a/ZFP/src/Makefile.am b/ZFP/src/Makefile.am deleted file mode 100644 index 2d7f7d92..00000000 --- a/ZFP/src/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright by The HDF Group. All rights reserved. - -# This is the Makefile.am for the HDF5 ZFP filter library. -# -# Ed Hartnett 1/15/19 - -# This is where HDF5 wants us to install plugins. -plugindir = @HDF5_PLUGIN_DIR@ - -# The libh5zfp library for plugin module. -# Build it as shared library. -#plugin_LTLIBRARIES = libh5zfp.la -#libh5zfp_la_SOURCES = H5Zzfp.c diff --git a/config/cmake/binex/example/CMakeLists.txt b/config/cmake/binex/example/CMakeLists.txt index 35e7c429..7054735f 100644 --- a/config/cmake/binex/example/CMakeLists.txt +++ b/config/cmake/binex/example/CMakeLists.txt @@ -67,6 +67,15 @@ foreach (example ${dyn_examples} ${extra_examples}) endforeach () if (H5PL_BUILD_TESTING) + # Set plugin path relative to PROJECT_SOURCE_DIR + # Windows: HDF5/HDFPLExamples/example -> ../../lib/plugin + # Unix/Mac: HDF5/share/HDFPLExamples/example -> ../../../lib/plugin + if (WIN32) + set (PLUGIN_RELATIVE_PATH "../../lib/plugin") + else () + set (PLUGIN_RELATIVE_PATH "../../../lib/plugin") + endif () + macro (ADD_H5_TEST testname) add_test ( NAME ${testname}-clearall @@ -102,6 +111,8 @@ if (H5PL_BUILD_TESTING) -D "TEST_ERRREF=1" -D "GREP_ERRREF=Filter present but encoding disabled" -D "TEST_LIBRARY_DIRECTORY=${TESTLIBDIR}" + -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" + -D "TEST_ENV_VALUE=${PROJECT_SOURCE_DIR}/${PLUGIN_RELATIVE_PATH}" -P "${H5PL_RESOURCES_DIR}/runTest.cmake" ) set_tests_properties (${testname}-ERR PROPERTIES DEPENDS ${testname}-clearall) @@ -123,6 +134,8 @@ if (H5PL_BUILD_TESTING) -D "TEST_OUTPUT=${testname}.out" -D "TEST_REFERENCE=${testname}.tst" -D "TEST_LIBRARY_DIRECTORY=${TESTLIBDIR}" + -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" + -D "TEST_ENV_VALUE=${PROJECT_SOURCE_DIR}/${PLUGIN_RELATIVE_PATH}" -P "${H5PL_RESOURCES_DIR}/runTest.cmake" ) set_tests_properties (${testname} PROPERTIES DEPENDS ${testname}-clearall) @@ -142,6 +155,8 @@ if (H5PL_BUILD_TESTING) -D "TEST_EXPECT=0" -D "TEST_REFERENCE=${testname}.ddl" -D "TEST_LIBRARY_DIRECTORY=${TESTLIBDIR}" + -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" + -D "TEST_ENV_VALUE=${PROJECT_BINARY_DIR}/../plugins" -P "${H5PL_RESOURCES_DIR}/runTest.cmake" ) else () @@ -158,6 +173,8 @@ if (H5PL_BUILD_TESTING) -D "TEST_EXPECT=0" -D "TEST_REFERENCE=${testname}.ddl" -D "TEST_LIBRARY_DIRECTORY=${TESTLIBDIR}" + -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" + -D "TEST_ENV_VALUE=${PROJECT_SOURCE_DIR}/${PLUGIN_RELATIVE_PATH}" -P "${H5PL_RESOURCES_DIR}/runTest.cmake" ) else () @@ -174,6 +191,8 @@ if (H5PL_BUILD_TESTING) -D "TEST_MASK_MOD=1" -D "TEST_REFERENCE=${testname}.ddl" -D "TEST_LIBRARY_DIRECTORY=${TESTLIBDIR}" + -D "TEST_ENV_VAR=HDF5_PLUGIN_PATH" + -D "TEST_ENV_VALUE=${PROJECT_SOURCE_DIR}/${PLUGIN_RELATIVE_PATH}" -P "${H5PL_RESOURCES_DIR}/runTest.cmake" ) endif () diff --git a/config/cmake/cacheinit.cmake b/config/cmake/cacheinit.cmake index 6b5a7fb5..098dc1f0 100644 --- a/config/cmake/cacheinit.cmake +++ b/config/cmake/cacheinit.cmake @@ -17,7 +17,7 @@ set (USE_SHARED_LIBS ON CACHE BOOL "Use Shared Libraries" FORCE) -set (H5PL_BUILD_TESTING ON CACHE BOOL "Build h5blosc Unit Testing" FORCE) +set (H5PL_BUILD_TESTING ON CACHE BOOL "Build h5pl Unit Testing" FORCE) set (H5PL_H5PL_BUILD_TESTING ON CACHE BOOL "Enable h5pl examples" FORCE) set (H5PL_BUILD_EXAMPLES ON CACHE BOOL "Build h5pl Examples" FORCE) diff --git a/docs/RegisteredFilterPlugins.md b/docs/RegisteredFilterPlugins.md index 502bfc11..b5c818b1 100644 --- a/docs/RegisteredFilterPlugins.md +++ b/docs/RegisteredFilterPlugins.md @@ -61,6 +61,7 @@ Upon receiving a request with the above information, HDF Group will register the |`32028` |SPERR |SPERR is a lossy scientific (floating-point) data compressor that produces one of the best rate-distortion curves| |`32029` |TERSE/PROLIX |A lossless and fast compression of the diffraction data| |`32030` |FFMPEG |A lossy compression filter based on ffmpeg video library| +|`32031` |JPEG2000 | A compression filter for lossy and lossless coding| > [!NOTE] > Please contact the maintainer of a filter plugin for help with the plugin or its filter in the HDF5 library. @@ -871,3 +872,19 @@ License: Under MIT License ##### Contact Cai Lab at University of Michigan: https://www.cai-lab.org + +--- + +### JPEG2000 + +#### Filter Description + +JPEG2000 is the Swiss Army knife of image codecs. It supports lossy and lossless coding, up to 16384 components, bit depth up to 38 bits/sample, terapixel images, resolution and quality scalability, progressive decoding and sub-frame latency, region-of-interest accessibility, non-iterative optimal rate control, discontinuous media such as optical flow data and stereo disparity maps. + +#### Plugin ID `32031` Information + +https://github.com/hmaarrfk/hdf5_jpeg2000/ + +##### Contact +Mark Harfouche +mark dot harfouche at gmail dot com