diff options
-rw-r--r-- | src/H5Dvirtual.c | 137 | ||||
-rw-r--r-- | src/H5Olayout.c | 1 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 1 | ||||
-rw-r--r-- | src/H5Shyper.c | 46 | ||||
-rw-r--r-- | 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); |