diff options
author | jrmainzer <72230804+jrmainzer@users.noreply.github.com> | 2021-11-23 01:20:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-23 01:20:56 (GMT) |
commit | 28d0a7b1b93e3918f3c8ee361af3280a2c9ee8a4 (patch) | |
tree | 0ac1b135f2c8a8bd9dbb980ebdbeb36dcf89f2c2 /src/H5Pdxpl.c | |
parent | 65d6d256cf9d04dbeb275025cc2b01d0f36ed3f1 (diff) | |
parent | 68c00b3fa1c0f4ba9b8e9724beb1d0b0b31f69ad (diff) | |
download | hdf5-28d0a7b1b93e3918f3c8ee361af3280a2c9ee8a4.zip hdf5-28d0a7b1b93e3918f3c8ee361af3280a2c9ee8a4.tar.gz hdf5-28d0a7b1b93e3918f3c8ee361af3280a2c9ee8a4.tar.bz2 |
Merge pull request #1217 from jrmainzer/selection_io_with_subfiling_vfd
Selection io with subfiling vfd
Diffstat (limited to 'src/H5Pdxpl.c')
-rw-r--r-- | src/H5Pdxpl.c | 287 |
1 files changed, 278 insertions, 9 deletions
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 70fc982..46dc94c 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -68,7 +68,7 @@ #define H5D_XFER_BTREE_SPLIT_RATIO_SIZE sizeof(double[3]) #define H5D_XFER_BTREE_SPLIT_RATIO_DEF \ { \ - 0.1f, 0.5f, 0.9f \ + 0.1, 0.5, 0.9 \ } #define H5D_XFER_BTREE_SPLIT_RATIO_ENC H5P__dxfr_btree_split_ratio_enc #define H5D_XFER_BTREE_SPLIT_RATIO_DEC H5P__dxfr_btree_split_ratio_dec @@ -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() */ @@ -1030,7 +1052,7 @@ H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size) /* Copy into application buffer */ len = HDstrlen(pexp); if (expression) { - HDstrncpy(expression, pexp, MIN(len + 1, size)); + HDstrncpy(expression, pexp, size); if (len >= size) expression[size - 1] = '\0'; } /* end if */ @@ -1486,9 +1508,8 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right) H5TRACE4("e", "iddd", plist_id, left, middle, right); /* Check arguments */ - if (left < (double)0.0f || left > (double)1.0f || middle < (double)0.0f || middle > (double)1.0f || - right < (double)0.0f || right > (double)1.0f) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0<=X<=1.0") + if (left < 0.0 || left > 1.0 || middle < 0.0 || middle > 1.0 || right < 0.0 || right > 1.0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0 <= X <= 1.0") /* Get the plist structure */ if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER))) @@ -2110,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 = NULL; /* 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 && plist && 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() */ |