[svn-r10402] Purpose: New way to do conversion test between floating-point types.

Description:  The 5th step of changing conversion test.  This checkin is only for conversion
of special values between floating-point types.

Solution: This test is seperated from regular value conversion.  It reuse the same function
test_conv_flt_1() in test/dtypes.c.  The source buffer of floating-point type is filled up
with 8 special values, +/-0, +/-infinity, +/-QNaN, +/-SNaN.

Platforms tested: h5committest, fuss, and modi4.
This commit is contained in:
Raymond Lu 2005-03-24 11:27:54 -05:00
parent 0d1ca67ebc
commit 87252df68c
2 changed files with 219 additions and 55 deletions

View File

@ -3511,8 +3511,28 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);
H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE);
H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE);
/*If the destination no implied mantissa bit, we'll need to set
*the 1st bit of mantissa to 1. The Intel-Linux long double is
*this case.*/
if (H5T_NORM_NONE==dst.u.f.norm)
H5T_bit_set (d, dst.u.f.mpos+dst.u.f.msize-1, 1, TRUE);
goto padding;
}
} else if (H5T_NORM_NONE==src.u.f.norm && H5T_bit_find (s, src.u.f.mpos, src.u.f.msize-1,
H5T_BIT_LSB, TRUE)<0 && H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
H5T_BIT_LSB, FALSE)<0) {
/*This is a special case for the source of no implied mantissa bit.
*If the exponent bits are all 1s and only the 1st bit of mantissa
*is set to 1. It's infinity. The Intel-Linux "long double" is this case.*/
/* +Inf or -Inf */
H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1);
H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE);
H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE);
/*If the destination no implied mantissa bit, we'll need to set
*the 1st bit of mantissa to 1.*/
if (H5T_NORM_NONE==dst.u.f.norm)
H5T_bit_set (d, dst.u.f.mpos+dst.u.f.msize-1, 1, TRUE);
goto padding;
} else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
H5T_BIT_LSB, FALSE)<0) {
/*
@ -9663,7 +9683,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
} else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize,
H5T_BIT_LSB, FALSE)<0) {
/*
* NaN. There are many NaN values, so we just set all bits to zero.
* NaN. Just set all bits to zero.
*/
goto padding;
}
@ -9802,7 +9822,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
H5T_bit_dec(int_buf, 0, 8*buf_size);
H5T_bit_neg(int_buf, 0, 8*buf_size);
/*copy source value into destiny*/
/*copy source value into destination*/
H5T_bit_copy (d, dst.offset, int_buf, 0, dst.prec-1);
H5T_bit_set (d, (dst.offset + dst.prec-1), 1, TRUE);
} else if(except_ret == H5T_CONV_ABORT)
@ -9966,7 +9986,7 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
uint8_t dbuf[64]; /*temp destination buffer */
/* Conversion-related variables */
hsize_t expo; /*destiny exponent */
hsize_t expo; /*destination exponent */
hsize_t expo_max; /*maximal possible exponent value */
size_t sign; /*source sign bit value */
hbool_t is_max_neg; /*source is maximal negative value*/
@ -10151,7 +10171,7 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* step. */
H5T_bit_set(int_buf, src.prec, buf_size*8-src.prec, 0);
/* Set sign bit in destiny */
/* Set sign bit in destination */
H5T_bit_set_d(d, dst.u.f.sign, 1, (hsize_t)sign);
}
@ -10269,10 +10289,10 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
}
if(except_ret == H5T_CONV_UNHANDLED) {
/* Set exponent in destiny */
/* Set exponent in destination */
H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, expo);
/* Copy mantissa into destiny */
/* Copy mantissa into destination */
H5T_bit_copy(d, dst.u.f.mpos, int_buf, 0, buf_size*8 > dst.u.f.msize ? dst.u.f.msize : buf_size*8);
}

View File

