[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:
Neil Fortner 2013-02-05 12:07:02 -05:00
parent d7a07d62a4
commit 0e3517d34f
5 changed files with 1229 additions and 1 deletions

View File

@ -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",

View File

@ -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)

View File

@ -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.

View File

@ -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() */

File diff suppressed because it is too large Load Diff