diff options
-rw-r--r-- | .github/workflows/main.yml | 1 | ||||
-rw-r--r-- | config/cmake/ConfigureChecks.cmake | 45 | ||||
-rw-r--r-- | config/cmake/ConversionTests.c | 93 | ||||
-rw-r--r-- | config/cmake/HDFTests.c | 33 | ||||
-rw-r--r-- | configure.ac | 57 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 39 |
6 files changed, 171 insertions, 97 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7a0eb69..3f878b1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,3 +36,4 @@ 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 c088926..7c2475a 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -978,6 +978,8 @@ H5ConversionTests (${HDF_PREFIX}_DISABLE_SOME_LDOUBLE_CONV FALSE "Checking IF th #----------------------------------------------------------------------------- # 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 @@ -985,8 +987,7 @@ if (${HDF_PREFIX}_SIZEOF__FLOAT16) # 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. + # 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) @@ -997,21 +998,24 @@ if (${HDF_PREFIX}_SIZEOF__FLOAT16) 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 + # 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 (${h5_compiled_float16_test}) + 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, @@ -1025,16 +1029,21 @@ if (${HDF_PREFIX}_SIZEOF__FLOAT16) "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 "Failed to compile test program to check for _Float16 support") + 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 () - set (${HDF_PREFIX}_HAVE__FLOAT16 0) + message (STATUS "_Float16 support has been disabled since the required macros (FLT16_MAX, FLT16_EPSILON, etc. were not found)") endif () else () - set (${HDF_PREFIX}_HAVE__FLOAT16 0) + 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 5a3e016..8e103bd 100644 --- a/config/cmake/ConversionTests.c +++ b/config/cmake/ConversionTests.c @@ -286,6 +286,99 @@ int HDF_NO_UBSAN main(void) #endif +#ifdef H5_FLOAT16_CONVERSION_FUNCS_LINK_TEST + +#define __STDC_WANT_IEC_60559_TYPES_EXT__ + +#include <stdlib.h> +#include <float.h> + +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__ diff --git a/config/cmake/HDFTests.c b/config/cmake/HDFTests.c index fd0beb2..095f113 100644 --- a/config/cmake/HDFTests.c +++ b/config/cmake/HDFTests.c @@ -192,36 +192,3 @@ int main () } #endif /* HAVE_IOEO */ - -#ifdef CHECK_FLOAT16 - -#define __STDC_WANT_IEC_60559_TYPES_EXT__ -#include <float.h> - -int -main(int argc, char **argv) -{ - signed char a; - _Float16 b; - double c; - - /* Convert signed char to _Float16 */ - a = 1; - b = (_Float16)a; - - /* Convert back */ - b = 3.0f16; - a = (signed char)b; - - /* Convert double to _Float16 */ - c = 5.0; - b = (_Float16)c; - - /* Convert back */ - b = 3.0f16; - c = (double)b; - - return 0; -} - -#endif /* CHECK_FLOAT16 */ diff --git a/configure.ac b/configure.ac index 7d67f2d..6c83932 100644 --- a/configure.ac +++ b/configure.ac @@ -549,13 +549,13 @@ 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. The main function we're interested in - # is fabsf16. Check for these here. + # datatype conversion support. Check for these here. AC_CHECK_DECL([FLT16_EPSILON], [], [], [[ #define __STDC_WANT_IEC_60559_TYPES_EXT__ #include <float.h>]]) @@ -581,37 +581,25 @@ 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 - # 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( - [AC_LANG_PROGRAM([ - #define __STDC_WANT_IEC_60559_TYPES_EXT__ - #include <float.h> - ],[ - signed char a; - _Float16 b; - double c; - /* Convert signed char to _Float16 */ - a = 1; - b = (_Float16)a; - /* Convert back */ - b = 3.0f16; - a = (signed char)b; - /* Convert double to _Float16 */ - c = 5.0; - b = (_Float16)c; - /* Convert back */ - b = 3.0f16; - c = (double)b; - ])] - , [hdf5_cv_float16_prog_compiled=yes], [hdf5_cv_float16_prog_compiled=no], [hdf5_cv_float16_prog_compiled=no])]) - - if test ${hdf5_cv_float16_prog_compiled} = "yes" ; 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 @@ -638,6 +626,7 @@ if test "$ac_cv_sizeof__Float16" != 0; then 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" @@ -653,7 +642,7 @@ if test "$ac_cv_sizeof__Float16" != 0; then fi fi - AC_MSG_CHECKING([if _Float16 support is available]) + AC_MSG_CHECKING([if _Float16 support is enabled]) AC_MSG_RESULT([$HAVE__FLOAT16]) fi diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 035894b..f050953 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -288,14 +288,17 @@ New Features -------- - Added support for _Float16 16-bit half-precision floating-point datatype - Native support for the _Float16 C datatype has been added on platforms - where: + Support for the _Float16 C datatype has been added on platforms where: - The _Float16 datatype and its associated macros (FLT16_MIN, FLT16_MAX, FLT16_EPSILON, etc.) are available - - A simple test program using the _Float16 datatype can be successfully - compiled at configuration time (some compilers are buggy with - respect to the _Float16 datatype) + - A simple test program that converts between the _Float16 datatype and + other datatypes with casts can be successfully compiled and run at + configure time. Some compilers appear to be buggy or feature-incomplete + in this regard and will generate calls to compiler-internal functions + for converting between the _Float16 datatype and other datatypes, but + will not link these functions into the build, resulting in build + failures. The following new macros have been added: @@ -318,16 +321,20 @@ New Features _Float16. Some compilers have issues with this. + H5T_NATIVE_FLOAT16 - This macro maps to the ID of an HDF5 datatype representing + the native C _Float16 datatype for the platform. If + support for the _Float16 datatype is not available, the + macro will map to H5I_INVALID_HID and should not be used. + H5T_IEEE_F16BE - This macro maps to the ID of an HDF5 datatype representing - a big-endian IEEE 754 16-bit floating-point datatype. + a big-endian IEEE 754 16-bit floating-point datatype. This + datatype is available regardless of whether _Float16 support + is available or not. H5T_IEEE_F16LE - This macro maps to the ID of an HDF5 datatype representing a little-endian IEEE 754 16-bit floating-point datatype. - - H5T_NATIVE_FLOAT16 - This macro maps to an HDF5 datatype representing the - native C _Float16 datatype for the platform. If support - for the _Float16 datatype is not available, the macro - will map to H5I_INVALID_HID and should not be used. + This datatype is available regardless of whether _Float16 + support is available or not. The following new hard datatype conversion paths have been added, but will only be used when _Float16 support is available: @@ -341,7 +348,15 @@ New Features H5T_NATIVE_LDOUBLE <-> H5T_NATIVE_FLOAT16 The H5T_NATIVE_LDOUBLE -> H5T_NATIVE_FLOAT16 hard conversion path will only - be available and used if H5_LDOUBLE_TO_FLOAT16_CORRECT has a value of 1 + be available and used if H5_LDOUBLE_TO_FLOAT16_CORRECT has a value of 1. Otherwise, + the conversion will be emulated in software by the library. + + Note that in the absence of any compiler flags for architecture-specific + tuning, the generated code for datatype conversions with the _Float16 type + may perform conversions by first promoting the type to float. Use of + architecture-specific tuning compiler flags may instead allow for the + generation of specialized instructions, such as AVX512-FP16 instructions, + if available. - Implemented optimized support for vector I/O in the Subfiling VFD |