From b0c346caa201cdc5bf40a314910ac33c75ba8951 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Thu, 24 Feb 2005 17:54:05 -0500 Subject: [svn-r10081] Purpose: Some Kind of Verification Description: The library didn't handle incorrect hardware conversion for datatype. It simply did convert to incorrect data if any hardware didn't handle correctly. Solution: During configuration, incorrect hardware conversion is detected and some macros are defined. Use these macros to decide whether to register hardware conversion in H5T.c. If no hardware conversion function is registered for certain pair of datatypes, software conversion function will be used as the conversion path. Although slower than hardware conversion, we're more confident software conversion is accurate. So in one sentence to describe library's behavior, if some hardware conversion doesn't work well, software conversion will be used instead. Platforms tested: h5committest and fuss. Misc. update: some changes to configure's comments. --- configure.in | 6 +++--- src/H5T.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- src/H5config.h.in | 2 +- test/dsets.c | 1 + test/dtypes.c | 8 ++++---- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index ce8be8a..6b09d21 100644 --- a/configure.in +++ b/configure.in @@ -2618,7 +2618,7 @@ fi if test ${hdf5_cv_sw_ulong_to_fp_bottom_bit_works} = "yes"; then AC_DEFINE([SW_ULONG_TO_FP_BOTTOM_BIT_WORKS], [1], - [Define if your system can accurately convert unsigned long long values to floating-point values.]) + [Define if your system can accurately convert unsigned (long) long values to floating-point values.]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -2626,7 +2626,7 @@ fi dnl ---------------------------------------------------------------------- dnl Set the flag to indicate that the machine can accurately convert -dnl 'float' or 'double' to 'unsigned (long) long' values. +dnl 'float' or 'double' to 'unsigned long long' values. dnl (This flag should be set for all machines, except for PGI compiler dnl where round-up happens when the fraction of float-point value is greater dnl than 0.5. @@ -2663,7 +2663,7 @@ fi dnl ---------------------------------------------------------------------- dnl Set the flag to indicate that the machine can accurately convert -dnl 'float', 'double' or 'long double' to 'unsigned (long) long' values. +dnl 'float', 'double' or 'long double' to 'unsigned long long' values. dnl (This flag should be set for all machines, except for HP-UX machines dnl where the maximal number for unsigned long long is 0x7fffffffffffffff dnl during conversion. diff --git a/src/H5T.c b/src/H5T.c index c848eb0..5913d95 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -993,8 +993,10 @@ H5T_init_interface(void) */ /* floating point */ +#if H5_CONVERT_DENORMAL_FLOAT status |= H5T_register(H5T_PERS_HARD, "flt_dbl", native_float, native_double, H5T_conv_float_double, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_flt", native_double, native_float, H5T_conv_double_float, H5AC_dxpl_id); +#endif /*H5_CONVERT_DENORMAL_FLOAT*/ /* from long_long */ status |= H5T_register(H5T_PERS_HARD, "llong_ullong", native_llong, native_ullong, H5T_conv_llong_ullong, H5AC_dxpl_id); @@ -1099,104 +1101,149 @@ H5T_init_interface(void) /* From char to floats */ status |= H5T_register(H5T_PERS_HARD, "schar_flt", native_schar, native_float, H5T_conv_schar_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "schar_dbl", native_schar, native_double, H5T_conv_schar_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "schar_ldbl", native_schar, native_ldouble, H5T_conv_schar_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From unsigned char to floats */ status |= H5T_register(H5T_PERS_HARD, "uchar_flt", native_uchar, native_float, H5T_conv_uchar_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "uchar_dbl", native_uchar, native_double, H5T_conv_uchar_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "uchar_ldbl", native_uchar, native_ldouble, H5T_conv_uchar_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From short to floats */ status |= H5T_register(H5T_PERS_HARD, "short_flt", native_short, native_float, H5T_conv_short_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "short_dbl", native_short, native_double, H5T_conv_short_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "short_ldbl", native_short, native_ldouble, H5T_conv_short_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From unsigned short to floats */ status |= H5T_register(H5T_PERS_HARD, "ushort_flt", native_ushort, native_float, H5T_conv_ushort_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "ushort_dbl", native_ushort, native_double, H5T_conv_ushort_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "ushort_ldbl", native_ushort, native_ldouble, H5T_conv_ushort_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From int to floats */ status |= H5T_register(H5T_PERS_HARD, "int_flt", native_int, native_float, H5T_conv_int_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "int_dbl", native_int, native_double, H5T_conv_int_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "int_ldbl", native_int, native_ldouble, H5T_conv_int_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From unsigned int to floats */ status |= H5T_register(H5T_PERS_HARD, "uint_flt", native_uint, native_float, H5T_conv_uint_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "uint_dbl", native_uint, native_double, H5T_conv_uint_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "uint_ldbl", native_uint, native_ldouble, H5T_conv_uint_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From long to floats */ status |= H5T_register(H5T_PERS_HARD, "long_flt", native_long, native_float, H5T_conv_long_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "long_dbl", native_long, native_double, H5T_conv_long_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "long_ldbl", native_long, native_ldouble, H5T_conv_long_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From unsigned long to floats */ +#if H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS status |= H5T_register(H5T_PERS_HARD, "ulong_flt", native_ulong, native_float, H5T_conv_ulong_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "ulong_dbl", native_ulong, native_double, H5T_conv_ulong_double, H5AC_dxpl_id); +#endif /*H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS*/ +#if H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS && H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "ulong_ldbl", native_ulong, native_ldouble, H5T_conv_ulong_ldouble, H5AC_dxpl_id); +#endif /* H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS && H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ /* From long long to floats */ status |= H5T_register(H5T_PERS_HARD, "llong_flt", native_llong, native_float, H5T_conv_llong_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "llong_dbl", native_llong, native_double, H5T_conv_llong_double, H5AC_dxpl_id); +#if H5_SW_INTEGER_TO_LDOUBLE_WORKS status |= H5T_register(H5T_PERS_HARD, "llong_ldbl", native_llong, native_ldouble, H5T_conv_llong_ldouble, H5AC_dxpl_id); +#endif /*H5_SW_INTEGER_TO_LDOUBLE_WORKS*/ -#ifdef H5_ULLONG_TO_FP_CAST_WORKS /* From unsigned long long to floats */ +#if H5_ULLONG_TO_FP_CAST_WORKS && H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS status |= H5T_register(H5T_PERS_HARD, "ullong_flt", native_ullong, native_float, H5T_conv_ullong_float, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "ullong_dbl", native_ullong, native_double, H5T_conv_ullong_double, H5AC_dxpl_id); +#endif /*H5_ULLONG_TO_FP_CAST_WORKS && H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS*/ +#if H5_ULLONG_TO_FP_CAST_WORKS && H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS && H5_SW_INTEGER_TO_LDOUBLE_WORKS && H5_ULLONG_TO_LDOUBLE_PRECISION_WORKS status |= H5T_register(H5T_PERS_HARD, "ullong_ldbl", native_ullong, native_ldouble, H5T_conv_ullong_ldouble, H5AC_dxpl_id); -#endif /* H5_ULLONG_TO_FP_CAST_WORKS */ +#endif /*H5_ULLONG_TO_FP_CAST_WORKS && H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS && H5_SW_INTEGER_TO_LDOUBLE_WORKS && H5_ULLONG_TO_LDOUBLE_PRECISION_WORKS*/ /* From floats to char */ status |= H5T_register(H5T_PERS_HARD, "flt_schar", native_float, native_schar, H5T_conv_float_schar, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_schar", native_double, native_schar, H5T_conv_double_schar, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_schar", native_ldouble, native_schar, H5T_conv_ldouble_schar, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to unsigned char */ status |= H5T_register(H5T_PERS_HARD, "flt_uchar", native_float, native_uchar, H5T_conv_float_uchar, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_uchar", native_double, native_uchar, H5T_conv_double_uchar, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_uchar", native_ldouble, native_uchar, H5T_conv_ldouble_uchar, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to short */ status |= H5T_register(H5T_PERS_HARD, "flt_short", native_float, native_short, H5T_conv_float_short, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_short", native_double, native_short, H5T_conv_double_short, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_short", native_ldouble, native_short, H5T_conv_ldouble_short, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to unsigned short */ status |= H5T_register(H5T_PERS_HARD, "flt_ushort", native_float, native_ushort, H5T_conv_float_ushort, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_ushort", native_double, native_ushort, H5T_conv_double_ushort, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_ushort", native_ldouble, native_ushort, H5T_conv_ldouble_ushort, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to int */ status |= H5T_register(H5T_PERS_HARD, "flt_int", native_float, native_int, H5T_conv_float_int, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_int", native_double, native_int, H5T_conv_double_int, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_int", native_ldouble, native_int, H5T_conv_ldouble_int, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to unsigned int */ status |= H5T_register(H5T_PERS_HARD, "flt_uint", native_float, native_uint, H5T_conv_float_uint, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_uint", native_double, native_uint, H5T_conv_double_uint, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS && H5_CV_LDOUBLE_TO_UINT_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_uint", native_ldouble, native_uint, H5T_conv_ldouble_uint, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS && H5_CV_LDOUBLE_TO_UINT_WORKS*/ - /* From floats to long */ status |= H5T_register(H5T_PERS_HARD, "flt_long", native_float, native_long, H5T_conv_float_long, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_long", native_double, native_long, H5T_conv_double_long, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_long", native_ldouble, native_long, H5T_conv_ldouble_long, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to unsigned long */ status |= H5T_register(H5T_PERS_HARD, "flt_ulong", native_float, native_ulong, H5T_conv_float_ulong, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_ulong", native_double, native_ulong, H5T_conv_double_ulong, H5AC_dxpl_id); +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_ulong", native_ldouble, native_ulong, H5T_conv_ldouble_ulong, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ /* From floats to long long */ +#ifndef H5_HW_FP_TO_LLONG_NOT_WORKS status |= H5T_register(H5T_PERS_HARD, "flt_llong", native_float, native_llong, H5T_conv_float_llong, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_llong", native_double, native_llong, H5T_conv_double_llong, H5AC_dxpl_id); +#endif /*H5_HW_FP_TO_LLONG_NOT_WORKS*/ +#if H5_SW_LDOUBLE_TO_INTEGER_WORKS && !H5_HW_FP_TO_LLONG_NOT_WORKS status |= H5T_register(H5T_PERS_HARD, "ldbl_llong", native_ldouble, native_llong, H5T_conv_ldouble_llong, H5AC_dxpl_id); +#endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS && !H5_HW_FP_TO_LLONG_NOT_WORKS*/ /* From floats to unsigned long long */ +#if H5_FP_TO_ULLONG_BOTTOM_BIT_WORKS && H5_FP_TO_ULLONG_RIGHT_MAXIMUM status |= H5T_register(H5T_PERS_HARD, "flt_ullong", native_float, native_ullong, H5T_conv_float_ullong, H5AC_dxpl_id); status |= H5T_register(H5T_PERS_HARD, "dbl_ullong", native_double, native_ullong, H5T_conv_double_ullong, H5AC_dxpl_id); +#endif /*H5_FP_TO_ULLONG_BOTTOM_BIT_WORKS && H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ +#if H5_FP_TO_ULLONG_BOTTOM_BIT_WORKS && H5_SW_LDOUBLE_TO_INTEGER_WORKS && H5_FP_TO_ULLONG_RIGHT_MAXIMUM status |= H5T_register(H5T_PERS_HARD, "ldbl_ullong", native_ldouble, native_ullong, H5T_conv_ldouble_ullong, H5AC_dxpl_id); +#endif /*H5_FP_TO_ULLONG_BOTTOM_BIT_WORKS && H5_SW_LDOUBLE_TO_INTEGER_WORKS && H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ /* * The special no-op conversion is the fastest, so we list it last. The diff --git a/src/H5config.h.in b/src/H5config.h.in index fb928eb..5bc0a04 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -540,7 +540,7 @@ values. */ #undef SW_LDOUBLE_TO_INTEGER_WORKS -/* Define if your system can accurately convert unsigned long long values to +/* Define if your system can accurately convert unsigned (long) long values to floating-point values. */ #undef SW_ULONG_TO_FP_BOTTOM_BIT_WORKS diff --git a/test/dsets.c b/test/dsets.c index da5c5d5..8646485 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -5122,6 +5122,7 @@ int main(void) nerrors += test_missing_chunk(file)<0 ?1:0; if (H5Fclose(file)<0) goto error; + if (nerrors) goto error; printf("All dataset tests passed.\n"); h5_cleanup(FILENAME, fapl); diff --git a/test/dtypes.c b/test/dtypes.c index f5bfb3c..bf99433 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -7396,11 +7396,11 @@ run_float_int_conv(const char *name) #if H5_SIZEOF_LONG_LONG!=H5_SIZEOF_LONG if(!strcmp(name, "hw")) { /* Hardware conversion */ /* Windows .NET 2003 doesn't work for hardware conversion of this case. - * .NET should define this macro H5_HW_FLOAT_TO_LLONG_NOT_WORKS. */ -#ifndef H5_HW_FLOAT_TO_LLONG_NOT_WORKS + * .NET should define this macro H5_HW_FP_TO_LLONG_NOT_WORKS. */ +#ifndef H5_HW_FP_TO_LLONG_NOT_WORKS nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); -#endif /*H5_HW_FLOAT_TO_LLONG_NOT_WORKS*/ +#endif /*H5_HW_FP_TO_LLONG_NOT_WORKS*/ } else { /* Software conversion */ nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); @@ -7999,7 +7999,7 @@ main(void) /* Test software integer-float conversion functions */ nerrors += run_int_float_conv("sw"); - + reset_hdf5(); if (nerrors) { -- cgit v0.12