summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-04-28 17:02:12 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-04-28 17:02:12 (GMT)
commit12ba2eed6ad676507de5ad5aabe2e3631d8a1100 (patch)
tree57488773a49ee6c58f52352412052aa789505113
parentb3d2f04490363a24f1d43581116a61356ca89f77 (diff)
downloadhdf5-12ba2eed6ad676507de5ad5aabe2e3631d8a1100.zip
hdf5-12ba2eed6ad676507de5ad5aabe2e3631d8a1100.tar.gz
hdf5-12ba2eed6ad676507de5ad5aabe2e3631d8a1100.tar.bz2
[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
-rw-r--r--config/irix6.x5
-rwxr-xr-xconfigure22
-rw-r--r--configure.in17
-rw-r--r--src/H5Tconv.c4
-rw-r--r--src/H5config.h.in4
-rw-r--r--test/dtypes.c57
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;