[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:
Quincey Koziol 2004-04-10 09:44:58 -05:00
parent 48d84a1bbc
commit eb7a675f0a
3 changed files with 132 additions and 19 deletions

View File

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

View File

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

View File

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