From f395c2bb032888fbca30de953b41b44517d49089 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Wed, 29 Apr 2015 12:04:10 -0500 Subject: [svn-r26967] Refactor VDS unlimited dimension code to correctly handle case where selections have discrete blocks and the extent is set by the minimum (untested, and there is still no way to set that preference). Tested: ummon --- src/H5Dvirtual.c | 137 +++++++++++++++++++++++++++++++++++++------------------ src/H5Olayout.c | 1 + src/H5Oprivate.h | 1 + src/H5Pdcpl.c | 1 + src/H5Shyper.c | 46 ++++++++++++++----- src/H5Sprivate.h | 3 +- 6 files changed, 131 insertions(+), 58 deletions(-) diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 67f405f..40fe7ac 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -161,6 +161,7 @@ H5D__virtual_copy_layout(H5O_layout_t *layout) layout->storage.u.virt.list[i].unlim_extent_virtual = orig_list[i].unlim_extent_virtual; layout->storage.u.virt.list[i].clip_size_source = orig_list[i].clip_size_source; layout->storage.u.virt.list[i].clip_size_virtual = orig_list[i].clip_size_virtual; + layout->storage.u.virt.list[i].clip_size_virtual_incl_trail = orig_list[i].clip_size_virtual_incl_trail; layout->storage.u.virt.list[i].source_space_status = orig_list[i].source_space_status; layout->storage.u.virt.list[i].virtual_space_status = orig_list[i].virtual_space_status; } /* end for */ @@ -332,8 +333,10 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) { H5O_storage_virtual_t *storage; hsize_t new_dims[H5S_MAX_RANK]; + hsize_t max_dims[H5S_MAX_RANK]; hsize_t curr_dims[H5S_MAX_RANK]; hsize_t clip_size; + hsize_t clip_size_incl_trail; int rank; hbool_t changed = FALSE; /* Whether the VDS extent changed */ size_t i; @@ -350,9 +353,11 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) if((rank = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions") - /* Initialize new_dims to HSIZE_UNDEF */ - for(i = 0; i < (size_t)rank; i++) + /* Initialize new_dims and max_dims to HSIZE_UNDEF */ + for(i = 0; i < (size_t)rank; i++) { new_dims[i] = HSIZE_UNDEF; + max_dims[i] = HSIZE_UNDEF; + } /* end for */ /* Iterate over mappings */ for(i = 0; i < storage->list_nalloc; i++) @@ -376,40 +381,78 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) if(H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions") - /* Check if the source extent in the unlimited dimension - * changed since the last time the VDS extent/mapping - * was updated */ - if(curr_dims[storage->list[i].unlim_dim_source] - == storage->list[i].unlim_extent_source) - /* Use cached result for clip size */ - clip_size = storage->list[i].clip_size_virtual; - else { - /* Get size that virtual selection would be clipped - * to to match size of source selection */ - if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") - - /* If we are setting the extent by the maximum of all - * mappings, clip virtual_select. Note that if we used the - * cached clip_size above, the selection will already be - * clipped to the correct size. */ - if(storage->set_extent_max) + /* Check if we are setting extent by maximum or minimum of + * mappings */ + if(storage->set_extent_max) { + /* Check if the source extent in the unlimited dimension + * changed since the last time the VDS extent/mapping + * was updated */ + if(curr_dims[storage->list[i].unlim_dim_source] + == storage->list[i].unlim_extent_source) + /* Use cached result for clip size */ + clip_size = storage->list[i].clip_size_virtual; + else { + /* Get size that virtual selection would be clipped to + * to match size of source selection */ + if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") + + /* Clip virtual_select. Note that if we used the cached + * clip_size above, the selection will already be + * clipped to the correct size. */ if(H5S_hyper_clip_unlim(storage->list[i].virtual_select, clip_size)) HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") - /* Update cached values unlim_extent_source and - * clip_size_virtual */ - storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; - storage->list[i].clip_size_virtual = clip_size; - } /* end else */ + /* Update cached values unlim_extent_source and + * clip_size_virtual */ + storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; + storage->list[i].clip_size_virtual = clip_size; + } /* end else */ - /* Update new_dims */ - if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF) - || (storage->set_extent_max ? (clip_size - > (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]) - : (clip_size - < (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]))) - new_dims[storage->list[i].unlim_dim_virtual] = clip_size; + /* Update new_dims */ + if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF) + || (clip_size + > (hsize_t)new_dims[storage->list[i].unlim_dim_virtual])) + new_dims[storage->list[i].unlim_dim_virtual] = clip_size; + } /* end if */ + else { + /* Check if the source extent in the unlimited dimension + * changed since the last time the VDS extent/mapping was + * updated */ + if(curr_dims[storage->list[i].unlim_dim_source] + == storage->list[i].unlim_extent_source) { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* Use cached result for clip size */ + clip_size = storage->list[i].clip_size_virtual; + clip_size_incl_trail = storage->list[i].clip_size_virtual_incl_trail; + } //VDSINC + else { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* Get size that virtual selection would be clipped to + * to match size of source selection. Also get the clip + * size including the trailing space (gap between + * blocks). */ + if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size, &clip_size_incl_trail) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") + + /* Update cached values unlim_extent_source, + * clip_size_virtual, and clip_size_virtual_incl_trail + */ + storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source]; + storage->list[i].clip_size_virtual = clip_size; + storage->list[i].clip_size_virtual_incl_trail = clip_size_incl_trail; + } /* end else */ + + /* Update new_dims and max_dims */ + if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF) + || (clip_size_incl_trail + < (hsize_t)new_dims[storage->list[i].unlim_dim_virtual])) + new_dims[storage->list[i].unlim_dim_virtual] = clip_size_incl_trail; + if((max_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF) + || (clip_size + > (hsize_t)max_dims[storage->list[i].unlim_dim_virtual])) + max_dims[storage->list[i].unlim_dim_virtual] = clip_size; + } /* end else */ } /* end if */ } /* end if */ @@ -417,17 +460,21 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions") - /* Calculate new extent */ + /* Calculate new extent. Apply max_dims first, so min_dims takes precedent. + */ for(i = 0; i < (size_t)rank; i++) { - if((new_dims[i] != HSIZE_UNDEF) && (new_dims[i] != curr_dims[i])) { - changed = TRUE; - curr_dims[i] = new_dims[i]; - } /* end if */ - if(storage->min_dims[i] > curr_dims[i]) { + if(new_dims[i] == HSIZE_UNDEF) + new_dims[i] = curr_dims[i]; + if((max_dims[i] != HSIZE_UNDEF) && (new_dims[i] > max_dims[i])) { + HDassert(0 && "Checking code coverage..."); //VDSINC + new_dims[i] = max_dims[i]; + } //VDSINC + if(new_dims[i] < storage->min_dims[i]) { HDassert(0 && "Checking code coverage..."); //VDSINC + new_dims[i] = storage->min_dims[i]; + } //VDSINC + if(new_dims[i] != curr_dims[i]) changed = TRUE; - curr_dims[i] = storage->min_dims[i]; - } /* end if */ } /* end for */ /* If we did not change the VDS dimensions and we are setting the extent by @@ -435,7 +482,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) if(changed || !storage->set_extent_max) { /* Update VDS extent */ if(changed) - if(H5S_set_extent(dset->shared->space, curr_dims) < 0) + if(H5S_set_extent(dset->shared->space, new_dims) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") /* Iterate over mappings again to update source selections and virtual @@ -449,7 +496,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) /* Update virtual mapping extent. Note this function does not * clip the selection. */ if(changed) - if(H5S_set_extent(storage->list[i].virtual_select, curr_dims) < 0) + if(H5S_set_extent(storage->list[i].virtual_select, new_dims) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") /* Check if we are setting extent by the minimum of mappings */ @@ -466,7 +513,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) /* Check if the virtual extent in the unlimited dimension * changed since the last time the VDS extent/mapping was * updated */ - if(curr_dims[storage->list[i].unlim_dim_virtual] + if(new_dims[storage->list[i].unlim_dim_virtual] == storage->list[i].unlim_extent_virtual) { HDassert(0 && "Checking code coverage..."); //VDSINC /* Use cached result for clip size */ @@ -476,12 +523,12 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) HDassert(0 && "Checking code coverage..."); //VDSINC /* Get size that source selection will be clipped to to * match size of virtual selection */ - if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].virtual_select, &clip_size) < 0) + if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].virtual_select, &clip_size, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") /* Update cached values unlim_extent_virtual and * clip_size_source */ - storage->list[i].unlim_extent_virtual = curr_dims[storage->list[i].unlim_dim_virtual]; + storage->list[i].unlim_extent_virtual = new_dims[storage->list[i].unlim_dim_virtual]; storage->list[i].clip_size_source = clip_size; } /* end else */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index fb9bb9c..cf5b3d2 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -309,6 +309,7 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, mesg->storage.u.virt.list[i].unlim_extent_virtual = HSIZE_UNDEF; mesg->storage.u.virt.list[i].clip_size_source = HSIZE_UNDEF; mesg->storage.u.virt.list[i].clip_size_virtual = HSIZE_UNDEF; + mesg->storage.u.virt.list[i].clip_size_virtual_incl_trail = HSIZE_UNDEF; /* Update min_dims */ if(H5D_virtual_update_min_dims(mesg, i) < 0) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 74cc9a4..0211093 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -433,6 +433,7 @@ typedef struct H5O_storage_virtual_ent_t { hsize_t unlim_extent_source; /* Extent of unlimited dimension in source dset last time virtual_select was patched to match selection */ hsize_t unlim_extent_virtual; /* Extent of unlimited dimension in virtual dset last time source_select was patched to match selection */ hsize_t clip_size_virtual; /* Size selection would be clipped to in virtual selection, ignoring other mappings, when source extent == unlim_extent_source */ + hsize_t clip_size_virtual_incl_trail; /* Like above, but includes gap after last block */ hsize_t clip_size_source; /* Size selection would be clipped to in source selection when virtual extent == unlim_extent_virtual */ H5O_virtual_space_status_t source_space_status; /* Extent patching status of source_select */ H5O_virtual_space_status_t virtual_space_status; /* Extent patching status of virtual_select */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 575de9c..8f400cf 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1676,6 +1676,7 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_extent_virtual = HSIZE_UNDEF; layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_source = HSIZE_UNDEF; layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_virtual = HSIZE_UNDEF; + layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_virtual_incl_trail = HSIZE_UNDEF; layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_space_status = H5O_VIRTUAL_STATUS_USER; layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_space_status = H5O_VIRTUAL_STATUS_USER; diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 81306c9..6bff292 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -9741,8 +9741,8 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_hyper_get_clip_extent(const H5S_t *clip_space, - const H5S_t *match_space, hsize_t *clip_space_unlim_extent) +H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, + hsize_t *clip_size, hsize_t *clip_size_incl_trail) { const H5S_hyper_sel_t *clip_hslab; /* Convenience pointer to hyperslab info */ const H5S_hyper_sel_t *match_hslab; /* Convenience pointer to hyperslab info */ @@ -9759,7 +9759,7 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, HDassert(match_space); match_hslab = match_space->select.sel_info.hslab; HDassert(match_space); - HDassert(clip_space_unlim_extent); + HDassert(clip_size); HDassert(clip_hslab->unlim_dim >= 0); HDassert(match_hslab->unlim_dim >= 0); HDassert(clip_hslab->num_elem_non_unlim == match_hslab->num_elem_non_unlim); @@ -9767,17 +9767,25 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, /* Calculate number of slices */ num_slices = match_space->select.num_elem / match_hslab->num_elem_non_unlim; - if(num_slices == 0) - *clip_space_unlim_extent = 0; + if(num_slices == 0) { + *clip_size = 0; + if(clip_size_incl_trail) { + HDassert(0 && "Checking code coverage..."); //VDSINC + *clip_size_incl_trail = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start; + } //VDSINC + } /* end if */ else if(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block == H5S_UNLIMITED) { - HDassert(0 && "Checking code coverage..."); //VDSINC /* Unlimited block, just set the extent large enough for the block size * to match num_slices */ HDassert(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].count == (hsize_t)1); - *clip_space_unlim_extent = + *clip_size = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + num_slices; + if(clip_size_incl_trail) { + HDassert(0 && "Checking code coverage..."); //VDSINC + *clip_size_incl_trail = *clip_size; + } //VDSINC } /* end if */ else { /* Unlimited count, need to match extent so a block (possibly) gets cut @@ -9793,20 +9801,34 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, if(rem_slices > 0) { HDassert(0 && "Checking code coverage..."); //VDSINC - /* Must end extent in middle of partial block */ - *clip_space_unlim_extent = + /* Must end extent in middle of partial block (or beginning of empty + * block if include_trailing_space and rem_slices == 0) */ + *clip_size = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + (count * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride) + rem_slices; - } //VDSINC - else + if(clip_size_incl_trail) { + HDassert(0 && "Checking code coverage..."); //VDSINC + *clip_size_incl_trail = *clip_size; + } //VDSINC + } /* end if */ + else { /* End extent at end of last block */ - *clip_space_unlim_extent = + *clip_size = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + ((count - (hsize_t)1) * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride) + clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block; + if(clip_size_incl_trail) { + HDassert(0 && "Checking code coverage..."); //VDSINC + /* Include gap after last block */ + *clip_size_incl_trail = + clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + + (count + * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride); + } //VDSINC + } /* end else */ } /* end else */ FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index ebfa88e..2900839 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -269,7 +269,8 @@ H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_off H5_DLL herr_t H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size); H5_DLL herr_t H5S_hyper_clip_to_extent(H5S_t *space); H5_DLL herr_t H5S_hyper_get_clip_extent(const H5S_t *clip_space, - const H5S_t *match_space, hsize_t *clip_space_unlim_extent); + const H5S_t *match_space, hsize_t *clip_size, + hsize_t *clip_size_incl_trail); /* Operations on selection iterators */ H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); -- cgit v0.12