From 12ba2eed6ad676507de5ad5aabe2e3631d8a1100 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 28 Apr 2004 12:02:12 -0500 Subject: [svn-r8425] Purpose: Bug fix (sorta) Description: The SGI machines have problems accurately (and consistently) converting unsigned long values to float and double values, so put in a bit of a hack in the datatype conversion test code to allow them to get "close enough". This hack is enabled at configure time by a flag which should only be set on machines with this problem. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest --- config/irix6.x | 5 +++++ configure | 22 +++++++++++++++++++++ configure.in | 17 +++++++++++++++++ src/H5Tconv.c | 4 ++-- src/H5config.h.in | 4 ++++ test/dtypes.c | 57 ++++++++++++++++++++++++++++++++++--------------------- 6 files changed, 85 insertions(+), 24 deletions(-) diff --git a/config/irix6.x b/config/irix6.x index 57cf186..dcdf91e 100644 --- a/config/irix6.x +++ b/config/irix6.x @@ -140,3 +140,8 @@ if test -z "$cxx_flags_set"; then PROFILE_CPPFLAGS= cxx_flags_set=yes fi + +# Hard set flag to indicate that the 'unsigned long long' to floating-point +# value conversion are broken by the compilers (as of 4/27/04 - QAK) +hdf5_cv_sw_ulong_to_fp_bottom_bit_works=${hdf5_cv_sw_ulong_to_fp_bottom_bit_works='no'} + diff --git a/configure b/configure index aed1b1b..b2efb89 100755 --- a/configure +++ b/configure @@ -33263,6 +33263,28 @@ else echo "${ECHO_T}no" >&6 fi +echo "$as_me:$LINENO: checking if accurately converting unsigned long long to floating-point values works" >&5 +echo $ECHO_N "checking if accurately converting unsigned long long to floating-point values works... $ECHO_C" >&6 +if test "${hdf5_cv_sw_ulong_to_fp_bottom_bit_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + hdf5_cv_sw_ulong_to_fp_bottom_bit_works=yes +fi + + +if test ${hdf5_cv_sw_ulong_to_fp_bottom_bit_works} = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define SW_ULONG_TO_FP_BOTTOM_BIT_WORKS 1 +_ACEOF + + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + H5_VERSION="`cut -d' ' -f3 $srcdir/README.txt | head -1`" diff --git a/configure.in b/configure.in index 2b1a52f..dee22c2 100644 --- a/configure.in +++ b/configure.in @@ -2381,6 +2381,23 @@ else fi dnl ---------------------------------------------------------------------- +dnl Set the flag to indicate that the machine can accurately convert +dnl 'unsigned long long' values to 'float' and 'double' values. +dnl (This flag should be set for all machines, except for the SGIs, where +dnl the cache value is set in the config/irix6.x config file) +dnl +AC_MSG_CHECKING([if accurately converting unsigned long long to floating-point values works]) +AC_CACHE_VAL([hdf5_cv_sw_ulong_to_fp_bottom_bit_works], [hdf5_cv_sw_ulong_to_fp_bottom_bit_works=yes]) + +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.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +dnl ---------------------------------------------------------------------- dnl Set some variables for general configuration information to be saved dnl and installed with the libraries. dnl diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 78744d5..156e359 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -9369,9 +9369,9 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts, */ /* Check 1st dropoff bit, see if it's set. */ - if(H5T_bit_get_d(int_buf, (first-dst.u.f.msize-1), 1)) { + if(H5T_bit_get_d(int_buf, ((first-dst.u.f.msize)-1), 1)) { /* Check all bits after 1st dropoff bit, see if any of them is set. */ - if((first-dst.u.f.msize-1) > 0 && H5T_bit_get_d(int_buf, 0, (first-dst.u.f.msize-1))) + if(((first-dst.u.f.msize)-1) > 0 && H5T_bit_get_d(int_buf, 0, ((first-dst.u.f.msize)-1))) do_round = 1; else { /* The .50...0 case */ /* Check if the least significant bit is odd. */ diff --git a/src/H5config.h.in b/src/H5config.h.in index 3a2924c..dffdb8a 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -501,6 +501,10 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Define if your system can accurately convert unsigned long long values to + floating-point values. */ +#undef SW_ULONG_TO_FP_BOTTOM_BIT_WORKS + /* Define if your system supports pthread_attr_setscope(&attribute, PTHREAD_SCOPE_SYSTEM) call. */ #undef SYSTEM_SCOPE_THREADS diff --git a/test/dtypes.c b/test/dtypes.c index 27b4874..7e0b71b 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -4494,6 +4494,35 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) } } } +/* On some machines (notably the SGI machines) unsigned long values + * are not converted to float or double values correctly, they are + * consistently off by the lowest bit being rounded oppositely to our + * software conversion routines output. So, on those machines, we allow + * the converted value to be +/- 1 from the machine's value. -QAK + */ +#ifndef H5_SW_ULONG_TO_FP_BOTTOM_BIT_WORKS + if(dst_size==sizeof(unsigned)) { + unsigned tmp_s, tmp_h; + HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned)); + HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned)); + if((tmp_s+1)==tmp_h || (tmp_s-1)==tmp_h) + continue; /*no error*/ + } /* end if */ + else if (dst_size==sizeof(unsigned long)) { + unsigned long tmp_s, tmp_h; + HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long)); + HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long)); + if((tmp_s+1)==tmp_h || (tmp_s-1)==tmp_h) + continue; /*no error*/ + } /* end if */ + else if (dst_size==sizeof(unsigned long long)) { + unsigned long long tmp_s, tmp_h; + HDmemcpy(&tmp_s,&buf[j*dst_size],sizeof(unsigned long long)); + HDmemcpy(&tmp_h,&hw[0],sizeof(unsigned long long)); + if((tmp_s+1)==tmp_h || (tmp_s-1)==tmp_h) + continue; /*no error*/ + } /* end if */ +#endif /* end H5_ULONG_FP_BOTTOM_BIT_WORKS */ /* Print errors */ if (0==fails_this_test++) @@ -5546,26 +5575,16 @@ run_int_float_conv(const char *name) nerrors += test_conv_int_float(name, H5T_NATIVE_LONG, H5T_NATIVE_FLOAT); nerrors += test_conv_int_float(name, H5T_NATIVE_LONG, H5T_NATIVE_DOUBLE); - /* Temporarily disable these tests for software conversion. They fail on - * some systems(like modi4, premium, o2 and arabica) - */ - if(!strcmp(name, "hw")) { - nerrors += test_conv_int_float(name, H5T_NATIVE_ULONG, H5T_NATIVE_FLOAT); - nerrors += test_conv_int_float(name, H5T_NATIVE_ULONG, H5T_NATIVE_DOUBLE); - } + nerrors += test_conv_int_float(name, H5T_NATIVE_ULONG, H5T_NATIVE_FLOAT); + nerrors += test_conv_int_float(name, H5T_NATIVE_ULONG, H5T_NATIVE_DOUBLE); #endif #if H5_SIZEOF_LONG_LONG!=H5_SIZEOF_LONG nerrors += test_conv_int_float(name, H5T_NATIVE_LLONG, H5T_NATIVE_FLOAT); nerrors += test_conv_int_float(name, H5T_NATIVE_LLONG, H5T_NATIVE_DOUBLE); - /* Temporarily disable these tests for software conversion. They fail on - * some systems(like modi4, premium, o2 and arabica) - */ - if(!strcmp(name, "hw")) { - nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_FLOAT); - nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_DOUBLE); - } + nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_FLOAT); + nerrors += test_conv_int_float(name, H5T_NATIVE_ULLONG, H5T_NATIVE_DOUBLE); #endif return nerrors; @@ -5621,14 +5640,8 @@ run_float_int_conv(const char *name) nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); - /* Temporarily disable these two tests for software conversion because of - * the bug in pgcc compiler. - * Will turn it back once the problem is solved. - */ - if(!strcmp(name, "hw")) { - nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_ULLONG); - nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULLONG); - } + nerrors += test_conv_int_float(name, H5T_NATIVE_FLOAT, H5T_NATIVE_ULLONG); + nerrors += test_conv_int_float(name, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULLONG); #endif return nerrors; -- cgit v0.12