diff options
-rw-r--r-- | src/H5Dvirtual.c | 44 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 128 | ||||
-rw-r--r-- | src/H5S.c | 12 | ||||
-rw-r--r-- | src/H5Sall.c | 1 | ||||
-rw-r--r-- | src/H5Shyper.c | 45 | ||||
-rw-r--r-- | src/H5Snone.c | 1 | ||||
-rw-r--r-- | src/H5Spkg.h | 6 | ||||
-rw-r--r-- | src/H5Spoint.c | 1 | ||||
-rw-r--r-- | src/H5Sprivate.h | 4 | ||||
-rw-r--r-- | src/H5Sselect.c | 53 | ||||
-rw-r--r-- | test/vds.c | 53 |
11 files changed, 306 insertions, 42 deletions
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 09519bf..db45ceb 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -574,7 +574,7 @@ H5D__virtual_open_source_dset(const H5D_t *vdset, if(HDstrcmp(source_dset->file_name, ".")) { /* Open the source file */ if(NULL == (src_file = H5F_open(source_dset->file_name, H5F_INTENT(vdset->oloc.file) & H5F_ACC_RDWR, H5P_FILE_CREATE_DEFAULT, vdset->shared->layout.storage.u.virt.source_fapl, dxpl_id))) - H5E_clear_stack(NULL); //Quick hack until proper support for H5Fopen with missing file is implemented VDSINC HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENFILE, FAIL, "unable to open source file") + H5E_clear_stack(NULL); /* Quick hack until proper support for H5Fopen with missing file is implemented */ else src_file_open = TRUE; } /* end if */ @@ -591,7 +591,7 @@ H5D__virtual_open_source_dset(const H5D_t *vdset, /* Open the source dataset */ if(NULL == (source_dset->dset = H5D__open_name(&src_root_loc, source_dset->dset_name, vdset->shared->layout.storage.u.virt.source_dapl, dxpl_id))) - H5E_clear_stack(NULL); //Quick hack until proper support for H5Fopen with missing file is implemented VDSINC HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + H5E_clear_stack(NULL); /* Quick hack until proper support for H5Dopen with missing file is implemented */ else /* Patch the source selection if necessary */ if(virtual_ent->source_space_status != H5O_VIRTUAL_STATUS_CORRECT) { @@ -1352,13 +1352,21 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) changed = TRUE; } /* end for */ - /* If we did not change the VDS dimensions, there is nothing more to update - */ - if(changed || (!storage->init && (storage->view == H5D_VDS_FIRST_MISSING))) { + /* Update extent if it changed */ + if(changed) { /* Update VDS extent */ if(H5S_set_extent(dset->shared->space, new_dims) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space") + /* Mark the space as dirty, for later writing to the file */ + if(H5F_INTENT(dset->oloc.file) & H5F_ACC_RDWR) + if(H5D__mark(dset, dxpl_id, H5D_MARK_SPACE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty") + } /* end if */ + + /* If we did not change the VDS dimensions, there is nothing more to update + */ + if(changed || (!storage->init && (storage->view == H5D_VDS_FIRST_MISSING))) { /* Iterate over mappings again to update source selections and virtual * mapping extents */ for(i = 0; i < storage->list_nalloc; i++) { @@ -1516,7 +1524,6 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id) } /* end for */ } /* end if */ - /* Call H5D__mark so dataspace is updated on disk? VDSINC */ /* Mark layout as fully initialized */ storage->init = TRUE; @@ -1555,14 +1562,16 @@ H5D__virtual_init(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const H5D_t *dset, storage = &dset->shared->layout.storage.u.virt; HDassert(storage->list || (storage->list_nused == 0)); - /* Patch the virtual selection dataspaces */ + /* Patch the virtual selection dataspaces. Note we always patch the space + * status because this layout could be from an old version held in the + * object header message code. We cannot update that held message because + * the layout message is constant, so just overwrite the values here (and + * invalidate other fields by setting storage->init to FALSE below). */ for(i = 0; i < storage->list_nused; i++) { - if(storage->list[i].virtual_space_status != H5O_VIRTUAL_STATUS_CORRECT) { - if(H5S_extent_copy(storage->list[i].source_dset.virtual_select, dset->shared->space) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") - storage->list[i].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; - HDassert(storage->list[i].sub_dset_nalloc == 0); - } /* end if */ + if(H5S_extent_copy(storage->list[i].source_dset.virtual_select, dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent") + storage->list[i].virtual_space_status = H5O_VIRTUAL_STATUS_CORRECT; + HDassert(storage->list[i].sub_dset_nalloc == 0); } /* end for */ /* Get dataset access property list */ @@ -1589,6 +1598,10 @@ H5D__virtual_init(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, const H5D_t *dset, if((storage->source_dapl = H5P_copy_plist(dapl, FALSE)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dapl") + /* Mark layout as not fully initialized (must be done prior to I/O for + * unlimited/printf selections) */ + storage->init = FALSE; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__virtual_init() */ @@ -2069,8 +2082,9 @@ H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HDassert(source_dset->dset); HDassert(source_dset->clipped_source_select); - /* Extend source dataset if necessary and there is an unlimited - * dimension VDSINC */ + /* In the future we may wish to extent this implementation to extend + * source datasets if a write to a virtual dataset goes past the current + * extent in the unlimited dimension. -NAF */ /* Project intersection of file space and mapping virtual space onto * mapping source space */ if(H5S_select_project_intersection(source_dset->virtual_select, source_dset->clipped_source_select, file_space, &projected_src_space) < 0) diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index f687104..0c6184b 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1805,7 +1805,10 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, H5O_layout_t layout; /* Layout information for setting chunk info */ H5S_t *vspace; /* Virtual dataset space selection */ H5S_t *src_space; /* Source dataset space selection */ - hssize_t nelmts; /* Number of elements */ + H5S_sel_type select_type; /* Selection type */ + hsize_t nelmts_vs; /* Number of elements in virtual selection */ + hsize_t nelmts_ss; /* Number of elements in source selection */ + H5S_t *tmp_space = NULL; /* Temporary dataspace */ hbool_t new_layout = FALSE; /* Whether we are adding a new virtual layout message to plist */ H5O_storage_virtual_ent_t *ent = NULL; /* Convenience pointer to new VDS entry */ hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */ @@ -1825,14 +1828,43 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") if(NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - nelmts = H5S_GET_SELECT_NPOINTS(vspace); - if((nelmts != H5S_UNLIMITED) - && (nelmts != H5S_GET_SELECT_NPOINTS(src_space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual and source space selections have different numbers of elements") - /* Check for unlimited selections having the same number of elements in the - * non-unlimited dimensions, and check for printf selections having the - * correct numbers of elements and unlimited/non-unlimited dimensions VDSINC - */ + + /* Check for point selections (currently unsupported) */ + if(H5S_SEL_ERROR == (select_type = H5S_GET_SELECT_TYPE(vspace))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection type") + if(select_type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "point selections not currently supported with virtual datasets") + if(H5S_SEL_ERROR == (select_type = H5S_GET_SELECT_TYPE(src_space))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection type") + if(select_type == H5S_SEL_POINTS) + HGOTO_ERROR(H5E_PLIST, H5E_UNSUPPORTED, FAIL, "point selections not currently supported with virtual datasets") + + /* Get number of elements in spaces */ + nelmts_vs = (hsize_t)H5S_GET_SELECT_NPOINTS(vspace); + nelmts_ss = (hsize_t)H5S_GET_SELECT_NPOINTS(src_space); + + /* Check for unlimited vspace */ + if(nelmts_vs == H5S_UNLIMITED) { + /* Check for unlimited src_space */ + if(nelmts_ss == H5S_UNLIMITED) { + hsize_t nenu_vs; /* Number of elements in the non-unlimited dimensions of vspace */ + hsize_t nenu_ss; /* Number of elements in the non-unlimited dimensions of src_space */ + + /* Non-printf unlimited selection. Make sure both selections have + * the same number of elements in the non-unlimited dimension */ + if(H5S_get_select_num_elem_non_unlim(vspace, &nenu_vs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + if(H5S_get_select_num_elem_non_unlim(src_space, &nenu_ss) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + if(nenu_vs != nenu_ss) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "numbers of elemnts in the non-unlimited dimensions is different for source and virtual spaces") + } /* end if */ + /* We will handle the printf case after parsing the source names */ + } /* end if */ + else + /* Limited selections. Check number of points is the same. */ + if(nelmts_vs != nelmts_ss) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual and source space selections have different numbers of elements") #ifndef H5_HAVE_C99_DESIGNATED_INITIALIZER /* If the compiler doesn't support C99 designated initializers, check if @@ -1913,7 +1945,6 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, ent->source_dset.clipped_source_select = ent->source_select; ent->source_dset.clipped_virtual_select = ent->source_dset.virtual_select; } /* end if */ - ent->unlim_extent_source = HSIZE_UNDEF; ent->unlim_extent_virtual = HSIZE_UNDEF; ent->clip_size_source = HSIZE_UNDEF; @@ -1921,6 +1952,38 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, ent->source_space_status = H5O_VIRTUAL_STATUS_USER; ent->virtual_space_status = H5O_VIRTUAL_STATUS_USER; + /* Check for printf selection */ + if((nelmts_vs == H5S_UNLIMITED) && (nelmts_ss != H5S_UNLIMITED)) { + /* Make sure there at least one %b substitution in the source file or + * dataset name */ + if((ent->psfn_nsubs == 0) && (ent->psdn_nsubs == 0)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unlimited virtual selection, limited source selection, and no printf specifiers in source names") + + /* Make sure virtual space uses hyperslab selection */ + if(H5S_GET_SELECT_TYPE(vspace) != H5S_SEL_HYPERSLABS) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "virtual selection with printf mapping must be hyperslab") + + /* Get first block in virtual selection */ + if(NULL == (tmp_space = H5S_hyper_get_unlim_block(vspace, (hsize_t)0))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get first block in virtual selection") + + /* Check that the number of elements in one block in the virtual + * selection matches the total number of elements in the source + * selection */ + nelmts_vs = (hsize_t)H5S_GET_SELECT_NPOINTS(tmp_space); + if(nelmts_vs != nelmts_ss) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "virtual (single block) and source space selections have different numbers of elements") + + /* Close tmp_space */ + if(H5S_close(tmp_space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "can't close dataspace") + tmp_space = NULL; + } /* end if */ + else + /* Make sure there are no printf substitutions */ + if((ent->psfn_nsubs > 0) || (ent->psdn_nsubs > 0)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "printf specifier(s) in source name(s) without an unlimited virtual selection and limited source selection") + /* Update min_dims */ if(H5D_virtual_update_min_dims(&layout, layout.storage.u.virt.list_nused) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions") @@ -1972,6 +2035,11 @@ done: /* Free list if necessary */ if(free_list) layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(layout.storage.u.virt.list); + + /* Free temporary space */ + if(tmp_space) + if(H5S_close(tmp_space) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "can't close dataspace") } /* end if */ } /* end if */ @@ -2108,14 +2176,44 @@ H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index) if(H5D_VIRTUAL != layout.type) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout") - /* Attempt to open source dataset and patch extent if extent status is not - * H5O_VIRTUAL_STATUS_CORRECT, otherwise if status is - * H5O_VIRTUAL_STATUS_INVALID, patch with bounds of selection VDSINC */ - - /* Get the source space */ + /* Check index */ if(index >= layout.storage.u.virt.list_nused) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); + + /* Attempt to open source dataset and patch extent if extent status is not + * H5O_VIRTUAL_STATUS_CORRECT? -NAF */ + /* If source space status is H5O_VIRTUAL_STATUS_INVALID, patch with bounds + * of selection */ + if((layout.storage.u.virt.list[index].source_space_status + == H5O_VIRTUAL_STATUS_INVALID) + && (layout.storage.u.virt.list[index].unlim_dim_source < 0)) { + hsize_t bounds_start[H5S_MAX_RANK]; + hsize_t bounds_end[H5S_MAX_RANK]; + int rank; + int i; + + /* Get rank of source space */ + if((rank = H5S_GET_EXTENT_NDIMS(layout.storage.u.virt.list[index].source_select)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get source space rank") + + /* Get bounds of selection */ + if(H5S_SELECT_BOUNDS(layout.storage.u.virt.list[index].source_select, bounds_start, bounds_end) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection bounds") + + /* Adjust bounds to extent */ + for(i = 0; i < rank; i++) + bounds_end[i]++; + + /* Set extent */ + if(H5S_set_extent_simple(layout.storage.u.virt.list[index].source_select, (unsigned)rank, bounds_end, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set source space extent") + + /* Update source space status */ + layout.storage.u.virt.list[index].source_space_status = H5O_VIRTUAL_STATUS_SEL_BOUNDS; + } /* end if */ + + /* Get the source space */ if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_select, FALSE, TRUE))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") @@ -1268,7 +1268,7 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/], } /* Do it */ - if (H5S__set_extent_simple(space, (unsigned)rank, dims, max)<0) + if (H5S_set_extent_simple(space, (unsigned)rank, dims, max)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent") done: @@ -1277,7 +1277,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5S__set_extent_simple + * Function: H5S_set_extent_simple * * Purpose: This is where the real work happens for * H5Sset_extent_simple(). @@ -1292,13 +1292,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5S__set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, +H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, const hsize_t *max) { unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) /* Check args */ HDassert(rank <= H5S_MAX_RANK); @@ -1354,7 +1354,7 @@ H5S__set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims, done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5S__set_extent_simple() */ +} /* H5S_set_extent_simple() */ /*------------------------------------------------------------------------- @@ -1465,7 +1465,7 @@ H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], /* Create the space and set the extent */ if(NULL==(ret_value=H5S_create(H5S_SIMPLE))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace") - if(H5S__set_extent_simple(ret_value,rank,dims,maxdims)<0) + if(H5S_set_extent_simple(ret_value,rank,dims,maxdims)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "can't set dimensions") done: diff --git a/src/H5Sall.c b/src/H5Sall.c index 1b9ceec..7e33980 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -78,6 +78,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S_all_bounds, H5S_all_offset, H5S_all_unlim_dim, + NULL, H5S_all_is_contiguous, H5S_all_is_single, H5S_all_is_regular, diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 8736b69..898c3df 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -65,6 +65,8 @@ static herr_t H5S_hyper_deserialize(const H5F_t *f, H5S_t *space, static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset); static int H5S_hyper_unlim_dim(const H5S_t *space); +static herr_t H5S_hyper_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim); static htri_t H5S_hyper_is_contiguous(const H5S_t *space); static htri_t H5S_hyper_is_single(const H5S_t *space); static htri_t H5S_hyper_is_regular(const H5S_t *space); @@ -102,6 +104,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S_hyper_bounds, H5S_hyper_offset, H5S_hyper_unlim_dim, + H5S_hyper_num_elem_non_unlim, H5S_hyper_is_contiguous, H5S_hyper_is_single, H5S_hyper_is_regular, @@ -3007,6 +3010,48 @@ H5S_hyper_unlim_dim(const H5S_t *space) /*-------------------------------------------------------------------------- NAME + H5S_hyper_num_elem_non_unlim + PURPOSE + Return number of elements in the non-unlimited dimensions + USAGE + herr_t H5S_hyper_num_elem_non_unlim(space,num_elem_non_unlim) + H5S_t *space; IN: Dataspace pointer to check + hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Returns the number of elements in a slice through the non-unlimited + dimensions of the selection. Fails if the selection has no unlimited + dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_hyper_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(space); + HDassert(num_elem_non_unlim); + + /* Get number of elements in the non-unlimited dimensions */ + if(space->select.sel_info.hslab->unlim_dim >= 0) + *num_elem_non_unlim = space->select.sel_info.hslab->num_elem_non_unlim; + else + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "selection has no unlimited dimension") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_hyper_num_elem_non_unlim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_hyper_is_contiguous PURPOSE Check if a hyperslab selection is contiguous within the dataspace extent. diff --git a/src/H5Snone.c b/src/H5Snone.c index b4e2f0e..23433a1 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -79,6 +79,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{ H5S_none_bounds, H5S_none_offset, H5S_none_unlim_dim, + NULL, H5S_none_is_contiguous, H5S_none_is_single, H5S_none_is_regular, diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 7805777..f719201 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -154,6 +154,9 @@ typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsiz typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset); /* Method to get unlimited dimension of selection (or -1 for none) */ typedef int (*H5S_sel_unlim_dim_func_t)(const H5S_t *space); +/* Method to get the number of elements in a slice through the unlimited dimension */ +typedef herr_t (*H5S_sel_num_elem_non_unlim_func_t)(const H5S_t *space, + hsize_t *num_elem_non_unlim); /* Method to determine if current selection is contiguous */ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space); /* Method to determine if current selection is a single block */ @@ -184,6 +187,7 @@ typedef struct { H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */ H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */ H5S_sel_unlim_dim_func_t unlim_dim; /* Method to get unlimited dimension of selection (or -1 for none) */ + H5S_sel_num_elem_non_unlim_func_t num_elem_non_unlim; /* Method to get the number of elements in a slice through the unlimited dimension */ H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */ H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */ H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */ @@ -262,8 +266,6 @@ H5_DLLVAR const H5S_select_class_t H5S_sel_none[1]; H5_DLLVAR const H5S_select_class_t H5S_sel_point[1]; /* Extent functions */ -H5_DLL herr_t H5S__set_extent_simple(H5S_t *space, unsigned rank, - const hsize_t *dims, const hsize_t *max); H5_DLL herr_t H5S_extent_release(H5S_extent_t *extent); H5_DLL herr_t H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max); diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 1ea4a23..d10b600 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -80,6 +80,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{ H5S_point_bounds, H5S_point_offset, H5S_point_unlim_dim, + NULL, H5S_point_is_contiguous, H5S_point_is_single, H5S_point_is_regular, diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 91e4513..8918a4f 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -190,6 +190,8 @@ H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, H5S_t *ds); H5_DLL H5S_t *H5S_read(const struct H5O_loc_t *loc, hid_t dxpl_id); H5_DLL htri_t H5S_set_extent(H5S_t *space, const hsize_t *size); H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size); +H5_DLL herr_t H5S_set_extent_simple(H5S_t *space, unsigned rank, + const hsize_t *dims, const hsize_t *max); H5_DLL H5S_t *H5S_create(H5S_class_t type); H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], const hsize_t maxdims[/*rank*/]); @@ -221,6 +223,8 @@ H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space); H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset); H5_DLL int H5S_get_select_unlim_dim(const H5S_t *space); +H5_DLL herr_t H5S_get_select_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim); H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset); H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index bb74b14..86a8c43 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -507,7 +507,7 @@ H5S_select_deserialize(const H5F_t *f, H5S_t **space, const uint8_t **p) /* Patch the rank of the allocated dataspace */ (void)HDmemset(dims, 0, (size_t)rank * sizeof(dims[0])); - if(H5S__set_extent_simple(tmp_space, rank, dims, NULL) < 0) + if(H5S_set_extent_simple(tmp_space, rank, dims, NULL) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set dimensions") } /* end if */ else @@ -731,6 +731,51 @@ H5S_get_select_unlim_dim(const H5S_t *space) /*-------------------------------------------------------------------------- NAME + H5S_get_select_num_elem_non_unlim + PURPOSE + Gets the number of elements in the non-unlimited dimensions + USAGE + herr_t H5S_get_select_num_elem_non_unlim(space,num_elem_non_unlim) + H5S_t *space; IN: Dataspace pointer to check + hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Returns the number of elements in a slice through the non-unlimited + dimensions of the selection. Fails if the selection has no unlimited + dimension. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_get_select_num_elem_non_unlim(const H5S_t *space, + hsize_t *num_elem_non_unlim) +{ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(space); + HDassert(num_elem_non_unlim); + + /* Check for selection callback */ + if(!space->select.type->num_elem_non_unlim) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type has no num_elem_non_unlim callback") + + /* Make selection callback */ + if((*space->select.type->num_elem_non_unlim)(space, num_elem_non_unlim) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_get_select_unlim_dim() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_select_is_contiguous PURPOSE Determines if a selection is contiguous in the dataspace @@ -2240,7 +2285,7 @@ H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space, else if((src_intersect_space->select.type->type == H5S_SEL_POINTS) || (src_space->select.type->type == H5S_SEL_POINTS) || (dst_space->select.type->type == H5S_SEL_POINTS)) - HDassert(0 && "Not yet implemented...");//VDSINC + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") else { HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS); /* Intersecting space is hyperslab selection. Call the hyperslab @@ -2314,7 +2359,7 @@ H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) /* Check for point selection in subtract_space, convert to * hyperslab */ if(subtract_space->select.type->type == H5S_SEL_POINTS) - HDassert(0 && "Not yet implemented...");//VDSINC + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") /* Check for point or all selection in space, convert to hyperslab */ @@ -2340,7 +2385,7 @@ H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection") } /* end if */ else if(space->select.type->type == H5S_SEL_POINTS) - HDassert(0 && "Not yet implemented...");//VDSINC + HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported") HDassert(space->select.type->type == H5S_SEL_HYPERSLABS); HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS); @@ -461,6 +461,7 @@ test_api(test_api_config_t config, hid_t fapl) hsize_t block[2]; /* Hyperslab block */ hsize_t coord[10]; /* Point selection array */ size_t size_out; + herr_t ret; unsigned i; /* Initialize vspace */ @@ -616,6 +617,7 @@ test_api(test_api_config_t config, hid_t fapl) ex_dcpl = -1; +#ifdef VDS_POINT_SELECTIONS /* VDS does not currently support point selections */ /* * Test 3: Point - point selection */ @@ -892,6 +894,57 @@ test_api(test_api_config_t config, hid_t fapl) if(H5Pclose(ex_dcpl) < 0) TEST_ERROR ex_dcpl = -1; +#else /* VDS_POINT_SELECTIONS */ + /* + * Test 3: Verify point selections fail + */ + /* Clear virtual layout in DCPL */ + if(H5Pset_layout(dcpl, H5D_VIRTUAL) < 0) + TEST_ERROR + + /* Create source dataspace */ + if((srcspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Create virtual dataspace */ + if((vspace[0] = H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR + + /* Select points in source space */ + coord[0] = 5; + coord[1] = 15; + coord[2] = 7; + coord[3] = 19; + coord[4] = 8; + coord[5] = 0; + coord[6] = 2; + coord[7] = 14; + coord[8] = 8; + coord[9] = 18; + if(H5Sselect_elements(srcspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Select points in virtual space */ + coord[0] = 3; + coord[1] = 12; + coord[2] = 7; + coord[3] = 11; + coord[4] = 4; + coord[5] = 9; + coord[6] = 7; + coord[7] = 11; + coord[8] = 5; + coord[9] = 5; + if(H5Sselect_elements(vspace[0], H5S_SELECT_SET, (size_t)5, coord) < 0) + TEST_ERROR + + /* Attempt to add virtual layout mapping */ + H5E_BEGIN_TRY { + ret = H5Pset_virtual(dcpl, vspace[0], src_file[0], src_dset[0], srcspace[0]); + } H5E_END_TRY + if(ret >= 0) + TEST_ERROR +#endif /* VDS_POINT_SELECTIONS */ /* |