mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
[svn-r23230] Purpose: Implement H5Dscatter and H5Dgather
Description: Adds 2 new API functions, H5Dscatter and H5Dgather. H5Dscatter retrieves data from a specified callback function and scatters it into a selection, defined by a supplied dataspace, within a supplied memory buffer. H5Dgather gathers data from a selection within a supplied memory buffer and passes it in a contiguous form to a supplied callback function. Added tests for these functions Tested: jam, ostrich, koala (h5committest); ummon
This commit is contained in:
parent
d7a07d62a4
commit
0e3517d34f
@ -99,7 +99,9 @@ $Source = "";
|
||||
"H5A_operator2_t" => "x",
|
||||
"H5A_info_t" => "x",
|
||||
"H5AC_cache_config_t" => "x",
|
||||
"H5D_gather_func_t" => "x",
|
||||
"H5D_operator_t" => "x",
|
||||
"H5D_scatter_func_t" => "x",
|
||||
"H5E_auto_t" => "x",
|
||||
"H5E_auto1_t" => "x",
|
||||
"H5E_auto2_t" => "x",
|
||||
|
@ -106,6 +106,9 @@ New Features
|
||||
|
||||
Library:
|
||||
--------
|
||||
- Added new API functions H5Dscatter and H5Dgather to scatter data to and
|
||||
and gather data from a selection within a memory buffer.
|
||||
(NAF - 2013/02/05)
|
||||
- The library now supports the data conversion from enumeration to numeric
|
||||
(integer and floating-point number) datatypes. See Issue 8221.
|
||||
(SLU - 2012/10/23)
|
||||
|
@ -107,6 +107,15 @@ extern "C" {
|
||||
typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim,
|
||||
const hsize_t *point, void *operator_data);
|
||||
|
||||
/* Define the operator function pointer for H5Dscatter() */
|
||||
typedef herr_t (*H5D_scatter_func_t)(void **src_buf/*out*/,
|
||||
size_t *src_buf_bytes_used/*out*/,
|
||||
void *op_data);
|
||||
|
||||
/* Define the operator function pointer for H5Dgather() */
|
||||
typedef herr_t (*H5D_gather_func_t)(const void *dst_buf,
|
||||
size_t dst_buf_bytes_used, void *op_data);
|
||||
|
||||
H5_DLL hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id,
|
||||
hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id);
|
||||
H5_DLL hid_t H5Dcreate_anon(hid_t file_id, hid_t type_id, hid_t space_id,
|
||||
@ -131,6 +140,10 @@ H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_
|
||||
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
|
||||
hid_t buf_type, hid_t space);
|
||||
H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
|
||||
H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id,
|
||||
hid_t dst_space_id, void *dst_buf);
|
||||
H5_DLL herr_t H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id,
|
||||
size_t dst_buf_size, void *dst_buf, H5D_gather_func_t op, void *op_data);
|
||||
H5_DLL herr_t H5Ddebug(hid_t dset_id);
|
||||
|
||||
/* Symbols defined for compatibility with previous versions of the HDF5 API.
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "H5Dpkg.h" /* Dataset functions */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5FLprivate.h" /* Free Lists */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
|
||||
|
||||
/****************/
|
||||
@ -361,7 +362,7 @@ done:
|
||||
* copies them into the gather buffer TGATH_BUF.
|
||||
* Each element is ELMT_SIZE bytes and arranged in application
|
||||
* memory according to SPACE.
|
||||
* The caller is requesting that at most NELMTS be gathered.
|
||||
* The caller is requesting that exactly NELMTS be gathered.
|
||||
*
|
||||
* Return: Success: Number of elements copied.
|
||||
* Failure: 0
|
||||
@ -899,3 +900,200 @@ H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info)
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__compound_opt_write() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dscatter
|
||||
*
|
||||
* Purpose: Scatters data provided by the callback op to the
|
||||
* destination buffer dst_buf, where the dimensions of
|
||||
* dst_buf and the selection to be scattered to are specified
|
||||
* by the dataspace dst_space_id. The type of the data to be
|
||||
* scattered is specified by type_id.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 14 Jan 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id,
|
||||
hid_t dst_space_id, void *dst_buf)
|
||||
{
|
||||
H5T_t *type; /* Datatype */
|
||||
H5S_t *dst_space; /* Dataspace */
|
||||
H5S_sel_iter_t iter; /* Selection iteration info*/
|
||||
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
|
||||
void *src_buf = NULL; /* Source (contiguous) data buffer */
|
||||
size_t src_buf_nbytes = 0; /* Size of src_buf */
|
||||
size_t type_size; /* Datatype element size */
|
||||
hssize_t nelmts; /* Number of remaining elements in selection */
|
||||
size_t nelmts_scatter = 0; /* Number of elements to scatter to dst_buf */
|
||||
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
|
||||
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE5("e", "x*xii*x", op, op_data, type_id, dst_space_id, dst_buf);
|
||||
|
||||
/* Check args */
|
||||
if(op == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid callback function pointer")
|
||||
if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
|
||||
if(NULL == (dst_space= (H5S_t *)H5I_object_verify(dst_space_id, H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
|
||||
if(dst_buf == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination buffer provided")
|
||||
|
||||
/* Fill the DXPL cache values for later use */
|
||||
if(H5D__get_dxpl_cache(H5P_DATASET_XFER_DEFAULT, &dxpl_cache) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
|
||||
|
||||
/* Get datatype element size */
|
||||
if(0 == (type_size = H5T_GET_SIZE(type)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size")
|
||||
|
||||
/* Get number of elements in dataspace */
|
||||
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(dst_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection")
|
||||
|
||||
/* Initialize selection iterator */
|
||||
if(H5S_select_iter_init(&iter, dst_space, type_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information")
|
||||
iter_init = TRUE;
|
||||
|
||||
/* Loop until all data has been scattered */
|
||||
while(nelmts > 0) {
|
||||
/* Make callback to retrieve data */
|
||||
if(op(&src_buf, &src_buf_nbytes, op_data) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CALLBACK, FAIL, "callback operator returned failure")
|
||||
|
||||
/* Calculate number of elements */
|
||||
nelmts_scatter = src_buf_nbytes / type_size;
|
||||
|
||||
/* Check callback results */
|
||||
if(!src_buf)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback did not return a buffer")
|
||||
if(src_buf_nbytes == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback returned a buffer size of 0")
|
||||
if(src_buf_nbytes % type_size)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buffer size is not a multiple of datatype size")
|
||||
if(nelmts_scatter > (size_t)nelmts)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback returned more elements than in selection")
|
||||
|
||||
/* Scatter data */
|
||||
if(H5D__scatter_mem(src_buf, dst_space, &iter, nelmts_scatter, dxpl_cache, dst_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "scatter failed")
|
||||
|
||||
nelmts -= (hssize_t)nelmts_scatter;
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
/* Release selection iterator */
|
||||
if(iter_init) {
|
||||
if(H5S_SELECT_ITER_RELEASE(&iter) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator")
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* H5Dscatter() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dgather
|
||||
*
|
||||
* Purpose: Gathers data provided from the source buffer src_buf to
|
||||
* contiguous buffer dst_buf, then calls the callback op.
|
||||
* The dimensions of src_buf and the selection to be gathered
|
||||
* are specified by the dataspace src_space_id. The type of
|
||||
* the data to be gathered is specified by type_id.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 16 Jan 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, size_t dst_buf_size,
|
||||
void *dst_buf, H5D_gather_func_t op, void *op_data)
|
||||
{
|
||||
H5T_t *type; /* Datatype */
|
||||
H5S_t *src_space; /* Dataspace */
|
||||
H5S_sel_iter_t iter; /* Selection iteration info*/
|
||||
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
|
||||
size_t type_size; /* Datatype element size */
|
||||
hssize_t nelmts; /* Number of remaining elements in selection */
|
||||
size_t dst_buf_nelmts; /* Number of elements that can fit in dst_buf */
|
||||
size_t nelmts_gathered; /* Number of elements gathered from src_buf */
|
||||
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
|
||||
H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE7("e", "i*xiz*xx*x", src_space_id, src_buf, type_id, dst_buf_size,
|
||||
dst_buf, op, op_data);
|
||||
|
||||
/* Check args */
|
||||
if(NULL == (src_space= (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
|
||||
if(src_buf == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source buffer provided")
|
||||
if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
|
||||
if(dst_buf_size == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination buffer size is 0")
|
||||
if(dst_buf == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination buffer provided")
|
||||
if(op == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid callback function pointer")
|
||||
|
||||
/* Fill the DXPL cache values for later use */
|
||||
if(H5D__get_dxpl_cache(H5P_DATASET_XFER_DEFAULT, &dxpl_cache) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
|
||||
|
||||
/* Get datatype element size */
|
||||
if(0 == (type_size = H5T_GET_SIZE(type)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size")
|
||||
|
||||
/* Get number of elements in dst_buf_size */
|
||||
dst_buf_nelmts = dst_buf_size / type_size;
|
||||
if(dst_buf_nelmts == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination buffer is not large enough to hold one element")
|
||||
|
||||
/* Get number of elements in dataspace */
|
||||
if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(src_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection")
|
||||
|
||||
/* Initialize selection iterator */
|
||||
if(H5S_select_iter_init(&iter, src_space, type_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information")
|
||||
iter_init = TRUE;
|
||||
|
||||
/* Loop until all data has been scattered */
|
||||
while(nelmts > 0) {
|
||||
/* Gather data */
|
||||
if(0 == (nelmts_gathered = H5D__gather_mem(src_buf, src_space, &iter, MIN(dst_buf_nelmts, (size_t)nelmts), dxpl_cache, dst_buf)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTCOPY, FAIL, "gather failed")
|
||||
HDassert(nelmts_gathered == MIN(dst_buf_nelmts, (size_t)nelmts));
|
||||
|
||||
/* Make callback to process dst_buf */
|
||||
if(op(dst_buf, nelmts_gathered * type_size, op_data) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CALLBACK, FAIL, "callback operator returned failure")
|
||||
|
||||
nelmts -= (hssize_t)nelmts_gathered;
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
/* Release selection iterator */
|
||||
if(iter_init) {
|
||||
if(H5S_SELECT_ITER_RELEASE(&iter) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator")
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* H5Dgather() */
|
||||
|
||||
|
1012
test/dsets.c
1012
test/dsets.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user