Skip to content

Commit

Permalink
Work around issues with MacOS 13
Browse files Browse the repository at this point in the history
Add CMake status message about _Float16 test-compile program
  • Loading branch information
jhendersonHDF committed Mar 2, 2024
1 parent a209e23 commit 10c1c55
Show file tree
Hide file tree
Showing 9 changed files with 722 additions and 387 deletions.
1 change: 0 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,3 @@ jobs:
name: "CMake Workflows"
uses: ./.github/workflows/cmake.yml
if: "!contains(github.event.head_commit.message, 'skip-ci')"

124 changes: 71 additions & 53 deletions config/cmake/ConfigureChecks.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -362,56 +362,6 @@ if (NOT ${HDF_PREFIX}_SIZEOF_OFF64_T)
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
#-----------------------------------------------------------------------------
Expand Down Expand Up @@ -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")
Expand All @@ -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 ()
Expand Down Expand Up @@ -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 ()
29 changes: 29 additions & 0 deletions config/cmake/ConversionTests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions config/cmake/H5pubconf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@
Expand Down
39 changes: 32 additions & 7 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 10c1c55

Please sign in to comment.