From 5b92a99024214884428796394fef7376c2d09f3f Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Mon, 11 May 2015 14:01:42 -0500 Subject: [svn-r27049] Rename H5Pset/get_virtual_dataspace_bounds to H5Pset/get_virtual_view and rename enum argument. Add support for AND and NOTA/NOTB operations with unlimited selections. Add some tests for unlimited selections. Other minor fixes/cleanup. Note: "clipped" status of unlimited selections is not properly updated with H5Sselect_copy. This is a deliberate omission since fixing it would take work and we are planning to eliminate the clipped status anyways. Tested: ummon --- src/H5Dprivate.h | 2 +- src/H5Dpublic.h | 10 +- src/H5Dvirtual.c | 133 ++---- src/H5Olayout.c | 3 +- src/H5Oprivate.h | 3 +- src/H5Pdapl.c | 69 +-- src/H5Pdcpl.c | 1 - src/H5Ppublic.h | 5 +- src/H5Shyper.c | 321 ++++++++++---- src/H5Sprivate.h | 3 +- test/vds.c | 1295 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 11 files changed, 1614 insertions(+), 231 deletions(-) diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index a89f937..88a04ec 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -52,7 +52,7 @@ #define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */ #define H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */ #define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */ -#define H5D_ACS_VDS_BOUNDS_NAME "vds_bounds" /* VDS bounds option */ +#define H5D_ACS_VDS_VIEW_NAME "vds_view" /* VDS view option */ /* ======== Data transfer properties ======== */ #define H5D_XFER_MAX_TEMP_BUF_NAME "max_temp_buf" /* Maximum temp buffer size */ diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index e4b1311..a1f87e3 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -95,11 +95,11 @@ typedef enum H5D_fill_value_t { } H5D_fill_value_t; /* Values for VDS bounds option */ -typedef enum H5D_vds_bounds_t { - H5D_VDS_ERROR = -1, - H5D_VDS_MAX = 0, - H5D_VDS_MIN = 1 -} H5D_vds_bounds_t; +typedef enum H5D_vds_view_t { + H5D_VDS_ERROR = -1, + H5D_VDS_FIRST_MISSING = 0, + H5D_VDS_LAST_AVAILABLE = 1 +} H5D_vds_view_t; /********************/ /* Public Variables */ diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 109078f..6415afd 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -161,7 +161,6 @@ 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 */ @@ -333,10 +332,8 @@ 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; @@ -348,17 +345,15 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) HDassert(dset); storage = &dset->shared->layout.storage.u.virt; HDassert(dset->shared->layout.storage.type == H5D_VIRTUAL); - HDassert((storage->bounds == H5D_VDS_MAX) || (storage->bounds == H5D_VDS_MIN)); + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); /* Get rank of VDS */ 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 and max_dims to HSIZE_UNDEF */ - for(i = 0; i < (size_t)rank; i++) { + /* Initialize new_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++) @@ -382,77 +377,40 @@ 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 we are setting extent by maximum or minimum of - * mappings */ - if(storage->bounds == H5D_VDS_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. */ + /* 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, storage->view == H5D_VDS_FIRST_MISSING) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") + + /* If we are setting the extent by the last available data, + * 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->view == H5D_VDS_LAST_AVAILABLE) 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 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 { - /* 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; + /* 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->view == H5D_VDS_FIRST_MISSING ? (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; } /* end if */ } /* end if */ @@ -460,15 +418,10 @@ 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. Apply max_dims first, so min_dims takes precedent. - */ + /* Calculate new extent */ for(i = 0; i < (size_t)rank; 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]; @@ -479,7 +432,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) /* If we did not change the VDS dimensions and we are setting the extent by * maximum, there is nothing more to update */ - if(changed || (storage->bounds == H5D_VDS_MIN)) { + if(changed || (storage->view == H5D_VDS_FIRST_MISSING)) { /* Update VDS extent */ if(changed) if(H5S_set_extent(dset->shared->space, new_dims) < 0) @@ -500,7 +453,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) 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 */ - if(storage->bounds == H5D_VDS_MIN) { + if(storage->view == H5D_VDS_FIRST_MISSING) { /* Clip virtual selection to extent (only necessary if the * extent changed, otherwise it will already be clipped to * the extent) */ @@ -512,15 +465,13 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) * changed since the last time the VDS extent/mapping was * updated */ if(new_dims[storage->list[i].unlim_dim_virtual] - == storage->list[i].unlim_extent_virtual) { - HDassert(0 && "Checking code coverage..."); //VDSINC + == storage->list[i].unlim_extent_virtual) /* Use cached result for clip size */ clip_size = storage->list[i].clip_size_source; - } //VDSINC else { /* 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, NULL) < 0) + if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].virtual_select, &clip_size, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size") /* Update cached values unlim_extent_virtual and @@ -675,8 +626,8 @@ H5D__virtual_init(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const H5D_t *dset, HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for dapl ID") /* Get bounds option */ - if(H5P_get(dapl, H5D_ACS_VDS_BOUNDS_NAME, &dset->shared->layout.storage.u.virt.bounds) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache number of slots") + if(H5P_get(dapl, H5D_ACS_VDS_VIEW_NAME, &dset->shared->layout.storage.u.virt.view) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get virtual view option") done: FUNC_LEAVE_NOAPI(ret_value) @@ -770,7 +721,7 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HDassert(file_space); storage = &io_info->dset->shared->layout.storage.u.virt; - HDassert((storage->bounds == H5D_VDS_MAX) || (storage->bounds == H5D_VDS_MIN)); + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); /* Iterate over mappings */ for(i = 0; i < storage->list_nused; i++) { @@ -878,7 +829,7 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HDassert(file_space); storage = &io_info->dset->shared->layout.storage.u.virt; - HDassert((storage->bounds == H5D_VDS_MAX) || (storage->bounds == H5D_VDS_MIN)); + HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE)); /* Iterate over mappings */ for(i = 0; i < storage->list_nused; i++) { diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 9f1afb3..dce41cf 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -251,7 +251,7 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh, mesg->storage.u.virt.list_nused = 0; mesg->storage.u.virt.list = NULL; mesg->storage.u.virt.list_nalloc = 0; - mesg->storage.u.virt.bounds = H5D_VDS_ERROR; + mesg->storage.u.virt.view = H5D_VDS_ERROR; /* Decode heap block if it exists */ if(mesg->storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF) { @@ -309,7 +309,6 @@ 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 fcb0649..09a5b9c 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -433,7 +433,6 @@ 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 */ @@ -450,7 +449,7 @@ typedef struct H5O_storage_virtual_t { /* Not stored */ size_t list_nalloc; /* Number of slots allocated */ hsize_t min_dims[H5S_MAX_RANK]; /* Minimum extent of VDS (maximum of all non-unlimited selection bounds) */ - H5D_vds_bounds_t bounds; /* Whether we set the extent by the maximum (TRUE) or minimum (FALSE) of unlimited selections */ + H5D_vds_view_t view; /* Method for calculating the extent of the virtual dataset with unlimited selections */ } H5O_storage_virtual_t; typedef struct H5O_storage_t { diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index fbd83a6..af4b988 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -62,10 +62,10 @@ #define H5D_ACS_PREEMPT_READ_CHUNKS_ENC H5P__encode_double #define H5D_ACS_PREEMPT_READ_CHUNKS_DEC H5P__decode_double /* Definitions for VDS bounds option */ -#define H5D_ACS_VDS_BOUNDS_SIZE sizeof(H5D_vds_bounds_t) -#define H5D_ACS_VDS_BOUNDS_DEF H5D_VDS_MAX -#define H5D_ACS_VDS_BOUNDS_ENC H5P__dacc_vds_bounds_enc -#define H5D_ACS_VDS_BOUNDS_DEC H5P__dacc_vds_bounds_dec +#define H5D_ACS_VDS_VIEW_SIZE sizeof(H5D_vds_view_t) +#define H5D_ACS_VDS_VIEW_DEF H5D_VDS_LAST_AVAILABLE +#define H5D_ACS_VDS_VIEW_ENC H5P__dacc_vds_view_enc +#define H5D_ACS_VDS_VIEW_DEC H5P__dacc_vds_view_dec /******************/ /* Local Typedefs */ @@ -85,8 +85,8 @@ static herr_t H5P__dacc_reg_prop(H5P_genclass_t *pclass); /* Property list callbacks */ -static herr_t H5P__dacc_vds_bounds_enc(const void *value, void **pp, size_t *size); -static herr_t H5P__dacc_vds_bounds_dec(const void **pp, void *value); +static herr_t H5P__dacc_vds_view_enc(const void *value, void **pp, size_t *size); +static herr_t H5P__dacc_vds_view_dec(const void **pp, void *value); /*********************/ @@ -142,7 +142,7 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass) size_t rdcc_nslots = H5D_ACS_DATA_CACHE_NUM_SLOTS_DEF; /* Default raw data chunk cache # of slots */ size_t rdcc_nbytes = H5D_ACS_DATA_CACHE_BYTE_SIZE_DEF; /* Default raw data chunk cache # of bytes */ double rdcc_w0 = H5D_ACS_PREEMPT_READ_CHUNKS_DEF; /* Default raw data chunk cache dirty ratio */ - H5D_vds_bounds_t bounds_option = H5D_ACS_VDS_BOUNDS_DEF; /* Default VDS bounds option */ + H5D_vds_view_t virtual_view = H5D_ACS_VDS_VIEW_DEF; /* Default VDS view option */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -162,9 +162,9 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, H5D_ACS_PREEMPT_READ_CHUNKS_ENC, H5D_ACS_PREEMPT_READ_CHUNKS_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - /* Register the VDS bounds option */ - if(H5P_register_real(pclass, H5D_ACS_VDS_BOUNDS_NAME, H5D_ACS_VDS_BOUNDS_SIZE, &bounds_option, - NULL, NULL, NULL, H5D_ACS_VDS_BOUNDS_ENC, H5D_ACS_VDS_BOUNDS_DEC, + /* Register the VDS view option */ + if(H5P_register_real(pclass, H5D_ACS_VDS_VIEW_NAME, H5D_ACS_VDS_VIEW_SIZE, &virtual_view, + NULL, NULL, NULL, H5D_ACS_VDS_VIEW_ENC, H5D_ACS_VDS_VIEW_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") @@ -302,7 +302,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Pset_virtual_dataspace_bounds + * Function: H5Pset_virtual_view * * Purpose: VDSINC * @@ -314,7 +314,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Pset_virtual_dataspace_bounds(hid_t plist_id, H5D_vds_bounds_t bounds_option) +H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view) { H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* return value */ @@ -322,7 +322,7 @@ H5Pset_virtual_dataspace_bounds(hid_t plist_id, H5D_vds_bounds_t bounds_option) FUNC_ENTER_API(FAIL) /* Check argument */ - if((bounds_option != H5D_VDS_MAX) && (bounds_option != H5D_VDS_MIN)) + if((view != H5D_VDS_FIRST_MISSING) && (view != H5D_VDS_LAST_AVAILABLE)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid bounds option") /* Get the plist structure */ @@ -330,20 +330,21 @@ H5Pset_virtual_dataspace_bounds(hid_t plist_id, H5D_vds_bounds_t bounds_option) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Update property list */ - if(H5P_set(plist, H5D_ACS_VDS_BOUNDS_NAME, &bounds_option) < 0) + if(H5P_set(plist, H5D_ACS_VDS_VIEW_NAME, &view) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value") done: FUNC_LEAVE_API(ret_value) -} /* end H5Pset_virtual_dataspace_bounds() */ +} /* end H5Pset_virtual_view() */ /*------------------------------------------------------------------------- - * Function: H5Pget_virtual_dataspace_bounds + * Function: H5Pget_virtual_view * * Purpose: VDSINC * - * Return: Success: H5D_VDS_MAX or H5D_VDS_MIN + * Return: Success: H5D_VDS_FIRST_MISSING or + * H5D_VDS_LAST_AVAILABLE * Failure: H5D_VDS_ERROR * * Programmer: Neil Fortner @@ -351,11 +352,11 @@ done: * *------------------------------------------------------------------------- */ -H5D_vds_bounds_t -H5Pget_virtual_dataspace_bounds(hid_t plist_id) +H5D_vds_view_t +H5Pget_virtual_view(hid_t plist_id) { H5P_genplist_t *plist; /* Property list pointer */ - H5D_vds_bounds_t ret_value; /* Return value */ + H5D_vds_view_t ret_value; /* Return value */ FUNC_ENTER_API(H5D_VDS_ERROR) @@ -364,16 +365,16 @@ H5Pget_virtual_dataspace_bounds(hid_t plist_id) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5D_VDS_ERROR, "can't find object for ID") /* Get value from property list */ - if(H5P_get(plist, H5D_ACS_VDS_BOUNDS_NAME, &ret_value) < 0) + if(H5P_get(plist, H5D_ACS_VDS_VIEW_NAME, &ret_value) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5D_VDS_ERROR, "unable to set value") done: FUNC_LEAVE_API(ret_value) -} /* end H5Pget_virtual_dataspace_bounds() */ +} /* end H5Pget_virtual_view() */ /*------------------------------------------------------------------------- - * Function: H5P__dacc_vds_bounds_enc + * Function: H5P__dacc_vds_view_enc * * Purpose: Callback routine which is called whenever the vds bounds * property in the dataset access property list is encoded. @@ -387,30 +388,30 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5P__dacc_vds_bounds_enc(const void *value, void **_pp, size_t *size) +H5P__dacc_vds_view_enc(const void *value, void **_pp, size_t *size) { - const H5D_vds_bounds_t *bounds = (const H5D_vds_bounds_t *)value; /* Create local alias for values */ + const H5D_vds_view_t *view = (const H5D_vds_view_t *)value; /* Create local alias for values */ uint8_t **pp = (uint8_t **)_pp; FUNC_ENTER_STATIC_NOERR /* Sanity check */ - HDassert(bounds); + HDassert(view); HDassert(size); if(NULL != *pp) /* Encode EDC property */ - *(*pp)++ = (uint8_t)*bounds; + *(*pp)++ = (uint8_t)*view; /* Size of EDC property */ (*size)++; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5P__dacc_vds_bounds_enc() */ +} /* end H5P__dacc_vds_view_enc() */ /*------------------------------------------------------------------------- - * Function: H5P__dacc_vds_bounds_dec + * Function: H5P__dacc_vds_view_dec * * Purpose: Callback routine which is called whenever the vds bounds * property in the dataset access property list is encoded. @@ -424,9 +425,9 @@ H5P__dacc_vds_bounds_enc(const void *value, void **_pp, size_t *size) *------------------------------------------------------------------------- */ static herr_t -H5P__dacc_vds_bounds_dec(const void **_pp, void *_value) +H5P__dacc_vds_view_dec(const void **_pp, void *_value) { - H5D_vds_bounds_t *bounds = (H5D_vds_bounds_t *)_value; /* EDC property */ + H5D_vds_view_t *view = (H5D_vds_view_t *)_value; const uint8_t **pp = (const uint8_t **)_pp; FUNC_ENTER_STATIC_NOERR @@ -434,11 +435,11 @@ H5P__dacc_vds_bounds_dec(const void **_pp, void *_value) /* Sanity checks */ HDassert(pp); HDassert(*pp); - HDassert(bounds); + HDassert(view); /* Decode EDC property */ - *bounds = (H5D_vds_bounds_t)*(*pp)++; + *view = (H5D_vds_view_t)*(*pp)++; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5P__dacc_vds_bounds_dec() */ +} /* end H5P__dacc_vds_view_dec() */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 8f400cf..575de9c 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1676,7 +1676,6 @@ 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/H5Ppublic.h b/src/H5Ppublic.h index 7932716..5ea857a 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -393,9 +393,8 @@ H5_DLL herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots/*out*/, size_t *rdcc_nbytes/*out*/, double *rdcc_w0/*out*/); -H5_DLL herr_t H5Pset_virtual_dataspace_bounds(hid_t plist_id, - H5D_vds_bounds_t bounds_option); -H5_DLL H5D_vds_bounds_t H5Pget_virtual_dataspace_bounds(hid_t plist_id); +H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view); +H5_DLL H5D_vds_view_t H5Pget_virtual_view(hid_t plist_id); /* Dataset xfer property list (DXPL) routines */ H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char* expression); diff --git a/src/H5Shyper.c b/src/H5Shyper.c index e177d7d..468f87e 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -45,6 +45,8 @@ static herr_t H5S_hyper_generate_spans(H5S_t *space); #ifdef NEW_HYPERSLAB_API static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); #endif /*NEW_HYPERSLAB_API*/ +static void H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, + hsize_t *count, hsize_t *block, hssize_t offset, hsize_t clip_size); /* Selection callbacks */ static herr_t H5S_hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); @@ -1674,8 +1676,11 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection) } /* end if */ /* If there is an unlimited dimension, we must update the selection */ - if(H5S_hyper_clip_to_extent(dst) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab") + /* Disabled to make chunk I/O work. This is a quick hack - no sense in a + * proper fix since we are planning to change how unlimited selections work + * anyways. VDSINC */ + /*if(H5S_hyper_clip_to_extent(dst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")*/ done: FUNC_LEAVE_NOAPI(ret_value) @@ -6484,13 +6489,15 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Check for unlimited dimension */ for(u = 0; uextent.rank; u++) if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) { - if(unlim_dim >= 0) + if(unlim_dim >= 0) { + HDassert(0 && "Checking code coverage..."); //VDSINC HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") + } //VDSINC else { - if(op != H5S_SELECT_SET) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot use unlimited selection to modify existing selection") - if(count[u] == block[u] /* == H5S_UNLIMITED */) + if(count[u] == block[u] /* == H5S_UNLIMITED */) { + HDassert(0 && "Checking code coverage..."); //VDSINC HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") + } //VDSINC unlim_dim = (int)u; } /* end else */ } /* end if */ @@ -6734,9 +6741,65 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Sanity check */ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - /* Cannot modify unlimited selections */ - if(space->select.sel_info.hslab->unlim_dim >= 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection") + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + hsize_t tmp_count = opt_count[unlim_dim]; + hsize_t tmp_block = opt_block[unlim_dim]; + + HDassert(0 && "Checking code coverage..."); //VDSINC + /* Check for invalid operation */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + + /* Get bounds of existing selection */ + if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Patch count and block to remove unlimited and include the + * existing selection */ + H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, space->select.offset[unlim_dim], bounds_end[unlim_dim]); + HDassert((tmp_count == 1) || (opt_count != _ones)); + HDassert((tmp_block == 1) || (opt_block != _ones)); + if(opt_count != _ones) { + HDassert(opt_count == int_count); + int_count[unlim_dim] = tmp_count; + } /* end if */ + if(opt_block != _ones) { + HDassert(opt_block == int_block); + int_block[unlim_dim] = tmp_block; + } /* end if */ + } /* end if */ + else if(space->select.sel_info.hslab->unlim_dim >= 0) { + /* Check for invalid operation */ + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") + + /* Convert to limited selection */ + space->select.sel_info.hslab->unlim_dim = -1; + + /* Currently just use the existing clip size. This is not ideal and + * may give surprising results. Note this will work differently + * when we switch to the new way of handling unlimited selections + * (unlimited selections have no clip size or clipped version). See + * below. VDSINC */ +#if 0 //VDSINC + /* Clip unlimited selection to include new selection */ + if(H5S_hyper_clip_unlim(space, + (hsize_t)((hssize_t)start[space->select.sel_info.hslab->unlim_dim] + + space->select.offset[space->select.sel_info.hslab->unlim_dim] + + (((hssize_t)opt_count[space->select.sel_info.hslab->unlim_dim] + - (hssize_t)1) + * (hssize_t)opt_stride[space->select.sel_info.hslab->unlim_dim]) + + (hssize_t)opt_block[space->select.sel_info.hslab->unlim_dim])) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") +#endif + } /* end if */ /* Check if there's no hyperslab span information currently */ if(NULL == space->select.sel_info.hslab->span_lst) @@ -7161,10 +7224,6 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection") } //VDSINC else { - if(op != H5S_SELECT_SET) { - HDassert(0 && "Checking code coverage..."); //VDSINC - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot use unlimited selection to modify existing selection") - } //VDSINC if(count[u] == block[u] /* == H5S_UNLIMITED */) { HDassert(0 && "Checking code coverage..."); //VDSINC HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited") @@ -7343,8 +7402,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab") /* Allocate space for the hyperslab selection information */ - if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab info") + if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info") /* Save the diminfo */ space->select.num_elem=1; @@ -7368,23 +7427,25 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* 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 = HSSIZET_MIN; + 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; + space->select.sel_info.hslab->diminfo_valid = TRUE; /* Indicate that there's no slab information */ - space->select.sel_info.hslab->span_lst=NULL; + space->select.sel_info.hslab->span_lst = NULL; /* Handle unlimited selections */ if(unlim_dim >= 0) { space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1; for(u = 0; u < space->extent.rank; u++) { + /* Save start/stride/count/block */ space->select.sel_info.hslab->opt_unlim_diminfo[u].start = start[u]; space->select.sel_info.hslab->opt_unlim_diminfo[u].stride = opt_stride[u]; space->select.sel_info.hslab->opt_unlim_diminfo[u].count = opt_count[u]; space->select.sel_info.hslab->opt_unlim_diminfo[u].block = opt_block[u]; + /* Calculate num_elem_non_unlim */ if((int)u != unlim_dim) space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]); } /* end for */ @@ -7398,29 +7459,83 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Sanity check */ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS); - /* Cannot modify unlimited selections */ - if(space->select.sel_info.hslab->unlim_dim >= 0) { + /* Handle unlimited selections */ + if(unlim_dim >= 0) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + hsize_t tmp_count = opt_count[unlim_dim]; + hsize_t tmp_block = opt_block[unlim_dim]; + HDassert(0 && "Checking code coverage..."); //VDSINC - HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection") - } //VDSINC + /* Check for invalid operation */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTB))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation with unlimited selection") + + /* Get bounds of existing selection */ + if(H5S_hyper_bounds(space, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Patch count and block to remove unlimited and include the + * existing selection */ + H5S__hyper_get_clip_diminfo(start[unlim_dim], opt_stride[unlim_dim], &tmp_count, &tmp_block, space->select.offset[unlim_dim], bounds_end[unlim_dim]); + HDassert((tmp_count == 1) || (opt_count != _ones)); + HDassert((tmp_block == 1) || (opt_block != _ones)); + if(opt_count != _ones) { + HDassert(opt_count == int_count); + int_count[unlim_dim] = tmp_count; + } /* end if */ + if(opt_block != _ones) { + HDassert(opt_block == int_block); + int_block[unlim_dim] = tmp_block; + } /* end if */ + } /* end if */ + else if(space->select.sel_info.hslab->unlim_dim >= 0) { + /* Check for invalid operation */ + if(unlim_dim >= 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection with another unlimited selection") + if(!((op == H5S_SELECT_AND) || (op == H5S_SELECT_NOTA))) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported operation on unlimited selection") + + /* Convert to limited selection */ + space->select.sel_info.hslab->unlim_dim = -1; + + /* Currently just use the existing clip size. This is not ideal and + * may give surprising results. Note this will work differently + * when we switch to the new way of handling unlimited selections + * (unlimited selections have no clip size or clipped version). See + * below. VDSINC */ +#if 0 //VDSINC + /* Clip unlimited selection to include new selection */ + if(H5S_hyper_clip_unlim(space, + (hsize_t)((hssize_t)start[space->select.sel_info.hslab->unlim_dim] + + space->select.offset[space->select.sel_info.hslab->unlim_dim] + + (((hssize_t)opt_count[space->select.sel_info.hslab->unlim_dim] + - (hssize_t)1) + * (hssize_t)opt_stride[space->select.sel_info.hslab->unlim_dim]) + + (hssize_t)opt_block[space->select.sel_info.hslab->unlim_dim])) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection") +#endif + } /* end if */ /* Check if there's no hyperslab span information currently */ - if(space->select.sel_info.hslab->span_lst==NULL) - if(H5S_hyper_generate_spans(space)<0) + if(NULL == space->select.sel_info.hslab->span_lst) + if(H5S_hyper_generate_spans(space) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree") + /* Indicate that the regular dimensions are no longer valid */ + space->select.sel_info.hslab->diminfo_valid = FALSE; + /* Add in the new hyperslab information */ if(H5S_generate_hyperslab (space, op, start, opt_stride, opt_count, opt_block)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs") - - /* Indicate that the regular dimensions are no longer valid */ - space->select.sel_info.hslab->diminfo_valid=FALSE; } /* end if */ else HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") /* Set selection type */ - space->select.type=H5S_sel_hyper; + space->select.type = H5S_sel_hyper; done: FUNC_LEAVE_NOAPI(ret_value) @@ -9538,6 +9653,63 @@ done: /*-------------------------------------------------------------------------- NAME + H5S__hyper_get_clip_diminfo + PURPOSE + Calculates the count and block required to clip the specified + unlimited dimension to include clip_size. The returned selection may + extent beyond clip_size. + USAGE + VDSINC + RETURNS + Non-negative on success/Negative on failure. + DESCRIPTION + This function recalculates the internal description of the hyperslab + to make the unlimited dimension extend to the specified extent. if + superset is TRUE, then the hyperslab can be clipped to a size equal to + or greater than clip_size. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Note this function takes the offset into account. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5S__hyper_get_clip_diminfo(hsize_t start, hsize_t stride, hsize_t *count, + hsize_t *block, hssize_t offset, hsize_t clip_size) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Check for selection outside clip size */ + if((hsize_t)((hssize_t)start + offset) >= clip_size) { + if(*block == H5S_UNLIMITED) + *block = 0; + else + *count = 0; + } /* end if */ + /* Check for single block in unlimited dimension */ + else if(*count == (hsize_t)1) { + HDassert(*block == H5S_UNLIMITED); + + /* Calculate actual block size for this clip size */ + *block = (hsize_t)((hssize_t)clip_size - ((hssize_t)start + offset)); + } /* end if */ + else { + HDassert(*count == H5S_UNLIMITED); + HDassert(*block != H5S_UNLIMITED); + HDassert((hssize_t)clip_size > offset); + + /* Calculate initial count (last block may be partial) */ + *count = (hsize_t)((hssize_t)clip_size - ((hssize_t)start + offset) + + (hssize_t)stride - (hssize_t)1) / stride; + HDassert(*count > (hsize_t)0); + } /* end else */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5S__hyper_get_clip_diminfo() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_hyper_clip_unlim PURPOSE Clips the unlimited dimension of the hyperslab selection to the @@ -9548,7 +9720,10 @@ done: Non-negative on success/Negative on failure. DESCRIPTION This function recalculates the internal description of the hyperslab - to make the unlimited dimension extend to the specified extent. + to make the unlimited dimension extend to the specified extent. if + superset is TRUE, then the hyperslab can be clipped to a size equal to + or greater than clip_size. If include_offset is TRUE, then the offset + is taken into account. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Note this function takes the offset into account. @@ -9584,33 +9759,20 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) /* Initialize opt_diminfo with opt_unlim_diminfo */ hslab->opt_diminfo[hslab->unlim_dim] = hslab->opt_unlim_diminfo[hslab->unlim_dim]; - /* Check for selection outside clip size */ - if((hsize_t)((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start - + space->select.offset[hslab->unlim_dim]) - >= clip_size) { - if(hslab->opt_diminfo[hslab->unlim_dim].block == H5S_UNLIMITED) - hslab->opt_diminfo[hslab->unlim_dim].block = 0; - else - hslab->opt_diminfo[hslab->unlim_dim].count = 0; + /* Get initial diminfo */ + H5S__hyper_get_clip_diminfo(hslab->opt_diminfo[hslab->unlim_dim].start, hslab->opt_diminfo[hslab->unlim_dim].stride, &hslab->opt_diminfo[hslab->unlim_dim].count, &hslab->opt_diminfo[hslab->unlim_dim].block, space->select.offset[hslab->unlim_dim], clip_size); + /* Check for nothing returned */ + if((hslab->opt_diminfo[hslab->unlim_dim].block == 0) + || (hslab->opt_diminfo[hslab->unlim_dim].count == 0)) { + /* Set num_elem */ space->select.num_elem = (hsize_t)0; /* Mark that opt_diminfo is valid */ hslab->diminfo_valid = TRUE; - - HGOTO_DONE(SUCCEED) } /* end if */ - /* Check for single block in unlimited dimension */ - if(hslab->opt_diminfo[hslab->unlim_dim].count == (hsize_t)1) { - HDassert(hslab->opt_diminfo[hslab->unlim_dim].block == H5S_UNLIMITED); - - /* Calculate actual block size for this clip size */ - 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])); - + else if(hslab->opt_unlim_diminfo[hslab->unlim_dim].count == (hsize_t)1) { /* Calculate number of elements */ space->select.num_elem = hslab->opt_diminfo[hslab->unlim_dim].block * hslab->num_elem_non_unlim; @@ -9619,26 +9781,13 @@ H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size) hslab->diminfo_valid = TRUE; } /* end if */ 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 - - ((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; - HDassert(hslab->opt_diminfo[hslab->unlim_dim].count > (hsize_t)0); - /* Calculate number of elements */ space->select.num_elem = hslab->opt_diminfo[hslab->unlim_dim].count * hslab->opt_diminfo[hslab->unlim_dim].block * hslab->num_elem_non_unlim; - /* Check if last block is partial */ + /* Check if last block is partial. If superset is set, just keep the + * last block complete to speed computation. */ 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) @@ -9754,7 +9903,7 @@ done: --------------------------------------------------------------------------*/ herr_t 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) + hsize_t *clip_size, hbool_t 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 */ @@ -9780,12 +9929,12 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, num_slices = match_space->select.num_elem / match_hslab->num_elem_non_unlim; 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 */ + HDassert(incl_trail && "Checking code coverage..."); //VDSINC + HDassert(!incl_trail && "Checking code coverage..."); //VDSINC + *clip_size = incl_trail + ? clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + : 0; + } //VDSINC else if(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block == H5S_UNLIMITED) { /* Unlimited block, just set the extent large enough for the block size * to match num_slices */ @@ -9794,10 +9943,6 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, *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 @@ -9812,7 +9957,8 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block); if(rem_slices > 0) { - HDassert(0 && "Checking code coverage..."); //VDSINC + HDassert(incl_trail && "Checking code coverage..."); //VDSINC + HDassert(!incl_trail && "Checking code coverage..."); //VDSINC /* Must end extent in middle of partial block (or beginning of empty * block if include_trailing_space and rem_slices == 0) */ *clip_size = @@ -9820,24 +9966,21 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, + (count * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride) + rem_slices; - 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_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) - /* Include gap after last block */ - *clip_size_incl_trail = + if(incl_trail) + /* End extent just before first missing block */ + *clip_size = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start + (count * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride); + else + /* End extent at end of last block */ + *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; } /* end else */ } /* end else */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 2900839..c796c31 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -269,8 +269,7 @@ 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_size, - hsize_t *clip_size_incl_trail); + const H5S_t *match_space, hsize_t *clip_size, hbool_t 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); diff --git a/test/vds.c b/test/vds.c index 5092d1e..033c228 100644 --- a/test/vds.c +++ b/test/vds.c @@ -1005,7 +1005,7 @@ test_basic_io(unsigned config, hid_t fapl) hsize_t count[4]; /* Hyperslab count */ hsize_t block[4]; /* Hyperslab block */ hsize_t coord[10]; /* Point selection array */ - int buf[10][26]; /* Write and expecte read buffer */ + int buf[10][26]; /* Write and expected read buffer */ int rbuf[10][26]; /* Read buffer */ int evbuf[10][26]; /* Expected VDS "buffer" */ int erbuf[10][26]; /* Expected read buffer */ @@ -1135,6 +1135,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -1295,6 +1296,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -1483,6 +1485,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -1746,6 +1749,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -2021,6 +2025,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -2489,6 +2494,7 @@ test_basic_io(unsigned config, hid_t fapl) vdset = -1; if(H5Fclose(srcfile[0]) < 0) TEST_ERROR + srcfile[0] = -1; if(H5Fclose(vfile) < 0) TEST_ERROR vfile = -1; @@ -2550,6 +2556,1292 @@ error: /*------------------------------------------------------------------------- + * Function: test_unlim + * + * Purpose: Tests VDS with unlimited selections + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Neil Fortner + * Thursday, April 30, 2015 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_unlim(unsigned config, hid_t fapl) +{ + char srcfilename[FILENAME_BUF_SIZE]; + char vfilename[FILENAME_BUF_SIZE]; + hid_t srcfile[4] = {-1, -1, -1, -1}; /* Files with source dsets */ + hid_t vfile = -1; /* File with virtual dset */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t srcdcpl = -1; /* DCPL for source dset */ + hid_t dapl = -1; /* Dataset access property list */ + hid_t srcspace[4] = {-1, -1, -1, -1}; /* Source dataspaces */ + hid_t vspace[4] = {-1, -1, -1, -1}; /* Virtual dset dataspaces */ + hid_t memspace = -1; /* Memory dataspace */ + hid_t filespace = -1; /* File dataspace */ + hid_t srcdset[4] = {-1, -1, -1, -1}; /* Source datsets */ + hid_t vdset = -1; /* Virtual dataset */ + hsize_t dims[2] = {10, 10}; /* Data space current size */ + hsize_t mdims[2] = {10, 20}; /* Data space maximum size */ + hsize_t cdims[2] = {4, 4}; /* Chunk dimensions */ + hsize_t start[4]; /* Hyperslab start */ + hsize_t stride[4]; /* Hyperslab stride */ + hsize_t count[4]; /* Hyperslab count */ + hsize_t block[4]; /* Hyperslab block */ + hsize_t coord[10]; /* Point selection array */ + int buf[10][20]; /* Write and expected read buffer */ + int rbuf[10][20]; /* Read buffer */ + int erbuf[10][20]; /* Expected read buffer */ + int ndims; /* Number of dimensions */ + int i, j; + + TESTING("virtual dataset I/O with unlimited selections") + + h5_fixname(FILENAME[0], fapl, vfilename, sizeof vfilename); + h5_fixname(FILENAME[1], fapl, srcfilename, sizeof srcfilename); + + /* Create DCPLs */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + if((srcdcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + TEST_ERROR + + /* Create DAPL */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + TEST_ERROR + + /* Set chunk dimensions */ + if(H5Pset_chunk(srcdcpl, 2, cdims) < 0) + TEST_ERROR + + /* Create memory space */ + if((memspace = H5Screate_simple(2, mdims, NULL)) < 0) + TEST_ERROR + + + /* + * Test 1: 2 Source datasets, single unlimited hyperslab virtual mappings + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[0] = 5; + mdims[0] = 5; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[0] = 10; + + /* Select hyperslab in source space */ + start[0] = 0; + start[1] = 0; + count[0] = 5; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + start[0] = 5; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = -1; + + /* Write data directly to source datasets */ + /* Select hyperslab in memory */ + start[0] = 0; + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i][j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[0] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[0] = 5; + dims[1] = 15; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[0])) < 0) + TEST_ERROR + start[1] = 10; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimensions will not have changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is now visible due to the change to + * H5D_VDS_LAST_AVAILABLE */ + for(i = 0; i < 5; i++) + for(j = 0; j < 5; j++) + erbuf[i][j + 10] = buf[i][j]; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[0] = 5; + dims[1] = 20; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 10; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[1] = 10; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 5; i++) + for(j = 0; j < 10; j++) + erbuf[i + 5][j + 10] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimensions will not have changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 20) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is no longer visible due to the + * change to H5D_VDS_FIRST_MISSING */ + for(i = 5; i < 10; i++) + for(j = 15; j < 20; j++) + erbuf[i][j] = -1; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 15) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* + * Test 2: 2 Source datasets, interleaved slices, single element wide + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create virtual dataspaces */ + dims[0] = 10; + dims[1] = 10; + if((vspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + if((vspace[1] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + + /* Create source dataspace */ + dims[1] = 5; + mdims[1] = 10; + if((srcspace[0] = H5Screate_simple(2, dims, mdims)) < 0) + TEST_ERROR + mdims[1] = 20; + + /* Select hyperslab in source space */ + start[0] = 0; + start[1] = 0; + count[0] = 10; + count[1] = H5S_UNLIMITED; + if(H5Sselect_hyperslab(srcspace[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Select hyperslabs in virtual spaces */ + start[0] = 0; + start[1] = 0; + stride[0] = 1; + stride[1] = 2; + count[0] = 1; + count[1] = H5S_UNLIMITED; + block[0] = 10; + block[1] = 1; + if(H5Sselect_hyperslab(vspace[0], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + start[1] = 1; + if(H5Sselect_hyperslab(vspace[1], H5S_SELECT_SET, start, stride, count, block) < 0) + TEST_ERROR + + /* Add virtual layout mappings */ + if(H5Pset_virtual(dcpl, vspace[0], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset1", srcspace[0]) < 0) + TEST_ERROR + if(H5Pset_virtual(dcpl, vspace[1], config & TEST_IO_DIFFERENT_FILE ? srcfilename : ".", "src_dset2", srcspace[0]) < 0) + TEST_ERROR + + /* Create virtual file */ + if((vfile = H5Fcreate(vfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Create source file if requested */ + if(config & TEST_IO_DIFFERENT_FILE) { + if((srcfile[0] = H5Fcreate(srcfilename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + } /* end if */ + else { + srcfile[0] = vfile; + if(H5Iinc_ref(srcfile[0]) < 0) + TEST_ERROR + } /* end if */ + + /* Create source datasets */ + if((srcdset[0] = H5Dcreate2(srcfile[0], "src_dset1", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dcreate2(srcfile[0], "src_dset2", H5T_NATIVE_INT, srcspace[0], H5P_DEFAULT, srcdcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Create virtual dataset */ + if((vdset = H5Dcreate2(vfile, "v_dset", H5T_NATIVE_INT, vspace[0], H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + TEST_ERROR + + /* Populate write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] = (i * (int)mdims[1]) + j; + + /* Initialize erbuf */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + erbuf[i][j] = -1; + + /* Write data directly to source datasets */ + /* Select hyperslab in memory */ + start[0] = 0; + start[1] = 0; + count[0] = 10; + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + + /* Write first dataset */ + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][2 * j] = buf[i][j]; + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write second dataset */ + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][(2 * j) + 1] = buf[i][j]; + + /* Close srcdsets and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 10) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Reopen srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[0] = H5Dopen2(srcfile[0], "src_dset1", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[0] */ + dims[1] = 7; + if(H5Dset_extent(srcdset[0], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 2; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[0])) < 0) + TEST_ERROR + start[1] = 5; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[0], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf to reflect only new data that is now visible under + * H5D_VDS_FIRST_MISSING (first slice) */ + for(i = 0; i < 10; i++) + erbuf[i][10] = buf[i][0]; + + /* Close srcdset[0] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimension will only changed to add one more slice. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 11) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_LAST_AVAILABLE */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_LAST_AVAILABLE) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is now visible due to the change to + * H5D_VDS_LAST_AVAILABLE (second new slice) */ + for(i = 0; i < 10; i++) + erbuf[i][12] = buf[i][1]; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 13) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Reopen srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(config & TEST_IO_DIFFERENT_FILE) + if((srcfile[0] = H5Fopen(srcfilename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) + TEST_ERROR + if((srcdset[1] = H5Dopen2(srcfile[0], "src_dset2", H5P_DEFAULT)) < 0) + TEST_ERROR + } /* end if */ + + /* Extend srcdset[1] */ + dims[1] = 10; + if(H5Dset_extent(srcdset[1], dims) < 0) + TEST_ERROR + + /* Adjust write buffer */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + buf[i][j] += (int)mdims[0] * (int)mdims[1]; + + /* Write to new area of srcdset */ + count[1] = 5; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if((filespace = H5Dget_space(srcdset[1])) < 0) + TEST_ERROR + start[1] = 5; + if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, NULL, count, NULL) < 0) + TEST_ERROR + if(H5Dwrite(srcdset[1], H5T_NATIVE_INT, memspace, filespace, H5P_DEFAULT, buf[0]) < 0) + TEST_ERROR + + /* Update erbuf */ + for(i = 0; i < 10; i++) + for(j = 0; j < 5; j++) + erbuf[i][(2 * j) + 11] = buf[i][j]; + + /* Close srcdset[1] and srcfile if config option specified */ + if(config & TEST_IO_CLOSE_SRC) { + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + + if(config & TEST_IO_DIFFERENT_FILE) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + } /* end if */ + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions. Note that since we are using + * H5D_VDS_FIRST_MISSING and we only extended one source dataset the + * dimensions will not have changed. */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 20) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close VDS and reopen with view set to H5D_VDS_FIRST_MISSING */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + if(H5Pset_virtual_view(dapl, H5D_VDS_FIRST_MISSING) < 0) + TEST_ERROR + if((vdset = H5Dopen2(vfile, "v_dset", dapl)) < 0) + TEST_ERROR + + /* Update erbuf to reflect new data that is no longer visible due to the + * change to H5D_VDS_FIRST_MISSING */ + for(i = 0; i < 10; i++) + for(j = 15; j < 20; j += 2) + erbuf[i][j] = -1; + + /* Get VDS space */ + if((filespace = H5Dget_space(vdset)) < 0) + TEST_ERROR + + /* Get VDS space dimensions */ + if((ndims = H5Sget_simple_extent_ndims(filespace)) < 0) + TEST_ERROR + if(ndims != 2) + TEST_ERROR + if(H5Sget_simple_extent_dims(filespace, dims, mdims) < 0) + TEST_ERROR + if(dims[0] != 10) + TEST_ERROR + if(dims[1] != 14) + TEST_ERROR + if(mdims[0] != 10) + TEST_ERROR + if(mdims[1] != 20) + TEST_ERROR + + /* Close filespace */ + if(H5Sclose(filespace) < 0) + TEST_ERROR + + /* Read data through virtual dataset */ + /* Reset rbuf */ + //HDmemset(rbuf[0], 0, sizeof(rbuf)); VDSINC + /* Initialize erbuf - used now instead of setting fill value because fill + * values do not work VDSINC */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + rbuf[i][j] = -1; + + /* Select hyperslab in memory space */ + start[1] = 0; + if(H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, NULL, dims, NULL) < 0) + TEST_ERROR + + /* Read data */ + if(H5Dread(vdset, H5T_NATIVE_INT, memspace, H5S_ALL, H5P_DEFAULT, rbuf[0]) < 0) + TEST_ERROR + + /* Verify read data */ + for(i = 0; i < (int)mdims[0]; i++) + for(j = 0; j < (int)mdims[1]; j++) + if(rbuf[i][j] != erbuf[i][j]) + TEST_ERROR + + /* Close */ + if(!(config & TEST_IO_CLOSE_SRC)) { + if(H5Dclose(srcdset[0]) < 0) + TEST_ERROR + srcdset[0] = -1; + if(H5Dclose(srcdset[1]) < 0) + TEST_ERROR + srcdset[1] = -1; + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + else if(!(config & TEST_IO_DIFFERENT_FILE)) { + if(H5Fclose(srcfile[0]) < 0) + TEST_ERROR + srcfile[0] = -1; + } /* end if */ + if(H5Dclose(vdset) < 0) + TEST_ERROR + vdset = -1; + if(H5Fclose(vfile) < 0) + TEST_ERROR + vfile = -1; + if(H5Sclose(srcspace[0]) < 0) + TEST_ERROR + srcspace[0] = -1; + if(H5Sclose(vspace[0]) < 0) + TEST_ERROR + vspace[0] = -1; + if(H5Sclose(vspace[1]) < 0) + TEST_ERROR + vspace[1] = -1; + + + /* Close */ + if(H5Pclose(dcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(srcdcpl) < 0) + TEST_ERROR + dcpl = -1; + if(H5Pclose(dapl) < 0) + TEST_ERROR + dapl = -1; + if(H5Sclose(memspace) < 0) + TEST_ERROR + memspace = -1; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + for(i = 0; i < (int)(sizeof(srcdset) / sizeof(srcdset[0])); i++) { + if(srcdset[i] >= 0) + (void)H5Dclose(srcdset[i]); + } /* end for */ + if(vdset >= 0) + (void)H5Dclose(vdset); + for(i = 0; i < (int)(sizeof(srcfile) / sizeof(srcfile[0])); i++) { + if(srcfile[i] >= 0) + (void)H5Fclose(srcfile[i]); + } /* end for */ + if(vfile >= 0) + (void)H5Fclose(vfile); + for(i = 0; i < (int)(sizeof(srcspace) / sizeof(srcspace[0])); i++) { + if(srcspace[i] >= 0) + (void)H5Sclose(srcspace[i]); + } /* end for */ + for(i = 0; i < (int)(sizeof(vspace) / sizeof(vspace[0])); i++) { + if(vspace[i] >= 0) + (void)H5Sclose(vspace[i]); + } /* end for */ + if(filespace >= 0) + (void)H5Sclose(filespace); + if(memspace >= 0) + (void)H5Sclose(memspace); + if(dcpl >= 0) + (void)H5Pclose(dcpl); + if(srcdcpl >= 0) + (void)H5Pclose(srcdcpl); + if(dapl >= 0) + (void)H5Pclose(dapl); + } H5E_END_TRY; + + return 1; +} /* end test_unlim() */ + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests datasets with virtual layout @@ -2583,6 +3875,7 @@ main(void) for(bit_config = 0; bit_config < TEST_IO_NTESTS; bit_config++) { printf("Config: %s%s\n", bit_config & TEST_IO_CLOSE_SRC ? "closed source dataset, " : "", bit_config & TEST_IO_DIFFERENT_FILE ? "different source file" : "same source file"); nerrors += test_basic_io(bit_config, fapl); + nerrors += test_unlim(bit_config, fapl); } /* end for */ /* Verify symbol table messages are cached */ -- cgit v0.12