From eb7a675f0a1bb565bdeb4c97697c9821c5ce72cc Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 10 Apr 2004 09:44:58 -0500 Subject: [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 --- src/H5Dio.c | 26 ++++-------- src/H5Shyper.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5Sprivate.h | 3 ++ 3 files changed, 132 insertions(+), 19 deletions(-) diff --git a/src/H5Dio.c b/src/H5Dio.c index 1008215..207efbf 100644 --- a/src/H5Dio.c +++ b/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() */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 589ddd0..6a6d604 100644 --- a/src/H5Shyper.c +++ b/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() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 2fcdad7..94510b2 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -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); -- cgit v0.12