diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-12-13 18:14:36 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-12-13 18:14:36 (GMT) |
commit | a8161177b98fb2a85c92288294efe3fbace2fbeb (patch) | |
tree | 86cd881bd3f6294015588df4fa38d15101cc35d5 /src | |
parent | 15830ae10ac760ee46777f7bba6c9e10ed0e5906 (diff) | |
download | hdf5-a8161177b98fb2a85c92288294efe3fbace2fbeb.zip hdf5-a8161177b98fb2a85c92288294efe3fbace2fbeb.tar.gz hdf5-a8161177b98fb2a85c92288294efe3fbace2fbeb.tar.bz2 |
[svn-r7943] Purpose:
Bug fix.
Description:
Using a selection offset with hyperslab selections in chunked datasets
was getting into an infinite loop and hanging the application.
Solution:
Apply the selection offset to the hyperslab selection properly.
Platforms tested:
FreeBSD 4.9 (sleipnir) w & w/o parallel
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dio.c | 12 | ||||
-rw-r--r-- | src/H5Shyper.c | 72 | ||||
-rw-r--r-- | src/H5Sprivate.h | 5 |
3 files changed, 78 insertions, 11 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 1e6dcaf..562ee22 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -2293,6 +2293,10 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp if(H5S_hyper_convert(fm->file_space)<0) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") + /* Normalize the hyperslab selections by adjusting them by the offset */ + if(H5S_hyper_normalize_offset(fm->file_space)<0) + HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") + #ifdef QAK { int mpi_rank; @@ -2339,6 +2343,10 @@ H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_sp if(H5S_hyper_convert(fm->mem_space)<0) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") + /* Normalize the hyperslab selections by adjusting them by the offset */ + if(H5S_hyper_normalize_offset(fm->mem_space)<0) + HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") + /* If the selections are the same shape, use the file chunk information * to generate the memory chunk information quickly. */ @@ -2743,11 +2751,11 @@ H5D_create_chunk_mem_map_hyper(const fm_map *fm) assert(fm->f_ndims>0); /* Get offset of first block in file selection */ - if(H5S_get_select_hyper_blocklist(fm->file_space, (hsize_t)0, (hsize_t)1, file_off)<0) + if(H5S_get_select_hyper_blocklist(fm->file_space, 1, (hsize_t)0, (hsize_t)1, file_off)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection block info") /* Get offset of first block in memory selection */ - if(H5S_get_select_hyper_blocklist(fm->mem_space, (hsize_t)0, (hsize_t)1, mem_off)<0) + if(H5S_get_select_hyper_blocklist(fm->mem_space, 1, (hsize_t)0, (hsize_t)1, mem_off)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection block info") /* Calculate the adjustment for memory selection from file selection */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 5ddf5a3..7422de2 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -2410,7 +2410,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblocks, hsize_t *buf) +H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startblock, hsize_t numblocks, hsize_t *buf) { H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ @@ -2435,11 +2435,20 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numbloc /* Set some convienence values */ ndims=space->extent.u.simple.rank; fast_dim=ndims-1; - /* - * Use the "application dimension information" to pass back to the user - * the blocks they set, not the optimized, internal information. - */ - diminfo=space->select.sel_info.hslab.app_diminfo; + + /* Check which set of dimension information to use */ + if(internal) + /* + * Use the "optimized dimension information" to pass back information + * on the blocks set, not the "application information". + */ + diminfo=space->select.sel_info.hslab.diminfo; + else + /* + * Use the "application dimension information" to pass back to the user + * the blocks they set, not the optimized, internal information. + */ + diminfo=space->select.sel_info.hslab.app_diminfo; /* Build the tables of count sizes as well as the initial offset */ for(i=0; i<ndims; i++) { @@ -2570,7 +2579,7 @@ H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, hsize_t numbloc /* Go get the correct number of blocks */ if(numblocks>0) - ret_value = H5S_get_select_hyper_blocklist(space,startblock,numblocks,buf); + ret_value = H5S_get_select_hyper_blocklist(space,0,startblock,numblocks,buf); else ret_value=SUCCEED; /* Successfully got 0 blocks... */ @@ -3919,6 +3928,55 @@ done: /*-------------------------------------------------------------------------- NAME + H5S_hyper_normalize_offset + PURPOSE + "Normalize" a hyperslab selection by adjusting it's coordinates by the + amount of the selection offset. + USAGE + herr_t H5S_hyper_normalize_offset(space) + H5S_t *space; IN/OUT: Pointer to dataspace to move + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves the hyperslab selection by the selection offset and then resets + the selection offset to zeros. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_hyper_normalize_offset(H5S_t *space) +{ + unsigned u; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_normalize_offset); + + assert(space); + + /* Check if there is an offset currently */ + if(space->select.offset) { + /* Invert the selection offset */ + for(u=0; u<space->extent.u.simple.rank; u++) + space->select.offset[u] =- space->select.offset[u]; + + /* Call the existing 'adjust' routine */ + if(H5S_hyper_adjust(space, space->select.offset)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab normalization"); + + /* Zero out the selection offset */ + for(u=0; u<space->extent.u.simple.rank; u++) + space->select.offset[u] = 0; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5S_hyper_normalize_offset() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_hyper_append_span PURPOSE Create a new span and append to span list diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index c3089d6..a734993 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -233,8 +233,8 @@ H5_DLL herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, /* Operations on hyperslab selections */ H5_DLL herr_t H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hssize_t start[], const hsize_t *stride, const hsize_t count[], const hsize_t *block); -H5_DLL herr_t H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, - hsize_t numblocks, hsize_t *buf); +H5_DLL herr_t H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, + hsize_t startblock, hsize_t numblocks, hsize_t *buf); H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hssize_t *coords); H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space); @@ -242,6 +242,7 @@ H5_DLL herr_t H5S_hyper_convert(H5S_t *space); H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2); H5_DLL herr_t H5S_hyper_adjust(H5S_t *space, const hssize_t *offset); H5_DLL herr_t H5S_hyper_move(H5S_t *space, const hssize_t *offset); +H5_DLL herr_t H5S_hyper_normalize_offset(H5S_t *space); /* Operations on selection iterators */ H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); |