From a3fd0e95a7c179efb956fe1b36ab1af128fe323e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 13 May 2004 15:33:27 -0500 Subject: [svn-r8513] 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 | 136 +++++++++++++++++++++++++++++++++++++++++++------------ src/H5Sprivate.h | 2 +- 3 files changed, 111 insertions(+), 31 deletions(-) diff --git a/src/H5Dio.c b/src/H5Dio.c index 068782c..8ccb441 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -110,7 +110,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(const 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); @@ -2646,7 +2646,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 169d58a..7094134 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); /* Needed for use in hyperslab code (H5Shyper.c) */ #ifdef NEW_HYPERSLAB_API static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); @@ -190,7 +193,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; @@ -312,6 +314,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); @@ -3736,7 +3739,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 */ @@ -3754,7 +3757,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) @@ -5305,6 +5309,56 @@ H5S_hyper_rebuild (H5S_t *space) FUNC_LEAVE_NOAPI(ret_value); } /* 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() */ + #ifndef NEW_HYPERSLAB_API /*------------------------------------------------------------------------- @@ -5707,6 +5761,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]; @@ -5717,19 +5772,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; @@ -6024,22 +6084,6 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper } /* end else */ } /* end else */ - /* Set selection type */ - result->select.type=H5S_SEL_HYPERSLABS; - - /* Set selection methods */ - result->select.get_seq_list=H5S_hyper_get_seq_list; - result->select.get_npoints=H5S_hyper_npoints; - result->select.release=H5S_hyper_release; - result->select.is_valid=H5S_hyper_is_valid; - result->select.serial_size=H5S_hyper_serial_size; - result->select.serialize=H5S_hyper_serialize; - result->select.bounds=H5S_hyper_bounds; - result->select.is_contiguous=H5S_hyper_is_contiguous; - result->select.is_single=H5S_hyper_is_single; - result->select.is_regular=H5S_hyper_is_regular; - result->select.iter_init=H5S_hyper_iter_init; - done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5S_operate_hyperslab() */ @@ -6278,11 +6322,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if((*space->select.release)(space)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); - /* 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"); - /* 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]; @@ -6293,6 +6334,8 @@ 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 */ @@ -6302,6 +6345,11 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* 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"); + /* Add in the new hyperslab information */ if(H5S_generate_hyperslab (space, op, start, opt_stride, opt_count, opt_block)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); @@ -6312,6 +6360,22 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, else HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); + /* Set selection type */ + space->select.type=H5S_SEL_HYPERSLABS; + + /* Set selection methods */ + space->select.get_seq_list=H5S_hyper_get_seq_list; + space->select.get_npoints=H5S_hyper_npoints; + space->select.release=H5S_hyper_release; + space->select.is_valid=H5S_hyper_is_valid; + space->select.serial_size=H5S_hyper_serial_size; + space->select.serialize=H5S_hyper_serialize; + space->select.bounds=H5S_hyper_bounds; + space->select.is_contiguous=H5S_hyper_is_contiguous; + space->select.is_single=H5S_hyper_is_single; + space->select.is_regular=H5S_hyper_is_regular; + space->select.iter_init=H5S_hyper_iter_init; + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5S_select_hyperslab() */ @@ -6432,7 +6496,7 @@ H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hssize_t start[], HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); /* Copy the first dataspace */ - if (NULL==(new_space=H5S_copy (space))) + if (NULL==(new_space=H5S_copy (space, TRUE))) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy data space"); /* Go modify the selection in the new dataspace */ @@ -6479,8 +6543,16 @@ H5S_combine_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) assert(space2); assert(op>H5S_SELECT_NOOP && opselect.sel_info.hslab.span_lst==NULL) + if(H5S_hyper_generate_spans(space1)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree"); + if(space2->select.sel_info.hslab.span_lst==NULL) + if(H5S_hyper_generate_spans(space2)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree"); + /* Copy the first dataspace */ - if (NULL==(new_space=H5S_copy (space1))) + if (NULL==(new_space=H5S_copy (space1, TRUE))) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy data space"); /* Free the current selection for the new dataspace */ @@ -6595,6 +6667,14 @@ H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) assert(space2); assert(op>H5S_SELECT_NOOP && opselect.sel_info.hslab.span_lst==NULL) + if(H5S_hyper_generate_spans(space1)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree"); + if(space2->select.sel_info.hslab.span_lst==NULL) + if(H5S_hyper_generate_spans(space2)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree"); + /* Take ownership of the dataspace's hyperslab spans */ /* (These are freed later) */ tmp_spans=space1->select.sel_info.hslab.span_lst; 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