mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[svn-r8335] Purpose:
Code optimization Description: Change algorithm to directly use coordinates describing a chunk's position in a dataspace instead of creating a dataspace with the chunk's position selected. This reduces the number of copies of dataspaces we need to keep around. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.9 (sleipnir) w/parallel too minor to require h5committest
This commit is contained in:
parent
48d84a1bbc
commit
eb7a675f0a
26
src/H5Dio.c
26
src/H5Dio.c
@ -2669,13 +2669,13 @@ done:
|
||||
static herr_t
|
||||
H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
{
|
||||
H5S_t *tmp_fspace=NULL; /* Temporary file dataspace */
|
||||
hssize_t sel_points; /* Number of elements in file selection */
|
||||
hssize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
|
||||
hssize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
|
||||
hssize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
|
||||
hssize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
|
||||
hsize_t count[H5O_LAYOUT_NDIMS]; /* Hyperslab count information */
|
||||
hssize_t end[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
|
||||
hsize_t chunk_index; /* Index of chunk */
|
||||
int curr_dim; /* Current dimension to increment */
|
||||
unsigned u; /* Local index variable */
|
||||
@ -2686,16 +2686,12 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
/* Sanity check */
|
||||
assert(fm->f_ndims>0);
|
||||
|
||||
/* Make a copy of file dataspace */
|
||||
if((tmp_fspace = H5S_copy(fm->file_space))==NULL)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
|
||||
|
||||
/* Get number of elements selected in file */
|
||||
if((sel_points=H5S_get_select_npoints(tmp_fspace))<0)
|
||||
if((sel_points=H5S_get_select_npoints(fm->file_space))<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements")
|
||||
|
||||
/* Get bounding box for selection (to reduce the number of chunks to iterate over) */
|
||||
if(H5S_get_select_bounds(tmp_fspace, sel_start, sel_end)<0)
|
||||
if(H5S_get_select_bounds(fm->file_space, sel_start, sel_end)<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Set initial chunk location & hyperslab size */
|
||||
@ -2704,12 +2700,9 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
start_coords[u]=(sel_start[u]/(hssize_t)fm->layout->dim[u])*(hssize_t)fm->layout->dim[u];
|
||||
coords[u]=start_coords[u];
|
||||
count[u]=fm->layout->dim[u];
|
||||
end[u]=(coords[u]+count[u])-1;
|
||||
} /* end for */
|
||||
|
||||
/* Select initial chunk as hyperslab */
|
||||
if(H5S_select_hyperslab(tmp_fspace,H5S_SELECT_SET,coords,NULL,count,NULL)<0) /*lint !e772 The coords and count arrays should always be initialized */
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create hyperslab selection")
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
|
||||
@ -2717,7 +2710,7 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
/* Iterate through each chunk in the dataset */
|
||||
while(sel_points) {
|
||||
/* Check for intersection of temporary chunk and file selection */
|
||||
if(H5S_hyper_intersect(tmp_fspace,fm->file_space)==TRUE) {
|
||||
if(H5S_hyper_intersect_block(fm->file_space,coords,end)==TRUE) {
|
||||
H5S_t *tmp_fchunk; /* Temporary file dataspace */
|
||||
H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into tree */
|
||||
hssize_t chunk_points; /* Number of elements in chunk selection */
|
||||
@ -2797,6 +2790,7 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
/* Increment chunk location in fastest changing dimension */
|
||||
H5_CHECK_OVERFLOW(count[curr_dim],hsize_t,hssize_t);
|
||||
coords[curr_dim]+=(hssize_t)count[curr_dim];
|
||||
end[curr_dim]+=(hssize_t)count[curr_dim];
|
||||
|
||||
/* Bring chunk location back into bounds, if necessary */
|
||||
if(coords[curr_dim]>sel_end[curr_dim]) {
|
||||
@ -2809,22 +2803,16 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
|
||||
|
||||
/* Increment chunk location in current dimension */
|
||||
coords[curr_dim]+=(hssize_t)count[curr_dim];
|
||||
end[curr_dim]=(coords[curr_dim]+(hssize_t)count[curr_dim])-1;
|
||||
} while(coords[curr_dim]>sel_end[curr_dim]);
|
||||
|
||||
/* Re-Calculate the index of this chunk */
|
||||
if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
|
||||
HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
|
||||
} /* end if */
|
||||
|
||||
/* Move template chunk's offset to current location of chunk */
|
||||
if(H5S_hyper_move(tmp_fspace,coords)<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't move chunk selection")
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
if(tmp_fspace)
|
||||
if(H5S_close(tmp_fspace)<0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file dataspace copy")
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D_create_chunk_file_map_hyper() */
|
||||
|
||||
|
122
src/H5Shyper.c
122
src/H5Shyper.c
@ -3624,6 +3624,7 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5S_hyper_convert() */
|
||||
|
||||
#ifdef LATER
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
@ -3740,6 +3741,127 @@ H5S_hyper_intersect (H5S_t *space1, H5S_t *space2)
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5S_hyper_intersect() */
|
||||
#endif /* LATER */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_hyper_intersect_block_helper
|
||||
PURPOSE
|
||||
Helper routine to detect intersections in span trees
|
||||
USAGE
|
||||
htri_t H5S_hyper_intersect_block_helper(spans, start, end)
|
||||
H5S_hyper_span_info_t *spans; IN: First span tree to operate with
|
||||
hssize_t *offset; IN: Selection offset coordinate
|
||||
hssize_t *start; IN: Starting coordinate for block
|
||||
hssize_t *end; IN: Ending coordinate for block
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Quickly detect intersections between span tree and block
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
static htri_t
|
||||
H5S_hyper_intersect_block_helper (const H5S_hyper_span_info_t *spans, hssize_t *offset, hssize_t *start, hssize_t *end)
|
||||
{
|
||||
H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */
|
||||
htri_t status; /* Status from recursive call */
|
||||
htri_t ret_value=FALSE; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_intersect_block_helper);
|
||||
|
||||
/* Sanity check */
|
||||
assert(spans);
|
||||
assert(offset);
|
||||
assert(start);
|
||||
assert(end);
|
||||
|
||||
/* Get the span list for spans in this tree */
|
||||
curr=spans->head;
|
||||
|
||||
/* Iterate over the spans in the tree */
|
||||
while(curr!=NULL) {
|
||||
/* Check for span entirely before block */
|
||||
if((curr->high+*offset)<*start)
|
||||
/* Advance to next span in this dimension */
|
||||
curr=curr->next;
|
||||
/* If this span is past the end of the block, then we're done in this dimension */
|
||||
else if((curr->low+*offset)>*end)
|
||||
HGOTO_DONE(FALSE)
|
||||
/* block & span overlap */
|
||||
else {
|
||||
if(curr->down==NULL)
|
||||
HGOTO_DONE(TRUE)
|
||||
else {
|
||||
/* Recursively check spans in next dimension down */
|
||||
if((status=H5S_hyper_intersect_block_helper(curr->down,offset+1,start+1,end+1))<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
|
||||
|
||||
/* If there is a span intersection in the down dimensions, the span trees overlap */
|
||||
if(status==TRUE)
|
||||
HGOTO_DONE(TRUE);
|
||||
|
||||
/* No intersection in down dimensions, advance to next span */
|
||||
curr=curr->next;
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end while */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5S_hyper_intersect_block_helper() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5S_hyper_intersect_block
|
||||
PURPOSE
|
||||
Detect intersections in span trees
|
||||
USAGE
|
||||
htri_t H5S_hyper_intersect_block(space, start, end)
|
||||
H5S_t *space; IN: First dataspace to operate on span tree
|
||||
hssize_t *start; IN: Starting coordinate for block
|
||||
hssize_t *end; IN: Ending coordinate for block
|
||||
RETURNS
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Quickly detect intersections between span tree and block
|
||||
GLOBAL VARIABLES
|
||||
COMMENTS, BUGS, ASSUMPTIONS
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
htri_t
|
||||
H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end)
|
||||
{
|
||||
htri_t ret_value=FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_intersect_block);
|
||||
|
||||
/* Sanity check */
|
||||
assert(space);
|
||||
assert(start);
|
||||
assert(end);
|
||||
|
||||
/* Check for 'all' selection, instead of a hyperslab selection */
|
||||
/* (Technically, this shouldn't be in the "hyperslab" routines...) */
|
||||
if(space->select.type==H5S_SEL_ALL)
|
||||
HGOTO_DONE(TRUE);
|
||||
|
||||
/* Check that the space selections both have span trees */
|
||||
if(space->select.sel_info.hslab.span_lst==NULL)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree");
|
||||
|
||||
/* Perform the span-by-span intersection check */
|
||||
if((ret_value=H5S_hyper_intersect_block_helper(space->select.sel_info.hslab.span_lst,space->select.offset,start,end))<0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value);
|
||||
} /* H5S_hyper_intersect_block() */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
@ -241,7 +241,10 @@ 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);
|
||||
H5_DLL herr_t H5S_hyper_convert(H5S_t *space);
|
||||
#ifdef LATER
|
||||
H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2);
|
||||
#endif /* LATER */
|
||||
H5_DLL htri_t H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user