diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2013-02-13 21:55:48 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2013-02-13 21:55:48 (GMT) |
commit | 749522bbd654596191c7cad929c00b1a62466cda (patch) | |
tree | 6457ae1e2e92166aee3d608b4760565e16744a7d /test | |
parent | 8dcb0ee3d069b03c1146086dc186fc135ae83bf2 (diff) | |
download | hdf5-749522bbd654596191c7cad929c00b1a62466cda.zip hdf5-749522bbd654596191c7cad929c00b1a62466cda.tar.gz hdf5-749522bbd654596191c7cad929c00b1a62466cda.tar.bz2 |
[svn-r23265] Merge revisions 23230, 23234, and 23237 to 1.8 branch
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; ummon (1.8)
Diffstat (limited to 'test')
-rw-r--r-- | test/dsets.c | 1028 |
1 files changed, 1028 insertions, 0 deletions
diff --git a/test/dsets.c b/test/dsets.c index 7283aae..abbbe2c 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -8251,6 +8251,1028 @@ error: /*------------------------------------------------------------------------- + * Function: test_scatter + * + * Purpose: Tests H5Dscatter with a variety of different selections + * and source buffer sizes. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Wednesday, January 16, 2013 + * + *------------------------------------------------------------------------- + */ +typedef struct scatter_info_t { + int *src_buf; /* Source data buffer */ + size_t block; /* Maximum number of elements to return to H5Dscatter() */ + size_t size; /* Remaining number of elements to return */ +} scatter_info_t; + +#define TEST_SCATTER_CHECK_ARR(ARR, EXP) \ + for(i=0; i<(int)(sizeof(ARR)/sizeof(ARR[0])); i++) \ + for(j=0; j<(int)(sizeof(ARR[0])/sizeof(ARR[0][0])); j++) \ + for(k=0; k<(int)(sizeof(ARR[0][0])/sizeof(ARR[0][0][0])); k++) \ + if(ARR[i][j][k] != EXP[i][j][k]) { \ + H5_FAILED(); AT(); \ + printf(" " #ARR "[%d][%d][%d] == %d, " #EXP "[%d][%d][%d] == %d\n", i, j, k, ARR[i][j][k], i, j, k, EXP[i][j][k]); \ + goto error; \ + } + +static herr_t +scatter_cb(void **src_buf/*out*/, size_t *src_buf_bytes_used/*out*/, + void *_scatter_info) +{ + scatter_info_t *scatter_info = (scatter_info_t *)_scatter_info; + size_t nelmts; /* Number of elements to return in src_buf */ + + /* Calculate number of elements */ + nelmts = MIN(scatter_info->block, scatter_info->size); + HDassert(nelmts > 0); + + /* Set output variables */ + *src_buf = (void *)scatter_info->src_buf; + *src_buf_bytes_used = nelmts * sizeof(scatter_info->src_buf[0]); + + /* Update scatter_info */ + scatter_info->src_buf += nelmts; + scatter_info->size -= nelmts; + + return SUCCEED; +} + +static herr_t +test_scatter(void) +{ + hid_t sid = -1; /* Dataspace ID */ + hsize_t dim[3] = {8, 5, 8}; /* Dataspace dimensions */ + hsize_t start[3] = {0, 0, 0}; + hsize_t stride[3] = {0, 0, 0}; + hsize_t count[3] = {0, 0, 0}; + hsize_t block[3] = {0, 0, 0}; + hsize_t start2[3] = {0, 0, 0}; + hsize_t count2[3] = {0, 0, 0}; + hsize_t point[4][3] = {{2, 3, 2}, {3, 0, 2}, {7, 2, 0}, {0, 1, 5}}; + size_t src_buf_size; + int src_buf[36]; /* Source data buffer */ + int dst_buf[8][5][8]; /* Destination data buffer */ + int expect_dst_buf[8][5][8]; /* Expected destination data buffer */ + scatter_info_t scatter_info; /* Operator data for callback */ + int i, j, k, src_i; /* Local index variables */ + + TESTING("H5Dscatter()"); + + /* Create dataspace */ + if((sid = H5Screate_simple(3, dim, NULL)) < 0) TEST_ERROR + + /* Initialize src_buf */ + for(i=0; i<(int)(sizeof(src_buf)/sizeof(src_buf[0])); i++) + src_buf[i] = i + 1; + + + /* + * Test 1: Simple case + */ + /* Select hyperslab */ + count[0] = 1; + count[1] = 1; + count[2] = 8; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Initialize dst_buf and expect_dst_buf */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + for(i=0; i<8; i++) + expect_dst_buf[0][0][i] = src_buf[i]; + + /* Loop over buffer sizes */ + for(src_buf_size=1; src_buf_size<=9; src_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Set up scatter info */ + scatter_info.src_buf = src_buf; + scatter_info.block = src_buf_size; + scatter_info.size = 8; + + /* Scatter data */ + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + /* Verify data */ + TEST_SCATTER_CHECK_ARR(dst_buf, expect_dst_buf) + } /* end for */ + + + /* + * Test 2: Single block in dataset + */ + /* Select hyperslab */ + start[0] = 3; + start[1] = 2; + start[2] = 4; + count[0] = 2; + count[1] = 3; + count[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + src_i = 0; + for(i=3; i<5; i++) + for(j=2; j<5; j++) + for(k=4; k<6; k++) + expect_dst_buf[i][j][k] = src_buf[src_i++]; + + /* Loop over buffer sizes */ + for(src_buf_size=1; src_buf_size<=13; src_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Set up scatter info */ + scatter_info.src_buf = src_buf; + scatter_info.block = src_buf_size; + scatter_info.size = 12; + + /* Scatter data */ + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + /* Verify data */ + TEST_SCATTER_CHECK_ARR(dst_buf, expect_dst_buf) + } /* end for */ + + + /* + * Test 3: Multiple blocks + */ + /* Select hyperslab */ + start[0] = 1; + start[1] = 1; + start[2] = 1; + stride[0] = 3; + stride[1] = 4; + stride[2] = 5; + count[0] = 3; + count[1] = 1; + count[2] = 2; + block[0] = 1; + block[1] = 3; + block[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride ,count, block) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. Note that the algorithm used here (if statement) would not + * work for overlapping hyperslabs. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + src_i = 0; + for(i=1; i<8; i++) + for(j=1; j<4; j++) + for(k=1; k<8; k++) + if((hsize_t)i >= start[0] + && ((hsize_t)i - start[0]) % stride[0] < block[0] + && ((hsize_t)i - start[0]) / stride[0] < count[0] + && (hsize_t)j >= start[1] + && ((hsize_t)j - start[1]) % stride[1] < block[1] + && ((hsize_t)j - start[1]) / stride[1] < count[1] + && (hsize_t)k >= start[2] + && ((hsize_t)k - start[2]) % stride[2] < block[2] + && ((hsize_t)k - start[2]) / stride[2] < count[2]) + expect_dst_buf[i][j][k] = src_buf[src_i++]; + + /* Loop over buffer sizes */ + for(src_buf_size=1; src_buf_size<=37; src_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Set up scatter info */ + scatter_info.src_buf = src_buf; + scatter_info.block = src_buf_size; + scatter_info.size = 36; + + /* Scatter data */ + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + /* Verify data */ + TEST_SCATTER_CHECK_ARR(dst_buf, expect_dst_buf) + } /* end for */ + + + /* + * Test 4: Compound selection + */ + /* Select hyperslabs */ + start[0] = 2; + start[1] = 1; + start[2] = 1; + count[0] = 2; + count[1] = 3; + count[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + start2[0] = 1; + start2[1] = 2; + start2[2] = 2; + count2[0] = 3; + count2[1] = 2; + count2[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start2, NULL ,count2, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + src_i = 0; + for(i=1; i<4; i++) + for(j=1; j<4; j++) + for(k=1; k<4; k++) + if(!(((hsize_t)i >= start[0] && (hsize_t)i < start[0] + count[0]) + && ((hsize_t)j >= start[1] && (hsize_t)j < start[1] + count[1]) + && ((hsize_t)k >= start[2] && (hsize_t)k < start[2] + count[2])) + != !(((hsize_t)i >= start2[0] && (hsize_t)i < start2[0] + count2[0]) + && ((hsize_t)j >= start2[1] && (hsize_t)j < start2[1] + count2[1]) + && ((hsize_t)k >= start2[2] && (hsize_t)k < start2[2] + count2[2]))) + expect_dst_buf[i][j][k] = src_buf[src_i++]; + + /* Loop over buffer sizes */ + for(src_buf_size=1; src_buf_size<=17; src_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Set up scatter info */ + scatter_info.src_buf = src_buf; + scatter_info.block = src_buf_size; + scatter_info.size = 16; + + /* Scatter data */ + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + /* Verify data */ + TEST_SCATTER_CHECK_ARR(dst_buf, expect_dst_buf) + } /* end for */ + + + /* + * Test 5: Point selection + */ + /* Select hyperslabs */ + if(H5Sselect_elements(sid, H5S_SELECT_SET, sizeof(point) / sizeof(point[0]), (hsize_t *)point) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + for(i=0; i<(int)(sizeof(point) / sizeof(point[0])); i++) + expect_dst_buf[point[i][0]][point[i][1]][point[i][2]] + = src_buf[i]; + + /* Loop over buffer sizes */ + for(src_buf_size=1; src_buf_size<=5; src_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Set up scatter info */ + scatter_info.src_buf = src_buf; + scatter_info.block = src_buf_size; + scatter_info.size = 4; + + /* Scatter data */ + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + /* Verify data */ + TEST_SCATTER_CHECK_ARR(dst_buf, expect_dst_buf) + } /* end for */ + + + /* Close everything */ + if(H5Sclose(sid) < 0) TEST_ERROR + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} /* end test_scatter() */ + + +/*------------------------------------------------------------------------- + * Function: test_gather + * + * Purpose: Tests H5Dgather with a variety of different selections and + * destination buffer sizes. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Wednesday, January 16, 2013 + * + *------------------------------------------------------------------------- + */ +typedef struct gather_info_t { + int *expect_dst_buf; /* Expected destination data buffer */ + size_t max_nelmts; /* Maximum number of elements passed to callback */ + hbool_t last_call; /* Whether this should be the last time the callback is called */ +} gather_info_t; + +static herr_t +gather_cb(const void *dst_buf, size_t dst_buf_bytes_used, + void *_gather_info) +{ + gather_info_t *gather_info = (gather_info_t *)_gather_info; + size_t nelmts; /* Number of elements in src_buf */ + int i; /* Local index variable */ + + HDassert(dst_buf_bytes_used > 0); + + /* Calculate number of elements */ + nelmts = dst_buf_bytes_used / sizeof(gather_info->expect_dst_buf[0]); + + /* Make sure the number of bytes is a multiple of the number of elements */ + if(nelmts * sizeof(gather_info->expect_dst_buf[0]) != dst_buf_bytes_used) + TEST_ERROR + + /* Make sure we weren't passed more data than we requested to be passed at + * once */ + if(nelmts > gather_info->max_nelmts) + TEST_ERROR + + /* If we were passed less data than requested, make sure this is the last + * time the callback was called */ + if(gather_info->last_call) + TEST_ERROR + if(nelmts < gather_info->max_nelmts) + gather_info->last_call = TRUE; + + /* Compare data and expected data */ + for(i=0; i<(int)nelmts; i++) + if(((const int *)dst_buf)[i] != *((gather_info->expect_dst_buf)++)) + TEST_ERROR + + return SUCCEED; + +error: + return FAIL; +} + +static herr_t +test_gather(void) +{ + hid_t sid = -1; /* Dataspace ID */ + hsize_t dim[3] = {8, 5, 8}; /* Dataspace dimensions */ + hsize_t start[3] = {0, 0, 0}; + hsize_t stride[3] = {0, 0, 0}; + hsize_t count[3] = {0, 0, 0}; + hsize_t block[3] = {0, 0, 0}; + hsize_t start2[3] = {0, 0, 0}; + hsize_t count2[3] = {0, 0, 0}; + hsize_t point[4][3] = {{2, 3, 2}, {3, 0, 2}, {7, 2, 0}, {0, 1, 5}}; + size_t dst_buf_size; + int src_buf[8][5][8]; /* Source data buffer */ + int dst_buf[36]; /* Destination data buffer */ + int expect_dst_buf[36]; /* Expected destination data buffer */ + gather_info_t gather_info; /* Operator data for callback */ + int i, j, k, dst_i; /* Local index variables */ + + TESTING("H5Dgather()"); + + /* Create dataspace */ + if((sid = H5Screate_simple(3, dim, NULL)) < 0) TEST_ERROR + + /* Initialize src_buf */ + for(i=0; i<(int)(sizeof(src_buf)/sizeof(src_buf[0])); i++) + for(j=0; j<(int)(sizeof(src_buf[0])/sizeof(src_buf[0][0])); j++) + for(k=0; k<(int)(sizeof(src_buf[0][0])/sizeof(src_buf[0][0][0])); k++) + src_buf[i][j][k] = 1 + k + + (int)(sizeof(src_buf[0][0]) / sizeof(src_buf[0][0][0])) * j + + (int)(sizeof(src_buf[0]) / sizeof(src_buf[0][0][0])) * i; + + + /* + * Test 1: Simple case + */ + /* Select hyperslab */ + count[0] = 1; + count[1] = 1; + count[2] = 8; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + for(i=0; i<8; i++) + expect_dst_buf[i] = src_buf[0][0][i]; + + /* Loop over buffer sizes */ + for(dst_buf_size=1; dst_buf_size<=9; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + 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; + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size - 1; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]) - 1, dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + if(gather_info.expect_dst_buf - expect_dst_buf != 8) TEST_ERROR + + + /* + * Test 2: Single block in dataset + */ + /* Select hyperslab */ + start[0] = 3; + start[1] = 2; + start[2] = 4; + count[0] = 2; + count[1] = 3; + count[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + dst_i = 0; + for(i=3; i<5; i++) + for(j=2; j<5; j++) + for(k=4; k<6; k++) + expect_dst_buf[dst_i++] = src_buf[i][j][k]; + + /* Loop over buffer sizes */ + for(dst_buf_size=1; dst_buf_size<=13; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + if(gather_info.expect_dst_buf - expect_dst_buf != 12) TEST_ERROR + } /* end for */ + + + /* + * Test 3: Multiple blocks + */ + /* Select hyperslab */ + start[0] = 1; + start[1] = 1; + start[2] = 1; + stride[0] = 3; + stride[1] = 4; + stride[2] = 5; + count[0] = 3; + count[1] = 1; + count[2] = 2; + block[0] = 1; + block[1] = 3; + block[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride ,count, block) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. Note that the algorithm used here (if statement) would not + * work for overlapping hyperslabs. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + dst_i = 0; + for(i=1; i<8; i++) + for(j=1; j<4; j++) + for(k=1; k<8; k++) + if((hsize_t)i >= start[0] + && ((hsize_t)i - start[0]) % stride[0] < block[0] + && ((hsize_t)i - start[0]) / stride[0] < count[0] + && (hsize_t)j >= start[1] + && ((hsize_t)j - start[1]) % stride[1] < block[1] + && ((hsize_t)j - start[1]) / stride[1] < count[1] + && (hsize_t)k >= start[2] + && ((hsize_t)k - start[2]) % stride[2] < block[2] + && ((hsize_t)k - start[2]) / stride[2] < count[2]) + expect_dst_buf[dst_i++] = src_buf[i][j][k]; + + /* Loop over buffer sizes */ + for(dst_buf_size=1; dst_buf_size<=37; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + if(gather_info.expect_dst_buf - expect_dst_buf != 36) TEST_ERROR + } /* end for */ + + + /* + * Test 4: Compound selection + */ + /* Select hyperslabs */ + start[0] = 2; + start[1] = 1; + start[2] = 1; + count[0] = 2; + count[1] = 3; + count[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + start2[0] = 1; + start2[1] = 2; + start2[2] = 2; + count2[0] = 3; + count2[1] = 2; + count2[2] = 2; + if(H5Sselect_hyperslab(sid, H5S_SELECT_XOR, start2, NULL ,count2, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + dst_i = 0; + for(i=1; i<4; i++) + for(j=1; j<4; j++) + for(k=1; k<4; k++) + if(!(((hsize_t)i >= start[0] && (hsize_t)i < start[0] + count[0]) + && ((hsize_t)j >= start[1] && (hsize_t)j < start[1] + count[1]) + && ((hsize_t)k >= start[2] && (hsize_t)k < start[2] + count[2])) + != !(((hsize_t)i >= start2[0] && (hsize_t)i < start2[0] + count2[0]) + && ((hsize_t)j >= start2[1] && (hsize_t)j < start2[1] + count2[1]) + && ((hsize_t)k >= start2[2] && (hsize_t)k < start2[2] + count2[2]))) + expect_dst_buf[dst_i++] = src_buf[i][j][k]; + + /* Loop over buffer sizes */ + for(dst_buf_size=1; dst_buf_size<=17; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + if(gather_info.expect_dst_buf - expect_dst_buf != 16) TEST_ERROR + } /* end for */ + + + /* + * Test 5: Point selection + */ + /* Select hyperslabs */ + if(H5Sselect_elements(sid, H5S_SELECT_SET, sizeof(point) / sizeof(point[0]), (hsize_t *)point) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + /* Iterate over block containing selection, checking if each element is in + * selection. */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + for(i=0; i<(int)(sizeof(point) / sizeof(point[0])); i++) + expect_dst_buf[i] = src_buf[point[i][0]][point[i][1]][point[i][2]]; + + /* Loop over buffer sizes */ + for(dst_buf_size=1; dst_buf_size<=5; dst_buf_size++) { + /* Reset dst_buf */ + (void)HDmemset(dst_buf, 0, sizeof(dst_buf)); + + /* Initialize gather_info */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = dst_buf_size; + gather_info.last_call = FALSE; + + /* Gather data */ + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, dst_buf_size * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* Verify that all data has been gathered (and verified) */ + if(gather_info.expect_dst_buf - expect_dst_buf != 4) TEST_ERROR + } /* end for */ + + + /* Close everything */ + if(H5Sclose(sid) < 0) TEST_ERROR + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} /* end test_gather() */ + + +/*------------------------------------------------------------------------- + * Function: test_scatter_error + * + * Purpose: Tests H5Dscatter with a variety of different conditions + * that should cause errors. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Monday, February 4, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +scatter_error_cb_fail(void **src_buf/*out*/, size_t *src_buf_bytes_used/*out*/, + void *_scatter_info) +{ + scatter_info_t *scatter_info = (scatter_info_t *)_scatter_info; + size_t nelmts; /* Number of elements to return in src_buf */ + + /* Calculate number of elements */ + nelmts = MIN(scatter_info->block, scatter_info->size); + HDassert(nelmts > 0); + + /* Set output variables */ + *src_buf = (void *)scatter_info->src_buf; + *src_buf_bytes_used = nelmts * sizeof(scatter_info->src_buf[0]); + + return FAIL; +} + +static herr_t +scatter_error_cb_null(void **src_buf/*out*/, size_t *src_buf_bytes_used/*out*/, + void *_scatter_info) +{ + scatter_info_t *scatter_info = (scatter_info_t *)_scatter_info; + size_t nelmts; /* Number of elements to return in src_buf */ + + /* Calculate number of elements */ + nelmts = MIN(scatter_info->block, scatter_info->size); + HDassert(nelmts > 0); + + /* Set output variables */ + *src_buf = NULL; + *src_buf_bytes_used = nelmts * sizeof(scatter_info->src_buf[0]); + + return SUCCEED; +} + +static herr_t +scatter_error_cb_unalign(void **src_buf/*out*/, size_t *src_buf_bytes_used/*out*/, + void *_src_buf_bytes_used) +{ + /* Set output variables */ + *src_buf = _src_buf_bytes_used; + *src_buf_bytes_used = *(size_t *)_src_buf_bytes_used; + + return SUCCEED; +} + +static herr_t +test_scatter_error(void) +{ + hid_t sid = -1; /* Dataspace ID */ + hsize_t dim[1] = {10}; /* Dataspace dimensions */ + hsize_t start[3] = {2}; + hsize_t count[3] = {6}; + int src_buf[7]; /* Source data buffer */ + int dst_buf[10]; /* Destination data buffer */ + scatter_info_t scatter_info; /* Operator data for callback */ + size_t cb_unalign_nbytes; /* Number of bytes to return for unaligned test */ + herr_t ret; /* Return value */ + int i; /* Local index variable */ + + TESTING("H5Dscatter() error conditions"); + + /* Create dataspace */ + if((sid = H5Screate_simple(1, dim, NULL)) < 0) TEST_ERROR + + /* Initialize src_buf */ + for(i=0; i<(int)(sizeof(src_buf)/sizeof(src_buf[0])); i++) + src_buf[i] = i + 1; + + /* Select hyperslab */ + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Verify that base configuration passes */ + scatter_info.src_buf = src_buf; + scatter_info.block = sizeof(src_buf)/sizeof(src_buf[0]); + scatter_info.size = 6; + if(H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf) < 0) + TEST_ERROR + + + /* + * Test invalid parameters + */ + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(NULL, NULL, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_cb, &scatter_info, sid, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, H5T_NATIVE_INT, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, NULL); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* + * Test returning too many elements in callback + */ + scatter_info.src_buf = src_buf; + scatter_info.size = 7; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_cb, &scatter_info, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* + * Test callback returns failure + */ + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_error_cb_fail, &scatter_info, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* + * Test callback returns NULL buffer + */ + scatter_info.src_buf = src_buf; + scatter_info.size = 6; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_error_cb_null, &scatter_info, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* + * Test callback returns 0 for src_buf_bytes_used + */ + cb_unalign_nbytes = 0; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_error_cb_unalign, &cb_unalign_nbytes, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* + * Test callback returns src_buf_bytes_used that is not a multiple of + * datatype size + */ + cb_unalign_nbytes = sizeof(src_buf[0]) - 1; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_error_cb_unalign, &cb_unalign_nbytes, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + cb_unalign_nbytes = sizeof(src_buf[0]) + 1; + H5E_BEGIN_TRY { + ret = H5Dscatter(scatter_error_cb_unalign, &cb_unalign_nbytes, H5T_NATIVE_INT, sid, dst_buf); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* Close everything */ + if(H5Sclose(sid) < 0) TEST_ERROR + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} /* end test_scatter_error() */ + + +/*------------------------------------------------------------------------- + * Function: test_gather_error + * + * Purpose: Tests H5Dgather with a variety of different conditions + * that should cause errors. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Neil Fortner + * Monday, February 4, 2013 + * + *------------------------------------------------------------------------- + */ +static herr_t +gather_error_cb_fail(const void UNUSED *dst_buf, + size_t UNUSED dst_buf_bytes_used, void UNUSED *op_data) +{ + return FAIL; +} + +static herr_t +test_gather_error(void) +{ + hid_t sid = -1; /* Dataspace ID */ + hsize_t dim[1] = {10}; /* Dataspace dimensions */ + hsize_t start[1] = {2}; + hsize_t count[1] = {6}; + int src_buf[10]; /* Source data buffer */ + int dst_buf[6]; /* Destination data buffer */ + int expect_dst_buf[6]; /* Expected destination data buffer */ + gather_info_t gather_info; /* Operator data for callback */ + herr_t ret; /* Return value */ + int i; /* Local index variable */ + + TESTING("H5Dgather() error conditions"); + + /* Create dataspace */ + if((sid = H5Screate_simple(1, dim, NULL)) < 0) TEST_ERROR + + /* Initialize src_buf */ + for(i=0; i<(int)(sizeof(src_buf)/sizeof(src_buf[0])); i++) + src_buf[i] = 1 + i; + + /* Select hyperslab */ + if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, NULL ,count, NULL) < 0) + TEST_ERROR + + /* Initialize expect_dst_buf */ + (void)HDmemset(expect_dst_buf, 0, sizeof(expect_dst_buf)); + for(i=0; i<6; i++) + expect_dst_buf[i] = src_buf[i + 2]; + + /* Verify that base configuration passes */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.max_nelmts = 6; + gather_info.last_call = FALSE; + if(H5Dgather(sid, src_buf, H5T_NATIVE_INT, 6 * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info) < 0) + TEST_ERROR + + /* + * Test invalid parameters + */ + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + ret = H5Dgather(H5T_NATIVE_INT, src_buf, H5T_NATIVE_INT, 6 * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + ret = H5Dgather(sid, NULL, H5T_NATIVE_INT, 6 * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + ret = H5Dgather(sid, src_buf, sid, 6 * sizeof(dst_buf[0]), dst_buf, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + ret = H5Dgather(sid, src_buf, H5T_NATIVE_INT, 0, dst_buf, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + ret = H5Dgather(sid, src_buf, H5T_NATIVE_INT, 1, dst_buf, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + 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]), NULL, gather_cb, &gather_info); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + gather_info.expect_dst_buf = expect_dst_buf; + gather_info.last_call = FALSE; + H5E_BEGIN_TRY { + 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 + + + /* + * Test callback returns failure + */ + 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, gather_error_cb_fail, NULL); + } H5E_END_TRY + if(ret >= 0) TEST_ERROR + + + /* Close everything */ + if(H5Sclose(sid) < 0) TEST_ERROR + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(sid); + } H5E_END_TRY; + return -1; +} /* end test_gather_error() */ + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests the dataset interface (H5D) @@ -8386,6 +9408,12 @@ main(void) /* Close 2nd FAPL */ if(H5Pclose(fapl2) < 0) TEST_ERROR + /* Tests that do not use files */ + nerrors += (test_scatter() < 0 ? 1 : 0); + nerrors += (test_gather() < 0 ? 1 : 0); + nerrors += (test_scatter_error() < 0 ? 1 : 0); + nerrors += (test_gather_error() < 0 ? 1 : 0); + /* Verify symbol table messages are cached */ nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0); |