From c78a6aedafdf878d0cdd18977d5b10a90763b20d Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Wed, 23 Jun 1999 11:16:51 -0500 Subject: [svn-r1371] Changes since 19990618 ---------------------- ./configure.in ./configure [REGENERATED] Now that compound struct conversions don't make so many calls to convert their members I turned the H5T debugging back on by default (it will still be disabled in a production version). ./src/H5AC.c ./src/H5B.c Made it possible to turn off messages about debugging these two packages using the same method as for all other packages. Just supply an invalid file descriptor number or use the shell to redirect said descriptor to /dev/null like this: $ HDF5_DEBUG=99,ac,b 99>/dev/null a.out ./src/H5T.c Changed the name of the old compound conversion function from `struct' to `struct(no-opt)' to be more consistent with the new version named `struct(opt)'. Fixed a bug in H5T_cmp() that caused any two VL types to compare as being equal. Removed duplicate code for bitfield comparisons in H5T_cmp(). ./src/H5Tconv.c Relaxed some constraints in the new compound conversion function so it applies to more cases. Also eliminated a memcpy in a tight loop. ./test/cmpd_dset.c Added a `--noopt' command line switch which unregisters the optimized compound conversion so we can test the non-optimized version. --- configure | 2 +- configure.in | 2 +- src/H5AC.c | 6 ++- src/H5B.c | 6 ++- src/H5T.c | 18 ++++----- src/H5Tconv.c | 112 +++++++++++++++++++++++++++++++++++-------------------- test/cmpd_dset.c | 15 +++++++- 7 files changed, 104 insertions(+), 57 deletions(-) diff --git a/configure b/configure index 5e84ec4..efe71ac 100755 --- a/configure +++ b/configure @@ -5100,7 +5100,7 @@ fi all_packages="ac,b,d,e,f,g,hg,hl,i,mf,mm,o,p,s,t,v,z" if test X = "X$DEBUG_PKG" -o Xyes = "X$DEBUG_PKG"; then - DEBUG_PKG="d,e,f,g,hg,i,mm,o,p,s,v,z" + DEBUG_PKG="d,e,f,g,hg,i,mm,o,p,s,t,v,z" CPPFLAGS="$CPPFLAGS -UNDEBUG" echo "$ac_t""default ($DEBUG_PKG)" 1>&6 elif test Xall = "X$DEBUG_PKG"; then diff --git a/configure.in b/configure.in index e2789df..005984f 100644 --- a/configure.in +++ b/configure.in @@ -505,7 +505,7 @@ AC_ARG_ENABLE(debug, AC_SUBST(DEBUG_PKG) all_packages="ac,b,d,e,f,g,hg,hl,i,mf,mm,o,p,s,t,v,z" if test X = "X$DEBUG_PKG" -o Xyes = "X$DEBUG_PKG"; then - DEBUG_PKG="d,e,f,g,hg,i,mm,o,p,s,v,z" + DEBUG_PKG="d,e,f,g,hg,i,mm,o,p,s,t,v,z" CPPFLAGS="$CPPFLAGS -UNDEBUG" AC_MSG_RESULT(default ($DEBUG_PKG)) elif test Xall = "X$DEBUG_PKG"; then diff --git a/src/H5AC.c b/src/H5AC.c index 78033e4..862eb8c 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -641,7 +641,11 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, const haddr_t *addr, #ifdef H5AC_DEBUG static int ncalls = 0; if (0 == ncalls++) { - fprintf(stderr, "H5AC: debugging cache (expensive)\n"); + if (H5DEBUG(AC)) { + fprintf(H5DEBUG(AC), "H5AC: debugging cache (expensive)\n"); + } else { + fprintf(stderr, "H5AC: debugging cache (expensive)\n"); + } } #endif diff --git a/src/H5B.c b/src/H5B.c index a27a444..43051ca 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -2120,7 +2120,11 @@ H5B_assert(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, FUNC_ENTER(H5B_assert, FAIL); if (0==ncalls++) { - fprintf(stderr, "H5B: debugging B-trees (expensive)\n"); + if (H5DEBUG(B)) { + fprintf(H5DEBUG(B), "H5B: debugging B-trees (expensive)\n"); + } else { + fprintf(stderr, "H5B: debugging B-trees (expensive)\n"); + } } /* Initialize the queue */ bt = H5AC_find(f, H5AC_BT, addr, type, udata); diff --git a/src/H5T.c b/src/H5T.c index 5b3262a..76afffa 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -953,7 +953,7 @@ H5T_init_interface(void) status |= H5Tregister(H5T_PERS_SOFT, "fbo", floatpt, floatpt, H5T_conv_order); - status |= H5Tregister(H5T_PERS_SOFT, "struct", + status |= H5Tregister(H5T_PERS_SOFT, "struct(no-opt)", compound, compound, H5T_conv_struct); status |= H5Tregister(H5T_PERS_SOFT, "struct(opt)", @@ -6186,19 +6186,21 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) } } else if (H5T_VLEN==dt1->type) { - /* Sort memory VL datatypes before disk datatypes, somewhat arbitrarily */ - if(dt1->u.vlen.type==H5T_VLEN_MEMORY && dt1->u.vlen.type==H5T_VLEN_DISK) { + /* Arbitrarily sort memory VL datatypes before disk datatypes */ + if (dt1->u.vlen.type==H5T_VLEN_MEMORY && + dt2->u.vlen.type==H5T_VLEN_DISK) { HGOTO_DONE(-1); - } - else if(dt1->u.vlen.type==H5T_VLEN_DISK && dt1->u.vlen.type==H5T_VLEN_MEMORY) { + } else if (dt1->u.vlen.type==H5T_VLEN_DISK && + dt2->u.vlen.type==H5T_VLEN_MEMORY) { HGOTO_DONE(1); } + } else if (H5T_OPAQUE==dt1->type) { HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag)); } else { /* - * Atomic data types... + * Atomic datatypes... */ if (dt1->u.atomic.order < dt2->u.atomic.order) HGOTO_DONE(-1); if (dt1->u.atomic.order > dt2->u.atomic.order) HGOTO_DONE(1); @@ -6303,10 +6305,6 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) /*void */ break; - case H5T_OPAQUE: - /*void */ - break; - case H5T_REFERENCE: if (dt1->u.atomic.u.r.rtype < dt2->u.atomic.u.r.rtype) { HGOTO_DONE(-1); diff --git a/src/H5Tconv.c b/src/H5Tconv.c index f469c61..dc9a7bc 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1145,12 +1145,14 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * For each member of the struct * If sizeof detination type <= sizeof source type then * Convert member to destination type for all elements - * Move member as far left as possible for all elements + * Move memb to BKG buffer for all elements + * Else + * Move member as far left as possible for all elements * * For each member of the struct (in reverse order) * If not destination type then * Convert member to destination type for all elements - * Move member to correct position in BKG for all elements + * Move member to correct position in BKG for all elements * * Copy BKG to BUF for all elements * @@ -1194,7 +1196,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t offset; /*byte offset wrt struct */ uintn elmtno; /*element counter */ intn i, j; /*counters */ - H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); + H5T_conv_struct_t *priv = NULL; /*private data */ FUNC_ENTER (H5T_conv_struct_opt, FAIL); @@ -1215,26 +1217,63 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, assert (H5T_COMPOUND==src->type); assert (H5T_COMPOUND==dst->type); - /* - * This optimized version only works when the source and destination - * datatypes are the same size. - */ - if (src->size < dst->size) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "conversion is unsupported by this function"); - } - /* Initialize data which is relatively constant */ if (H5T_conv_struct_init (src, dst, cdata)<0) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); } + priv = (H5T_conv_struct_t *)(cdata->priv); + src2dst = priv->src2dst; + + /* + * If the destination type is not larger than the source type then + * this conversion function is guaranteed to work (provided all + * members can be converted also). Otherwise the determination is + * quite a bit more complicated. Essentially we have to make sure + * that there is always room in the source buffer to do the + * conversion of a member in place. This is basically the same pair + * of loops as in the actual conversion except it checks that there + * is room for each conversion instead of actually doing anything. + */ + if (dst->size > src->size) { + for (i=0, offset=0; iu.compnd.nmembs; i++) { + if (src2dst[i]<0) continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + src_memb_size = src_memb->size / priv->memb_nelmts[i]; + dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; + for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) { + if (dst_memb_size > src_memb_size) { + offset += src_memb_size; + } + } + } + for (i=src->u.compnd.nmembs-1; i>=0; --i) { + if (src2dst[i]<0) continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + src_memb_size = src_memb->size / priv->memb_nelmts[i]; + dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; + + for (j=priv->memb_nelmts[i]-1; j>=0; --j) { + if (dst_memb_size > src_memb_size) { + offset -= src_memb_size; + if (dst_memb_size > src->size-offset) { + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "convertion is unsupported by this " + "function"); + } + } + } + } + } break; case H5T_CONV_FREE: /* * Free the private conversion data. */ + priv = (H5T_conv_struct_t *)(cdata->priv); H5MM_xfree(priv->src2dst); H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); @@ -1253,30 +1292,30 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, NULL == (dst = H5I_object(dst_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } - assert(src->size>=dst->size); - assert(priv); - assert(bkg && cdata->need_bkg>=H5T_BKG_TEMP); + /* Update cached data if necessary */ if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata)<0) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); } + priv = (H5T_conv_struct_t *)(cdata->priv); + src2dst = priv->src2dst; + assert(priv); + assert(bkg && cdata->need_bkg>=H5T_BKG_TEMP); /* * Insure that members are sorted. */ H5T_sort_value(src, NULL); H5T_sort_value(dst, NULL); - src2dst = priv->src2dst; /* * For each member where the destination is not larger than the - * source, stride through all the elements converting only that - * member in each element. - * - * Shift struct member (converted or not) as far left as possible - * within each element. + * source, stride through all the elements converting only that member + * in each element and then copying the element to its final + * destination in the bkg buffer. Otherwise move the element as far + * left as possible in the buffer. */ for (i=0, offset=0; iu.compnd.nmembs; i++) { if (src2dst[i]<0) continue; @@ -1299,13 +1338,11 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, "unable to convert compound data " "type member"); } - for (xbuf=buf, elmtno=0; elmtnooffset+j*src_memb_size, - dst_memb_size); + for (elmtno=0; elmtnosize; + xbkg += stride ? stride : dst->size; } - offset += dst_memb_size; } else { for (xbuf=buf, elmtno=0; elmtnou.compnd.nmembs-1; i>=0; --i) { if (src2dst[i]<0) continue; @@ -1347,16 +1382,11 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, "unable to convert compound data " "type member"); } - } else { - offset -= dst_memb_size; - xbuf = buf + offset; - xbkg = bkg + dst_memb->offset + j*dst_memb_size; - } - - for (elmtno=0; elmtnosize; - xbkg += stride ? stride : dst->size; + for (elmtno=0; elmtnosize; + xbkg += stride ? stride : dst->size; + } } } } diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 08499a6..6777ea9 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -80,11 +80,13 @@ typedef struct s5_t { * Friday, January 23, 1998 * * Modifications: - * + * Robb Matzke, 1999-06-23 + * If the command line switch `--noopt' is present then the fast + * compound datatype conversion is turned off. *------------------------------------------------------------------------- */ int -main (void) +main (int argc, char *argv[]) { /* First dataset */ static s1_t s1[NX*NY]; @@ -134,6 +136,15 @@ main (void) h5_reset(); + /* Turn off optimized compound converter? */ + if (argc>1) { + if (argc>2 || strcmp("--noopt", argv[1])) { + fprintf(stderr, "usage: %s [--noopt]\n", argv[0]); + exit(1); + } + H5Tunregister(H5T_PERS_DONTCARE, NULL, -1, -1, H5T_conv_struct_opt); + } + /* Create the file */ fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); -- cgit v0.12