summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Henderson <jhenderson@hdfgroup.org>2024-03-02 02:29:45 (GMT)
committerJordan Henderson <jhenderson@hdfgroup.org>2024-03-02 22:07:41 (GMT)
commit10c1c557359837d97d21e966ed8286382da0d122 (patch)
tree8644081c36c679c2b72c1d9f365a74f7da911d92
parenta209e23d79c41b0e3d78bb8394d1b2f704d7db77 (diff)
downloadhdf5-10c1c557359837d97d21e966ed8286382da0d122.zip
hdf5-10c1c557359837d97d21e966ed8286382da0d122.tar.gz
hdf5-10c1c557359837d97d21e966ed8286382da0d122.tar.bz2
Work around issues with MacOS 13
Add CMake status message about _Float16 test-compile program
-rw-r--r--.github/workflows/main.yml1
-rw-r--r--config/cmake/ConfigureChecks.cmake124
-rw-r--r--config/cmake/ConversionTests.c29
-rw-r--r--config/cmake/H5pubconf.h.in3
-rw-r--r--configure.ac39
-rw-r--r--src/H5T.c392
-rw-r--r--src/H5Tconv.c2
-rw-r--r--src/H5Tpkg.h10
-rw-r--r--test/dt_arith.c509
9 files changed, 722 insertions, 387 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3f878b1..7a0eb69 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -36,4 +36,3 @@ jobs:
name: "CMake Workflows"
uses: ./.github/workflows/cmake.yml
if: "!contains(github.event.head_commit.message, 'skip-ci')"
-
diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake
index 25de5b0..c088926 100644
--- a/config/cmake/ConfigureChecks.cmake
+++ b/config/cmake/ConfigureChecks.cmake
@@ -363,56 +363,6 @@ endif ()
HDF_CHECK_TYPE_SIZE (time_t ${HDF_PREFIX}_SIZEOF_TIME_T)
#-----------------------------------------------------------------------------
-# Check if _Float16 type is available
-#-----------------------------------------------------------------------------
-HDF_CHECK_TYPE_SIZE (_Float16 ${HDF_PREFIX}_SIZEOF__FLOAT16)
-if (${HDF_PREFIX}_SIZEOF__FLOAT16)
- # Ask for _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. The main function we're interested in
- # is fabsf16. 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)
- # Finally, some compilers like OneAPI on MSVC appear to just be broken,
- # as support for _Float16 and its macros can be detected properly, but
- # then code is generated that uses the __truncsfhf2, __truncdfhf2,
- # __extendhfsf2 functions, which end up being unresolved with MSVC. Let's
- # try to compile a program that will generate these functions as a last
- # resort for checking for _Float16 support.
- message (VERBOSE "Compiling test program for _Float16 support")
- try_compile (
- h5_compiled_float16_test
- ${CMAKE_BINARY_DIR}
- ${HDF_RESOURCES_DIR}/HDFTests.c
- COMPILE_DEFINITIONS "-DCHECK_FLOAT16"
- C_STANDARD 99
- )
-
- if (${h5_compiled_float16_test})
- set (${HDF_PREFIX}_HAVE__FLOAT16 1)
-
- # Check if we can use fabsf16
- CHECK_FUNCTION_EXISTS (fabsf16 ${HDF_PREFIX}_HAVE_FABSF16)
- endif ()
- else ()
- set (${HDF_PREFIX}_HAVE__FLOAT16 0)
- endif ()
-else ()
- set (${HDF_PREFIX}_HAVE__FLOAT16 0)
-endif ()
-
-#-----------------------------------------------------------------------------
# Extra C99 types
#-----------------------------------------------------------------------------
@@ -941,7 +891,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")
@@ -951,14 +902,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 ()
@@ -1020,3 +974,67 @@ 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
+#-----------------------------------------------------------------------------
+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. The main function we're interested in
+ # is fabsf16. 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 MSVC appear to just be broken, as support
+ # for _Float16 and its macros can be detected properly, but then code is
+ # generated that uses the __truncsfhf2, __truncdfhf2, __extendhfsf2 functions,
+ # which end up being unresolved with MSVC. Let's try to compile a program
+ # that will generate these functions to check for _Float16 support.
+ message (STATUS "Compiling test program to check for _Float16 support")
+ try_compile (
+ h5_compiled_float16_test
+ ${CMAKE_BINARY_DIR}
+ ${HDF_RESOURCES_DIR}/HDFTests.c
+ COMPILE_DEFINITIONS "-DCHECK_FLOAT16"
+ C_STANDARD 99
+ )
+
+ if (${h5_compiled_float16_test})
+ # 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"
+ )
+
+ set (${HDF_PREFIX}_HAVE__FLOAT16 1)
+
+ # Check if we can use fabsf16
+ CHECK_FUNCTION_EXISTS (fabsf16 ${HDF_PREFIX}_HAVE_FABSF16)
+ else ()
+ message (STATUS "Failed to compile test program to check for _Float16 support")
+ endif ()
+ else ()
+ set (${HDF_PREFIX}_HAVE__FLOAT16 0)
+ endif ()
+else ()
+ set (${HDF_PREFIX}_HAVE__FLOAT16 0)
+endif ()
diff --git a/config/cmake/ConversionTests.c b/config/cmake/ConversionTests.c
index 725f049..5a3e016 100644
--- a/config/cmake/ConversionTests.c
+++ b/config/cmake/ConversionTests.c
@@ -285,3 +285,32 @@ int HDF_NO_UBSAN main(void)
}
#endif
+
+#ifdef H5_LDOUBLE_TO_FLOAT16_CORRECT_TEST
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+
+#include <stdlib.h>
+#include <float.h>
+#include <math.h>
+#include <limits.h>
+
+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 5be6dc4..5682c2a 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -393,6 +393,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@
diff --git a/configure.ac b/configure.ac
index 2fdfbb6..7d67f2d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -581,12 +581,11 @@ if test "$ac_cv_sizeof__Float16" != 0; then
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
- # Finally, some compilers like OneAPI on MSVC appear to just be broken,
- # as support for _Float16 and its macros can be detected properly, but
- # then code is generated that uses the __truncsfhf2, __truncdfhf2,
- # __extendhfsf2 functions, which end up being unresolved with MSVC. Let's
- # try to compile a program that will generate these functions as a last
- # resort for checking for _Float16 support.
+ # Some compilers like OneAPI on MSVC appear to just be broken, as support
+ # for _Float16 and its macros can be detected properly, but then code is
+ # generated that uses the __truncsfhf2, __truncdfhf2, __extendhfsf2 functions,
+ # which end up being unresolved with MSVC. Let's try to compile a program
+ # that will generate these functions to check for _Float16 support.
AC_MSG_CHECKING([if _Float16 program can be compiled])
AC_CACHE_VAL([hdf5_cv_float16_prog_compiled],
[AC_RUN_IFELSE(
@@ -614,7 +613,33 @@ if test "$ac_cv_sizeof__Float16" != 0; then
if test ${hdf5_cv_float16_prog_compiled} = "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])
+ fi
+
HAVE__FLOAT16="yes"
# Check if we can use fabsf16
diff --git a/src/H5T.c b/src/H5T.c
index a340211..ab284b6 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -398,105 +398,105 @@ H5T_order_t H5T_native_order_g = H5T_ORDER_ERROR;
* If more of these are added, the new ones must be added to the list of
* types to reset in H5T_term_package().
*/
-hid_t H5T_IEEE_F16BE_g = FAIL;
-hid_t H5T_IEEE_F16LE_g = FAIL;
-hid_t H5T_IEEE_F32BE_g = FAIL;
-hid_t H5T_IEEE_F32LE_g = FAIL;
-hid_t H5T_IEEE_F64BE_g = FAIL;
-hid_t H5T_IEEE_F64LE_g = FAIL;
-
-hid_t H5T_VAX_F32_g = FAIL;
-hid_t H5T_VAX_F64_g = FAIL;
-
-hid_t H5T_STD_I8BE_g = FAIL;
-hid_t H5T_STD_I8LE_g = FAIL;
-hid_t H5T_STD_I16BE_g = FAIL;
-hid_t H5T_STD_I16LE_g = FAIL;
-hid_t H5T_STD_I32BE_g = FAIL;
-hid_t H5T_STD_I32LE_g = FAIL;
-hid_t H5T_STD_I64BE_g = FAIL;
-hid_t H5T_STD_I64LE_g = FAIL;
-hid_t H5T_STD_U8BE_g = FAIL;
-hid_t H5T_STD_U8LE_g = FAIL;
-hid_t H5T_STD_U16BE_g = FAIL;
-hid_t H5T_STD_U16LE_g = FAIL;
-hid_t H5T_STD_U32BE_g = FAIL;
-hid_t H5T_STD_U32LE_g = FAIL;
-hid_t H5T_STD_U64BE_g = FAIL;
-hid_t H5T_STD_U64LE_g = FAIL;
-hid_t H5T_STD_B8BE_g = FAIL;
-hid_t H5T_STD_B8LE_g = FAIL;
-hid_t H5T_STD_B16BE_g = FAIL;
-hid_t H5T_STD_B16LE_g = FAIL;
-hid_t H5T_STD_B32BE_g = FAIL;
-hid_t H5T_STD_B32LE_g = FAIL;
-hid_t H5T_STD_B64BE_g = FAIL;
-hid_t H5T_STD_B64LE_g = FAIL;
-hid_t H5T_STD_REF_OBJ_g = FAIL;
-hid_t H5T_STD_REF_DSETREG_g = FAIL;
-hid_t H5T_STD_REF_g = FAIL;
-
-hid_t H5T_UNIX_D32BE_g = FAIL;
-hid_t H5T_UNIX_D32LE_g = FAIL;
-hid_t H5T_UNIX_D64BE_g = FAIL;
-hid_t H5T_UNIX_D64LE_g = FAIL;
-
-hid_t H5T_C_S1_g = FAIL;
-
-hid_t H5T_FORTRAN_S1_g = FAIL;
-
-hid_t H5T_NATIVE_SCHAR_g = FAIL;
-hid_t H5T_NATIVE_UCHAR_g = FAIL;
-hid_t H5T_NATIVE_SHORT_g = FAIL;
-hid_t H5T_NATIVE_USHORT_g = FAIL;
-hid_t H5T_NATIVE_INT_g = FAIL;
-hid_t H5T_NATIVE_UINT_g = FAIL;
-hid_t H5T_NATIVE_LONG_g = FAIL;
-hid_t H5T_NATIVE_ULONG_g = FAIL;
-hid_t H5T_NATIVE_LLONG_g = FAIL;
-hid_t H5T_NATIVE_ULLONG_g = FAIL;
-hid_t H5T_NATIVE_FLOAT16_g = FAIL;
-hid_t H5T_NATIVE_FLOAT_g = FAIL;
-hid_t H5T_NATIVE_DOUBLE_g = FAIL;
-hid_t H5T_NATIVE_LDOUBLE_g = FAIL;
-hid_t H5T_NATIVE_B8_g = FAIL;
-hid_t H5T_NATIVE_B16_g = FAIL;
-hid_t H5T_NATIVE_B32_g = FAIL;
-hid_t H5T_NATIVE_B64_g = FAIL;
-hid_t H5T_NATIVE_OPAQUE_g = FAIL;
-hid_t H5T_NATIVE_HADDR_g = FAIL;
-hid_t H5T_NATIVE_HSIZE_g = FAIL;
-hid_t H5T_NATIVE_HSSIZE_g = FAIL;
-hid_t H5T_NATIVE_HERR_g = FAIL;
-hid_t H5T_NATIVE_HBOOL_g = FAIL;
-
-hid_t H5T_NATIVE_INT8_g = FAIL;
-hid_t H5T_NATIVE_UINT8_g = FAIL;
-hid_t H5T_NATIVE_INT_LEAST8_g = FAIL;
-hid_t H5T_NATIVE_UINT_LEAST8_g = FAIL;
-hid_t H5T_NATIVE_INT_FAST8_g = FAIL;
-hid_t H5T_NATIVE_UINT_FAST8_g = FAIL;
-
-hid_t H5T_NATIVE_INT16_g = FAIL;
-hid_t H5T_NATIVE_UINT16_g = FAIL;
-hid_t H5T_NATIVE_INT_LEAST16_g = FAIL;
-hid_t H5T_NATIVE_UINT_LEAST16_g = FAIL;
-hid_t H5T_NATIVE_INT_FAST16_g = FAIL;
-hid_t H5T_NATIVE_UINT_FAST16_g = FAIL;
-
-hid_t H5T_NATIVE_INT32_g = FAIL;
-hid_t H5T_NATIVE_UINT32_g = FAIL;
-hid_t H5T_NATIVE_INT_LEAST32_g = FAIL;
-hid_t H5T_NATIVE_UINT_LEAST32_g = FAIL;
-hid_t H5T_NATIVE_INT_FAST32_g = FAIL;
-hid_t H5T_NATIVE_UINT_FAST32_g = FAIL;
-
-hid_t H5T_NATIVE_INT64_g = FAIL;
-hid_t H5T_NATIVE_UINT64_g = FAIL;
-hid_t H5T_NATIVE_INT_LEAST64_g = FAIL;
-hid_t H5T_NATIVE_UINT_LEAST64_g = FAIL;
-hid_t H5T_NATIVE_INT_FAST64_g = FAIL;
-hid_t H5T_NATIVE_UINT_FAST64_g = FAIL;
+hid_t H5T_IEEE_F16BE_g = H5I_INVALID_HID;
+hid_t H5T_IEEE_F16LE_g = H5I_INVALID_HID;
+hid_t H5T_IEEE_F32BE_g = H5I_INVALID_HID;
+hid_t H5T_IEEE_F32LE_g = H5I_INVALID_HID;
+hid_t H5T_IEEE_F64BE_g = H5I_INVALID_HID;
+hid_t H5T_IEEE_F64LE_g = H5I_INVALID_HID;
+
+hid_t H5T_VAX_F32_g = H5I_INVALID_HID;
+hid_t H5T_VAX_F64_g = H5I_INVALID_HID;
+
+hid_t H5T_STD_I8BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I8LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I16BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I16LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I32BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I32LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I64BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_I64LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U8BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U8LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U16BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U16LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U32BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U32LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U64BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_U64LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B8BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B8LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B16BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B16LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B32BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B32LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B64BE_g = H5I_INVALID_HID;
+hid_t H5T_STD_B64LE_g = H5I_INVALID_HID;
+hid_t H5T_STD_REF_OBJ_g = H5I_INVALID_HID;
+hid_t H5T_STD_REF_DSETREG_g = H5I_INVALID_HID;
+hid_t H5T_STD_REF_g = H5I_INVALID_HID;
+
+hid_t H5T_UNIX_D32BE_g = H5I_INVALID_HID;
+hid_t H5T_UNIX_D32LE_g = H5I_INVALID_HID;
+hid_t H5T_UNIX_D64BE_g = H5I_INVALID_HID;
+hid_t H5T_UNIX_D64LE_g = H5I_INVALID_HID;
+
+hid_t H5T_C_S1_g = H5I_INVALID_HID;
+
+hid_t H5T_FORTRAN_S1_g = H5I_INVALID_HID;
+
+hid_t H5T_NATIVE_SCHAR_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UCHAR_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_SHORT_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_USHORT_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_LONG_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_ULONG_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_LLONG_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_ULLONG_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_FLOAT16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_FLOAT_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_DOUBLE_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_LDOUBLE_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_B8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_B16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_B32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_B64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_OPAQUE_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_HADDR_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_HSIZE_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_HSSIZE_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_HERR_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_HBOOL_g = H5I_INVALID_HID;
+
+hid_t H5T_NATIVE_INT8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_LEAST8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_LEAST8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_FAST8_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_FAST8_g = H5I_INVALID_HID;
+
+hid_t H5T_NATIVE_INT16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_LEAST16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_LEAST16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_FAST16_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_FAST16_g = H5I_INVALID_HID;
+
+hid_t H5T_NATIVE_INT32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_LEAST32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_LEAST32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_FAST32_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_FAST32_g = H5I_INVALID_HID;
+
+hid_t H5T_NATIVE_INT64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_LEAST64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_LEAST64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_INT_FAST64_g = H5I_INVALID_HID;
+hid_t H5T_NATIVE_UINT_FAST64_g = H5I_INVALID_HID;
/*
* Alignment constraints for HDF5 types. Accessing objects of these
@@ -1165,9 +1165,11 @@ H5T_init(void)
H5T__register_int(H5T_PERS_HARD, "flt_flt16", native_float, native_float16, H5T__conv_float__Float16);
status |= H5T__register_int(H5T_PERS_HARD, "dbl_flt16", native_double, native_float16,
H5T__conv_double__Float16);
+#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16
status |= H5T__register_int(H5T_PERS_HARD, "ldbl_flt16", native_ldouble, native_float16,
H5T__conv_ldouble__Float16);
#endif
+#endif
/* from long long */
status |=
@@ -1733,102 +1735,102 @@ H5T_top_term_package(void)
/* Reset all the datatype IDs */
if (H5T_IEEE_F32BE_g > 0) {
- H5T_IEEE_F16BE_g = FAIL;
- H5T_IEEE_F16LE_g = FAIL;
- H5T_IEEE_F32BE_g = FAIL;
- H5T_IEEE_F32LE_g = FAIL;
- H5T_IEEE_F64BE_g = FAIL;
- H5T_IEEE_F64LE_g = FAIL;
-
- H5T_STD_I8BE_g = FAIL;
- H5T_STD_I8LE_g = FAIL;
- H5T_STD_I16BE_g = FAIL;
- H5T_STD_I16LE_g = FAIL;
- H5T_STD_I32BE_g = FAIL;
- H5T_STD_I32LE_g = FAIL;
- H5T_STD_I64BE_g = FAIL;
- H5T_STD_I64LE_g = FAIL;
- H5T_STD_U8BE_g = FAIL;
- H5T_STD_U8LE_g = FAIL;
- H5T_STD_U16BE_g = FAIL;
- H5T_STD_U16LE_g = FAIL;
- H5T_STD_U32BE_g = FAIL;
- H5T_STD_U32LE_g = FAIL;
- H5T_STD_U64BE_g = FAIL;
- H5T_STD_U64LE_g = FAIL;
- H5T_STD_B8BE_g = FAIL;
- H5T_STD_B8LE_g = FAIL;
- H5T_STD_B16BE_g = FAIL;
- H5T_STD_B16LE_g = FAIL;
- H5T_STD_B32BE_g = FAIL;
- H5T_STD_B32LE_g = FAIL;
- H5T_STD_B64BE_g = FAIL;
- H5T_STD_B64LE_g = FAIL;
- H5T_STD_REF_OBJ_g = FAIL;
- H5T_STD_REF_DSETREG_g = FAIL;
- H5T_STD_REF_g = FAIL;
-
- H5T_UNIX_D32BE_g = FAIL;
- H5T_UNIX_D32LE_g = FAIL;
- H5T_UNIX_D64BE_g = FAIL;
- H5T_UNIX_D64LE_g = FAIL;
-
- H5T_C_S1_g = FAIL;
-
- H5T_FORTRAN_S1_g = FAIL;
-
- H5T_NATIVE_SCHAR_g = FAIL;
- H5T_NATIVE_UCHAR_g = FAIL;
- H5T_NATIVE_SHORT_g = FAIL;
- H5T_NATIVE_USHORT_g = FAIL;
- H5T_NATIVE_INT_g = FAIL;
- H5T_NATIVE_UINT_g = FAIL;
- H5T_NATIVE_LONG_g = FAIL;
- H5T_NATIVE_ULONG_g = FAIL;
- H5T_NATIVE_LLONG_g = FAIL;
- H5T_NATIVE_ULLONG_g = FAIL;
- H5T_NATIVE_FLOAT16_g = FAIL;
- H5T_NATIVE_FLOAT_g = FAIL;
- H5T_NATIVE_DOUBLE_g = FAIL;
- H5T_NATIVE_LDOUBLE_g = FAIL;
- H5T_NATIVE_B8_g = FAIL;
- H5T_NATIVE_B16_g = FAIL;
- H5T_NATIVE_B32_g = FAIL;
- H5T_NATIVE_B64_g = FAIL;
- H5T_NATIVE_OPAQUE_g = FAIL;
- H5T_NATIVE_HADDR_g = FAIL;
- H5T_NATIVE_HSIZE_g = FAIL;
- H5T_NATIVE_HSSIZE_g = FAIL;
- H5T_NATIVE_HERR_g = FAIL;
- H5T_NATIVE_HBOOL_g = FAIL;
-
- H5T_NATIVE_INT8_g = FAIL;
- H5T_NATIVE_UINT8_g = FAIL;
- H5T_NATIVE_INT_LEAST8_g = FAIL;
- H5T_NATIVE_UINT_LEAST8_g = FAIL;
- H5T_NATIVE_INT_FAST8_g = FAIL;
- H5T_NATIVE_UINT_FAST8_g = FAIL;
-
- H5T_NATIVE_INT16_g = FAIL;
- H5T_NATIVE_UINT16_g = FAIL;
- H5T_NATIVE_INT_LEAST16_g = FAIL;
- H5T_NATIVE_UINT_LEAST16_g = FAIL;
- H5T_NATIVE_INT_FAST16_g = FAIL;
- H5T_NATIVE_UINT_FAST16_g = FAIL;
-
- H5T_NATIVE_INT32_g = FAIL;
- H5T_NATIVE_UINT32_g = FAIL;
- H5T_NATIVE_INT_LEAST32_g = FAIL;
- H5T_NATIVE_UINT_LEAST32_g = FAIL;
- H5T_NATIVE_INT_FAST32_g = FAIL;
- H5T_NATIVE_UINT_FAST32_g = FAIL;
-
- H5T_NATIVE_INT64_g = FAIL;
- H5T_NATIVE_UINT64_g = FAIL;
- H5T_NATIVE_INT_LEAST64_g = FAIL;
- H5T_NATIVE_UINT_LEAST64_g = FAIL;
- H5T_NATIVE_INT_FAST64_g = FAIL;
- H5T_NATIVE_UINT_FAST64_g = FAIL;
+ H5T_IEEE_F16BE_g = H5I_INVALID_HID;
+ H5T_IEEE_F16LE_g = H5I_INVALID_HID;
+ H5T_IEEE_F32BE_g = H5I_INVALID_HID;
+ H5T_IEEE_F32LE_g = H5I_INVALID_HID;
+ H5T_IEEE_F64BE_g = H5I_INVALID_HID;
+ H5T_IEEE_F64LE_g = H5I_INVALID_HID;
+
+ H5T_STD_I8BE_g = H5I_INVALID_HID;
+ H5T_STD_I8LE_g = H5I_INVALID_HID;
+ H5T_STD_I16BE_g = H5I_INVALID_HID;
+ H5T_STD_I16LE_g = H5I_INVALID_HID;
+ H5T_STD_I32BE_g = H5I_INVALID_HID;
+ H5T_STD_I32LE_g = H5I_INVALID_HID;
+ H5T_STD_I64BE_g = H5I_INVALID_HID;
+ H5T_STD_I64LE_g = H5I_INVALID_HID;
+ H5T_STD_U8BE_g = H5I_INVALID_HID;
+ H5T_STD_U8LE_g = H5I_INVALID_HID;
+ H5T_STD_U16BE_g = H5I_INVALID_HID;
+ H5T_STD_U16LE_g = H5I_INVALID_HID;
+ H5T_STD_U32BE_g = H5I_INVALID_HID;
+ H5T_STD_U32LE_g = H5I_INVALID_HID;
+ H5T_STD_U64BE_g = H5I_INVALID_HID;
+ H5T_STD_U64LE_g = H5I_INVALID_HID;
+ H5T_STD_B8BE_g = H5I_INVALID_HID;
+ H5T_STD_B8LE_g = H5I_INVALID_HID;
+ H5T_STD_B16BE_g = H5I_INVALID_HID;
+ H5T_STD_B16LE_g = H5I_INVALID_HID;
+ H5T_STD_B32BE_g = H5I_INVALID_HID;
+ H5T_STD_B32LE_g = H5I_INVALID_HID;
+ H5T_STD_B64BE_g = H5I_INVALID_HID;
+ H5T_STD_B64LE_g = H5I_INVALID_HID;
+ H5T_STD_REF_OBJ_g = H5I_INVALID_HID;
+ H5T_STD_REF_DSETREG_g = H5I_INVALID_HID;
+ H5T_STD_REF_g = H5I_INVALID_HID;
+
+ H5T_UNIX_D32BE_g = H5I_INVALID_HID;
+ H5T_UNIX_D32LE_g = H5I_INVALID_HID;
+ H5T_UNIX_D64BE_g = H5I_INVALID_HID;
+ H5T_UNIX_D64LE_g = H5I_INVALID_HID;
+
+ H5T_C_S1_g = H5I_INVALID_HID;
+
+ H5T_FORTRAN_S1_g = H5I_INVALID_HID;
+
+ H5T_NATIVE_SCHAR_g = H5I_INVALID_HID;
+ H5T_NATIVE_UCHAR_g = H5I_INVALID_HID;
+ H5T_NATIVE_SHORT_g = H5I_INVALID_HID;
+ H5T_NATIVE_USHORT_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_g = H5I_INVALID_HID;
+ H5T_NATIVE_LONG_g = H5I_INVALID_HID;
+ H5T_NATIVE_ULONG_g = H5I_INVALID_HID;
+ H5T_NATIVE_LLONG_g = H5I_INVALID_HID;
+ H5T_NATIVE_ULLONG_g = H5I_INVALID_HID;
+ H5T_NATIVE_FLOAT16_g = H5I_INVALID_HID;
+ H5T_NATIVE_FLOAT_g = H5I_INVALID_HID;
+ H5T_NATIVE_DOUBLE_g = H5I_INVALID_HID;
+ H5T_NATIVE_LDOUBLE_g = H5I_INVALID_HID;
+ H5T_NATIVE_B8_g = H5I_INVALID_HID;
+ H5T_NATIVE_B16_g = H5I_INVALID_HID;
+ H5T_NATIVE_B32_g = H5I_INVALID_HID;
+ H5T_NATIVE_B64_g = H5I_INVALID_HID;
+ H5T_NATIVE_OPAQUE_g = H5I_INVALID_HID;
+ H5T_NATIVE_HADDR_g = H5I_INVALID_HID;
+ H5T_NATIVE_HSIZE_g = H5I_INVALID_HID;
+ H5T_NATIVE_HSSIZE_g = H5I_INVALID_HID;
+ H5T_NATIVE_HERR_g = H5I_INVALID_HID;
+ H5T_NATIVE_HBOOL_g = H5I_INVALID_HID;
+
+ H5T_NATIVE_INT8_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT8_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_LEAST8_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_LEAST8_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_FAST8_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_FAST8_g = H5I_INVALID_HID;
+
+ H5T_NATIVE_INT16_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT16_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_LEAST16_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_LEAST16_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_FAST16_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_FAST16_g = H5I_INVALID_HID;
+
+ H5T_NATIVE_INT32_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT32_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_LEAST32_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_LEAST32_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_FAST32_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_FAST32_g = H5I_INVALID_HID;
+
+ H5T_NATIVE_INT64_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT64_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_LEAST64_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_LEAST64_g = H5I_INVALID_HID;
+ H5T_NATIVE_INT_FAST64_g = H5I_INVALID_HID;
+ H5T_NATIVE_UINT_FAST64_g = H5I_INVALID_HID;
n++;
} /* end if */
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index d1cc307..a6629b5 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -8085,6 +8085,7 @@ H5T__conv_double__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t
H5_GCC_CLANG_DIAG_ON("pedantic")
}
+#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16
herr_t
H5T__conv_ldouble__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg)
@@ -8094,6 +8095,7 @@ H5T__conv_ldouble__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_
H5T_CONV_Ff(LDOUBLE, FLOAT16, long double, H5__Float16, -FLT16_MAX, FLT16_MAX);
H5_GCC_CLANG_DIAG_ON("pedantic")
}
+#endif
herr_t
H5T__conv__Float16_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride,
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 8f063b9..9cece45 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -143,6 +143,14 @@
#define H5T_CONV_INTERNAL_LDOUBLE_ULLONG 0
#endif
+/* Define an internal macro for converting long double to _Float16. Mac OS 13
+ * gives incorrect conversions that appear to be resolved in Mac OS 14. */
+#ifdef H5_HAVE__FLOAT16
+#if (H5_WANT_DATA_ACCURACY && defined(H5_LDOUBLE_TO_FLOAT16_CORRECT)) || (!H5_WANT_DATA_ACCURACY)
+#define H5T_CONV_INTERNAL_LDOUBLE_FLOAT16 1
+#endif
+#endif
+
/* Statistics about a conversion function */
struct H5T_stats_t {
unsigned ncalls; /*num calls to conversion function */
@@ -861,8 +869,10 @@ H5_DLL herr_t H5T__conv_float__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
H5_DLL herr_t H5T__conv_double__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+#ifdef H5T_CONV_INTERNAL_LDOUBLE_FLOAT16
H5_DLL herr_t H5T__conv_ldouble__Float16(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
+#endif
H5_DLL herr_t H5T__conv__Float16_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);
H5_DLL herr_t H5T__conv__Float16_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
diff --git a/test/dt_arith.c b/test/dt_arith.c
index 65dc240..173555f 100644
--- a/test/dt_arith.c
+++ b/test/dt_arith.c
@@ -2855,6 +2855,308 @@ my_isinf(int endian, const unsigned char *val, size_t size, size_t mpos, size_t
}
/*-------------------------------------------------------------------------
+ * Function: test_conv_flt_1_hw_conv_from_flt16
+ *
+ * Purpose: Helper function for test_conv_flt_1 to perform conversion
+ * from _Float16 to another type by casting. Also checks for
+ * overflow and underflow when the destination type is a type
+ * with a smaller width than _Float16.
+ *
+ * Return: -1 on failure
+ * 0 on success without overflow or underflow
+ * 1 on overflow
+ * 2 on underflow
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_HAVE__FLOAT16
+static int
+test_conv_flt_1_hw_conv_from_flt16(void *hw_dst, unsigned char *src_buf, size_t idx, dtype_t dst_type)
+{
+ H5__Float16 aligned;
+ int ret = 0;
+
+ memcpy(&aligned, src_buf + idx * sizeof(H5__Float16), sizeof(H5__Float16));
+
+ switch (dst_type) {
+ case FLT_FLOAT16:
+ *((H5__Float16 *)hw_dst) = aligned;
+ break;
+ case FLT_FLOAT:
+ *((float *)hw_dst) = (float)aligned;
+ break;
+ case FLT_DOUBLE:
+ *((double *)hw_dst) = (double)aligned;
+ break;
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ case FLT_LDOUBLE:
+ *((long double *)hw_dst) = (long double)aligned;
+ break;
+#endif
+ case INT_SCHAR:
+ case INT_UCHAR:
+ case INT_SHORT:
+ case INT_USHORT:
+ case INT_INT:
+ case INT_UINT:
+ case INT_LONG:
+ case INT_ULONG:
+ case INT_LLONG:
+ case INT_ULLONG:
+ case OTHER:
+ default:
+ H5_FAILED();
+ printf("invalid destination conversion datatype");
+ ret = -1;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+#endif
+
+/*-------------------------------------------------------------------------
+ * Function: test_conv_flt_1_hw_conv_from_flt
+ *
+ * Purpose: Helper function for test_conv_flt_1 to perform conversion
+ * from float to another type by casting. Also checks for
+ * overflow and underflow when the destination type is a
+ * type with a smaller width than float.
+ *
+ * Return: -1 on failure
+ * 0 on success without overflow or underflow
+ * 1 on overflow
+ * 2 on underflow
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_conv_flt_1_hw_conv_from_flt(void *hw_dst, unsigned char *src_buf, size_t idx, dtype_t dst_type)
+{
+ float aligned;
+ int ret = 0;
+
+ memcpy(&aligned, src_buf + idx * sizeof(float), sizeof(float));
+
+ switch (dst_type) {
+#ifdef H5_HAVE__FLOAT16
+ case FLT_FLOAT16:
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+
+ *((H5__Float16 *)hw_dst) = (H5__Float16)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabsf(aligned) > (float)FLT16_MAX)
+ ret = 1;
+ else if (fabsf(aligned) < (float)FLT16_MIN)
+ ret = 2;
+
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+ break;
+#endif
+ case FLT_FLOAT:
+ *((float *)hw_dst) = aligned;
+ break;
+ case FLT_DOUBLE:
+ *((double *)hw_dst) = (double)aligned;
+ break;
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ case FLT_LDOUBLE:
+ *((long double *)hw_dst) = (long double)aligned;
+ break;
+#endif
+ case INT_SCHAR:
+ case INT_UCHAR:
+ case INT_SHORT:
+ case INT_USHORT:
+ case INT_INT:
+ case INT_UINT:
+ case INT_LONG:
+ case INT_ULONG:
+ case INT_LLONG:
+ case INT_ULLONG:
+ case OTHER:
+ default:
+ H5_FAILED();
+ printf("invalid destination conversion datatype");
+ ret = -1;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: test_conv_flt_1_hw_conv_from_double
+ *
+ * Purpose: Helper function for test_conv_flt_1 to perform conversion
+ * from double to another type by casting. Also checks for
+ * overflow and underflow when the destination type is a
+ * type with a smaller width than double.
+ *
+ * Return: -1 on failure
+ * 0 on success without overflow or underflow
+ * 1 on overflow
+ * 2 on underflow
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_conv_flt_1_hw_conv_from_double(void *hw_dst, unsigned char *src_buf, size_t idx, dtype_t dst_type)
+{
+ double aligned;
+ int ret = 0;
+
+ memcpy(&aligned, src_buf + idx * sizeof(double), sizeof(double));
+
+ switch (dst_type) {
+#ifdef H5_HAVE__FLOAT16
+ case FLT_FLOAT16:
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+
+ *((H5__Float16 *)hw_dst) = (H5__Float16)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabs(aligned) > (double)FLT16_MAX)
+ ret = 1;
+ else if (fabs(aligned) < (double)FLT16_MIN)
+ ret = 2;
+
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+ break;
+#endif
+ case FLT_FLOAT:
+ *((float *)hw_dst) = (float)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabs(aligned) > (double)FLT_MAX)
+ ret = 1;
+ else if (fabs(aligned) < (double)FLT_MIN)
+ ret = 2;
+
+ break;
+ case FLT_DOUBLE:
+ *((double *)hw_dst) = aligned;
+ break;
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ case FLT_LDOUBLE:
+ *((long double *)hw_dst) = (long double)aligned;
+ break;
+#endif
+ case INT_SCHAR:
+ case INT_UCHAR:
+ case INT_SHORT:
+ case INT_USHORT:
+ case INT_INT:
+ case INT_UINT:
+ case INT_LONG:
+ case INT_ULONG:
+ case INT_LLONG:
+ case INT_ULLONG:
+ case OTHER:
+ default:
+ H5_FAILED();
+ printf("invalid destination conversion datatype");
+ ret = -1;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: test_conv_flt_1_hw_conv_from_ldouble
+ *
+ * Purpose: Helper function for test_conv_flt_1 to perform conversion
+ * from long double to another type by casting. Also checks
+ * for overflow and underflow when the destination type is a
+ * type with a smaller width than long double.
+ *
+ * Return: -1 on failure
+ * 0 on success without overflow or underflow
+ * 1 on overflow
+ * 2 on underflow
+ *
+ *-------------------------------------------------------------------------
+ */
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+static int
+test_conv_flt_1_hw_conv_from_ldouble(void *hw_dst, unsigned char *src_buf, size_t idx, dtype_t dst_type)
+{
+ long double aligned;
+ int ret = 0;
+
+ memcpy(&aligned, src_buf + idx * sizeof(long double), sizeof(long double));
+
+ switch (dst_type) {
+#ifdef H5_HAVE__FLOAT16
+ case FLT_FLOAT16:
+ /* Suppress warning about non-standard floating-point literal suffix */
+ H5_GCC_CLANG_DIAG_OFF("pedantic")
+
+ *((H5__Float16 *)hw_dst) = (H5__Float16)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabsl(aligned) > (long double)FLT16_MAX)
+ ret = 1;
+ else if (fabsl(aligned) < (long double)FLT16_MIN)
+ ret = 2;
+
+ H5_GCC_CLANG_DIAG_ON("pedantic")
+ break;
+#endif
+ case FLT_FLOAT:
+ *((float *)hw_dst) = (float)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabsl(aligned) > (long double)FLT_MAX)
+ ret = 1;
+ else if (fabsl(aligned) < (long double)FLT_MIN)
+ ret = 2;
+
+ break;
+ case FLT_DOUBLE:
+ *((double *)hw_dst) = (double)aligned;
+
+ /* Check for overflow and underflow */
+ if (fabsl(aligned) > (long double)DBL_MAX)
+ ret = 1;
+ else if (fabsl(aligned) < (long double)DBL_MIN)
+ ret = 2;
+
+ break;
+ case FLT_LDOUBLE:
+ *((long double *)hw_dst) = aligned;
+ break;
+ case INT_SCHAR:
+ case INT_UCHAR:
+ case INT_SHORT:
+ case INT_USHORT:
+ case INT_INT:
+ case INT_UINT:
+ case INT_LONG:
+ case INT_ULONG:
+ case INT_LLONG:
+ case INT_ULLONG:
+ case OTHER:
+ default:
+ H5_FAILED();
+ printf("invalid destination conversion datatype");
+ ret = -1;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+#endif
+
+/*-------------------------------------------------------------------------
* Function: test_conv_flt_1
*
* Purpose: Test conversion of floating point values from SRC to
@@ -2882,8 +3184,9 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst)
unsigned char *saved = NULL; /*original values */
char str[256]; /*hello string */
void *aligned = NULL; /*aligned buffer */
- float hw_f; /*hardware-converted */
- double hw_d; /*hardware-converted */
+ void *hw_p = NULL;
+ float hw_f; /*hardware-converted */
+ double hw_d; /*hardware-converted */
#ifdef H5_HAVE__FLOAT16
H5__Float16 hw_half;
#endif
@@ -3156,11 +3459,31 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst)
if (H5Tconvert(src, dst, nelmts, buf, NULL, H5P_DEFAULT) < 0)
goto error;
+ /* Set pointer to matching type for hardware conversion */
+ if (FLT_FLOAT == dst_type)
+ hw_p = &hw_f;
+ else if (FLT_DOUBLE == dst_type)
+ hw_p = &hw_d;
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ else if (FLT_LDOUBLE == dst_type)
+ hw_p = &hw_ld;
+#endif
+#ifdef H5_HAVE__FLOAT16
+ else if (FLT_FLOAT16 == dst_type)
+ hw_p = &hw_half;
+#endif
+ else
+ goto error;
+
+ /* Set convenience pointer for indexing into bytes of matching type */
+ hw = (unsigned char *)hw_p;
+
/* Check the software results against the hardware */
for (j = 0; j < nelmts; j++) {
- underflow = 0;
- hw_f = 911.0F;
- hw_d = 911.0;
+ int conv_ret = -1;
+
+ hw_f = 911.0F;
+ hw_d = 911.0;
#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
hw_ld = 911.0L;
#endif
@@ -3169,142 +3492,30 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst)
#endif
/* The hardware conversion */
- /* Check for underflow when src is a "larger" float than dst.*/
- if (FLT_FLOAT == src_type) {
- memcpy(aligned, saved + j * sizeof(float), sizeof(float));
- if (FLT_FLOAT == dst_type) {
- hw_f = *((float *)aligned);
- hw = (unsigned char *)&hw_f;
- }
- else if (FLT_DOUBLE == dst_type) {
- hw_d = (double)*((float *)aligned);
- hw = (unsigned char *)&hw_d;
-#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
- }
- else if (FLT_LDOUBLE == dst_type) {
- hw_ld = (long double)*((float *)aligned);
- hw = (unsigned char *)&hw_ld;
-#endif
- }
- else if (FLT_FLOAT16 == dst_type) {
#ifdef H5_HAVE__FLOAT16
- hw_half = (H5__Float16) * ((float *)aligned);
- hw = (unsigned char *)&hw_half;
-
- /* Suppress warning about non-standard floating-point literal suffix */
- H5_GCC_CLANG_DIAG_OFF("pedantic")
- underflow = fabsf(*((float *)aligned)) < (float)FLT16_MIN;
- overflow = fabsf(*((float *)aligned)) > (float)FLT16_MAX;
- H5_GCC_CLANG_DIAG_ON("pedantic")
-#else
- assert(0 && "Should not reach this point!");
+ if (FLT_FLOAT16 == src_type) {
+ conv_ret = test_conv_flt_1_hw_conv_from_flt16(hw_p, saved, j, dst_type);
+ }
+ else
#endif
- }
- else
- goto error;
+ if (FLT_FLOAT == src_type) {
+ conv_ret = test_conv_flt_1_hw_conv_from_flt(hw_p, saved, j, dst_type);
}
else if (FLT_DOUBLE == src_type) {
- memcpy(aligned, saved + j * sizeof(double), sizeof(double));
- if (FLT_FLOAT == dst_type) {
- hw_f = (float)(*((double *)aligned));
- hw = (unsigned char *)&hw_f;
- underflow = fabs(*((double *)aligned)) < (double)FLT_MIN;
- overflow = fabs(*((double *)aligned)) > (double)FLT_MAX;
- }
- else if (FLT_DOUBLE == dst_type) {
- hw_d = *((double *)aligned);
- hw = (unsigned char *)&hw_d;
-#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
- }
- else if (FLT_LDOUBLE == dst_type) {
- hw_ld = (long double)*((double *)aligned);
- hw = (unsigned char *)&hw_ld;
-#endif
- }
- else if (FLT_FLOAT16 == dst_type) {
-#ifdef H5_HAVE__FLOAT16
- hw_half = (H5__Float16) * ((double *)aligned);
- hw = (unsigned char *)&hw_half;
-
- /* Suppress warning about non-standard floating-point literal suffix */
- H5_GCC_CLANG_DIAG_OFF("pedantic")
- underflow = fabs(*((double *)aligned)) < (double)FLT16_MIN;
- overflow = fabs(*((double *)aligned)) > (double)FLT16_MAX;
- H5_GCC_CLANG_DIAG_ON("pedantic")
-#else
- assert(0 && "Should not reach this point!");
-#endif
- }
- else
- goto error;
-#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
+ conv_ret = test_conv_flt_1_hw_conv_from_double(hw_p, saved, j, dst_type);
}
+#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
else if (FLT_LDOUBLE == src_type) {
- memcpy(aligned, saved + j * sizeof(long double), sizeof(long double));
- if (FLT_FLOAT == dst_type) {
- hw_f = (float)*((long double *)aligned);
- hw = (unsigned char *)&hw_f;
- underflow = fabsl(*((long double *)aligned)) < (long double)FLT_MIN;
- overflow = fabsl(*((long double *)aligned)) > (long double)FLT_MAX;
- }
- else if (FLT_DOUBLE == dst_type) {
- hw_d = (double)*((long double *)aligned);
- hw = (unsigned char *)&hw_d;
- underflow = fabsl(*((long double *)aligned)) < (long double)DBL_MIN;
- overflow = fabsl(*((long double *)aligned)) > (long double)DBL_MAX;
- }
- else if (FLT_LDOUBLE == dst_type) {
- hw_ld = *((long double *)aligned);
- hw = (unsigned char *)&hw_ld;
- }
- else if (FLT_FLOAT16 == dst_type) {
-#ifdef H5_HAVE__FLOAT16
- hw_half = (H5__Float16) * ((long double *)aligned);
- hw = (unsigned char *)&hw_half;
-
- /* Suppress warning about non-standard floating-point literal suffix */
- H5_GCC_CLANG_DIAG_OFF("pedantic")
- underflow = fabsl(*((long double *)aligned)) < (long double)FLT16_MIN;
- overflow = fabsl(*((long double *)aligned)) > (long double)FLT16_MAX;
- H5_GCC_CLANG_DIAG_ON("pedantic")
-#else
- assert(0 && "Should not reach this point!");
-#endif
- }
- else
- goto error;
-#endif
+ conv_ret = test_conv_flt_1_hw_conv_from_ldouble(hw_p, saved, j, dst_type);
}
- else if (FLT_FLOAT16 == src_type) {
-#ifdef H5_HAVE__FLOAT16
- memcpy(aligned, saved + j * sizeof(H5__Float16), sizeof(H5__Float16));
- if (FLT_FLOAT == dst_type) {
- hw_f = (float)*((H5__Float16 *)aligned);
- hw = (unsigned char *)&hw_f;
- }
- else if (FLT_DOUBLE == dst_type) {
- hw_d = (double)*((H5__Float16 *)aligned);
- hw = (unsigned char *)&hw_d;
-#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
- }
- else if (FLT_LDOUBLE == dst_type) {
- hw_ld = (long double)*((H5__Float16 *)aligned);
- hw = (unsigned char *)&hw_ld;
-#endif
- }
- else if (FLT_FLOAT16 == dst_type) {
- hw_half = *((H5__Float16 *)aligned);
- hw = (unsigned char *)&hw_half;
- }
- else
- goto error;
-#else
- assert(0 && "Should not reach this point!");
#endif
- }
- else
+
+ if (conv_ret < 0)
goto error;
+ overflow = (conv_ret == 1);
+ underflow = (conv_ret == 2);
+
/* For Intel machines, the size of "long double" is 12 bytes, precision
* is 80 bits; for Intel IA64 and AMD processors, the size of "long double"
* is 16 bytes, precision is 80 bits. During hardware conversion, the
@@ -5324,7 +5535,19 @@ run_fp_tests(const char *name)
nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT16);
#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_FLOAT16, H5T_NATIVE_LDOUBLE);
+#ifdef H5_LDOUBLE_TO_FLOAT16_CORRECT
nerrors += test_conv_flt_1(name, TEST_NORMAL, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT16);
+#else
+ {
+ char str[256];
+
+ snprintf(str, sizeof(str), "Testing %s normalized %s -> %s conversions", name, "long double",
+ "_Float16");
+ printf("%-70s", str);
+ SKIPPED();
+ puts(" Test skipped due to compiler error in handling conversion.");
+ }
+#endif
#endif
#endif
@@ -5357,7 +5580,19 @@ run_fp_tests(const char *name)
nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT16);
#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_FLOAT16, H5T_NATIVE_LDOUBLE);
+#ifdef H5_LDOUBLE_TO_FLOAT16_CORRECT
nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT16);
+#else
+ {
+ char str[256];
+
+ snprintf(str, sizeof(str), "Testing %s denormalized %s -> %s conversions", name, "long double",
+ "_Float16");
+ printf("%-70s", str);
+ SKIPPED();
+ puts(" Test skipped due to compiler error in handling conversion.");
+ }
+#endif
#endif
#endif
@@ -5389,7 +5624,19 @@ run_fp_tests(const char *name)
nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT16);
#if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_FLOAT16, H5T_NATIVE_LDOUBLE);
+#ifdef H5_LDOUBLE_TO_FLOAT16_CORRECT
nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT16);
+#else
+ {
+ char str[256];
+
+ snprintf(str, sizeof(str), "Testing %s special %s -> %s conversions", name, "long double",
+ "_Float16");
+ printf("%-70s", str);
+ SKIPPED();
+ puts(" Test skipped due to compiler error in handling conversion.");
+ }
+#endif
#endif
#endif