diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dchunk.c | 67 | ||||
-rw-r--r-- | src/H5Dprivate.h | 11 | ||||
-rw-r--r-- | src/H5Oattribute.c | 45 | ||||
-rw-r--r-- | src/H5Pdxpl.c | 278 | ||||
-rw-r--r-- | src/H5S.c | 51 | ||||
-rw-r--r-- | src/H5Sprivate.h | 1 | ||||
-rw-r--r-- | src/H5Spublic.h | 8 | ||||
-rw-r--r-- | src/H5VLnative_dataset.c | 154 | ||||
-rw-r--r-- | src/H5private.h | 13 | ||||
-rw-r--r-- | src/H5system.c | 6 |
10 files changed, 465 insertions, 169 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index d6eb715..5fc7abb 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -604,8 +604,6 @@ H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage HDassert(offset); HDassert(storage_size); - *storage_size = 0; - /* Allocate dataspace and initialize it if it hasn't been. */ if (!(*layout->ops->is_space_alloc)(&layout->storage)) HGOTO_DONE(SUCCEED) @@ -5031,7 +5029,7 @@ H5D__chunk_collective_fill(const H5D_t *dset, H5D_chunk_coll_info_t *chunk_info, * order of offset in the file. */ if (need_addr_sort) - HDqsort(chunk_disp_array, blocks, sizeof(MPI_Aint), H5D__chunk_cmp_addr); + HDqsort(chunk_disp_array, (size_t)blocks, sizeof(MPI_Aint), H5D__chunk_cmp_addr); /* MSC - should use this if MPI_type_create_hindexed block is working: * mpi_code = MPI_Type_create_hindexed_block(blocks, block_len, chunk_disp_array, MPI_BYTE, @@ -6066,6 +6064,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) if (udata->chunk_in_cache) { HDassert(H5F_addr_defined(chunk_rec->chunk_addr)); + HDassert(ent); HDassert(H5F_addr_defined(ent->chunk_block.offset)); H5_CHECKED_ASSIGN(nbytes, size_t, shared_fo->layout.u.chunk.size, uint32_t); @@ -7499,6 +7498,36 @@ done: } /* end H5D__get_chunk_info_by_coord() */ /*------------------------------------------------------------------------- + * Function: H5D__chunk_iter_cb + * + * Purpose: Call the user-defined function with the chunk data. The iterator continues if + * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is + * returned. + * + * Return: Success: H5_ITER_CONT or H5_ITER_STOP + * Failure: Negative (H5_ITER_ERROR) + * + * Programmer: Gaute Hope + * August 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) +{ + int ret_value = 0; + + FUNC_ENTER_STATIC_NOERR + + const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata; + + ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, + chunk_rec->nbytes, data->op_data); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__chunk_iter_cb */ + +/*------------------------------------------------------------------------- * Function: H5D__chunk_iter * * Purpose: Iterate over all the chunks in the dataset with given callbak. @@ -7537,7 +7566,7 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) for (ent = rdcc->head; ent; ent = ent->next) /* Flush the chunk out to disk, to make certain the size is correct later */ if (H5D__chunk_flush_entry(dset, ent, FALSE) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "cannot flush indexed storage buffer") /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; @@ -7559,33 +7588,3 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) done: FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5D__chunk_iter() */ - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_iter_cb - * - * Purpose: Call the user-defined function with the chunk data. The iterator continues if - * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is - * returned. - * - * Return: Success: H5_ITER_CONT or H5_ITER_STOP - * Failure: Negative (H5_ITER_ERROR) - * - * Programmer: Gaute Hope - * August 2020 - * - *------------------------------------------------------------------------- - */ -static int -H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) -{ - int ret_value = 0; - - FUNC_ENTER_STATIC_NOERR - - const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata; - - ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, - chunk_rec->nbytes, data->op_data); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_iter_cb */ diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index f9ef772..ad9794d 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -79,11 +79,12 @@ #define H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME \ "local_no_collective_cause" /* cause of broken collective I/O in each process */ #define H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME \ - "global_no_collective_cause" /* cause of broken collective I/O in all processes */ -#define H5D_XFER_EDC_NAME "err_detect" /* EDC */ -#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */ -#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */ -#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */ + "global_no_collective_cause" /* cause of broken collective I/O in all processes */ +#define H5D_XFER_EDC_NAME "err_detect" /* EDC */ +#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */ +#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */ +#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */ +#define H5D_XFER_DSET_IO_SEL_NAME "dset_io_selection" /* Dataset I/O selection */ #ifdef H5_HAVE_INSTRUMENTED_LIBRARY /* Collective chunk instrumentation properties */ #define H5D_XFER_COLL_CHUNK_LINK_HARD_NAME "coll_chunk_link_hard" diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 0fc4cc6..56f7145 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -1901,48 +1901,3 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5O__attr_bh_info() */ - -#ifndef H5_NO_DEPRECATED_SYMBOLS - -/*------------------------------------------------------------------------- - * Function: H5O__attr_count - * - * Purpose: Determine the # of attributes on an object - * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * Monday, December 11, 2006 - * - *------------------------------------------------------------------------- - */ -int -H5O__attr_count(const H5O_loc_t *loc) -{ - H5O_t * oh = NULL; /* Pointer to actual object header */ - hsize_t nattrs; /* Number of attributes */ - int ret_value = -1; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* Check arguments */ - HDassert(loc); - - /* Protect the object header to iterate over */ - if (NULL == (oh = H5O_protect(loc, H5AC__READ_ONLY_FLAG, FALSE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") - - /* Retrieve # of attributes on object */ - if (H5O__attr_count_real(loc->file, oh, &nattrs) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count") - - /* Set return value */ - ret_value = (int)nattrs; - -done: - if (oh && H5O_unprotect(loc, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, FAIL, "unable to release object header") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O__attr_count */ -#endif /* H5_NO_DEPRECATED_SYMBOLS */ 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() */ @@ -84,7 +84,7 @@ H5FL_ARR_DEFINE(hsize_t, H5S_MAX_RANK); static const H5I_class_t H5I_DATASPACE_CLS[1] = {{ H5I_DATASPACE, /* ID class value */ 0, /* Class flags */ - 2, /* # of reserved IDs for class */ + 3, /* # of reserved IDs for class */ (H5I_free_t)H5S__close_cb /* Callback routine for closing objects of this class */ }}; @@ -277,55 +277,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5S_get_validiated_dataspace - PURPOSE - Get a pointer to a validated H5S_t pointer - USAGE - H5S_t *H5S_get_validated_space(dataspace_id, space) - hid_t space_id; IN: The ID of the dataspace - const H5S_t * space; OUT: A pointer to the dataspace - RETURNS - SUCCEED/FAIL - DESCRIPTION - Gets a pointer to a dataspace struct after validating it. The pointer - can be NULL (if the ID is H5S_ALL, for example). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -herr_t -H5S_get_validated_dataspace(hid_t space_id, const H5S_t **space) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(space); - - /* Check for invalid ID */ - if (space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid space_id (ID cannot be a negative number)") - - /* No special dataspace struct for H5S_ALL */ - if (H5S_ALL == space_id) - *space = NULL; - else { - /* Get the dataspace pointer */ - if (NULL == (*space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "space_id is not a dataspace ID") - - /* Check for valid selection */ - if (H5S_SELECT_VALID(*space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection + offset not within extent") - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_get_validated_dataspace() */ - -/*-------------------------------------------------------------------------- - NAME H5S_create PURPOSE Create empty, typed dataspace diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 56c1646..51a98a6 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -217,7 +217,6 @@ 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 herr_t H5S_get_validated_dataspace(hid_t space_id, const H5S_t **space /*out*/); H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], const hsize_t maxdims[/*rank*/]); H5_DLL herr_t H5S_set_version(H5F_t *f, H5S_t *ds); H5_DLL herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index c2c0aef..7962035 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -21,8 +21,12 @@ #include "H5public.h" #include "H5Ipublic.h" -/* Define atomic datatypes */ -#define H5S_ALL 0 /* (hid_t) */ +/* Define special dataspaces for dataset I/O operations */ +#define H5S_ALL 0 /* (hid_t) */ +#define H5S_BLOCK 1 /* (hid_t) */ +#define H5S_PLIST 2 /* (hid_t) */ + +/* Define value for 'unlimited' dimensions */ #define H5S_UNLIMITED HSIZE_UNDEF /* Define user-level maximum number of dimensions */ diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c index 978ecb3..3a7f105 100644 --- a/src/H5VLnative_dataset.c +++ b/src/H5VLnative_dataset.c @@ -49,6 +49,10 @@ /* Local Prototypes */ /********************/ +/* Helper routines for read/write API calls */ +static herr_t H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id, + hid_t mem_space_id, H5S_t **file_space, H5S_t **mem_space); + /*********************/ /* Package Variables */ /*********************/ @@ -62,6 +66,100 @@ /*******************/ /*------------------------------------------------------------------------- + * Function: H5VL__native_dataset_io_setup + * + * Purpose: Set up file and memory dataspaces for dataset I/O operation + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id, hid_t mem_space_id, + H5S_t **file_space, H5S_t **mem_space) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(dset); + HDassert(file_space && NULL == *file_space); + HDassert(mem_space && NULL == *mem_space); + + /* Set up file dataspace */ + if (H5S_ALL == file_space_id) + /* Use dataspace for dataset */ + *file_space = dset->shared->space; + else if (H5S_BLOCK == file_space_id) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_BLOCK is not allowed for file dataspace") + else if (H5S_PLIST == file_space_id) { + H5P_genplist_t *plist; /* Property list pointer */ + H5S_t * space; /* Dataspace to hold selection */ + + /* Get the plist structure */ + if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_DATASET, H5E_BADID, FAIL, "bad dataset transfer property list") + + /* 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_DATASET, H5E_CANTGET, FAIL, "error getting dataset I/O selection") + + /* Use dataspace for dataset */ + *file_space = dset->shared->space; + + /* Copy, but share, selection from property list to dataset's dataspace */ + if (H5S_SELECT_COPY(*file_space, space, TRUE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataset I/O selection") + } /* end else-if */ + else { + /* Get the dataspace pointer */ + if (NULL == (*file_space = (H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "file_space_id is not a dataspace ID") + } /* end else */ + + /* Get dataspace for memory buffer */ + if (H5S_ALL == mem_space_id) + *mem_space = *file_space; + else if (H5S_BLOCK == mem_space_id) { + hsize_t nelmts; /* # of selected elements in file */ + + /* Get the # of elements selected */ + nelmts = H5S_GET_SELECT_NPOINTS(*file_space); + + /* Check for any elements */ + if (nelmts > 0) { + /* Create a 1-D dataspace of the same # of elements */ + if (NULL == (*mem_space = H5S_create_simple(1, &nelmts, NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create simple memory dataspace") + } /* end if */ + else { + /* Create a NULL dataspace of the same # of elements */ + if (NULL == (*mem_space = H5S_create(H5S_NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create NULL memory dataspace") + } /* end else */ + } /* end if */ + else if (H5S_PLIST == mem_space_id) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_PLIST is not allowed for memory dataspace") + else { + /* Get the dataspace pointer */ + if (NULL == (*mem_space = (H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "mem_space_id is not a dataspace ID") + } /* end else */ + + /* Check for valid selections */ + if (H5S_SELECT_VALID(*file_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, + "selection + offset not within extent for file dataspace") + if (H5S_SELECT_VALID(*mem_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, + "selection + offset not within extent for memory dataspace") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__native_dataset_io_setup() */ + +/*------------------------------------------------------------------------- * Function: H5VL__native_dataset_create * * Purpose: Handles the dataset create callback @@ -172,10 +270,10 @@ herr_t H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, void *buf, void H5_ATTR_UNUSED **req) { - H5D_t * dset = (H5D_t *)obj; - const H5S_t *mem_space = NULL; - const H5S_t *file_space = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5D_t *dset = (H5D_t *)obj; + H5S_t *mem_space = NULL; + H5S_t *file_space = NULL; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -183,11 +281,10 @@ H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_ if (NULL == dset->oloc.file) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") - /* Get validated dataspace pointers */ - if (H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id") - if (H5S_get_validated_dataspace(file_space_id, &file_space) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id") + /* Get file & memory dataspaces */ + if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) < + 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces") /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); @@ -197,6 +294,17 @@ H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") done: + /* Clean up */ + if (H5S_BLOCK == mem_space_id && mem_space) { + if (H5S_close(mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, + "unable to release temporary memory dataspace for H5S_BLOCK") + } /* end if */ + else if (H5S_PLIST == file_space_id && file_space) + if (H5S_select_all(file_space, TRUE) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, + "unable to release file dataspace selection for H5S_PLIST") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_dataset_read() */ @@ -213,10 +321,10 @@ herr_t H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void H5_ATTR_UNUSED **req) { - H5D_t * dset = (H5D_t *)obj; - const H5S_t *mem_space = NULL; - const H5S_t *file_space = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5D_t *dset = (H5D_t *)obj; + H5S_t *mem_space = NULL; + H5S_t *file_space = NULL; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -224,11 +332,10 @@ H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid if (NULL == dset->oloc.file) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file") - /* Get validated dataspace pointers */ - if (H5S_get_validated_dataspace(mem_space_id, &mem_space) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from mem_space_id") - if (H5S_get_validated_dataspace(file_space_id, &file_space) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "could not get a validated dataspace from file_space_id") + /* Get file & memory dataspaces */ + if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) < + 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces") /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); @@ -238,6 +345,17 @@ H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") done: + /* Clean up */ + if (H5S_BLOCK == mem_space_id && mem_space) { + if (H5S_close(mem_space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, + "unable to release temporary memory dataspace for H5S_BLOCK") + } /* end if */ + else if (H5S_PLIST == file_space_id && file_space) + if (H5S_select_all(file_space, TRUE) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, + "unable to release file dataspace selection for H5S_PLIST") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_dataset_write() */ diff --git a/src/H5private.h b/src/H5private.h index 0e2cdec..bb416ef 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -113,22 +113,21 @@ #define H5_DEFAULT_VOL H5VL_NATIVE #ifdef H5_HAVE_WIN32_API + /* The following two defines must be before any windows headers are included */ #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ #define NOGDI /* Exclude Graphic Display Interface macros */ -#ifdef H5_HAVE_WINSOCK2_H -#include <winsock2.h> -#endif +#include <windows.h> + +#include <direct.h> /* For _getcwd() */ +#include <io.h> /* POSIX I/O */ +#include <winsock2.h> /* For GetUserName() */ #ifdef H5_HAVE_THREADSAFE #include <process.h> /* For _beginthread() */ #endif -#include <windows.h> -#include <direct.h> /* For _getcwd() */ -#include <io.h> /* POSIX I/O */ - #endif /*H5_HAVE_WIN32_API*/ #ifndef F_OK diff --git a/src/H5system.c b/src/H5system.c index dcb77dd..adfb758 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -365,7 +365,7 @@ Wsetenv(const char *name, const char *value, int overwrite) return (int)_putenv_s(name, value); } /* end Wsetenv() */ -#ifdef H5_HAVE_WINSOCK2_H +#ifdef H5_HAVE_WIN32_API #pragma comment(lib, "advapi32.lib") #endif @@ -450,12 +450,12 @@ char * Wgetlogin(void) { -#ifdef H5_HAVE_WINSOCK2_H +#ifdef H5_HAVE_WIN32_API DWORD bufferCount = WloginBuffer_count; if (GetUserName(Wlogin_buffer, &bufferCount) != 0) return (Wlogin_buffer); else -#endif /* H5_HAVE_WINSOCK2_H */ +#endif return NULL; } |