From cfb095ae9ce9d59eb5fbf407d60b5308fef67ba5 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Fri, 21 Jan 2005 15:52:21 -0500 Subject: [svn-r9856] Purpose: New test and minor bug fix Description: Fixed a bug related to user-define functions for derived floating-point data type, like H5Tset_fields, H5Tset_offset, H5Tset_precision, H5Tset_size. Added test for these functions and test for data type conversion between derived floating-point types. Platforms tested: h5committest and fuss --- src/H5T.c | 6 +- src/H5Tprecis.c | 6 +- test/dtypes.c | 370 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 376 insertions(+), 6 deletions(-) diff --git a/src/H5T.c b/src/H5T.c index e87a34b..58fc616 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -3412,9 +3412,9 @@ H5T_set_size(H5T_t *dt, size_t size) * The sign, mantissa, and exponent fields should be adjusted * first when decreasing the size of a floating point type. */ - if (dt->shared->u.atomic.u.f.sign >= prec || - dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize > prec || - dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize > prec) { + if (dt->shared->u.atomic.u.f.sign >= prec+offset || + dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize > prec+offset || + dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize > prec+offset) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first"); } break; diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c index c597848..9b2a0b4 100644 --- a/src/H5Tprecis.c +++ b/src/H5Tprecis.c @@ -242,9 +242,9 @@ H5T_set_precision(const H5T_t *dt, size_t prec) * first when decreasing the precision of a floating point * type. */ - if (dt->shared->u.atomic.u.f.sign >= prec || - dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize > prec || - dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize > prec) + if (dt->shared->u.atomic.u.f.sign >= prec+offset || + dt->shared->u.atomic.u.f.epos + dt->shared->u.atomic.u.f.esize > prec+offset || + dt->shared->u.atomic.u.f.mpos + dt->shared->u.atomic.u.f.msize > prec+offset) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first") break; diff --git a/test/dtypes.c b/test/dtypes.c index fb1c76f..ffc7a16 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -65,6 +65,7 @@ const char *FILENAME[] = { "dtypes3", "dtypes4", "dtypes5", + "dtypes6", NULL }; @@ -2327,6 +2328,371 @@ test_query(void) /*------------------------------------------------------------------------- + * Function: test_derived_flt + * + * Purpose: Tests user-define and query functions of floating-point types. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Raymond Lu + * Thursday, Jan 6, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_derived_flt(void) +{ + hid_t file=-1, tid1=-1, tid2=-1; + hid_t dxpl_id=-1; + char filename[1024]; + size_t precision, spos, epos, esize, mpos, msize, size, ebias; + int offset; + size_t src_size, dst_size; + unsigned char *buf=NULL, *saved_buf=NULL; + int *aligned=NULL; + int endian; /*endianess */ + size_t nelmts = NTESTELEM; + unsigned int fails_this_test = 0; + const size_t max_fails=40; /*max number of failures*/ + char str[256]; /*message string */ + unsigned int i, j; + + TESTING("user-define and query functions of floating-point types"); + + /* Create File */ + h5_fixname(FILENAME[5], H5P_DEFAULT, filename, sizeof filename); + if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) { + H5_FAILED(); + printf("Can't create file\n"); + goto error; + } + + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER))<0) { + H5_FAILED(); + printf("Can't create data transfer property list\n"); + goto error; + } + + if((tid1 = H5Tcopy(H5T_IEEE_F64LE))<0) { + H5_FAILED(); + printf("Can't copy data type\n"); + goto error; + } + + if((tid2 = H5Tcopy(H5T_IEEE_F32LE))<0) { + H5_FAILED(); + printf("Can't copy data type\n"); + goto error; + } + + /*------------------------------------------------------------------------ + * 1st floating-point type + * size=7 byte, precision=42 bits, offset=3 bits, mantissa size=31 bits, + * mantissa position=3, exponent size=10 bits, exponent position=34, + * exponent bias=511. It can be illustrated in little-endian order as + * + * 6 5 4 3 2 1 0 + * ???????? ???SEEEE EEEEEEMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMM??? + * + * To create a new floating-point type, the following properties must be + * set in the order of + * set fields -> set offset -> set precision -> set size. + * All these properties must be set before the type can function. Other + * properties can be set anytime. Derived type size cannot be expanded + * bigger than original size but can be decreased. There should be no + * holes among the significant bits. Exponent bias usually is set + * 2^(n-1)-1, where n is the exponent size. + *-----------------------------------------------------------------------*/ + if(H5Tset_fields(tid1, 44, 34, 10, 3, 31)<0) { + H5_FAILED(); + printf("Can't set fields\n"); + goto error; + } + if(H5Tset_offset(tid1, 3)<0) { + H5_FAILED(); + printf("Can't set offset\n"); + goto error; + } + if(H5Tset_precision(tid1, 42)<0) { + H5_FAILED(); + printf("Can't set precision\n"); + goto error; + } + if(H5Tset_size(tid1, 7)<0) { + H5_FAILED(); + printf("Can't set size\n"); + goto error; + } + if(H5Tset_ebias(tid1, 511)<0) { + H5_FAILED(); + printf("Can't set exponent bias\n"); + goto error; + } + if(H5Tset_pad(tid1, H5T_PAD_ZERO, H5T_PAD_ZERO)<0) { + H5_FAILED(); + printf("Can't set padding\n"); + goto error; + } + + if(H5Tcommit(file, "new float type 1", tid1)<0) { + H5_FAILED(); + printf("Can't set inpad\n"); + goto error; + } + if(H5Tclose(tid1)<0) { + H5_FAILED(); + printf("Can't close datatype\n"); + goto error; + } + + if((tid1 = H5Topen(file, "new float type 1"))<0) { + H5_FAILED(); + printf("Can't open datatype\n"); + goto error; + } + if(H5Tget_fields(tid1, &spos, &epos, &esize, &mpos, &msize)<0) { + H5_FAILED(); + printf("Can't get fields\n"); + goto error; + } + if(spos!=44 || epos!=34 || esize!=10 || mpos!=3 || msize!=31) { + H5_FAILED(); + printf("Wrong field values\n"); + goto error; + } + + if((precision = H5Tget_precision(tid1))!=42) { + H5_FAILED(); + printf("Can't get precision or wrong precision\n"); + goto error; + } + if((offset = H5Tget_offset(tid1))!=3) { + H5_FAILED(); + printf("Can't get offset or wrong offset\n"); + goto error; + } + if((size = H5Tget_size(tid1))!=7) { + H5_FAILED(); + printf("Can't get size or wrong size\n"); + goto error; + } + if((ebias = H5Tget_ebias(tid1))!=511) { + H5_FAILED(); + printf("Can't get exponent bias or wrong bias\n"); + goto error; + } + + /*-------------------------------------------------------------------------- + * 2nd floating-point type + * size=3 byte, precision=24 bits, offset=0 bits, mantissa size=16 bits, + * mantissa position=0, exponent size=7 bits, exponent position=16, exponent + * bias=63. It can be illustrated in little-endian order as + * + * 2 1 0 + * SEEEEEEE MMMMMMMM MMMMMMMM + *--------------------------------------------------------------------------*/ + if(H5Tset_fields(tid2, 23, 16, 7, 0, 16)<0) { + H5_FAILED(); + printf("Can't set fields\n"); + goto error; + } + if(H5Tset_offset(tid2, 0)<0) { + H5_FAILED(); + printf("Can't set offset\n"); + goto error; + } + if(H5Tset_precision(tid2, 24)<0) { + H5_FAILED(); + printf("Can't set precision\n"); + goto error; + } + if(H5Tset_size(tid2, 3)<0) { + H5_FAILED(); + printf("Can't set size\n"); + goto error; + } + if(H5Tset_ebias(tid2, 63)<0) { + H5_FAILED(); + printf("Can't set size\n"); + goto error; + } + if(H5Tset_pad(tid2, H5T_PAD_ZERO, H5T_PAD_ZERO)<0) { + H5_FAILED(); + printf("Can't set padding\n"); + goto error; + } + + if(H5Tcommit(file, "new float type 2", tid2)<0) { + H5_FAILED(); + printf("Can't set inpad\n"); + goto error; + } + if(H5Tclose(tid2)<0) { + H5_FAILED(); + printf("Can't close datatype\n"); + goto error; + } + + if((tid2 = H5Topen(file, "new float type 2"))<0) { + H5_FAILED(); + printf("Can't open datatype\n"); + goto error; + } + if(H5Tget_fields(tid2, &spos, &epos, &esize, &mpos, &msize)<0) { + H5_FAILED(); + printf("Can't get fields\n"); + goto error; + } + if(spos!=23 || epos!=16 || esize!=7 || mpos!=0 || msize!=16) { + H5_FAILED(); + printf("Wrong field values\n"); + goto error; + } + + if((precision = H5Tget_precision(tid2))!=24) { + H5_FAILED(); + printf("Can't get precision or wrong precision\n"); + goto error; + } + if((offset = H5Tget_offset(tid2))!=0) { + H5_FAILED(); + printf("Can't get offset or wrong offset\n"); + goto error; + } + if((size = H5Tget_size(tid2))!=3) { + H5_FAILED(); + printf("Can't get size or wrong size\n"); + goto error; + } + if((ebias = H5Tget_ebias(tid2))!=63) { + H5_FAILED(); + printf("Can't get exponent bias or wrong bias\n"); + goto error; + } + + /* Convert data from the 2nd to the 1st derived floating-point type. + * Then convert data from the 1st type back to the 2nd type. + * Compare the final data with the original data. + */ + src_size = H5Tget_size(tid2); + dst_size = H5Tget_size(tid1); + endian = H5Tget_order(tid2); + buf = (unsigned char*)malloc(nelmts*(MAX(src_size, dst_size))); + saved_buf = (unsigned char*)malloc(nelmts*src_size); + + for(i=0; i derived floating-point conversions"); + printf("%-70s", str); + HDfflush(stdout); + H5_FAILED(); + } + printf(" test %u elmt %u: \n", 1, (unsigned)i); + + printf(" src = "); + for (j=0; j=max_fails) { + HDputs(" maximum failures reached, aborting test..."); + goto error; + } + } + + if (buf) free(buf); + if (saved_buf) free(saved_buf); + + if(H5Tclose(tid1)<0) { + H5_FAILED(); + printf("Can't close datatype\n"); + goto error; + } + + if(H5Tclose(tid2)<0) { + H5_FAILED(); + printf("Can't close datatype\n"); + goto error; + } + + if(H5Pclose(dxpl_id)<0) { + H5_FAILED(); + printf("Can't close property list\n"); + goto error; + } + + if(H5Fclose(file)<0) { + H5_FAILED(); + printf("Can't close file\n"); + goto error; + } /* end if */ + + PASSED(); + reset_hdf5(); /*print statistics*/ + + return 0; + + error: + if (buf) free(buf); + if (saved_buf) free(saved_buf); + if (aligned) free(aligned); + HDfflush(stdout); + H5E_BEGIN_TRY { + H5Tclose (tid1); + H5Tclose (tid2); + H5Pclose (dxpl_id); + H5Fclose (file); + } H5E_END_TRY; + reset_hdf5(); /*print statistics*/ + return MAX((int)fails_this_test, 1); +} + + + +/*------------------------------------------------------------------------- * Function: test_transient * * Purpose: Tests transient data types. @@ -5286,6 +5652,10 @@ main(void) nerrors += test_conv_bitfield(); nerrors += test_opaque(); + /* Test user-define, query functions and software conversion + * for user-defined floating-point types */ + nerrors += test_derived_flt(); + /* Does floating point overflow generate a SIGFPE? */ generates_sigfpe(); -- cgit v0.12