From 19704681e19ad6e3d10d36f3337143c887f2baac Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 13 May 2004 15:33:20 -0500 Subject: [svn-r8512] Purpose: Code optimization Description: Defer creating the span trees for hyperslab selections until they are actually needed (which may be never, in certain circumstances). Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.9 (sleipnir) w/parallel --- src/H5Dio.c | 4 ++-- src/H5Shyper.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++----- src/H5Sprivate.h | 2 +- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/H5Dio.c b/src/H5Dio.c index 10845c9..8629744 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -111,7 +111,7 @@ static herr_t H5D_create_chunk_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_space, const H5S_t *mem_space, fm_map *fm); static herr_t H5D_destroy_chunk_map(fm_map *fm); static void H5D_free_chunk_info(void *chunk_info); -static herr_t H5D_create_chunk_file_map_hyper(const fm_map *fm); +static herr_t H5D_create_chunk_file_map_hyper(fm_map *fm); static herr_t H5D_create_chunk_mem_map_hyper(const fm_map *fm); static herr_t H5D_chunk_file_cb(void *elem, hid_t type_id, hsize_t ndims, hssize_t *coords, void *fm); @@ -2584,7 +2584,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_create_chunk_file_map_hyper(const fm_map *fm) +H5D_create_chunk_file_map_hyper(fm_map *fm) { hssize_t sel_points; /* Number of elements in file selection */ hssize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index d559066..874b57a 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -44,6 +44,9 @@ static herr_t H5S_hyper_free_span (H5S_hyper_span_t *span); static H5S_hyper_span_info_t *H5S_hyper_copy_span (H5S_hyper_span_info_t *spans); static herr_t H5S_hyper_span_scratch (H5S_hyper_span_info_t *spans, void *scr_value); static herr_t H5S_hyper_span_precompute (H5S_hyper_span_info_t *spans, size_t elmt_size); +static herr_t H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, + const hssize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]); +static herr_t H5S_hyper_generate_spans(H5S_t *space); static herr_t H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); static herr_t H5S_hyper_iter_block(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); static hsize_t H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter); @@ -186,7 +189,6 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) /* Check args */ assert(space && H5S_SEL_HYPERSLABS==space->select.type); assert(iter); - assert(space->select.sel_info.hslab.span_lst); /* Initialize the number of points to iterate over */ iter->elmt_left=space->select.num_elem; @@ -308,6 +310,7 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space) } /* end if */ else { /* Initialize the information needed for non-regular hyperslab I/O */ + assert(space->select.sel_info.hslab.span_lst); /* Make a copy of the span tree to iterate over */ iter->u.hyp.spans=H5S_hyper_copy_span(space->select.sel_info.hslab.span_lst); @@ -3732,7 +3735,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ htri_t -H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end) +H5S_hyper_intersect_block (H5S_t *space, hssize_t *start, hssize_t *end) { htri_t ret_value=FAIL; /* Return value */ @@ -3750,7 +3753,8 @@ H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end) /* 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"); + if(H5S_hyper_generate_spans(space)<0) + 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) @@ -5302,6 +5306,56 @@ H5S_hyper_rebuild (H5S_t *space) } /* H5S_hyper_rebuild() */ +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_generate_spans + PURPOSE + Create span tree for a regular hyperslab selection + USAGE + herr_t H5S_hyper_generate_spans(space) + H5S_t *space; IN/OUT: Pointer to dataspace + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Create a span tree representation of a regular hyperslab selection and + add it to the information for the hyperslab selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_hyper_generate_spans(H5S_t *space) +{ + hssize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */ + hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */ + hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */ + hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */ + unsigned u; /* Counter */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_generate_spans); + + assert(space); + assert(space->select.type==H5S_SEL_HYPERSLABS); + + /* Get the diminfo */ + for(u=0; uextent.u.simple.rank; u++) { + tmp_start[u]=space->select.sel_info.hslab.opt_diminfo[u].start; + tmp_stride[u]=space->select.sel_info.hslab.opt_diminfo[u].stride; + tmp_count[u]=space->select.sel_info.hslab.opt_diminfo[u].count; + tmp_block[u]=space->select.sel_info.hslab.opt_diminfo[u].block; + } /* end for */ + + /* Build the hyperslab information also */ + if(H5S_generate_hyperslab (space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5S_hyper_generate_spans() */ + + /*------------------------------------------------------------------------- * Function: H5S_generate_hyperlab * @@ -5702,6 +5756,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); /* Save the diminfo */ + space->select.num_elem=1; for(u=0; uextent.u.simple.rank; u++) { space->select.sel_info.hslab.app_diminfo[u].start = start[u]; space->select.sel_info.hslab.app_diminfo[u].stride = stride[u]; @@ -5712,19 +5767,24 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, space->select.sel_info.hslab.opt_diminfo[u].stride = opt_stride[u]; space->select.sel_info.hslab.opt_diminfo[u].count = opt_count[u]; space->select.sel_info.hslab.opt_diminfo[u].block = opt_block[u]; + space->select.num_elem*=(opt_count[u]*opt_block[u]); } /* end for */ /* Indicate that the dimension information is valid */ space->select.sel_info.hslab.diminfo_valid=TRUE; - /* Build the hyperslab information also */ - if(H5S_generate_hyperslab (space, H5S_SELECT_SET, start, opt_stride, opt_count, opt_block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); + /* Indicate that there's no slab information */ + space->select.sel_info.hslab.span_lst=NULL; } /* end if */ else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) { /* Sanity check */ assert(space->select.type==H5S_SEL_HYPERSLABS); + /* Check if there's no hyperslab span information currently */ + if(space->select.sel_info.hslab.span_lst==NULL) + if(H5S_hyper_generate_spans(space)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree"); + /* Indicate that the regular dimensions are no longer valid */ space->select.sel_info.hslab.diminfo_valid=FALSE; diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 947c34b..e766b52 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -254,7 +254,7 @@ 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 htri_t H5S_hyper_intersect_block (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