From 692fa69934553e34a7166fd919b90309bc4ecb23 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Fri, 8 Feb 2013 11:49:21 -0500 Subject: [svn-r23237] 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 --- src/H5Dscatgath.c | 10 +++++++--- test/dsets.c | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 74d6749..60a8800 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -1048,8 +1048,6 @@ H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, size_t dst_buf_size, 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) @@ -1068,6 +1066,11 @@ H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, size_t dst_buf_size, 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") + /* If dst_buf is not large enough to hold all the elements, make sure there + * is a callback */ + if(((size_t)nelmts > dst_buf_nelmts) && (op == NULL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback supplied and destination buffer too small") + /* 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") @@ -1081,10 +1084,11 @@ H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, size_t dst_buf_size, 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) + if(op && 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; + HDassert(op || (nelmts == 0)); } /* end while */ done: diff --git a/test/dsets.c b/test/dsets.c index 7689a81..7abe818 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -8624,6 +8624,22 @@ test_gather(void) if(gather_info.expect_dst_buf - expect_dst_buf != 8) TEST_ERROR } /* end for */ + /* Test without a callback */ + /* Loop over buffer sizes */ + for(dst_buf_size=8; dst_buf_size<=9; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, NULL, NULL) < 0) + TEST_ERROR + + /* Verify data */ + for(i=0; i<(int)(sizeof(dst_buf)/sizeof(dst_buf[0])); i++) + if(dst_buf[i] != expect_dst_buf[i]) + TEST_ERROR + } /* end for */ + /* Test with a dst_buf_size that is not a multiple of the datatype size */ /* Reset dst_buf */ dst_buf_size = 7; @@ -9155,7 +9171,7 @@ test_gather_error(void) gather_info.expect_dst_buf = expect_dst_buf; gather_info.last_call = FALSE; H5E_BEGIN_TRY { - ret = H5Dgather(sid, src_buf, H5T_NATIVE_INT, 6 * sizeof(dst_buf[0]), dst_buf, NULL, &gather_info); + ret = H5Dgather(sid, src_buf, H5T_NATIVE_INT, 5 * sizeof(dst_buf[0]), dst_buf, NULL, &gather_info); } H5E_END_TRY if(ret >= 0) TEST_ERROR -- cgit v0.12