From bd92e1e2a0ad218875243ef6a8476b8f9b81bd0c Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 19 Jul 2005 13:16:33 -0500 Subject: [svn-r11087] Purpose: Bug fix. Description: When converting floating-point numbers to integers and the values of floating-point number are greater than the maximal value of integer, Cray X1 generates floating exception. Solution: Added a test in configure to detect Cray X1's exception. Set a flag to indicate the machine that can handle overflow converting all floating-point to all integer types. This flag should be set for all machines, except for Cray X1 where floating exception is generated when the floating-point value is greater than the maximal integer value. Platforms tested: Cray X1 and h5committest. --- configure | 70 +++++++++++++++++++ configure.in | 31 +++++++++ src/H5config.h.in | 4 ++ test/dt_arith.c | 199 ++++++++++++++++++++++++++++++------------------------ 4 files changed, 214 insertions(+), 90 deletions(-) diff --git a/configure b/configure index 4c0f1ab..226019a 100755 --- a/configure +++ b/configure @@ -50545,6 +50545,76 @@ else echo "${ECHO_T}no" >&6 fi +echo "$as_me:$LINENO: checking if overflows normally converting floating-point to integer values" >&5 +echo $ECHO_N "checking if overflows normally converting floating-point to integer values... $ECHO_C" >&6 + +if test "${hdf5_cv_fp_to_integer_overflow_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + int main(void) + { + float f = 2147483648.0f; + int i; + + i = (int)f; + +done: + exit(0); + } + +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + hdf5_cv_fp_to_integer_overflow_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +hdf5_cv_fp_to_integer_overflow_works=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi + + +if test ${hdf5_cv_fp_to_integer_overflow_works} = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define FP_TO_INTEGER_OVERFLOW_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 3349078..6b3e08c 100644 --- a/configure.in +++ b/configure.in @@ -2757,6 +2757,37 @@ else fi dnl ---------------------------------------------------------------------- +dnl Set the flag to indicate that the machine can handle overflow converting +dnl all floating-point to all integer types. +dnl (This flag should be set for all machines, except for Cray X1 where +dnl floating exception is generated when the floating-point value is greater +dnl than the maximal integer value). +dnl +AC_MSG_CHECKING([if overflows normally converting floating-point to integer values]) + +AC_CACHE_VAL([hdf5_cv_fp_to_integer_overflow_works], + [AC_TRY_RUN([ + int main(void) + { + float f = 2147483648.0f; + int i; + + i = (int)f; + +done: + exit(0); + } + ], [hdf5_cv_fp_to_integer_overflow_works=yes], [hdf5_cv_fp_to_integer_overflow_works=no],)]) + +if test ${hdf5_cv_fp_to_integer_overflow_works} = "yes"; then + AC_DEFINE([FP_TO_INTEGER_OVERFLOW_WORKS], [1], + [Define if your system can handle overflow converting floating-point to integer 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/H5config.h.in b/src/H5config.h.in index 82eef9f..5a9a79e 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -25,6 +25,10 @@ /* As FC_FUNC, but for C identifiers containing underscores. */ #undef FC_FUNC_ +/* Define if your system can handle overflow converting floating-point to + integer values. */ +#undef FP_TO_INTEGER_OVERFLOW_WORKS + /* Define if your system roundup accurately convert floating-point to unsigned long long values. */ #undef FP_TO_ULLONG_BOTTOM_BIT_WORKS diff --git a/test/dt_arith.c b/test/dt_arith.c index e8fb1cd..3a4b13d 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -4505,128 +4505,147 @@ run_fp_int_conv(const char *name) int nerrors = 0; int test_values; int i; + int run_test = TRUE; + +#ifndef H5_FP_TO_INTEGER_OVERFLOW_WORKS + /* For Cray X1, the compiler generates floating exception when the + * conversion overflows. So disable all of the conversions from + * floating-point numbers to integers. + */ + run_test = FALSE; +#endif - for(i=0; i<3; i++) { - if(i==0) - test_values = TEST_NORMAL; - else if(i==1) - test_values = TEST_DENORM; - else - test_values = TEST_SPECIAL; - - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_SCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_SCHAR); - - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_UCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_UCHAR); + if(run_test) { + for(i=0; i<3; i++) { + if(i==0) + test_values = TEST_NORMAL; + else if(i==1) + test_values = TEST_DENORM; + else + test_values = TEST_SPECIAL; + + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_SCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_SCHAR); + + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_UCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_UCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_SHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_SHORT); - - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_USHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_USHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_SHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_SHORT); + + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_USHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_USHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_INT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_INT); - - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_UINT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_UINT); - + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_INT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_INT); + + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_UINT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_UINT); + #if H5_SIZEOF_LONG!=H5_SIZEOF_INT - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LONG); - - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_ULONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LONG); + + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_ULONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULONG); #endif - + #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_FP_TO_LLONG_NOT_WORKS. */ + 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_FP_TO_LLONG_NOT_WORKS. */ #ifndef H5_HW_FP_TO_LLONG_NOT_WORKS - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); #endif /*H5_HW_FP_TO_LLONG_NOT_WORKS*/ - } else { /* Software conversion */ - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); - } + } else { /* Software conversion */ + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_LLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_LLONG); + } #ifdef H5_FP_TO_ULLONG_RIGHT_MAXIMUM - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_ULLONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_FLOAT, H5T_NATIVE_ULLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_DOUBLE, H5T_NATIVE_ULLONG); #else /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ - { - char str[256]; /*hello string */ - - sprintf(str, "Testing %s %s -> %s conversions", - name, "float", "unsigned long long"); - printf("%-70s", str); - SKIPPED(); - HDputs(" Test skipped due to hardware conversion error."); - - sprintf(str, "Testing %s %s -> %s conversions", - name, "double", "unsigned long long"); - printf("%-70s", str); - SKIPPED(); - HDputs(" Test skipped due to hardware conversion error."); - } + { + char str[256]; /*hello string */ + + sprintf(str, "Testing %s %s -> %s conversions", + name, "float", "unsigned long long"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + + sprintf(str, "Testing %s %s -> %s conversions", + name, "double", "unsigned long long"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } #endif /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ #endif #if H5_SW_LDOUBLE_TO_INTEGER_WORKS #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); #if H5_CV_LDOUBLE_TO_UINT_WORKS - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); #else /*H5_CV_LDOUBLE_TO_UINT_WORKS*/ - { - char str[256]; /*string */ + { + char str[256]; /*string */ - sprintf(str, "Testing %s %s -> %s conversions", - name, "long double", "unsigned int"); - printf("%-70s", str); - SKIPPED(); - HDputs(" Test skipped due to hardware conversion error."); - } + sprintf(str, "Testing %s %s -> %s conversions", + name, "long double", "unsigned int"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } #endif /*H5_CV_LDOUBLE_TO_UINT_WORKS*/ #if H5_SIZEOF_LONG!=H5_SIZEOF_INT - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); #endif #if H5_SIZEOF_LONG_LONG!=H5_SIZEOF_LONG - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LLONG); #ifdef H5_FP_TO_ULLONG_RIGHT_MAXIMUM - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULLONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULLONG); #else /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ - { - char str[256]; /*string */ + { + char str[256]; /*string */ - sprintf(str, "Testing %s %s -> %s conversions", - name, "long double", "unsigned long long"); - printf("%-70s", str); - SKIPPED(); - HDputs(" Test skipped due to hardware conversion error."); - } + sprintf(str, "Testing %s %s -> %s conversions", + name, "long double", "unsigned long long"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } #endif /*H5_FP_TO_ULLONG_RIGHT_MAXIMUM*/ #endif #endif #else /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ - { - char str[256]; /*hello string */ + { + char str[256]; /*hello string */ - sprintf(str, "Testing %s %s -> %s conversions", - name, "long double", "all integers"); - printf("%-70s", str); - SKIPPED(); - HDputs(" Test skipped due to hardware conversion error."); - } + sprintf(str, "Testing %s %s -> %s conversions", + name, "long double", "all integers"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); + } #endif /*H5_SW_LDOUBLE_TO_INTEGER_WORKS*/ + } + } else { + char str[256]; /*string */ + + sprintf(str, "Testing %s %s -> %s conversions", + name, "all floating-point numbers", "all integers"); + printf("%-70s", str); + SKIPPED(); + HDputs(" Test skipped due to hardware conversion error."); } return nerrors; -- cgit v0.12