diff --git a/configure b/configure index 5e84ec4a64..efe71accbe 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 e2789df167..005984feb4 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 78033e4491..862eb8c18f 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 a27a444454..43051ca874 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 5b3262a04c..76afffa0cb 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 f469c61b74..dc9a7bc121 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 08499a6d03..6777ea9a56 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));