summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2005-02-24 22:54:05 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2005-02-24 22:54:05 (GMT)
commitb0c346caa201cdc5bf40a314910ac33c75ba8951 (patch)
tree808620c125a73088971c3b6291a58cb137593d79
parentb67493fcda5ffe9f51b65ee95ca23714b7d9a555 (diff)
downloadhdf5-b0c346caa201cdc5bf40a314910ac33c75ba8951.zip
hdf5-b0c346caa201cdc5bf40a314910ac33c75ba8951.tar.gz
hdf5-b0c346caa201cdc5bf40a314910ac33c75ba8951.tar.bz2
[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.
-rw-r--r--configure.in6
-rw-r--r--src/H5T.c53
-rw-r--r--src/H5config.h.in2
-rw-r--r--test/dsets.c1
-rw-r--r--test/dtypes.c8
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) {