From c1e74850e7961cf8fe29a52e041650d74cc97ebf Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 30 Apr 2015 12:29:25 -0500 Subject: [svn-r26984] Add support for unlimited selection being clipped in the middle of a block. Add tests for this (pure selection tests, needs testing with VDS). Various bug fixes. Tested: ummon --- src/H5Shyper.c | 61 ++++++++++++++++++++++++++++++++++++++++------------------ src/H5Spkg.h | 6 +++++- test/tselect.c | 33 +++++++++++++++---------------- 3 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 6bff292..9b854c0 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -6711,9 +6711,9 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Save unlim_dim */ space->select.sel_info.hslab->unlim_dim = unlim_dim; - /* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection is + /* Initialize unlim_dim_clip_size to HSSIZET_MIN so the selection is * clipped by H5S__hyper_clip_unlim() no matter what the extent is */ - space->select.sel_info.hslab->unlim_dim_clip_size = H5S_UNLIMITED; + space->select.sel_info.hslab->unlim_dim_clip_size = HSSIZET_MIN; /* Indicate that the dimension information is valid */ space->select.sel_info.hslab->diminfo_valid = TRUE; @@ -6736,11 +6736,6 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); } /* end for */ - /* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection - * is clipped by H5S__hyper_clip_to_extent() no matter what the - * extent is */ - space->select.sel_info.hslab->unlim_dim_clip_size = H5S_UNLIMITED; - /* Set opt_diminfo or span tree based on extent */ if(H5S_hyper_clip_to_extent(space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't set selection based on extent") @@ -7381,10 +7376,10 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Save unlim_dim */ space->select.sel_info.hslab->unlim_dim = unlim_dim; - /* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection is + /* Initialize unlim_dim_clip_size to HSSIZET_MIN so the selection is * clipped by H5S__hyper_clip_to_extent() no matter what the extent is */ - space->unlim_dim_clip_size = H5S_UNLIMITED; + space->unlim_dim_clip_size = HSSIZET_MIN; /* Indicate that the dimension information is valid */ space->select.sel_info.hslab->diminfo_valid=TRUE; @@ -9586,7 +9581,8 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) HDassert(hslab->unlim_dim >= 0); /* Check for no need to change size */ - if(clip_size == hslab->unlim_dim_clip_size) + if(((hssize_t)clip_size - space->select.offset[hslab->unlim_dim]) + == hslab->unlim_dim_clip_size) HGOTO_DONE(SUCCEED) /* Free previous spans, if any */ @@ -9623,8 +9619,8 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Calculate actual block size for this clip size */ hslab->opt_diminfo[hslab->unlim_dim].block = (hsize_t)((hssize_t)space->extent.size[hslab->unlim_dim] - - ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start) - + space->select.offset[hslab->unlim_dim]); + - ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start + + space->select.offset[hslab->unlim_dim])); /* Calculate number of elements */ space->select.num_elem = hslab->opt_diminfo[hslab->unlim_dim].block @@ -9636,15 +9632,16 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) else { HDassert(hslab->opt_diminfo[hslab->unlim_dim].count == H5S_UNLIMITED); HDassert(hslab->opt_diminfo[hslab->unlim_dim].block != H5S_UNLIMITED); + HDassert((hssize_t)clip_size > space->select.offset[hslab->unlim_dim]); /* Calculate initial count (last block may be partial) */ hslab->opt_diminfo[hslab->unlim_dim].count = - ((hsize_t)((hssize_t)clip_size + (hsize_t)((hssize_t)clip_size - ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start + space->select.offset[hslab->unlim_dim]) + (hssize_t)hslab->opt_diminfo[hslab->unlim_dim].stride - (hssize_t)1) - / hslab->opt_diminfo[hslab->unlim_dim].stride); + / hslab->opt_diminfo[hslab->unlim_dim].stride; HDassert(hslab->opt_diminfo[hslab->unlim_dim].count > (hsize_t)0); /* Calculate number of elements */ @@ -9655,12 +9652,37 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Check if last block is partial */ if(((hslab->opt_diminfo[hslab->unlim_dim].stride * (hslab->opt_diminfo[hslab->unlim_dim].count - (hsize_t)1)) - + hslab->opt_diminfo[hslab->unlim_dim].block - (hsize_t)1) + + hslab->opt_diminfo[hslab->unlim_dim].block) > ((hsize_t)((hssize_t)clip_size - - (hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start - + space->select.offset[hslab->unlim_dim]))) { + - ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start + + space->select.offset[hslab->unlim_dim])))) { + hsize_t start[H5S_MAX_RANK]; + hsize_t block[H5S_MAX_RANK]; + unsigned i; + /* Last block is partial, need to construct compound selection */ - HDassert(0 && "Not yet implemented...");//VDSINC + /* Fill start with zeros */ + HDmemset(start, 0, sizeof(start)); + + /* Set block to clip_size in unlimited dimension, H5S_MAX_SIZE in + * others so only unlimited dimension is clipped */ + for(i = 0; i < space->extent.rank; i++) + if((int)i == hslab->unlim_dim) + block[i] = (hsize_t)((hssize_t)clip_size + - space->select.offset[hslab->unlim_dim]); + else + block[i] = H5S_MAX_SIZE; + + /* Generate span tree in selection */ + if(H5S_hyper_generate_spans(space) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to generate span tree") + + /* Indicate that the regular dimensions are no longer valid */ + hslab->diminfo_valid = FALSE; + + /* "And" selection with calculate block to perform clip operation */ + if(H5S_generate_hyperslab(space, H5S_SELECT_AND, start, _ones, _ones, block) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") } /* end if */ else /* Last block is complete, simply mark that opt_diminfo is valid */ @@ -9668,7 +9690,8 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) } /* end else */ /* Save clip size */ - hslab->unlim_dim_clip_size = clip_size; + hslab->unlim_dim_clip_size = (hssize_t)clip_size + - space->select.offset[hslab->unlim_dim]; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 226edf1..77ca954 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -55,6 +55,10 @@ * and 'size' callbacks for places to change when updating this. */ #define H5O_SDSPACE_VERSION_LATEST H5O_SDSPACE_VERSION_2 +/* Maximum dimension size (highest value that is not a special value e.g. + * H5S_UNLIMITED) */ +#define H5S_MAX_SIZE ((hsize_t)(hssize_t)(-2)) + /* * Dataspace extent information @@ -124,7 +128,7 @@ typedef struct { * contains H5S_UNLIMITED in the count or block of the unlimited * dimension (if any). */ int unlim_dim; /* Dimension where selection is unlimited, or -1 if none */ - hsize_t unlim_dim_clip_size; /* Size to which the selection is clipped in unlimited dimension */ + hssize_t unlim_dim_clip_size; /* Size to which the selection is clipped in unlimited dimension */ hsize_t num_elem_non_unlim; /* # of elements in a "slice" excluding the unlimited dimension */ H5S_hyper_span_info_t *span_lst; /* List of hyperslab span information */ } H5S_hyper_sel_t; diff --git a/test/tselect.c b/test/tselect.c index df67ff6..5190223 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -13375,7 +13375,6 @@ test_hyper_unlim(void) if(HDmemcmp(&blocklist[6], eblock2, sizeof(eblock2))) ERROR("H5Sget_select_hyper_blocklist"); -#if 0 //VDSINC /* Set offset of selection */ ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); @@ -13393,10 +13392,10 @@ test_hyper_unlim(void) CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); /* Verify blocklist */ - eblock1[1] = 1; - eblock1[4] = 6; - eblock2[1] = 1; - eblock2[4] = 6; + eblock1[1] = 2; + eblock1[4] = 7; + eblock2[1] = 2; + eblock2[4] = 7; if(HDmemcmp(blocklist, eblock1, sizeof(eblock1))) { if(HDmemcmp(blocklist, eblock2, sizeof(eblock2))) ERROR("H5Sget_select_hyper_blocklist"); @@ -13408,9 +13407,9 @@ test_hyper_unlim(void) ERROR("H5Sget_select_hyper_blocklist"); /* Reset offset of selection */ - ret = H5Soffset_simple(sid, NULL); + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); -#endif /* * Now try with multiple blocks in unlimited dimension @@ -13454,7 +13453,6 @@ test_hyper_unlim(void) if(HDmemcmp(&blocklist[6], eblock2, sizeof(eblock2))) ERROR("H5Sget_select_hyper_blocklist"); -#if 0 //VDSINC /* Shrink dataspace */ dims[1] = 3; ret = H5Sset_extent_simple(sid, 3, dims, mdims); @@ -13476,7 +13474,6 @@ test_hyper_unlim(void) eblock1[4] = 2; if(HDmemcmp(blocklist, eblock1, sizeof(eblock1))) ERROR("H5Sget_select_hyper_blocklist"); -#endif //VDSINC /* Extend dataspace */ dims[1] = 4; @@ -13521,7 +13518,6 @@ test_hyper_unlim(void) if(HDmemcmp(blocklist, eblock1, sizeof(eblock1))) ERROR("H5Sget_select_hyper_blocklist"); -#if 0 //VDSINC /* Extend dataspace */ dims[1] = 6; ret = H5Sset_extent_simple(sid, 3, dims, mdims); @@ -13552,6 +13548,7 @@ test_hyper_unlim(void) ERROR("H5Sget_select_hyper_blocklist"); /* Set offset of selection */ + offset[1] = (hssize_t)-1; ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); @@ -13568,10 +13565,10 @@ test_hyper_unlim(void) CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); /* Verify blocklist */ - eblock1[1] = 1; - eblock1[4] = 2; - eblock2[1] = 4; - eblock2[4] = 5; + eblock1[1] = 2; + eblock1[4] = 3; + eblock2[1] = 5; + eblock2[4] = 6; if(HDmemcmp(blocklist, eblock1, sizeof(eblock1))) { if(HDmemcmp(blocklist, eblock2, sizeof(eblock2))) ERROR("H5Sget_select_hyper_blocklist"); @@ -13600,15 +13597,15 @@ test_hyper_unlim(void) CHECK(ret, FAIL, "H5Sget_select_hyper_blocklist"); /* Verify blocklist */ - eblock1[1] = 5; - eblock1[4] = 5; + eblock1[1] = 2; + eblock1[4] = 2; if(HDmemcmp(blocklist, eblock1, sizeof(eblock1))) ERROR("H5Sget_select_hyper_blocklist"); /* Reset offset of selection */ - ret = H5Soffset_simple(sid, NULL); + offset[1] = (hssize_t)0; + ret = H5Soffset_simple(sid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); -#endif //VDSINC //VDSINC write test saving unlim selection to file as region reference -- cgit v0.12