@ -111,7 +111,7 @@ static int num_opaque_conversions_g = 0;
* SIGFPE we run tests that might generate one in a child process.
*/
#if defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)
# define HANDLE_SIGFPE
/*#define HANDLE_SIGFPE*/
#endif
/* Allocates memory aligned on a certain boundary. */
@ -292,6 +292,70 @@ static int num_opaque_conversions_g = 0;
free(tmp2); \
}
/* Allocate buffer and initialize it with floating-point special values, +/-0, +/-infinity,
* +/-QNaN, +/-SNaN. It's for conversion test of floating-point as the source.
*/
#define INIT_FP_SPECIAL(SRC_SIZE, SRC_PREC, SRC_ORDR, SRC_MANT_DIG, DST_SIZE, \
BUF, SAVED, NELMTS) \
{ \
unsigned char *buf_p, *saved_p; \
unsigned char *value; \
int n; \
\
/*Total number of values*/ \
NELMTS = 2 * /*both positive and negative*/ \
4; /*infinity, SNaN, QNaN */ \
\
/* Allocate buffers */ \
BUF = (unsigned char*)aligned_malloc(NELMTS*MAX(SRC_SIZE, DST_SIZE)); \
SAVED = (unsigned char*)aligned_malloc( NELMTS*MAX(SRC_SIZE, DST_SIZE)); \
value = (unsigned char*)calloc(SRC_SIZE, sizeof(unsigned char)); \
\
buf_p = BUF; \
saved_p = SAVED; \
\
/* +0 */ \
H5T_bit_set(value, 0, SRC_PREC, FALSE); \
memcpy(buf_p, value, SRC_SIZE*sizeof(unsigned char)); \
buf_p += SRC_SIZE; \
\
for(n=0; n<2; n++) { \
if(n==1) { \
memset(value, 0, SRC_SIZE*sizeof(unsigned char)); \
/* -0 */ \
H5T_bit_set(value, SRC_PREC-1, 1, TRUE); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE);/*change order for big endian*/ \
memcpy(buf_p, value, SRC_SIZE*sizeof(unsigned char)); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE);/*change back the order for bit operation*/ \
buf_p += SRC_SIZE; \
} \
\
/* +/-infinity */ \
H5T_bit_set(value, SRC_MANT_DIG-1, SRC_PREC-SRC_MANT_DIG, TRUE); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change order for big endian*/ \
memcpy(buf_p, value, SRC_SIZE*sizeof(unsigned char)); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change back the order for bit operation*/ \
buf_p += SRC_SIZE; \
\
/* +/-SNaN */ \
H5T_bit_set(value, 0, 1, TRUE); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change order for big endian*/ \
memcpy(buf_p, value, SRC_SIZE*sizeof(unsigned char)); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change back the order for bit operation*/ \
buf_p += SRC_SIZE; \
\
/* +/-QNaN */ \
H5T_bit_set(value, SRC_MANT_DIG-2, 1, TRUE); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change order for big endian*/ \
memcpy(buf_p, value, SRC_SIZE*sizeof(unsigned char)); \
CHANGE_ORDER(value, SRC_ORDR, SRC_SIZE); /*change back the order for bit operation*/ \
buf_p += SRC_SIZE; \
} \
\
memcpy(SAVED, BUF, NELMTS*MAX(SRC_SIZE, DST_SIZE)); \
free(value); \
}
void some_dummy_func(float x);
static hbool_t overflows(unsigned char *origin_bits, hid_t src_id, size_t dst_num_bits);
static int my_isnan(dtype_t type, void *val);
@ -5702,7 +5766,7 @@ my_isnan(dtype_t type, void *val)
*-------------------------------------------------------------------------
*/
static int
test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
test_conv_flt_1 (const char *name, hbool_t run_special, hid_t src, hid_t dst)
{
dtype_t src_type, dst_type; /*data types */
const size_t ntests=NTESTS; /*number of tests */
@ -5807,8 +5871,16 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
if(sizeof(float)==sizeof(double))
HDputs("Sizeof(float)==sizeof(double) - some tests may not be sensible.");
if (OTHER==src_type || OTHER==dst_type) {
sprintf(str, "Testing random %s %s -> %s conversions",
if(!strcmp(name, "noop"))
sprintf(str, "Testing %s %s -> %s conversions",
name, src_type_name, dst_type_name);
else if(run_special)
sprintf(str, "Testing special %s %s -> %s conversions",
name, src_type_name, dst_type_name);
else
sprintf(str, "Testing regular %s %s -> %s conversions",
name, src_type_name, dst_type_name);
printf("%-70s", str);
H5_FAILED();
HDputs(" Unknown data type.");
@ -5834,31 +5906,67 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
/* Allocate and initialize the source buffer through macro INIT_FP. The BUF will be used
* for the conversion while the SAVED buffer will be used for the comparison later.
*/
if(src_type == FLT_FLOAT) {
INIT_FP(float, FLT_MAX, FLT_MIN, FLT_MAX_10_EXP, FLT_MIN_10_EXP, FLT_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
} else if(src_type == FLT_DOUBLE) {
INIT_FP(double, DBL_MAX, DBL_MIN, DBL_MAX_10_EXP, DBL_MIN_10_EXP, DBL_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
switch (run_special) {
case FALSE:
if(src_type == FLT_FLOAT) {
INIT_FP(float, FLT_MAX, FLT_MIN, FLT_MAX_10_EXP, FLT_MIN_10_EXP, FLT_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
} else if(src_type == FLT_DOUBLE) {
INIT_FP(double, DBL_MAX, DBL_MIN, DBL_MAX_10_EXP, DBL_MIN_10_EXP, DBL_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
} else if(src_type == FLT_LDOUBLE) {
INIT_FP(long double, LDBL_MAX, LDBL_MIN, LDBL_MAX_10_EXP, LDBL_MIN_10_EXP, LDBL_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
} else if(src_type == FLT_LDOUBLE) {
INIT_FP(long double, LDBL_MAX, LDBL_MIN, LDBL_MAX_10_EXP, LDBL_MIN_10_EXP, LDBL_MANT_DIG,
src_size, src_nbits, endian, dst_size, buf, saved, nelmts);
#endif
} else
goto error;
} else
goto error;
break;
case TRUE:
if(src_type == FLT_FLOAT) {
INIT_FP_SPECIAL(src_size, src_nbits, endian, FLT_MANT_DIG, dst_size,
buf, saved, nelmts);
} else if(src_type == FLT_DOUBLE) {
INIT_FP_SPECIAL(src_size, src_nbits, endian, DBL_MANT_DIG, dst_size,
buf, saved, nelmts);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
} else if(src_type == FLT_LDOUBLE) {
INIT_FP_SPECIAL(src_size, src_nbits, endian, LDBL_MANT_DIG, dst_size,
buf, saved, nelmts);
#endif
} else
goto error;
break;
default:
goto error;
}
for (i=0; i<ntests; i++) {
/*
* If it looks like it might take a long time then print a progress
* report between each test.
*/
if (ntests>1) {
sprintf(str, "Testing random %s %s -> %s conversions (test %d/%d)",
if(!strcmp(name, "noop"))
sprintf(str, "Testing %s %s -> %s conversions (test %d/%d)",
name, src_type_name, dst_type_name, (int)i+1, (int)ntests);
else if(run_special)
sprintf(str, "Testing special %s %s -> %s conversions (test %d/%d)",
name, src_type_name, dst_type_name, (int)i+1, (int)ntests);
else
sprintf(str, "Testing regular %s %s -> %s conversions (test %d/%d)",
name, src_type_name, dst_type_name, (int)i+1, (int)ntests);
} else {
sprintf(str, "Testing random %s %s -> %s conversions",
if(!strcmp(name, "noop"))
sprintf(str, "Testing %s %s -> %s conversions (test %d/%d)",
name, src_type_name, dst_type_name, (int)i+1, (int)ntests);
else if(run_special)
sprintf(str, "Testing special %s %s -> %s conversions",
name, src_type_name, dst_type_name);
else
sprintf(str, "Testing regular %s %s -> %s conversions",
name, src_type_name, dst_type_name);
}
printf("%-70s", str);
@ -6072,11 +6180,11 @@ test_conv_flt_1 (const char *name, hid_t src, hid_t dst)
printf("%*s", (int)(3*MAX(0, (ssize_t)dst_size-(ssize_t)src_size)), "");
if (FLT_FLOAT==src_type) {
float x;
HDmemcpy(&x, &saved[j*dst_size], sizeof(float));
HDmemcpy(&x, &saved[j*src_size], sizeof(float));
printf(" %29.20e\n", x);
} else if (FLT_DOUBLE==src_type) {
double x;
HDmemcpy(&x, &saved[j*dst_size], sizeof(double));
HDmemcpy(&x, &saved[j*src_size], sizeof(double));
printf(" %29.20e\n", x);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
} else {
@ -7404,7 +7512,58 @@ run_integer_tests(const char *name)
/*-------------------------------------------------------------------------
* Function: run_int_float_conv
* Function: run_fp_tests
*
* Purpose: Runs all floating-point tests.
*
* Return: Number of errors
*
* Programmer: Raymond Lu
* Tuesday, March 22, 2005
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
run_fp_tests(const char *name)
{
int nerrors = 0;
if(!strcmp(name, "noop")) {
nerrors += test_conv_flt_1("noop", FALSE, H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1("noop", FALSE, H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE);
nerrors += test_conv_flt_1("noop", FALSE, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LDOUBLE);
goto done;
}
/*Test normalized and denormalized values. FALSE indicates non-special values.*/
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1(name, FALSE, H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
#endif
/*Test special values, +/-0, +/-infinity, +/-QNaN, +/-SNaN.*/
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1(name, TRUE, H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
#endif
done:
return nerrors;
}
/*-------------------------------------------------------------------------
* Function: run_int_fp_conv
*
* Purpose: Runs all integer-float tests.
*
@ -7418,7 +7577,7 @@ run_integer_tests(const char *name)
*-------------------------------------------------------------------------
*/
static int
run_int_float_conv(const char *name)
run_int_fp_conv(const char *name)
{
int nerrors = 0;
@ -7520,7 +7679,7 @@ run_int_float_conv(const char *name)
/*-------------------------------------------------------------------------
* Function: run_float_int_conv
* Function: run_fp_int_conv
*
* Purpose: Runs all float-integer tests.
*
@ -7534,7 +7693,7 @@ run_int_float_conv(const char *name)
*-------------------------------------------------------------------------
*/
static int
run_float_int_conv(const char *name)
run_fp_int_conv(const char *name)
{
int nerrors = 0;
@ -8128,27 +8287,19 @@ main(void)
generates_sigfpe();
/* Test degenerate cases */
nerrors += test_conv_flt_1("noop", H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1("noop", H5T_NATIVE_DOUBLE, H5T_NATIVE_DOUBLE);
nerrors += run_fp_tests("noop");
/* Test hardware floating-point conversion functions */
nerrors += run_fp_tests("hw");
/* Test hardware integer conversion functions */
nerrors += run_integer_tests("hw");
/* Test hardware floating-point conversion functions */
nerrors += test_conv_flt_1("hw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
nerrors += test_conv_flt_1("hw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1("hw", H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1("hw", H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1("hw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1("hw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
#endif
/* Test hardware integer-float conversion functions */
nerrors += run_int_float_conv("hw");
nerrors += run_int_fp_conv("hw");
/* Test hardware float-integer conversion functions */
nerrors += run_float_int_conv("hw");
nerrors += run_fp_int_conv("hw");
/*----------------------------------------------------------------------
* Software tests
@ -8157,25 +8308,18 @@ main(void)
without_hardware_g = TRUE;
reset_hdf5();
/* Test software floating-point conversion functions */
nerrors += run_fp_tests("sw");
/* Test software integer conversion functions */
nerrors += test_conv_int_2();
nerrors += run_integer_tests("sw");
/* Test software floating-point conversion functions */
nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE);
nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT);
#if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE
nerrors += test_conv_flt_1("sw", H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1("sw", H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE);
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT);
nerrors += test_conv_flt_1("sw", H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE);
#endif
/* Test software float-integer conversion functions */
nerrors += run_float_int_conv("sw");
nerrors += run_fp_int_conv("sw");
/* Test software integer-float conversion functions */
nerrors += run_int_float_conv("sw");
nerrors += run_int_fp_conv("sw");
reset_hdf5();