From 3aa3af4fb6a4c4fe9c5b69306a31ee1fc1ed1bf6 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 20 Nov 2007 17:12:52 -0500 Subject: [PATCH] [svn-r14278] Description: - Remember # of elements in file selection, instead of querying more than once - Handle building chunk map for single element as special case Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode --- src/H5Dio.c | 323 +++++++++++++++++++++++++++++++---------------- src/H5Dpkg.h | 23 ++-- src/H5Pdcpl.c | 2 - src/H5Sall.c | 33 +++++ src/H5Shyper.c | 2 + src/H5Snone.c | 33 +++++ src/H5Spkg.h | 3 + src/H5Spoint.c | 54 ++++++++ src/H5Sprivate.h | 4 +- src/H5Sselect.c | 37 ++++++ 10 files changed, 396 insertions(+), 118 deletions(-) diff --git a/src/H5Dio.c b/src/H5Dio.c index 5b79aceb24..66ccd66915 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -93,9 +93,12 @@ static herr_t H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, /* Chunk operations */ static herr_t H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, - const H5T_t *mem_type, const H5S_t *file_space, const H5S_t *mem_space); + hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, + const H5T_t *mem_type); static herr_t H5D_destroy_chunk_map(const H5D_chunk_map_t *fm); static herr_t H5D_free_chunk_info(void *item, void *key, void *opdata); +static herr_t H5D_create_chunk_map_single(H5D_chunk_map_t *fm, + const H5D_io_info_t *io_info); static herr_t H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info); static herr_t H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm); @@ -1368,7 +1371,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, assert (buf); /* Map elements between file and memory for each chunk*/ - if(H5D_create_chunk_map(&fm, io_info, mem_type, file_space, mem_space) < 0) + if(H5D_create_chunk_map(&fm, io_info, nelmts, file_space, mem_space, mem_type) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't build chunk mapping") /* Set dataset storage for I/O info */ @@ -1759,7 +1762,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, assert (buf); /* Map elements between file and memory for each chunk*/ - if(H5D_create_chunk_map(&fm, io_info, mem_type, file_space, mem_space) < 0) + if(H5D_create_chunk_map(&fm, io_info, nelmts, file_space, mem_space, mem_type) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't build chunk mapping") /* Set dataset storage for I/O info */ @@ -2334,7 +2337,8 @@ done: */ static herr_t H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, - const H5T_t *mem_type, const H5S_t *file_space, const H5S_t *mem_space) + hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, + const H5T_t *mem_type) { H5D_t *dataset=io_info->dset; /* Local pointer to dataset info */ H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */ @@ -2355,7 +2359,7 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, /* Get layout for dataset */ fm->layout = &(dataset->shared->layout); - + fm->nelmts = nelmts; /* Check if the memory space is scalar & make equivalent memory space */ if((sm_ndims = H5S_GET_EXTENT_NDIMS(mem_space)) < 0) @@ -2365,7 +2369,6 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, /* Get dim number and dimensionality for each dataspace */ fm->f_ndims = f_ndims = dataset->shared->layout.u.chunk.ndims - 1; - if(H5S_get_simple_extent_dims(file_space, fm->f_dims, NULL) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality") @@ -2411,107 +2414,43 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, HGOTO_ERROR(H5E_DATASET,H5E_CANTCREATE,FAIL,"can't create skip list for chunk selections") /* Initialize "last chunk" information */ - fm->last_index=(hsize_t)-1; - fm->last_chunk_info=NULL; + fm->last_index = (hsize_t)-1; + fm->last_chunk_info = NULL; /* Point at the dataspaces */ fm->file_space = file_space; fm->mem_space = mem_space; - /* Get type of selection on disk & in memory */ - if((fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE) - HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space") - if((fm->msel_type = H5S_GET_SELECT_TYPE(mem_space)) < H5S_SEL_NONE) - HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space") - - /* If the selection is NONE or POINTS, set the flag to FALSE */ - if(fsel_type == H5S_SEL_POINTS || fsel_type == H5S_SEL_NONE) - sel_hyper_flag = FALSE; - else - sel_hyper_flag = TRUE; - - /* Check if file selection is a not a hyperslab selection */ - if(sel_hyper_flag) { - /* Build the file selection for each chunk */ - if(H5D_create_chunk_file_map_hyper(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - - /* Clean file chunks' hyperslab span "scratch" information */ - curr_node=H5SL_first(fm->fsel); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ - - /* Get pointer to chunk's information */ - chunk_info=H5SL_item(curr_node); - assert(chunk_info); - - /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->fspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") - - /* Get the next chunk node in the skip list */ - curr_node=H5SL_next(curr_node); - } /* end while */ - } /* end if */ - else { - /* Create temporary datatypes for selection iteration */ - if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") - - /* Spaces might not be the same shape, iterate over the file selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_file_cb, fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - - /* Reset "last chunk" info */ - fm->last_index=(hsize_t)-1; - fm->last_chunk_info=NULL; - } /* end else */ - - /* Build the memory selection for each chunk */ - if(sel_hyper_flag && H5S_select_shape_same(file_space, mem_space) == TRUE) { + /* Special case for only one element in selection */ + /* (usually appending a record) */ + if(nelmts == 1) { /* Reset chunk template information */ fm->mchunk_tmpl = NULL; - /* If the selections are the same shape, use the file chunk information - * to generate the memory chunk information quickly. - */ - if(H5D_create_chunk_mem_map_hyper(fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") + /* Set up chunk mapping for single element */ + if(H5D_create_chunk_map_single(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk selections for single element") } /* end if */ else { - size_t elmt_size; /* Memory datatype size */ + /* Get type of selection on disk & in memory */ + if((fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") + if((fm->msel_type = H5S_GET_SELECT_TYPE(mem_space)) < H5S_SEL_NONE) + HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") - /* Make a copy of equivalent memory space */ - if((tmp_mspace = H5S_copy(mem_space, TRUE, FALSE)) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") + /* If the selection is NONE or POINTS, set the flag to FALSE */ + if(fsel_type == H5S_SEL_POINTS || fsel_type == H5S_SEL_NONE) + sel_hyper_flag = FALSE; + else + sel_hyper_flag = TRUE; - /* De-select the mem space copy */ - if(H5S_select_none(tmp_mspace) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space") + /* Check if file selection is a not a hyperslab selection */ + if(sel_hyper_flag) { + /* Build the file selection for each chunk */ + if(H5D_create_chunk_file_map_hyper(fm, io_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - /* Save chunk template information */ - fm->mchunk_tmpl=tmp_mspace; - - /* Create temporary datatypes for selection iteration */ - if(f_tid<0) { - if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") - } /* end if */ - - /* Create selection iterator for memory selection */ - if((elmt_size=H5T_get_size(mem_type))==0) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid") - if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") - iter_init = TRUE; /* Selection iteration info has been initialized */ - - /* Spaces aren't the same shape, iterate over the memory selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_mem_cb, fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") - - /* Clean up hyperslab stuff, if necessary */ - if(fm->msel_type != H5S_SEL_POINTS) { - /* Clean memory chunks' hyperslab span "scratch" information */ + /* Clean file chunks' hyperslab span "scratch" information */ curr_node=H5SL_first(fm->fsel); while(curr_node) { H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ @@ -2521,13 +2460,89 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, assert(chunk_info); /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->mspace) < 0) + if(H5S_hyper_reset_scratch(chunk_info->fspace) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") /* Get the next chunk node in the skip list */ curr_node=H5SL_next(curr_node); } /* end while */ } /* end if */ + else { + /* Create temporary datatypes for selection iteration */ + if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") + + /* Spaces might not be the same shape, iterate over the file selection directly */ + if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_file_cb, fm) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") + + /* Reset "last chunk" info */ + fm->last_index=(hsize_t)-1; + fm->last_chunk_info=NULL; + } /* end else */ + + /* Build the memory selection for each chunk */ + if(sel_hyper_flag && H5S_select_shape_same(file_space, mem_space) == TRUE) { + /* Reset chunk template information */ + fm->mchunk_tmpl = NULL; + + /* If the selections are the same shape, use the file chunk information + * to generate the memory chunk information quickly. + */ + if(H5D_create_chunk_mem_map_hyper(fm) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") + } /* end if */ + else { + size_t elmt_size; /* Memory datatype size */ + + /* Make a copy of equivalent memory space */ + if((tmp_mspace = H5S_copy(mem_space, TRUE, FALSE)) == NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") + + /* De-select the mem space copy */ + if(H5S_select_none(tmp_mspace) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space") + + /* Save chunk template information */ + fm->mchunk_tmpl=tmp_mspace; + + /* Create temporary datatypes for selection iteration */ + if(f_tid<0) { + if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL))) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") + } /* end if */ + + /* Create selection iterator for memory selection */ + if((elmt_size=H5T_get_size(mem_type))==0) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid") + if(H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") + iter_init = TRUE; /* Selection iteration info has been initialized */ + + /* Spaces aren't the same shape, iterate over the memory selection directly */ + if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_mem_cb, fm) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") + + /* Clean up hyperslab stuff, if necessary */ + if(fm->msel_type != H5S_SEL_POINTS) { + /* Clean memory chunks' hyperslab span "scratch" information */ + curr_node=H5SL_first(fm->fsel); + while(curr_node) { + H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ + + /* Get pointer to chunk's information */ + chunk_info=H5SL_item(curr_node); + assert(chunk_info); + + /* Clean hyperslab span's "scratch" information */ + if(H5S_hyper_reset_scratch(chunk_info->mspace) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") + + /* Get the next chunk node in the skip list */ + curr_node=H5SL_next(curr_node); + } /* end while */ + } /* end if */ + } /* end else */ } /* end else */ done: @@ -2644,6 +2659,101 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_destroy_chunk_map() */ + +/*------------------------------------------------------------------------- + * Function: H5D_create_chunk_map_single + * + * Purpose: Create chunk selections when appending a single record + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, November 20, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t +#ifndef H5_HAVE_PARALLEL + UNUSED +#endif /* H5_HAVE_PARALLEL */ + *io_info) +{ + H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */ + H5D_chunk_info_t *new_chunk_info = NULL; /* chunk information to insert into skip list */ + hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ + hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_create_chunk_map_single) + + /* Sanity check */ + HDassert(fm->f_ndims > 0); + + /* Get coordinate for selection */ + if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") + + /* Allocate the file & memory chunk information */ + if(NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") + new_chunk_info->chunk_points = 1; + + /* Set chunk location & hyperslab size */ + for(u = 0; u < fm->f_ndims; u++) { + HDassert(sel_start[u] == sel_end[u]); + new_chunk_info->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u]; + } /* end for */ + new_chunk_info->coords[fm->f_ndims] = 0; + + /* Calculate the index of this chunk */ + if(H5V_chunk_index(fm->f_ndims, new_chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &new_chunk_info->index) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") + + /* Create chunk dataspace for selection operations (copy file space) */ + if((tmp_fchunk = H5S_copy(fm->file_space, FALSE, FALSE)) == NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") + + /* Resize chunk's dataspace dimensions to size of chunk */ + if(H5S_set_extent_real(tmp_fchunk, fm->chunk_dim) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions") + + /* Move selection back to have correct offset in chunk */ + if(H5S_SELECT_ADJUST_U(tmp_fchunk, new_chunk_info->coords) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") + +#ifdef H5_HAVE_PARALLEL + /* store chunk selection information */ + if(io_info->using_mpi_vfd) + fm->select_chunk[new_chunk_info->index] = TRUE; +#endif /* H5_HAVE_PARALLEL */ + + /* Set the file chunk dataspace */ + new_chunk_info->fspace = tmp_fchunk; + + /* Just point at the memory dataspace & selection */ + /* (Casting away const OK -QAK) */ + new_chunk_info->mspace = (H5S_t *)fm->mem_space; + + /* Indicate that the chunk's memory space is shared */ + new_chunk_info->mspace_shared = 1; + + /* Insert the new chunk into the skip list */ + if(H5SL_insert(fm->fsel, new_chunk_info, &new_chunk_info->index) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") + +done: + if(ret_value < 0) { + if(new_chunk_info) + (void)H5D_free_chunk_info(new_chunk_info, NULL, NULL); + if(tmp_fchunk) + (void)H5S_close(tmp_fchunk); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_create_chunk_map_single() */ + /*------------------------------------------------------------------------- * Function: H5D_create_chunk_file_map_hyper @@ -2658,15 +2768,18 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info) +H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t +#ifndef H5_HAVE_PARALLEL + UNUSED +#endif /* H5_HAVE_PARALLEL */ + *io_info) { - hssize_t ssel_points; /* Number of elements in file selection */ + hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ + hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ hsize_t sel_points; /* Number of elements in file selection */ - hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */ - hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */ - hsize_t end[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */ + hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */ + hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */ + hsize_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 */ @@ -2678,9 +2791,7 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_inf assert(fm->f_ndims>0); /* Get number of elements selected in file */ - if((ssel_points=H5S_GET_SELECT_NPOINTS(fm->file_space)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements") - H5_ASSIGN_OVERFLOW(sel_points,ssel_points,hssize_t,hsize_t); + sel_points = fm->nelmts; /* Get bounding box for selection (to reduce the number of chunks to iterate over) */ if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0) @@ -2731,7 +2842,7 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_inf } /* end if */ /* Move selection back to have correct offset in chunk */ - if(H5S_hyper_adjust_u(tmp_fchunk,coords) < 0) { + if(H5S_SELECT_ADJUST_U(tmp_fchunk, coords) < 0) { (void)H5S_close(tmp_fchunk); HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") } /* end if */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 9ac7f05c3f..4fbec67dc8 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -200,21 +200,26 @@ typedef struct H5D_chunk_info_t { /* Main structure holding the mapping between file chunks and memory */ typedef struct H5D_chunk_map_t { + H5O_layout_t *layout; /* Dataset layout information*/ + hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */ + + const H5S_t *file_space; /* Pointer to the file dataspace */ + unsigned f_ndims; /* Number of dimensions for file dataspace */ + hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */ + + const H5S_t *mem_space; /* Pointer to the memory dataspace */ + H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */ + H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */ + unsigned m_ndims; /* Number of dimensions for memory dataspace */ + H5S_sel_type msel_type; /* Selection type in memory */ + H5SL_t *fsel; /* Skip list containing file dataspaces for all chunks */ hsize_t last_index; /* Index of last chunk operated on */ H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */ - const H5S_t *file_space; /* Pointer to the file dataspace */ - const H5S_t *mem_space; /* Pointer to the memory dataspace */ - hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */ - H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */ - unsigned f_ndims; /* Number of dimensions for file dataspace */ - H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */ - unsigned m_ndims; /* Number of dimensions for memory dataspace */ hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */ hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */ hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */ - H5O_layout_t *layout; /* Dataset layout information*/ - H5S_sel_type msel_type; /* Selection type in memory */ + #ifdef H5_HAVE_PARALLEL hsize_t total_chunks; /* Number of total chunks */ hbool_t *select_chunk; /* store the information about whether this chunk is selected or not */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 97323dc1b4..8d6b9abaec 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -2722,8 +2722,6 @@ H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags/*out*/ size_t *cd_nelmts/*in_out*/, unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/) { - H5O_pline_t pline; /* Filter pipeline */ - H5Z_filter_info_t *filter; /* Pointer to filter information */ H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5Sall.c b/src/H5Sall.c index c216323953..5d01fecd00 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -45,6 +45,7 @@ static herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static htri_t H5S_all_is_contiguous(const H5S_t *space); static htri_t H5S_all_is_single(const H5S_t *space); static htri_t H5S_all_is_regular(const H5S_t *space); +static herr_t H5S_all_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S_all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ @@ -72,6 +73,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S_all_is_contiguous, H5S_all_is_single, H5S_all_is_regular, + H5S_all_adjust_u, H5S_all_iter_init, }}; @@ -693,6 +695,37 @@ H5S_all_is_regular(const H5S_t UNUSED *space) FUNC_LEAVE_NOAPI(TRUE); } /* H5S_all_is_regular() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_all_adjust_u + PURPOSE + Adjust an "all" selection by subtracting an offset + USAGE + herr_t H5S_all_adjust_u(space, offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hsize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_all_adjust_u(H5S_t UNUSED *space, const hsize_t UNUSED *offset) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5S_all_adjust_u) + + /* Check args */ + HDassert(space); + HDassert(offset); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5S_all_adjust_u() */ + /*-------------------------------------------------------------------------- NAME diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 7b851c655c..8acbfd52f6 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -60,6 +60,7 @@ static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) static htri_t H5S_hyper_is_contiguous(const H5S_t *space); static htri_t H5S_hyper_is_single(const H5S_t *space); static htri_t H5S_hyper_is_regular(const H5S_t *space); +static herr_t H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ @@ -92,6 +93,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S_hyper_is_contiguous, H5S_hyper_is_single, H5S_hyper_is_regular, + H5S_hyper_adjust_u, H5S_hyper_iter_init, }}; diff --git a/src/H5Snone.c b/src/H5Snone.c index 1faf10cf1a..89a1875ecf 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -46,6 +46,7 @@ static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); static htri_t H5S_none_is_contiguous(const H5S_t *space); static htri_t H5S_none_is_single(const H5S_t *space); static htri_t H5S_none_is_regular(const H5S_t *space); +static herr_t H5S_none_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ @@ -73,6 +74,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{ H5S_none_is_contiguous, H5S_none_is_single, H5S_none_is_regular, + H5S_none_adjust_u, H5S_none_iter_init, }}; @@ -649,6 +651,37 @@ H5S_none_is_regular(const H5S_t UNUSED *space) FUNC_LEAVE_NOAPI(TRUE); } /* H5S_none_is_regular() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_none_adjust_u + PURPOSE + Adjust an "none" selection by subtracting an offset + USAGE + herr_t H5S_none_adjust_u(space, offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hsize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_none_adjust_u(H5S_t UNUSED *space, const hsize_t UNUSED *offset) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5S_none_adjust_u) + + /* Check args */ + HDassert(space); + HDassert(offset); + + FUNC_LEAVE_NOAPI(FAIL) +} /* H5S_none_adjust_u() */ + /*-------------------------------------------------------------------------- NAME diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 667be6209d..71cc43b18a 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -141,6 +141,8 @@ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space); typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space); /* Method to determine if current selection is "regular" */ typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space); +/* Method to adjust a selection by an offset */ +typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset); /* Method to initialize iterator for current selection */ typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_sel_iter_t *sel_iter, const H5S_t *space); @@ -160,6 +162,7 @@ typedef struct { H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */ H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */ H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */ + H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */ H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */ } H5S_select_class_t; diff --git a/src/H5Spoint.c b/src/H5Spoint.c index fc9419154e..eb379458f0 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -47,6 +47,7 @@ static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) static htri_t H5S_point_is_contiguous(const H5S_t *space); static htri_t H5S_point_is_single(const H5S_t *space); static htri_t H5S_point_is_regular(const H5S_t *space); +static herr_t H5S_point_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space); /* Selection iteration callbacks */ @@ -74,6 +75,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{ H5S_point_is_contiguous, H5S_point_is_single, H5S_point_is_regular, + H5S_point_adjust_u, H5S_point_iter_init, }}; @@ -1193,6 +1195,58 @@ H5S_point_is_regular(const H5S_t *space) FUNC_LEAVE_NOAPI(ret_value); } /* H5S_point_is_regular() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_point_adjust_u + PURPOSE + Adjust a "point" selection by subtracting an offset + USAGE + herr_t H5S_point_adjust_u(space, offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hsize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves a point selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_point_adjust_u(H5S_t *space, const hsize_t *offset) +{ + H5S_pnt_node_t *node; /* Point node */ + unsigned rank; /* Dataspace rank */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_point_adjust_u) + + HDassert(space); + HDassert(offset); + + /* Iterate through the nodes, checking the bounds on each element */ + node = space->select.sel_info.pnt_lst->head; + rank = space->extent.rank; + while(node) { + unsigned u; /* Local index variable */ + + /* Adjust each coordinate for point node */ + for(u = 0; u < rank; u++) { + /* Check for offset moving selection negative */ + HDassert(node->pnt[u] >= offset[u]); + + /* Adjust node's coordinate location */ + node->pnt[u] -= offset[u]; + } /* end for */ + + /* Advance to next point node in selection */ + node = node->next; + } /* end while */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5S_point_adjust_u() */ + /*-------------------------------------------------------------------------- NAME diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 49b1df87b6..ec48de9fc3 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -155,6 +155,7 @@ typedef struct H5S_iostats_t { #define H5S_SELECT_IS_CONTIGUOUS(S) ((*(S)->select.type->is_contiguous)(S)) #define H5S_SELECT_IS_SINGLE(S) ((*(S)->select.type->is_single)(S)) #define H5S_SELECT_IS_REGULAR(S) ((*(S)->select.type->is_regular)(S)) +#define H5S_SELECT_ADJUST_U(S,O) ((*(S)->select.type->adjust_u)(S, O)) #define H5S_SELECT_ITER_COORDS(ITER,COORDS) ((*(ITER)->type->iter_coords)(ITER,COORDS)) #define H5S_SELECT_ITER_BLOCK(ITER,START,END) ((*(ITER)->type->iter_block)(ITER,START,END)) #define H5S_SELECT_ITER_NELMTS(ITER) ((*(ITER)->type->iter_nelmts)(ITER)) @@ -177,6 +178,7 @@ typedef struct H5S_iostats_t { #define H5S_SELECT_IS_CONTIGUOUS(S) (H5S_select_is_contiguous(S)) #define H5S_SELECT_IS_SINGLE(S) (H5S_select_is_single(S)) #define H5S_SELECT_IS_REGULAR(S) (H5S_select_is_regular(S)) +#define H5S_SELECT_ADJUST_U(S,O) (H5S_select_adjust_u(S, O)) #define H5S_SELECT_ITER_COORDS(ITER,COORDS) (H5S_select_iter_coords(ITER,COORDS)) #define H5S_SELECT_ITER_BLOCK(ITER,START,END) (H5S_select_iter_block(ITER,START,END)) #define H5S_SELECT_ITER_NELMTS(ITER) (H5S_select_iter_nelmts(ITER)) @@ -244,6 +246,7 @@ H5_DLL herr_t H5S_select_serialize(const H5S_t *space, uint8_t *buf); H5_DLL htri_t H5S_select_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_select_is_single(const H5S_t *space); H5_DLL htri_t H5S_select_is_regular(const H5S_t *space); +H5_DLL herr_t H5S_select_adjust_u(H5S_t *space, const hsize_t *offset); /* Operations on all selections */ H5_DLL herr_t H5S_select_all(H5S_t *space, hbool_t rel_prev); @@ -266,7 +269,6 @@ H5_DLL herr_t H5S_hyper_convert(H5S_t *space); H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2); #endif /* LATER */ H5_DLL htri_t H5S_hyper_intersect_block (H5S_t *space, hsize_t *start, hsize_t *end); -H5_DLL herr_t H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset); H5_DLL herr_t H5S_hyper_adjust_s(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, hssize_t *old_offset); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 616efc00f9..31fd05e64b 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -687,6 +687,43 @@ H5S_select_is_regular(const H5S_t *space) FUNC_LEAVE_NOAPI(ret_value); } /* H5S_select_is_regular() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_select_adjust_u + PURPOSE + Adjust a selection by subtracting an offset + USAGE + herr_t H5S_select_adjust_u(space, offset) + H5S_t *space; IN/OUT: Pointer to dataspace to adjust + const hsize_t *offset; IN: Offset to subtract + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Moves a selection by subtracting an offset from it. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This routine participates in the "Inlining C function pointers" + pattern, don't call it directly, use the appropriate macro + defined in H5Sprivate.h. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5S_select_adjust_u(H5S_t *space, const hsize_t *offset) +{ + herr_t ret_value; /* return value */ + + FUNC_ENTER_NOAPI_NOFUNC(H5S_select_adjust_u) + + /* Check args */ + HDassert(space); + + ret_value = (*space->select.type->adjust_u)(space, offset); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5S_select_adjust_u() */ + /*-------------------------------------------------------------------------- NAME