diff options
author | Dana Robinson <43805+derobins@users.noreply.github.com> | 2021-07-12 20:30:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-12 20:30:20 (GMT) |
commit | eebaee65290de59a4fbf1a426df09e32872d9efc (patch) | |
tree | ad1ed5e22cf84e5ab9981e5f798d96ee2dc2a389 /src/H5Pdxpl.c | |
parent | b9dbabc1523c13627ada0bcb04d780e7ad93b658 (diff) | |
download | hdf5-eebaee65290de59a4fbf1a426df09e32872d9efc.zip hdf5-eebaee65290de59a4fbf1a426df09e32872d9efc.tar.gz hdf5-eebaee65290de59a4fbf1a426df09e32872d9efc.tar.bz2 |
VFD SWMR: sync with develop (#830)
* Normalization with develop
* Removes checks and work-arounds for strtoll and strtoull (#769)
* Removes checks for (v)snprintf, which are C99 (#772)
* Update missing release note info. (#776)
* Replaces the H5_OVERRIDE macro with override (#773)
The macro is no longer necessary now that we require C++11.
* Cleans up some POSIX header bits in H5private.h (#783)
* Removes outdated checks for ways inline might be defined (#781)
These are obsolete now that we require C99.
* Removes checks for system(), which is C89/90 (#782)
* Removes C++ dependency on H5private.h (#774)
* Removes C++ dependency on H5private.h
Most C API calls have been removed, aside from a few uses of free,
where we just dropped the 'HD'. A couple of H5_ATTR_UNUSED macros
were also replaced with (void) statements.
* Committing clang-format changes
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Further simplifies Autotools type size checks (#789)
Also fixes an issue where clock_gettime and difftime are not detected
due to earlier simplifications of this code.
* Release Note (#784)
* Normalization of CMake H5pubconf.h with Autotools (#791)
Mostly just moving things around and changing the comments to keep the
delta small. The only symbol change is that for curl/curl.h which I
changed to H5_HAVE_CURL_CURL_H to match the Autotools. This symbol
is not used in the library and is just an artifact of the checks.
* Fix tools test (#794)
* Removes ancient Autotools cruft (#790)
* Reorganization of C and POSIX headers in H5public.h & H5private.h (#793)
* Reorganization of C and POSIX headers in H5public.h & H5private.h
Consolidated and removed duplicates
* It turns out Windows has sys/types.h
Co-authored-by: Larry Knox <lrknox@hdfgroup.org>
* Removes checks for signal and set/longjmp, which are C89 (#798)
Also removes checks for setjmp.h and stddef.h
* Assume frexpl/f and fabsl/f, which are C99 (#799)
* Assume the library has C99 types in C++ type code (#806)
* Assume the library has C99 types in C++ type code
* Committing clang-format changes
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Removes obsolete equivalents of C99's __func__ (#800)
* Cleans up POSIX/C bits in H5private.h (#804)
* Cleans up POSIX/C bits in H5private.h
* Assume difftime exists (C89)
* Reorg AC_CHECK_HEADERS so headers are in alphabetical order
* Split off networking-related AC_CHECK_HEADERS
* Remove unused UNAME_CYGWIN from configure.ac
* Remove checks for unused sys/timeb.h
* Tidying pass over H5private.h HD prefix macros
* Tidy H5win32defs.h
* Add HD prefix to various scanf calls
* Committing clang-format changes
* Fixes to the alarm(2) code used in the tests to make Windows happy
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
* Brings the tools getopt(3) replacement into the main library (#803)
* Moves get_option from the tools library to the C library
* Adds H5 prefix to get_option call and variables
* Renames the H5_get_option long options struct and enum
* Removes type guesses when C99 types are missing (#807)
* Assume C99 types exist in H5detect.c (#808)
* Fixes parallel issues from recent C99 changes
* Adds MPE FUNC --> __func__ changes missed in earlier PRs
* Fix typo
* Fixes parallel issues from recent C99 changes (#809)
* Fixes parallel issues from recent C99 changes
* Adds MPE FUNC --> __func__ changes missed in earlier PRs
* Even more missed FUNC --> __func__ macros
* Removes remaining H5_TIME_WITH_SYS_TIME cruft (#810)
Mostly from CMake
* Merges with develop
* Committing clang-format changes
* Normalization with develop
* direct_chunk test and H5Dget_chunk_storage_size changes
* Removes unused H5O call
* Brings some dataspace changes from the combo branch merge
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Larry Knox <lrknox@hdfgroup.org>
Diffstat (limited to 'src/H5Pdxpl.c')
-rw-r--r-- | src/H5Pdxpl.c | 278 |
1 files changed, 274 insertions, 4 deletions
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index de67dfd..046b046 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -159,6 +159,16 @@ #define H5D_XFER_XFORM_COPY H5P__dxfr_xform_copy #define H5D_XFER_XFORM_CMP H5P__dxfr_xform_cmp #define H5D_XFER_XFORM_CLOSE H5P__dxfr_xform_close +/* Definitions for dataset I/O selection property */ +#define H5D_XFER_DSET_IO_SEL_SIZE sizeof(H5S_t *) +#define H5D_XFER_DSET_IO_SEL_DEF NULL +#define H5D_XFER_DSET_IO_SEL_COPY H5P__dxfr_dset_io_hyp_sel_copy +#define H5D_XFER_DSET_IO_SEL_CMP H5P__dxfr_dset_io_hyp_sel_cmp +#define H5D_XFER_DSET_IO_SEL_CLOSE H5P__dxfr_dset_io_hyp_sel_close +#ifdef QAK +#define H5D_XFER_DSET_IO_SEL_ENC H5P__dxfr_edc_enc +#define H5D_XFER_DSET_IO_SEL_DEC H5P__dxfr_edc_dec +#endif /* QAK */ /******************/ /* Local Typedefs */ @@ -196,6 +206,9 @@ static herr_t H5P__dxfr_xform_del(hid_t prop_id, const char *name, size_t size, static herr_t H5P__dxfr_xform_copy(const char *name, size_t size, void *value); static int H5P__dxfr_xform_cmp(const void *value1, const void *value2, size_t size); static herr_t H5P__dxfr_xform_close(const char *name, size_t size, void *value); +static herr_t H5P__dxfr_dset_io_hyp_sel_copy(const char *name, size_t size, void *value); +static int H5P__dxfr_dset_io_hyp_sel_cmp(const void *value1, const void *value2, size_t size); +static herr_t H5P__dxfr_dset_io_hyp_sel_close(const char *name, size_t size, void *value); /*********************/ /* Package Variables */ @@ -262,7 +275,9 @@ static const H5Z_EDC_t H5D_def_enable_edc_g = H5D_XFER_EDC_DEF; /* Default static const H5Z_cb_t H5D_def_filter_cb_g = H5D_XFER_FILTER_CB_DEF; /* Default value for filter callback */ static const H5T_conv_cb_t H5D_def_conv_cb_g = H5D_XFER_CONV_CB_DEF; /* Default value for datatype conversion callback */ -static const void *H5D_def_xfer_xform_g = H5D_XFER_XFORM_DEF; /* Default value for data transform */ +static const void * H5D_def_xfer_xform_g = H5D_XFER_XFORM_DEF; /* Default value for data transform */ +static const H5S_t *H5D_def_dset_io_sel_g = + H5D_XFER_DSET_IO_SEL_DEF; /* Default value for dataset I/O selection */ /*------------------------------------------------------------------------- * Function: H5P__dxfr_reg_prop @@ -420,6 +435,13 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) H5D_XFER_XFORM_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the dataset I/O selection property */ + if (H5P__register_real(pclass, H5D_XFER_DSET_IO_SEL_NAME, H5D_XFER_DSET_IO_SEL_SIZE, + &H5D_def_dset_io_sel_g, NULL, NULL, NULL, NULL, NULL, NULL, + H5D_XFER_DSET_IO_SEL_COPY, H5D_XFER_DSET_IO_SEL_CMP, + H5D_XFER_DSET_IO_SEL_CLOSE) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dxfr_reg_prop() */ @@ -894,7 +916,7 @@ H5P__dxfr_xform_cmp(const void *_xform1, const void *_xform2, size_t H5_ATTR_UNU done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P__dxfr_xform_copy() */ +} /* end H5P__dxfr_xform_cmp() */ /*------------------------------------------------------------------------- * Function: H5P__dxfr_xform_close @@ -965,7 +987,7 @@ H5Pset_data_transform(hid_t plist_id, const char *expression) /* Create data transform info from expression */ if (NULL == (data_xform_prop = H5Z_xform_create(expression))) - HGOTO_ERROR(H5E_PLINE, H5E_NOSPACE, FAIL, "unable to create data transform info") + HGOTO_ERROR(H5E_PLIST, H5E_NOSPACE, FAIL, "unable to create data transform info") /* Update property list (takes ownership of transform) */ if (H5P_poke(plist, H5D_XFER_XFORM_NAME, &data_xform_prop) < 0) @@ -974,7 +996,7 @@ H5Pset_data_transform(hid_t plist_id, const char *expression) done: if (ret_value < 0) if (data_xform_prop && H5Z_xform_destroy(data_xform_prop) < 0) - HDONE_ERROR(H5E_PLINE, H5E_CLOSEERROR, FAIL, "unable to release data transform expression") + HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release data transform expression") FUNC_LEAVE_API(ret_value) } /* end H5Pset_data_transform() */ @@ -2109,3 +2131,251 @@ H5P__dxfr_edc_dec(const void **_pp, void *_value) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5P__dxfr_edc_dec() */ + +/*------------------------------------------------------------------------- + * Function: H5P__dxfr_dset_io_hyp_sel_copy + * + * Purpose: Creates a copy of the dataset I/O selection. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Sunday, January 31, 2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dxfr_dset_io_hyp_sel_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value) +{ + H5S_t *orig_space = *(H5S_t **)value; /* Original dataspace for property */ + H5S_t *new_space = NULL; /* New dataspace for property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* If there's a dataspace I/O selection set, copy it */ + if (orig_space) { + /* Make copy of dataspace */ + if (NULL == (new_space = H5S_copy(orig_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "error copying the dataset I/O selection") + + /* Set new value for property */ + *(void **)value = new_space; + } /* end if */ + +done: + /* Cleanup on error */ + if (ret_value < 0) + if (new_space && H5S_close(new_space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "error closing dataset I/O selection dataspace") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dxfr_dset_io_hyp_sel_copy() */ + +/*------------------------------------------------------------------------- + * Function: H5P__dxfr_dset_io_hyp_sel_cmp + * + * Purpose: Compare two dataset I/O selections. + * + * Return: positive if VALUE1 is greater than VALUE2, negative if VALUE2 is + * greater than VALUE1 and zero if VALUE1 and VALUE2 are equal. + * + * Programmer: Quincey Koziol + * Sunday, January 31, 2021 + * + *------------------------------------------------------------------------- + */ +static int +H5P__dxfr_dset_io_hyp_sel_cmp(const void *_space1, const void *_space2, size_t H5_ATTR_UNUSED size) +{ + const H5S_t *const *space1 = (const H5S_t *const *)_space1; /* Create local aliases for values */ + const H5S_t *const *space2 = (const H5S_t *const *)_space2; /* Create local aliases for values */ + herr_t ret_value = 0; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(space1); + HDassert(space1); + HDassert(size == sizeof(H5S_t *)); + + /* Check for a property being set */ + if (*space1 == NULL && *space2 != NULL) + HGOTO_DONE(-1); + if (*space1 != NULL && *space2 == NULL) + HGOTO_DONE(1); + + if (*space1) { + HDassert(*space2); + + /* Compare the extents of the dataspaces */ + /* (Error & not-equal count the same) */ + if (TRUE != H5S_extent_equal(*space1, *space2)) + HGOTO_DONE(-1); + + /* Compare the selection "shape" of the dataspaces */ + /* (Error & not-equal count the same) */ + if (TRUE != H5S_select_shape_same(*space1, *space2)) + HGOTO_DONE(-1); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dxfr_dset_io_hyp_sel_cmp() */ + +/*------------------------------------------------------------------------- + * Function: H5P__dxfr_dset_io_hyp_sel_close + * + * Purpose: Frees resources for dataset I/O selection + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Sunday, January 31, 2021 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__dxfr_dset_io_hyp_sel_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *_value) +{ + H5S_t *space = *(H5S_t **)_value; /* Dataspace for property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Release any dataspace */ + if (space && H5S_close(space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "error closing dataset I/O selection dataspace") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__dxfr_dset_io_hyp_sel_close() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_dataset_io_hyperslab_selection + * + * Purpose: H5Pset_dataset_io_hyperslab_selection() is designed to be used + * in conjunction with using H5S_PLIST for the file dataspace + * ID when making a call to H5Dread() or H5Dwrite(). When used + * with H5S_PLIST, the selection created by one or more calls to + * this routine is used for determining which dataset elements to + * access. + * + * 'rank' is the dimensionality of the selection and determines + * the size of the 'start', 'stride', 'count', and 'block' arrays. + * 'rank' must be between 1 and H5S_MAX_RANK, inclusive. + * + * The 'op', 'start', 'stride', 'count', and 'block' parameters + * behave identically to their behavior for H5Sselect_hyperslab(), + * please see the documentation for that routine for details about + * their use. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Saturday, January 30, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, const hsize_t start[], + const hsize_t stride[], const hsize_t count[], const hsize_t block[]) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5S_t * space; /* Dataspace to hold selection */ + hbool_t space_created = FALSE; /* Whether a new dataspace has been created */ + hbool_t reset_prop_on_error = FALSE; /* Whether to reset the property on failure */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "iIuSs*h*h*h*h", plist_id, rank, op, start, stride, count, block); + + /* Check arguments */ + if (rank < 1 || rank > H5S_MAX_RANK) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank value: %u", rank) + if (!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID)) + HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation") + if (start == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "'count' pointer is NULL") + if (stride != NULL) { + unsigned u; /* Local index variable */ + + /* Check for 0-sized strides */ + for (u = 0; u < rank; u++) + if (stride[u] == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value - stride[%u]==0", u) + } /* end if */ + if (count == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "'start' pointer is NULL") + /* block is allowed to be NULL, and will be assumed to be all '1's when NULL */ + + /* Get the plist structure */ + if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID") + + /* See if a dataset I/O selection is already set, and free it if it is */ + if (H5P_peek(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting dataset I/O selection") + + /* Check for operation on existing dataspace selection */ + if (NULL != space) { + int sndims; /* Rank of existing dataspace */ + + /* Get dimensions from current dataspace for selection */ + if ((sndims = H5S_GET_EXTENT_NDIMS(space)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection's dataspace rank") + + /* Check for different # of dimensions */ + if ((unsigned)sndims != rank) { + /* Set up new dataspace for 'set' operation, otherwise fail */ + if (op == H5S_SELECT_SET) { + /* Close previous dataspace */ + if (H5S_close(space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + + /* Reset 'space' pointer, so it's re-created */ + space = NULL; + + /* Set flag to reset property list on error */ + reset_prop_on_error = TRUE; + } /* end if */ + else + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "different rank for previous and new selections") + } /* end if */ + } /* end if */ + + /* Check for first time called */ + if (NULL == space) { + hsize_t dims[H5S_MAX_RANK]; /* Dimensions for new dataspace */ + unsigned u; /* Local index variable */ + + /* Initialize dimensions to largest possible actual size */ + for (u = 0; u < rank; u++) + dims[u] = (H5S_UNLIMITED - 1); + + /* Create dataspace of the correct dimensionality, with maximum dimensions */ + if (NULL == (space = H5S_create_simple(rank, dims, NULL))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create dataspace for selection") + space_created = TRUE; + } /* end if */ + + /* Set selection for dataspace */ + if (H5S_select_hyperslab(space, op, start, stride, count, block) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSELECT, FAIL, "can't create selection") + + /* Update property list (takes ownership of dataspace, if new) */ + if (H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection") + space_created = FALSE; /* Reset now that property owns the dataspace */ + +done: + /* Cleanup on failure */ + if (ret_value < 0) { + if (reset_prop_on_error && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection") + if (space_created && H5S_close(space) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_dataset_io_hyperslab_selection() */ |