To request a filter identifier, please contact
diff --git a/doxygen/examples/H5.format.2.0.html b/doxygen/examples/H5.format.2.0.html
index bde030f3853..37cb7282eb1 100644
--- a/doxygen/examples/H5.format.2.0.html
+++ b/doxygen/examples/H5.format.2.0.html
@@ -12598,9 +12598,8 @@
HDF5 Library and for filters requested and supported by third
parties. Filters supported by The HDF Group are documented
immediately below. Information on 3rd-party filters can be found at
- The HDF Group’s
- Contributions page.
+ The HDF Group’s
+ Registered Filters page.
@@ -12854,9 +12853,8 @@
HDF5 Library and for filters requested and supported by third
parties. Filters supported by The HDF Group are documented
immediately below. Information on 3rd-party filters can be found at
- The HDF Group’s
- Contributions page.
+ The HDF Group’s
+ Registered Filters page.
To request a filter identifier, please contact
diff --git a/src/H5Dmodule.h b/src/H5Dmodule.h
index 81f197d7147..27e5799968e 100644
--- a/src/H5Dmodule.h
+++ b/src/H5Dmodule.h
@@ -815,19 +815,10 @@
*
*
Data pipeline filters
*
- *
Filter
+ *
Built-in Filter
*
Description
*
*
- *
gzip compression
- *
Data compression using zlib.
- *
- *
- *
Szip compression
- *
Data compression using the Szip library. See The HDF Group website for more information
- * regarding the Szip filter.
- *
- *
*
N-bit compression
*
Data compression using an algorithm specialized for n-bit datatypes.
*
@@ -844,6 +835,19 @@
*
*
Fletcher32
*
Fletcher32 checksum for error-detection.
+ *
+ *
+ *
Optional Built-in Filter
+ *
Description
+ *
+ *
+ *
gzip compression
+ *
Data compression using zlib.
+ *
+ *
+ *
szip compression
+ *
Data compression using the szip library. The HDF Group now uses the libaec library for the szip
+filter.
*
*
*
@@ -861,6 +865,44 @@
* \li @see @ref subsubsec_dataset_filters_nbit
* \li @see @ref subsubsec_dataset_filters_scale
*
+ * \subsubsection subsubsec_dataset_transfer_dyn_filter Data Pipeline Dynamically Loaded Filters
+ * While the HDF5 “internal” compression methods work reasonably well on users’
+ * datasets, there are certain drawbacks to this implementation. First, the “internal” compression
+ * methods may not provide the optimal compression ratio, as do some newly developed or specialized
+ * compression methods. Secondly, if a data provider wants to use a “non-internal” compression for
+ * storing the data in HDF5, they have to write a filter function that uses the new compression method
+ * and then register it with the library. Data consumers of such HDF5 files will need to have the new filter
+ * function and use it with their applications to read the data, or they will need a modified version of the
+ * HDF5 Library that has the new filter as a part of the library.
+ *
+ * If a user of such data does not have a modified HDF5 Library installed on his system, command-line tools
+ * such as h5dump or h5ls will not be able to display the compressed data. Furthermore, it would be
+ * practically impossible to determine the compression method used, making the data stored in HDF5
+ * useless.
+ *
+ * It is clear that the internal HDF5 filter mechanism, while extensible, does not work well with third-party
+ * filters. It would be a maintenance nightmare to keep adding and supporting new compression methods
+ * in HDF5. For any set of HDF5 “internal” filters, there always will be data with which the “internal”
+filters
+ * will not achieve the optimal performance needed to address data I/O and storage problems. Thus the
+ * internal HDF5 filter mechanism is enhanced to address the issues discussed above.
+ *
+ * We have a feature of HDF5 called “dynamically loaded filters in HDF5.” This feature
+ * makes the HDF5 third-party filters available to an application at runtime. The third-party HDF5 filter
+ * function has to be a part of the HDF5 filter plugin installed on the system as a shared library or DLL.
+ *
+ * To use a third-party filter an HDF5 application should call the #H5Pset_filter function when setting the
+ * filter pipeline for a dataset creation property. The HDF5 Library will register the filter with the library
+ * and the filter will be applied when data is written to the file.
+ *
+ * When an application reads data compressed with a third-party HDF5 filter, the HDF5 Library will search
+ * for the required filter plugin, register the filter with the library (if the filter function is not
+registered) and
+ * apply it to the data on the read operation.
+ *
+ * For more information,
+ * \li @see @ref sec_filter_plugins
+ *
* \subsubsection subsubsec_dataset_transfer_drive File Drivers
* I/O is performed by the HDF5 virtual file layer. The file driver interface writes and reads blocks
* of data; each driver module implements the interface using different I/O mechanisms. The table
@@ -2685,8 +2727,25 @@ allocated if necessary.
* and minimum values, and they will get a much larger minimum-bits (poor compression)
*
*
- * \subsubsection subsubsec_dataset_filters_szip Using the Szip Filter
- * See The HDF Group website for further information regarding the Szip filter.
+ * \subsubsection subsubsec_dataset_filters_szip Using the SZip Filter
+ * See The HDF Group website for further information regarding the SZip filter.
+ *
+ * \subsubsection subsubsec_dataset_filters_dyn Using Dynamically-Loadable Filters
+ * \see \ref sec_filter_plugins for further information regarding the dynamically-loadable filters.
+ *
+ * HDF has a filter plugin repository of useful third-party plugins that can used
+ *
+ *
Filter
SetFilter Params
+ *
BLOSC
UD=32001,0,0
+ *
BSHUF
UD=32004,0,0
+ *
BZIP2
UD=307,0,1,9
+ *
JPEG
UD=32019,0,4,q,c,r,t
+ *
LZ4
UD=32004,0,1,3
+ *
LZF
UD=32000,1,3,0,0,0
+ *
SZ
UD=32017,1,5,2,7,20,40,0
+ *
ZFP
UD=32013,1,0,0
+ *
ZSTD
UD=32015,0,0
+ *
*
* Previous Chapter \ref sec_group - Next Chapter \ref sec_datatype
*
diff --git a/src/H5PLmodule.h b/src/H5PLmodule.h
index 37654869746..436e8bdfa0a 100644
--- a/src/H5PLmodule.h
+++ b/src/H5PLmodule.h
@@ -27,7 +27,257 @@
#define H5_MY_PKG_ERR H5E_PLUGIN
/** \page H5PL_UG The HDF5 Plugins
- * @todo Under Construction
+ *
+ * \section sec_filter_plugins HDF5 Filter Plugins
+ *
+ * \subsection subsec_filter_plugins_intro Introduction
+ * HDF5 supports compression of data using a stackable pipeline of filters which can be
+ * implemented for reading and writing datasets, both at runtime and post‐process.
+ * These filters are supported as dynamically loadable plugins, and users can even
+ * implement custom filters of their own design.
+ *
+ * \subsection subsec_filter_plugins_model Programming Model for Applications
+ * This section describes the programming model for an application that uses a third-party HDF5 filter
+ * plugin to write or read data. For simplicity of presentation, it is assumed that the HDF5 filter plugin is
+ * available on the system in a default location. The HDF5 filter plugin is discussed in detail in the
+ * \ref subsec_filter_plugins_prog section.
+ *
+ * \subsubsection subsubsec_filter_plugins_model_apply Applying a Third-party Filter When Creating and Writing
+ * a Dataset A third-party filter can be added to the HDF5 filter pipeline by using the H5Pset_filter
+ * function, as a user would do in the past. The identification number and the filter parameters should be
+ * available to the application. For example, if the application intends to apply the HDF5 bzip2 compression
+ * filter that was registered with The HDF Group and has an identification number 307
+ * (Registered
+ * Filters) then the application would follow the steps as outlined below: \code dcpl = H5Pcreate
+ * (H5P_DATASET_CREATE); status = H5Pset_filter (dcpl, (H5Z_filter_t)307, H5Z_FLAG_MANDATORY, (size_t)6,
+ * cd_values); dset = H5Dcreate (file, DATASET, H5T_STD_I32LE, space, H5P_DEFAULT, dcpl, status = H5Dwrite
+ * (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata[0]); \endcode
+ *
+ * \subsubsection subsubsec_filter_plugins_model_read Reading Data with an Applied Third-party Filter
+ * An application does not need to do anything special to read the data with a third-party filter applied. For
+ * example, if one wants to read data written in the previous example, the following regular steps should be
+ * taken: \code file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT); dset = H5Dopen (file, DATASET,
+ * H5P_DEFAULT); H5Dread (dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata[0]); \endcode
+ *
+ * The command-line utility h5dump, for example, will read and display the data as shown:
+ * \code
+ * HDF5 "h5ex_d_bzip2.h5" {
+ * GROUP "/" {
+ * DATASET "DS1" {
+ * DATATYPE H5T_STD_I32LE
+ * DATASPACE SIMPLE { ( 32, 64 ) / ( 32, 64 ) }
+ * STORAGE_LAYOUT {
+ * CHUNKED ( 4, 8 )
+ * SIZE 6410 (1.278:1 COMPRESSION)
+ * }
+ * FILTERS {
+ * USER_DEFINED_FILTER {
+ * FILTER_ID 307
+ * COMMENT HDF5 bzip2 filter; see http://www.hdfgroup.org/services/contributions.html
+ * PARAMS { 2 }
+ * }
+ * }
+ * FILLVALUE {
+ * FILL_TIME H5D_FILL_TIME_IFSET
+ * VALUE H5D_FILL_VALUE_DEFAULT
+ * }
+ * ALLOCATION_TIME {
+ * H5D_ALLOC_TIME_INCR
+ * }
+ * DATA {
+ * ...
+ * }
+ * }
+ * }
+ * }
+ * \endcode
+ *
+ * If the filter can not be loaded then h5dump will show the following:
+ * \code
+ * ...
+ * }
+ * DATA {h5dump error: unable to print data
+ * }
+ * ...
+ * \endcode
+ *
+ * \subsubsection subsubsec_filter_plugins_model_custom A Word of Caution When Using Custom Filters
+ * Data goes through the HDF5 filter pipeline only when it is written to the file or read into application
+ * memory space from the file. For example, the I/O operation is triggered with a call to #H5Fflush, or when
+ * a data item (HDF5 metadata or a raw data chunk) is evicted from the cache or brought into the cache.
+ * Please notice that #H5Dread/#H5Dwrite calls on the chunked datasets do not necessarily trigger I/O since
+ * the HDF5 Library uses a separate chunk cache.
+ *
+ * A data item may remain in the cache until the HDF5 Library is closed. If the HDF5 plugin that has to be
+ * applied to the data item becomes unavailable before the file and all objects in the file are closed, an
+ * error will occur. The following example demonstrates the issue. Please notice the position of the
+ * #H5Zunregister call:
+ *
+ * \code
+ * // Create a new group using compression.
+ * gcpl = H5Pcreate (H5P_GROUP_CREATE);
+ * status = H5Pset_filter(gcpl,H5Z_FILTER_BZIP2,H5Z_FLAG_MANDATORY,(size_t)1, cd_values);
+ * group = H5Gcreate (file, GNAME, H5P_DEFAULT, gcpl, H5P_DEFAULT);
+ * for (i=0; i < NGROUPS; i++) {
+ * sprintf(name, "group_%d", i);
+ * tmp_id = H5Gcreate (group, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ * status = H5Gclose(tmp_id);
+ * }
+ *
+ * status = H5Pclose (gcpl);
+ * status = H5Gclose (group);
+ *
+ * // Unregister the filter. Call to H5Fclose will fail because the library tries
+ * // to apply the filter that is not available anymore. This has a cascade effect
+ * // on H5Fclose.
+ * H5Zunregister(H5Z_FILTER_BZIP2);
+ * status = H5Fclose (file);
+ * \endcode
+ *
+ * Here is an error stack produced by the program:
+ * \code
+ * HDF5-DIAG: Error detected in HDF5 (xx.yy.zz) thread 0:
+ * #000: H5F.c line **** in H5Fclose(): decrementing file ID failed
+ * major: Object atom
+ * minor: Unable to close file
+ * #001: H5I.c line **** in H5I_dec_app_ref(): can't decrement ID ref count
+ * major: Object atom
+ * minor: Unable to decrement reference count
+ * #002: H5F.c line **** in H5F_close(): can't close file
+ * major: File accessibility
+ * minor: Unable to close file
+ * ...
+ * #026: H5Z.c line **** in H5Z_find(): required filter is not registered
+ * major: Data filters
+ * minor: Object not found
+ * \endcode
+ *
+ * To avoid the problem make sure to close all objects to which the filter is applied and flush them using
+ * the H5Fflush call before unregistering the filter.
+ *
+ * \subsection subsec_filter_plugins_prog Programming Model for HDF5 Filter Plugins
+ * This section describes how to create an HDF5 filter, an HDF5 filter plugin, and how to install the HDF5
+ * plugin on the system.
+ *
+ * \subsubsection subsubsec_filter_plugins_prog_write Writing a Filter Function
+ * The HDF5 filter function for the dynamically loaded filter feature should be written as any custom filter
+ * described in Custom Filters. See the
+ * “Example” section, section 5, of that document to get an idea of the simple filter function, and see the
+ * example of the more sophisticated HDF5 bzip2 filter function in the “Building an HDF5 bzip2 Plugin Example”
+ * section. The HDF5 bzip2 filter function is also available for download from Filter Plugin Repository.
+ *
+ * The user has to remember a few things when writing an HDF5 filter function.
+ *
1. An HDF5 filter is bidirectional.
+ * The filter handles both input and output to the file; a flag is passed to the filter to indicate the
+ * direction.
+ *
2. An HDF5 filter operates on a buffer.
+ * The filter reads data from a buffer, performs some sort of transformation on the data, places
+ * the result in the same or new buffer, and returns the buffer pointer and size to the caller.
+ *
3. An HDF5 filter should return zero in the case of failure.
+ *
+ * The signature of the HDF5 filter function and the accompanying filter structure (see the section below)
+ * are described in the HDF5 Reference Manual #H5Z_filter_t.
+ *
+ * \subsubsection subsubsec_filter_plugins_prog_reg Registering a Filter with The HDF Group
+ * If you are writing a filter that will be used by others, it would be a good idea to request a filter
+ * identification number and register it with The HDF Group. Please follow the procedure described at
+ * Registered
+ * Filters.
+ *
+ * The HDF Group anticipates that developers of HDF5 filter plugins will not only register new filters, but
+ * will also provide links to the source code and/or binaries for the corresponding HDF5 filter plugins.
+ *
+ * It is very important for the users of the filter that developers provide filter information in the “name”
+ * field of the filter structure, for example:
+ * \code
+ * const H5Z_class2_t H5Z_BZIP2[1] = {{
+ * H5Z_CLASS_T_VERS, // H5Z_class_t version
+ * (H5Z_filter_t)H5Z_FILTER_BZIP2, // Filter id number
+ * 1, // encoder_present flag (set to true)
+ * 1, // decoder_present flag (set to true)
+ * "HDF5 bzip2 filter; see http://www.hdfgroup.org/services/contributions.html",
+ * // Filter name for debugging
+ * NULL, // The "can apply" callback
+ * NULL, // The "set local" callback
+ * (H5Z_func_t)H5Z_filter_bzip2, // The actual filter function
+ * }};
+ * \endcode
+ *
+ * The HDF5 Library and command-line tools have access to the “name” field. An application can
+ * use the H5Pget_filter<*> functions to retrieve information about the filters.
+ *
+ * Using the example of the structure above, the h5dump tool will print the string “HDF5 bzip2
+ * filter found at …” pointing users to the applied filter (see the example in the \ref
+ * subsubsec_filter_plugins_model_read section) thus solving the problem of the filter’s origin.
+ *
+ * \subsubsection subsubsec_filter_plugins_prog_create Creating an HDF5 Filter Plugin
+ * The HDF5 filter plugin source should include:
+ *
1. The H5PLextern.h header file from the HDF5 distribution.
+ *
2. The definition of the filter structure (see the example shown in the section above).
+ *
3. The filter function (for example, H5Z_filter_bzip2).
+ *
4. The two functions necessary for the HDF5 Library to find the correct type of the plugin library
+ * while loading it at runtime and to get information about the filter function:
+ *
H5PL_type_t H5PLget_plugin_type(void);
+ *
const void* H5PLget_plugin_info(void);
+ * Here is an example of the functions above for the HDF5 bzip2 filter:
+ *
5. Other functions such as the source of the compression library may also be included.
+ *
+ * Build the HDF5 filter plugin as a shared library. The following steps should be taken:
+ *
1. When compiling, point to the HDF5 header files.
+ *
2. Use the appropriate linking flags.
+ *
3. Link with any required external libraries.
+ *
4. For example, if libbz2.so is installed on a Linux system, the HDF5 bzip2 plugin library
+ * libH5Zbzip2.so may be linked with libbz2.so instead of including bzip2 source into the
+ * plugin library.
+ * The complete example of the HDF5 bzip2 plugin library is provided at
+ * BZIP2 Filter Plugin
+ * and can be adopted for other plugins.
+ *
+ * \subsubsection subsubsec_filter_plugins_prog_install Installing an HDF5 Filter Plugin
+ * The default directory for an HDF5 filter plugin library is defined on UNIX-like systems as
+ * \code
+ * “/usr/local/hdf5/lib/plugin”
+ * \endcode
+ * and on Windows systems as
+ * \code
+ * "%ALLUSERSPROFILE%/hdf5/lib/plugin".
+ * \endcode
+ *
+ * The default path can be overwritten by a user with the #HDF5_PLUGIN_PATH environment variable.
+ * Several directories can be specified for the search path using “:” as a path separator for UNIX-like
+ * systems and “;” for Windows.
+ *
+ * Readers are encouraged to try the example in the “Building an HDF5 bzip2 Plugin Example” section.
+ *
+ * \subsection subsec_filter_plugins_design Design
+ * Dynamic loading of the HDF5 filter plugin (or filter library) is triggered only by two events: when an
+ * application calls the #H5Pset_filter function to set the filter for the first time, or when the data to
+ * which the filter is applied is read for the first time.
+ *
+ * \subsection subsec_filter_plugins_build Building an HDF5 bzip2 Plugin Example
+ * The HDF Group provides an repository of the HDF5 filter plugin that can be checked out from
+ * BZIP2 Filter Plugin.
+ *
+ * It contains the source code for the bzip2
+ * plugin library and an example that uses the plugin. It requires the HDF5 Library with the dynamically
+ * loaded feature and the bzip2 library being available on the system.
+ * The plugin and the example can be built using configure or CMake commands. For instructions on how
+ * to build with CMake, see the README.txt file in the source code distribution. The bzip2 library that can
+ * be built with CMake is available from:
+ * \code
+ * GIT_URL: "https://github.com/libarchive/bzip2.git"
+ * GIT_BRANCH: "master"
+ * \endcode
+ *
+ * See the documentation at
+ * hdf5_plugins/docs folder In
+ * particular:
+ * INSTALL_With_CMake
+ * USING_HDF5_AND_CMake
*/
/**
@@ -36,26 +286,6 @@
* Use the functions in this module to manage the loading behavior of HDF5
* plugins.
*
- *
- *
Create
Read
- *
- *
- * \snippet H5PL_examples.c create
- *
- *
- * \snippet H5PL_examples.c read
- *
- *
Update
Delete
- *
- *
- * \snippet H5PL_examples.c update
- *
- *
- * \snippet H5PL_examples.c delete
- *
- *
- *
- *
* \attention The loading behavior of HDF5 plugins can be controlled via the
* functions described below and certain environment variables, such
* as \c HDF5_PLUGIN_PRELOAD and \c HDF5_PLUGIN_PATH.
diff --git a/src/H5Zmodule.h b/src/H5Zmodule.h
index 8b1a0dedc4e..c7f8300fb7c 100644
--- a/src/H5Zmodule.h
+++ b/src/H5Zmodule.h
@@ -102,7 +102,7 @@
* Custom filters that have been registered with the library will have
* additional unique identifiers.
*
- * See \ref_dld_filters for more information on how an HDF5 application can
+ * See \ref sec_filter_plugins for more information on how an HDF5 application can
* apply a filter that is not registered with the HDF5 library.
*
* \defgroup H5ZPRE Predefined Filters
From 330b80a2665bee74d987491622c4023ef1ab8343 Mon Sep 17 00:00:00 2001
From: jhendersonHDF
Date: Mon, 18 Mar 2024 23:36:46 -0500
Subject: [PATCH 20/46] Add support for _Float16 16-bit floating point type
(#4065)
Fixed some conversion issues with Clang due to problematic undefined
behavior when casting a negative floating-point value to an integer
Fixed a bug in the library's software integer to floating-point
conversion function where a user's conversion exception function
returning H5T_CONV_UNHANDLED in the case of overflows would result in
incorrect data after conversion
Added configure checks for functions and macros related to _Float16
usage since some compilers expose the datatype but not the functions or
macros
Fixed a dt_arith test failure when H5_WANT_DCONV_EXCEPTION isn't defined
Fixed a few warnings from not explicitly casting some _Float16 variables
upwards
---
config/cmake/ConfigureChecks.cmake | 83 +-
config/cmake/ConversionTests.c | 122 ++
config/cmake/H5pubconf.h.in | 12 +
configure.ac | 103 ++
doxygen/dox/DDLBNF112.dox | 2 +-
doxygen/dox/DDLBNF114.dox | 654 ++++++++++
doxygen/dox/IntroHDF5.dox | 2 +-
doxygen/dox/LearnBasics1.dox | 4 +-
doxygen/dox/LearnBasics2.dox | 5 +
doxygen/dox/Specifications.dox | 1 +
.../examples/tables/predefinedDatatypes.dox | 12 +
hl/src/H5LT.c | 13 +-
hl/src/H5LTanalyze.c | 456 +++----
hl/src/H5LTanalyze.l | 3 +
hl/src/H5LTparse.c | 789 ++++++------
hl/src/H5LTparse.h | 63 +-
hl/src/H5LTparse.y | 8 +-
java/src/hdf/hdf5lib/HDF5Constants.java | 12 +
java/src/jni/h5Constants.c | 15 +
java/src/jni/h5util.c | 8 +-
release_docs/RELEASE.txt | 119 ++
src/H5Fmodule.h | 2 +-
src/H5Gmodule.h | 2 +-
src/H5T.c | 570 ++++++---
src/H5Tconv.c | 435 ++++++-
src/H5Tinit_float.c | 48 +-
src/H5Tmodule.h | 19 +-
src/H5Tnative.c | 28 +-
src/H5Tpkg.h | 96 ++
src/H5Tpublic.h | 19 +
src/H5private.h | 38 +-
src/H5trace.c | 8 +
test/API/H5_api_dataset_test.c | 10 +-
test/API/H5_api_test_util.c | 14 +-
test/dt_arith.c | 1062 +++++++++++++++--
test/dtypes.c | 425 ++++++-
test/ntypes.c | 121 ++
tools/lib/h5diff_array.c | 265 +++-
tools/lib/h5diff_util.c | 10 +-
tools/lib/h5tools_dump.c | 10 +-
tools/lib/h5tools_str.c | 12 +-
tools/lib/h5tools_type.c | 8 +-
tools/src/h5import/h5import.c | 108 ++
tools/src/h5ls/h5ls.c | 13 +-
tools/test/h5dump/CMakeTests.cmake | 8 +
tools/test/h5dump/CMakeTestsXML.cmake | 8 +
tools/test/h5dump/expected/tfloat16.ddl | 46 +
tools/test/h5dump/expected/tfloat16_be.ddl | 46 +
.../test/h5dump/expected/xml/tfloat16.h5.xml | 302 +++++
.../h5dump/expected/xml/tfloat16_be.h5.xml | 302 +++++
tools/test/h5dump/h5dumpgentest.c | 163 +++
tools/test/h5dump/testfiles/tfloat16.h5 | Bin 0 -> 2304 bytes
tools/test/h5dump/testfiles/tfloat16_be.h5 | Bin 0 -> 2304 bytes
tools/test/h5dump/testh5dump.sh.in | 8 +
tools/test/h5dump/testh5dumpxml.sh.in | 8 +
tools/test/h5ls/CMakeTests.cmake | 33 +
tools/test/h5ls/expected/tfloat16.ls | 8 +
tools/test/h5ls/expected/tfloat16_be.ls | 8 +
.../h5ls/expected/tfloat16_be_nosupport.ls | 8 +
.../test/h5ls/expected/tfloat16_nosupport.ls | 8 +
tools/test/h5ls/testh5ls.sh.in | 22 +-
61 files changed, 5765 insertions(+), 1022 deletions(-)
create mode 100644 doxygen/dox/DDLBNF114.dox
create mode 100644 tools/test/h5dump/expected/tfloat16.ddl
create mode 100644 tools/test/h5dump/expected/tfloat16_be.ddl
create mode 100644 tools/test/h5dump/expected/xml/tfloat16.h5.xml
create mode 100644 tools/test/h5dump/expected/xml/tfloat16_be.h5.xml
create mode 100644 tools/test/h5dump/testfiles/tfloat16.h5
create mode 100644 tools/test/h5dump/testfiles/tfloat16_be.h5
create mode 100644 tools/test/h5ls/expected/tfloat16.ls
create mode 100644 tools/test/h5ls/expected/tfloat16_be.ls
create mode 100644 tools/test/h5ls/expected/tfloat16_be_nosupport.ls
create mode 100644 tools/test/h5ls/expected/tfloat16_nosupport.ls
diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake
index 2905fe9ad08..a3eb80e6beb 100644
--- a/config/cmake/ConfigureChecks.cmake
+++ b/config/cmake/ConfigureChecks.cmake
@@ -808,7 +808,8 @@ macro (H5ConversionTests TEST def msg)
${CMAKE_BINARY_DIR}
${HDF_RESOURCES_DIR}/ConversionTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=-D${TEST}_TEST
- OUTPUT_VARIABLE OUTPUT
+ COMPILE_OUTPUT_VARIABLE ${TEST}_COMPILE_OUTPUT
+ RUN_OUTPUT_VARIABLE ${TEST}_RUN_OUTPUT
)
if (${TEST}_COMPILE)
if (${TEST}_RUN EQUAL "0")
@@ -818,14 +819,17 @@ macro (H5ConversionTests TEST def msg)
set (${TEST} "" CACHE INTERNAL ${msg})
message (VERBOSE "${msg}... no")
file (APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log
- "Test ${TEST} Run failed with the following output and exit code:\n ${OUTPUT}\n"
+ "Test ${TEST} Compile succeeded with the following output:\n ${${TEST}_COMPILE_OUTPUT}\n"
+ )
+ file (APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log
+ "Test ${TEST} Run failed with exit code ${${TEST}_RUN} and with the following output:\n ${${TEST}_RUN_OUTPUT}\n"
)
endif ()
else ()
set (${TEST} "" CACHE INTERNAL ${msg})
message (VERBOSE "${msg}... no")
file (APPEND ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log
- "Test ${TEST} Compile failed with the following output:\n ${OUTPUT}\n"
+ "Test ${TEST} Compile failed with the following output:\n ${${TEST}_COMPILE_OUTPUT}\n"
)
endif ()
else ()
@@ -887,3 +891,76 @@ H5ConversionTests (${HDF_PREFIX}_LLONG_TO_LDOUBLE_CORRECT TRUE "Checking IF corr
# some long double values
#-----------------------------------------------------------------------------
H5ConversionTests (${HDF_PREFIX}_DISABLE_SOME_LDOUBLE_CONV FALSE "Checking IF the cpu is power9 and cannot correctly converting long double values")
+
+#-----------------------------------------------------------------------------
+# Check if _Float16 type is available
+#-----------------------------------------------------------------------------
+message (STATUS "Checking if _Float16 support is available")
+set (${HDF_PREFIX}_HAVE__FLOAT16 0)
+HDF_CHECK_TYPE_SIZE (_Float16 ${HDF_PREFIX}_SIZEOF__FLOAT16)
+if (${HDF_PREFIX}_SIZEOF__FLOAT16)
+ # Request _Float16 support
+ set (CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} "-D__STDC_WANT_IEC_60559_TYPES_EXT__")
+
+ # Some compilers expose the _Float16 datatype, but not the macros and
+ # functions used with the datatype. We need the macros for proper
+ # datatype conversion support. Check for these here.
+ CHECK_SYMBOL_EXISTS (FLT16_EPSILON "float.h" h5_have_flt16_epsilon)
+ CHECK_SYMBOL_EXISTS (FLT16_MIN "float.h" h5_have_flt16_min)
+ CHECK_SYMBOL_EXISTS (FLT16_MAX "float.h" h5_have_flt16_max)
+ CHECK_SYMBOL_EXISTS (FLT16_MIN_10_EXP "float.h" h5_have_flt16_min_10_exp)
+ CHECK_SYMBOL_EXISTS (FLT16_MAX_10_EXP "float.h" h5_have_flt16_max_10_exp)
+ CHECK_SYMBOL_EXISTS (FLT16_MANT_DIG "float.h" h5_have_flt16_mant_dig)
+
+ if (h5_have_flt16_epsilon AND h5_have_flt16_min AND
+ h5_have_flt16_max AND h5_have_flt16_min_10_exp AND
+ h5_have_flt16_max_10_exp AND h5_have_flt16_mant_dig)
+ # Some compilers like OneAPI on Windows appear to detect _Float16 support
+ # properly up to this point, and, in the absence of any architecture-specific
+ # tuning compiler flags, will generate code for H5Tconv.c that performs
+ # software conversions on _Float16 variables with compiler-internal functions
+ # such as __extendhfsf2, __truncsfhf2, or __truncdfhf2. However, these
+ # compilers will fail to link these functions into the build for currently
+ # unknown reasons and cause the build to fail. Since these are compiler-internal
+ # functions that we don't appear to have much control over, let's try to
+ # compile a program that will generate these functions to check for _Float16
+ # support. If we fail to compile this program, we will simply disable
+ # _Float16 support for the time being.
+ H5ConversionTests (
+ ${HDF_PREFIX}_FLOAT16_CONVERSION_FUNCS_LINK
+ FALSE
+ "Checking if compiler can convert _Float16 type with casts"
+ )
+
+ if (${${HDF_PREFIX}_FLOAT16_CONVERSION_FUNCS_LINK})
+ # Finally, MacOS 13 appears to have a bug specifically when converting
+ # long double values to _Float16. Release builds of the dt_arith test
+ # would cause any assignments to a _Float16 variable to be elided,
+ # whereas Debug builds would perform incorrect hardware conversions by
+ # simply chopping off all the bytes of the value except for the first 2.
+ # These tests pass on MacOS 14, so let's perform a quick test to check
+ # if the hardware conversion is done correctly.
+ H5ConversionTests (
+ ${HDF_PREFIX}_LDOUBLE_TO_FLOAT16_CORRECT
+ TRUE
+ "Checking if correctly converting long double to _Float16 values"
+ )
+
+ if (NOT ${${HDF_PREFIX}_LDOUBLE_TO_FLOAT16_CORRECT})
+ message (VERBOSE "Conversions from long double to _Float16 appear to be incorrect. These will be emulated through a soft conversion function.")
+ endif ()
+
+ set (${HDF_PREFIX}_HAVE__FLOAT16 1)
+
+ # Check if we can use fabsf16
+ CHECK_FUNCTION_EXISTS (fabsf16 ${HDF_PREFIX}_HAVE_FABSF16)
+ else ()
+ message (STATUS "_Float16 support has been disabled because the compiler couldn't compile and run a test program for _Float16 conversions")
+ message (STATUS "Check ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log for information on why the test program couldn't be compiled/run")
+ endif ()
+ else ()
+ message (STATUS "_Float16 support has been disabled since the required macros (FLT16_MAX, FLT16_EPSILON, etc. were not found)")
+ endif ()
+else ()
+ message (STATUS "_Float16 support has been disabled since the _Float16 type was not found")
+endif ()
diff --git a/config/cmake/ConversionTests.c b/config/cmake/ConversionTests.c
index 725f0496f01..8e103bd3e97 100644
--- a/config/cmake/ConversionTests.c
+++ b/config/cmake/ConversionTests.c
@@ -285,3 +285,125 @@ int HDF_NO_UBSAN main(void)
}
#endif
+
+#ifdef H5_FLOAT16_CONVERSION_FUNCS_LINK_TEST
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+
+#include
+#include
+
+int HDF_NO_UBSAN main(void)
+{
+ _Float16 fl16_var;
+ signed char sc;
+ unsigned char usc;
+ short s;
+ unsigned short us;
+ int i;
+ unsigned int ui;
+ long l;
+ unsigned long ul;
+ long long ll;
+ unsigned long long ull;
+ float f;
+ double d;
+ long double ld;
+ int ret = 0;
+
+ /*
+ * Cast the _Float16 type between all the different C datatypes
+ * we support conversions for in H5Tconv.c to check if the compiler
+ * properly links any software conversion functions it may generate
+ * for the casts, such as __extendhfsf2 or __truncdfhf2.
+ */
+
+ fl16_var = 3.0f16;
+
+ sc = (signed char)fl16_var;
+ usc = (unsigned char)fl16_var;
+ s = (short)fl16_var;
+ us = (unsigned short)fl16_var;
+ i = (int)fl16_var;
+ ui = (unsigned int)fl16_var;
+ l = (long)fl16_var;
+ ul = (unsigned long)fl16_var;
+ ll = (long long)fl16_var;
+ ull = (unsigned long long)fl16_var;
+ f = (float)fl16_var;
+ d = (double)fl16_var;
+ ld = (long double)fl16_var;
+
+ sc = (signed char)3;
+ fl16_var = (_Float16)sc;
+
+ usc = (unsigned char)3;
+ fl16_var = (_Float16)usc;
+
+ s = (short)3;
+ fl16_var = (_Float16)s;
+
+ us = (unsigned short)3;
+ fl16_var = (_Float16)us;
+
+ i = (int)3;
+ fl16_var = (_Float16)i;
+
+ ui = (unsigned int)3;
+ fl16_var = (_Float16)ui;
+
+ l = (long)3;
+ fl16_var = (_Float16)l;
+
+ ul = (unsigned long)3;
+ fl16_var = (_Float16)ul;
+
+ ll = (long long)3;
+ fl16_var = (_Float16)ll;
+
+ ull = (unsigned long long)3;
+ fl16_var = (_Float16)ull;
+
+ f = (float)3.0f;
+ fl16_var = (_Float16)f;
+
+ d = (double)3.0;
+ fl16_var = (_Float16)d;
+
+ ld = (long double)3.0l;
+ fl16_var = (_Float16)ld;
+
+done:
+ exit(ret);
+}
+
+#endif
+
+#ifdef H5_LDOUBLE_TO_FLOAT16_CORRECT_TEST
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+
+#include
+#include
+#include
+#include
+
+int HDF_NO_UBSAN main(void)
+{
+ long double ld;
+ _Float16 half;
+ int ret = 1;
+
+ ld = 32.0L;
+ half = 64.0f16;
+
+ half = (_Float16)ld;
+
+ if (fabsl(ld - (long double)half) < LDBL_EPSILON)
+ ret = 0;
+
+done:
+ exit(ret);
+}
+
+#endif
diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in
index 8d866ec89a5..af8948d9f6e 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -131,6 +131,9 @@
/* Define if library information should be embedded in the executables */
#cmakedefine H5_HAVE_EMBEDDED_LIBINFO @H5_HAVE_EMBEDDED_LIBINFO@
+/* Define to 1 if you have the `fabsf16' function. */
+#cmakedefine H5_HAVE_FABSF16 @H5_HAVE_FABSF16@
+
/* Define to 1 if you have the `fcntl' function. */
#cmakedefine H5_HAVE_FCNTL @H5_HAVE_FCNTL@
@@ -143,6 +146,9 @@
/* Define if support for szip filter is enabled */
#cmakedefine H5_HAVE_FILTER_SZIP @H5_HAVE_FILTER_SZIP@
+/* Determine if _Float16 is available */
+#cmakedefine H5_HAVE__FLOAT16 @H5_HAVE__FLOAT16@
+
/* Determine if __float128 is available */
#cmakedefine H5_HAVE_FLOAT128 @H5_HAVE_FLOAT128@
@@ -384,6 +390,9 @@
/* Define if new-style references should be used with dimension scales */
#cmakedefine H5_DIMENSION_SCALES_WITH_NEW_REF @H5_DIMENSION_SCALES_WITH_NEW_REF@
+/* Define if your system can convert long double to _Float16 values correctly. */
+#cmakedefine H5_LDOUBLE_TO_FLOAT16_CORRECT @H5_LDOUBLE_TO_FLOAT16_CORRECT@
+
/* Define if your system can convert long double to (unsigned) long long
values correctly. */
#cmakedefine H5_LDOUBLE_TO_LLONG_ACCURATE @H5_LDOUBLE_TO_LLONG_ACCURATE@
@@ -586,6 +595,9 @@
/* The size of `_Quad', as computed by sizeof. */
#define H5_SIZEOF__QUAD @H5_SIZEOF__QUAD@
+/* The size of `_Float16', as computed by sizeof. */
+#define H5_SIZEOF__FLOAT16 @H5_SIZEOF__FLOAT16@
+
/* The size of `__float128', as computed by sizeof. */
#define H5_SIZEOF___FLOAT128 @H5_SIZEOF___FLOAT128@
diff --git a/configure.ac b/configure.ac
index b76f18ff29f..f33fb8b87b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -559,6 +559,109 @@ AC_CHECK_SIZEOF([float])
AC_CHECK_SIZEOF([double])
AC_CHECK_SIZEOF([long double])
+## ----------------------------------------------------------------------
+## Check if _Float16 support is available
+##
+AC_MSG_NOTICE([checking if _Float16 support is available])
+HAVE__FLOAT16="no"
+AC_CHECK_SIZEOF([_Float16])
+if test "$ac_cv_sizeof__Float16" != 0; then
+ # Some compilers expose the _Float16 datatype, but not the macros and
+ # functions used with the datatype. We need the macros for proper
+ # datatype conversion support. Check for these here.
+ AC_CHECK_DECL([FLT16_EPSILON], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+ AC_CHECK_DECL([FLT16_MIN], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+ AC_CHECK_DECL([FLT16_MAX], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+ AC_CHECK_DECL([FLT16_MIN_10_EXP], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+ AC_CHECK_DECL([FLT16_MAX_10_EXP], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+ AC_CHECK_DECL([FLT16_MANT_DIG], [], [], [[
+ #define __STDC_WANT_IEC_60559_TYPES_EXT__
+ #include ]])
+
+ if test "X$ac_cv_have_decl_FLT16_EPSILON" = "Xyes" &&
+ test "X$ac_cv_have_decl_FLT16_MIN" = "Xyes" &&
+ test "X$ac_cv_have_decl_FLT16_MAX" = "Xyes" &&
+ test "X$ac_cv_have_decl_FLT16_MIN_10_EXP" = "Xyes" &&
+ test "X$ac_cv_have_decl_FLT16_MAX_10_EXP" = "Xyes" &&
+ test "X$ac_cv_have_decl_FLT16_MANT_DIG" = "Xyes" ; then
+ # Some compilers like OneAPI on Windows appear to detect _Float16 support
+ # properly up to this point, and, in the absence of any architecture-specific
+ # tuning compiler flags, will generate code for H5Tconv.c that performs
+ # software conversions on _Float16 variables with compiler-internal functions
+ # such as __extendhfsf2, __truncsfhf2, or __truncdfhf2. However, these
+ # compilers will fail to link these functions into the build for currently
+ # unknown reasons and cause the build to fail. Since these are compiler-internal
+ # functions that we don't appear to have much control over, let's try to
+ # compile a program that will generate these functions to check for _Float16
+ # support. If we fail to compile this program, we will simply disable
+ # _Float16 support for the time being.
+ AC_MSG_CHECKING([if compiler can correctly compile and run a test program which converts _Float16 to other types with casts])
+ TEST_SRC="`(echo \"#define H5_FLOAT16_CONVERSION_FUNCS_LINK_TEST 1\"; cat $srcdir/config/cmake/ConversionTests.c)`"
+ AC_CACHE_VAL([hdf5_cv_float16_conversion_funcs_link],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([$TEST_SRC])],
+ [hdf5_cv_float16_conversion_funcs_link=yes], [hdf5_cv_float16_conversion_funcs_link=no], [hdf5_cv_float16_conversion_funcs_link=no])])
+
+ if test ${hdf5_cv_float16_conversion_funcs_link} = "yes"; then
+ AC_MSG_RESULT([yes])
+
+ # Finally, MacOS 13 appears to have a bug specifically when converting
+ # long double values to _Float16. Release builds of the dt_arith test
+ # would cause any assignments to a _Float16 variable to be elided,
+ # whereas Debug builds would perform incorrect hardware conversions by
+ # simply chopping off all the bytes of the value except for the first 2.
+ # These tests pass on MacOS 14, so let's perform a quick test to check
+ # if the hardware conversion is done correctly.
+ AC_MSG_CHECKING([if compiler can correctly convert long double values to _Float16])
+ TEST_SRC="`(echo \"#define H5_LDOUBLE_TO_FLOAT16_CORRECT_TEST 1\"; cat $srcdir/config/cmake/ConversionTests.c)`"
+ if test ${ac_cv_sizeof_long_double} = 0; then
+ hdf5_cv_ldouble_to_float16_correct=${hdf5_cv_ldouble_to_float16_correct=no}
+ else
+ AC_CACHE_VAL([hdf5_cv_ldouble_to_float16_correct],
+ [AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([$TEST_SRC])],
+ [hdf5_cv_ldouble_to_float16_correct=yes], [hdf5_cv_ldouble_to_float16_correct=no], [hdf5_cv_ldouble_to_float16_correct=yes])])
+ fi
+
+ if test ${hdf5_cv_ldouble_to_float16_correct} = "yes"; then
+ AC_DEFINE([LDOUBLE_TO_FLOAT16_CORRECT], [1],
+ [Define if your system can convert long double to _Float16 values correctly.])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_NOTICE([Conversions from long double to _Float16 appear to be incorrect. These will be emulated through a soft conversion function.])
+ fi
+
+ HAVE__FLOAT16="yes"
+
+ # Check if we can use fabsf16
+ AC_CHECK_FUNC([fabsf16], [AC_DEFINE([HAVE_FABSF16], [1],
+ [Define if has fabsf16 function])], [])
+
+ # Define HAVE__FLOAT16 macro for H5pubconf.h if _Float16 is available.
+ AC_DEFINE([HAVE__FLOAT16], [1], [Determine if _Float16 is available])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+
+ AC_MSG_CHECKING([if _Float16 support is enabled])
+ AC_MSG_RESULT([$HAVE__FLOAT16])
+fi
+
+# Define HAVE__FLOAT16 value to substitute into other files for conditional testing
+AC_SUBST([HAVE__FLOAT16])
+
## ----------------------------------------------------------------------
## Check if the Fortran interface should be enabled
##
diff --git a/doxygen/dox/DDLBNF112.dox b/doxygen/dox/DDLBNF112.dox
index 6809a0632ff..cfe34c321f9 100644
--- a/doxygen/dox/DDLBNF112.dox
+++ b/doxygen/dox/DDLBNF112.dox
@@ -1,4 +1,4 @@
-/** \page DDLBNF112 DDL in BNF for HDF5 1.12 and above
+/** \page DDLBNF112 DDL in BNF for HDF5 1.12 through HDF5 1.14.3
\todo Revise this & break it up!
diff --git a/doxygen/dox/DDLBNF114.dox b/doxygen/dox/DDLBNF114.dox
new file mode 100644
index 00000000000..61e9157e560
--- /dev/null
+++ b/doxygen/dox/DDLBNF114.dox
@@ -0,0 +1,654 @@
+/** \page DDLBNF114 DDL in BNF for HDF5 1.14.4 and above
+
+\todo Revise this & break it up!
+
+\section intro114 Introduction
+
+This document contains the data description language (DDL) for an HDF5 file. The
+description is in Backus-Naur Form (BNF).
+
+\section expo114 Explanation of Symbols
+
+This section contains a brief explanation of the symbols used in the DDL.
+
+\code{.unparsed}
+::= defined as
+ a token with the name tname
+ | one of or
+ opt zero or one occurrence of
+ * zero or more occurrence of
+ + one or more occurrence of
+ [0-9] an element in the range between 0 and 9
+ '[' the token within the quotes (used for special characters)
+ TBD To Be Decided
+\endcode
+
+\section ddl114 The DDL
+
+\code{.unparsed}
+ ::= HDF5 { opt }
+
+ ::=
+
+ ::= SUPER_BLOCK {
+ SUPERBLOCK_VERSION
+ FREELIST_VERSION
+ SYMBOLTABLE_VERSION
+ OBJECTHEADER_VERSION
+ OFFSET_SIZE
+ LENGTH_SIZE
+ BTREE_RANK
+ BTREE_LEAF
+ ISTORE_K
+
+ USER_BLOCK {
+ USERBLOCK_SIZE
+ }
+ }
+
+ ::= FILE_SPACE_STRATEGY
+ FREE_SPACE_PERSIST
+ FREE_SPACE_SECTION_THRESHOLD
+ FILE_SPACE_PAGE_SIZE
+
+ ::= H5F_FSPACE_STRATEGY_FSM_AGGR | H5F_FSPACE_STRATEGY_PAGE |
+ H5F_FSPACE_STRATEGY_AGGR | H5F_FSPACE_STRATEGY_NONE |
+ Unknown strategy
+
+ ::= GROUP "/" {
+ *
+ opt
+ opt
+ *
+ *
+ }
+
+ ::= | | |
+
+ ::= DATATYPE {
+
+ }
+
+ ::= the assigned name for anonymous named type is
+ in the form of #oid, where oid is the object id
+ of the type
+
+ ::= | |