From c243e1e13456365b0b555a9c82d5cc17f1436727 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 2 Jul 2009 17:34:20 -0500 Subject: [svn-r17148] Description: Refactor how chunked dataset information is computed, moving it earlier and avoiding more recomputation. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.7 (amazon) in debug mode Mac OS X/32 10.5.7 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5Dchunk.c | 136 ++++++++++++++++++++++++++++++++++++++++--------------- src/H5Ddeprec.c | 5 +- src/H5Dint.c | 5 +- src/H5Dmpio.c | 20 ++++---- src/H5Dpkg.h | 9 ++-- src/H5Olayout.c | 21 ++++++++- src/H5Oprivate.h | 3 ++ src/H5S.c | 63 ++++++++++++++++++++------ src/H5Sprivate.h | 1 + test/dsets.c | 4 +- 10 files changed, 194 insertions(+), 73 deletions(-) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 5c99c90..ba80de2 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -112,7 +112,6 @@ typedef struct H5D_chunk_it_ud1_t { const H5D_io_info_t *io_info; /* I/O info for dataset operation */ const hsize_t *dims; /* New dataset dimensions */ const hbool_t *shrunk_dims; /* Dimensions which have been shrunk */ - const hsize_t *down_chunks; /* "down" size of number of chunks in each dimension */ H5D_chunk_prune_stack_t *rm_stack; /* Stack of chunks outside the new dimensions */ H5S_t *chunk_space; /* Dataspace for a chunk */ uint32_t elmts_per_chunk;/* Elements in chunk */ @@ -122,10 +121,9 @@ typedef struct H5D_chunk_it_ud1_t { } H5D_chunk_it_ud1_t; /* Callback info for iteration to obtain chunk address and the index of the chunk for all chunks in the B-tree. */ -typedef struct H5D_chunk_id_ud2_t { +typedef struct H5D_chunk_it_ud2_t { /* down */ H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */ - const hsize_t *down_chunks; /* "down chunk" element counts for chunks */ /* up */ haddr_t *chunk_addr; /* Array of chunk addresses to fill in */ @@ -270,6 +268,88 @@ H5FL_DEFINE_STATIC(H5D_chunk_prune_stack_t); /*------------------------------------------------------------------------- + * Function: H5D_chunk_set_info_real + * + * Purpose: Internal routine to set the information about chunks for a dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, June 30, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_chunk_set_info_real(H5O_layout_t *layout, unsigned ndims, const hsize_t *curr_dims) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_chunk_set_info_real, FAIL) + + /* Sanity checks */ + HDassert(layout); + HDassert(ndims > 0); + HDassert(curr_dims); + + /* Compute the # of chunks in dataset dimensions */ + for(u = 0, layout->u.chunk.nchunks = 1; u < ndims; u++) { + /* Round up to the next integer # of chunks, to accomodate partial chunks */ + layout->u.chunk.chunks[u] = ((curr_dims[u] + layout->u.chunk.dim[u]) - 1) / layout->u.chunk.dim[u]; + + /* Accumulate the # of chunks */ + layout->u.chunk.nchunks *= layout->u.chunk.chunks[u]; + } /* end for */ + + /* Get the "down" sizes for each dimension */ + if(H5V_array_down(ndims, layout->u.chunk.chunks, layout->u.chunk.down_chunks) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_chunk_set_info_real() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_chunk_set_info + * + * Purpose: Sets the information about chunks for a dataset + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, June 30, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_chunk_set_info(const H5D_t *dset) +{ + hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Curr. size of dataset dimensions */ + int sndims; /* Rank of dataspace */ + unsigned ndims; /* Rank of dataspace */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_chunk_set_info, FAIL) + + /* Sanity checks */ + HDassert(dset); + + /* Get the dim info for dataset */ + if((sndims = H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace dimensions") + H5_ASSIGN_OVERFLOW(ndims, sndims, int, unsigned); + + /* Set the layout information */ + if(H5D_chunk_set_info_real(&dset->shared->layout, ndims, curr_dims) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout's chunk info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_chunk_set_info() */ + + +/*------------------------------------------------------------------------- * Function: H5D_chunk_construct * * Purpose: Constructs new chunked layout information for dataset @@ -407,6 +487,10 @@ H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id) H5D_chunk_cinfo_cache_reset(&(rdcc->last)); } /* end else */ + /* Set the number of chunks in dataset */ + if(H5D_chunk_set_info(dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set # of chunks for dataset") + /* Compose chunked index info struct */ idx_info.f = f; idx_info.dxpl_id = dxpl_id; @@ -514,24 +598,14 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info for(u = 0; u < f_ndims; u++) { /* Keep the size of the chunk dimensions as hsize_t for various routines */ fm->chunk_dim[u] = fm->layout->u.chunk.dim[u]; - - /* Round up to the next integer # of chunks, to accomodate partial chunks */ - fm->chunks[u] = ((fm->f_dims[u] + dataset->shared->layout.u.chunk.dim[u]) - 1) / dataset->shared->layout.u.chunk.dim[u]; } /* end for */ - /* Compute the "down" size of 'chunks' information */ - if(H5V_array_down(f_ndims, fm->chunks, fm->down_chunks) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") - #ifdef H5_HAVE_PARALLEL /* Calculate total chunk in file map*/ fm->select_chunk = NULL; - fm->total_chunks = 1; - for(u = 0; u < fm->f_ndims; u++) - fm->total_chunks = fm->total_chunks * fm->chunks[u]; if(io_info->using_mpi_vfd) { - H5_CHECK_OVERFLOW(fm->total_chunks, hsize_t, size_t); - if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->total_chunks * sizeof(H5D_chunk_info_t *)))) + H5_CHECK_OVERFLOW(fm->layout->u.chunk.nchunks, hsize_t, size_t); + if(NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc((size_t)fm->layout->u.chunk.nchunks * sizeof(H5D_chunk_info_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") } /* end if */ #endif /* H5_HAVE_PARALLEL */ @@ -901,7 +975,7 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t chunk_info->coords[fm->f_ndims] = 0; /* Calculate the index of this chunk */ - if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_info->index) < 0) + if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_info->index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Copy selection for file's dataspace into chunk dataspace */ @@ -985,9 +1059,8 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t end[u] = (coords[u] + fm->chunk_dim[u]) - 1; } /* end for */ - /* Calculate the index of this chunk */ - if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0) + if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Iterate through each chunk in the dataset */ @@ -1104,8 +1177,8 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[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->u.chunk.dim, fm->down_chunks, &chunk_index) < 0) + /* Re-calculate the index of this chunk */ + if(H5V_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") } /* end if */ } /* end while */ @@ -1253,7 +1326,7 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_file_cb) /* Calculate the index of this chunk */ - if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0) + if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Find correct chunk in file & memory skip list */ @@ -1365,7 +1438,7 @@ H5D_chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_mem_cb) /* Calculate the index of this chunk */ - if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->down_chunks, &chunk_index) < 0) + if(H5V_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Find correct chunk in file & memory skip list */ @@ -3318,8 +3391,7 @@ H5D_chunk_prune_fill(const H5D_chunk_rec_t *chunk_rec, H5D_chunk_it_ud1_t *udata HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab") /* Calculate the index of this chunk */ - if(H5V_chunk_index(rank, chunk_rec->offset, layout->u.chunk.dim, udata->down_chunks, - &io_info->store->chunk.index) < 0) + if(H5V_chunk_index(rank, chunk_rec->offset, layout->u.chunk.dim, layout->u.chunk.down_chunks, &io_info->store->chunk.index) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, H5_ITER_ERROR, "can't get chunk index") /* Lock the chunk into the cache, to get a pointer to the chunk buffer */ @@ -3575,8 +3647,6 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) H5D_chunk_common_ud_t idx_udata; /* User data for index removal routine */ H5S_t *chunk_space = NULL; /* Dataspace for a chunk */ hsize_t chunk_dims[H5O_LAYOUT_NDIMS]; /* Chunk dimensions */ - hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Current number of chunks in each dimension */ - hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of elements in each dimension */ hsize_t hyper_start[H5O_LAYOUT_NDIMS]; /* Starting location of hyperslab */ uint32_t elmts_per_chunk; /* Elements in chunk */ unsigned rank; /* Current # of dimensions */ @@ -3611,16 +3681,11 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) /* (also compute the dimensions which have been shrunk) */ elmts_per_chunk = 1; for(u = 0; u < rank; u++) { - chunks[u] = ((curr_dims[u] + layout->u.chunk.dim[u]) - 1) / layout->u.chunk.dim[u]; elmts_per_chunk *= layout->u.chunk.dim[u]; chunk_dims[u] = layout->u.chunk.dim[u]; shrunk_dims[u] = curr_dims[u] < old_dims[u]; } /* end for */ - /* Get the "down" sizes for each dimension */ - if(H5V_array_down(rank, chunks, down_chunks) < 0) - HGOTO_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") - /* Create a dataspace for a chunk & set the extent */ if(NULL == (chunk_space = H5S_create_simple(rank, chunk_dims, NULL))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") @@ -3646,7 +3711,6 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims) udata.idx_info = &idx_info; udata.dims = curr_dims; udata.shrunk_dims = shrunk_dims; - udata.down_chunks = down_chunks; udata.elmts_per_chunk = elmts_per_chunk; udata.chunk_space = chunk_space; udata.hyper_start = hyper_start; @@ -3789,7 +3853,7 @@ H5D_chunk_addrmap_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_addrmap_cb) /* Compute the index for this chunk */ - if(H5V_chunk_index(rank, chunk_rec->offset, udata->common.mesg->u.chunk.dim, udata->down_chunks, &chunk_index) < 0) + if(H5V_chunk_index(rank, chunk_rec->offset, udata->common.mesg->u.chunk.dim, udata->common.mesg->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, H5_ITER_ERROR, "can't get chunk index") /* Set it in the userdata to return */ @@ -3814,12 +3878,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[], - const hsize_t down_chunks[]) +H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]) { H5D_chk_idx_info_t idx_info; /* Chunked index info */ H5D_t *dset = io_info->dset; /* Local pointer to dataset info */ - H5D_chunk_it_ud2_t udata; /* User data for iteration callback */ + H5D_chunk_it_ud2_t udata; /* User data for iteration callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_chunk_addrmap, FAIL) @@ -3832,7 +3895,6 @@ H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[], /* Set up user data for B-tree callback */ HDmemset(&udata, 0, sizeof(udata)); udata.common.mesg = &dset->shared->layout; - udata.down_chunks = down_chunks; udata.chunk_addr = chunk_addr; /* Compose chunked index info struct */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 5b0621e..637cb70 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -346,9 +346,12 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) /* Updated the dataset's info if the dataspace was successfully extended */ if(changed) { /* Update the index values for the cached chunks for this dataset */ - if(H5D_CHUNKED == dataset->shared->layout.type) + if(H5D_CHUNKED == dataset->shared->layout.type) { + if(H5D_chunk_set_info(dataset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks") if(H5D_chunk_update_cache(dataset, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices") + } /* end if */ /* Allocate space for the new parts of the dataset, if appropriate */ fill = &dataset->shared->dcpl_cache.fill; diff --git a/src/H5Dint.c b/src/H5Dint.c index 7247b46..5e47856 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2366,9 +2366,12 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) *------------------------------------------------------------------------- */ /* Update the index values for the cached chunks for this dataset */ - if(H5D_CHUNKED == dset->shared->layout.type) + if(H5D_CHUNKED == dset->shared->layout.type) { + if(H5D_chunk_set_info(dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to update # of chunks") if(H5D_chunk_update_cache(dset, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices") + } /* end if */ /* Allocate space for the new parts of the dataset, if appropriate */ if(expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY) diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index afa9201..e111404 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -843,7 +843,7 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type } /* end if */ /* Retrieve total # of chunks in dataset */ - H5_ASSIGN_OVERFLOW(total_chunks, fm->total_chunks, hsize_t, size_t); + H5_ASSIGN_OVERFLOW(total_chunks, fm->layout->u.chunk.nchunks, hsize_t, size_t); /* Handle special case when dataspace dimensions only allow one chunk in * the dataset. [This sometimes is used by developers who want the @@ -997,7 +997,7 @@ if(H5DEBUG(D)) total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * total_chunks); /* Retrieve chunk address map */ - if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0) + if(H5D_chunk_addrmap(io_info, total_chunk_addr_array) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address") /* Get chunk with lowest address */ @@ -1103,7 +1103,7 @@ H5D_multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ #endif /* Retrieve total # of chunks in dataset */ - H5_ASSIGN_OVERFLOW(total_chunk, fm->total_chunks, hsize_t, size_t); + H5_ASSIGN_OVERFLOW(total_chunk, fm->layout->u.chunk.nchunks, hsize_t, size_t); HDassert(total_chunk != 0); /* Allocate memories */ @@ -1706,7 +1706,7 @@ H5D_sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm, * 0, we would always want to obtain the chunk addresses individually * for each process. */ - bsearch_coll_chunk_threshold = (sum_chunk * 100) / ((int)fm->total_chunks * mpi_size); + bsearch_coll_chunk_threshold = (sum_chunk * 100) / ((int)fm->layout->u.chunk.nchunks * mpi_size); if((bsearch_coll_chunk_threshold > H5D_ALL_CHUNK_ADDR_THRES_COL) && ((sum_chunk / mpi_size) >= H5D_ALL_CHUNK_ADDR_THRES_COL_NUM)) many_chunk_opt = H5D_OBTAIN_ALL_CHUNK_ADDR_COL; @@ -1725,19 +1725,19 @@ if(H5DEBUG(D)) HDfprintf(H5DEBUG(D), "Coming inside H5D_OBTAIN_ALL_CHUNK_ADDR_COL\n"); #endif /* Allocate array for chunk addresses */ - if(NULL == (total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * (size_t)fm->total_chunks))) + if(NULL == (total_chunk_addr_array = H5MM_malloc(sizeof(haddr_t) * (size_t)fm->layout->u.chunk.nchunks))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory chunk address array") /* Retrieve all the chunk addresses with process 0 */ if((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0) HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi rank") if(mpi_rank == 0) { - if(H5D_chunk_addrmap(io_info, total_chunk_addr_array, fm->down_chunks) < 0) + if(H5D_chunk_addrmap(io_info, total_chunk_addr_array) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address") } /* end if */ /* Broadcasting the MPI_IO option info. and chunk address info. */ - if(MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array, (int)(sizeof(haddr_t) * fm->total_chunks), MPI_BYTE, (int)0, io_info->comm))) + if(MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array, (int)(sizeof(haddr_t) * fm->layout->u.chunk.nchunks), MPI_BYTE, (int)0, io_info->comm))) HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code) } /* end if */ @@ -1869,12 +1869,12 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain mpi size") /* Setup parameters */ - H5_ASSIGN_OVERFLOW(total_chunks, fm->total_chunks, hsize_t, int); + H5_ASSIGN_OVERFLOW(total_chunks, fm->layout->u.chunk.nchunks, hsize_t, int); percent_nproc_per_chunk = H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME); #if defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) && defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) chunk_opt_mode = (H5FD_mpio_chunk_opt_t)H5P_peek_unsigned(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME); if((chunk_opt_mode == H5FD_MPIO_CHUNK_MULTI_IO) || (percent_nproc_per_chunk == 0)) { - if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0) + if(H5D_chunk_addrmap(io_info, chunk_addr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address"); for(ic = 0; ic < total_chunks; ic++) assign_io_mode[ic] = H5D_CHUNK_IO_MODE_COL; @@ -1931,7 +1931,7 @@ H5D_obtain_mpio_mode(H5D_io_info_t* io_info, H5D_chunk_map_t *fm, #endif /* calculating the chunk address */ - if(H5D_chunk_addrmap(io_info, chunk_addr, fm->down_chunks) < 0) { + if(H5D_chunk_addrmap(io_info, chunk_addr) < 0) { HDfree(nproc_per_chunk); #if !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) HDfree(ind_this_chunk); diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 5ce45a8..215b7ca 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -342,12 +342,9 @@ typedef struct H5D_chunk_map_t { hsize_t last_index; /* Index of last chunk operated on */ H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */ - 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 */ #ifdef H5_HAVE_PARALLEL - hsize_t total_chunks; /* Number of chunks covered by dataspace */ H5D_chunk_info_t **select_chunk; /* Store the information about whether this chunk is selected or not */ #endif /* H5_HAVE_PARALLEL */ } H5D_chunk_map_t; @@ -578,6 +575,9 @@ H5_DLL htri_t H5D_chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op); H5_DLL herr_t H5D_chunk_cinfo_cache_reset(H5D_chunk_cached_t *last); H5_DLL herr_t H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id); +H5_DLL herr_t H5D_chunk_set_info(const H5D_t *dset); +H5_DLL herr_t H5D_chunk_set_info_real(H5O_layout_t *layout, unsigned ndims, + const hsize_t *curr_dims); H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id); H5_DLL hbool_t H5D_chunk_is_space_alloc(const H5O_layout_t *layout); @@ -594,8 +594,7 @@ H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwr H5_DLL herr_t H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dims); #ifdef H5_HAVE_PARALLEL -H5_DLL herr_t H5D_chunk_addrmap(const H5D_io_info_t *io_info, - haddr_t chunk_addr[], const hsize_t down_chunks[]); +H5_DLL herr_t H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]); #endif /* H5_HAVE_PARALLEL */ H5_DLL herr_t H5D_chunk_update_cache(H5D_t *dset, hid_t dxpl_id); H5_DLL herr_t H5D_chunk_copy(H5F_t *f_src, H5O_layout_t *layout_src, diff --git a/src/H5Olayout.c b/src/H5Olayout.c index da8f2a8..3483c3e 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -630,13 +630,30 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst, case H5D_CHUNKED: if(H5D_chunk_is_space_alloc(layout_src)) { + hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /* Curr. size of dataset dimensions */ + int sndims; /* Rank of dataspace */ + unsigned ndims; /* Rank of dataspace */ + /* Layout is not created in the destination file, reset index address */ if(H5D_chunk_idx_reset(layout_dst, TRUE) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to reset chunked storage index in dest") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset chunked storage index in dest") + + /* Get the dim info for dataset */ + if((sndims = H5S_extent_get_dims(udata->src_space_extent, curr_dims, NULL)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "can't get dataspace dimensions") + H5_ASSIGN_OVERFLOW(ndims, sndims, int, unsigned); + + /* Set the source layout chunk information */ + if(H5D_chunk_set_info_real(layout_src, ndims, curr_dims) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL, "can't set layout's chunk info") + + /* Set the dest. layout chunk info also */ + if(H5D_chunk_set_info_real(layout_dst, ndims, curr_dims) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL, "can't set layout's chunk info") /* Create chunked layout */ if(H5D_chunk_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, cpy_info, udata->src_pline, dxpl_id) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy chunked storage") } /* if ( H5F_addr_defined(layout_srct->u.chunk.addr)) */ break; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index bf416f4..0835e6f 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -367,6 +367,9 @@ typedef struct H5O_layout_chunk_t { unsigned ndims; /* Num dimensions in chunk */ uint32_t dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in elements */ uint32_t size; /* Size of chunk in bytes */ + hsize_t nchunks; /* Number of chunks in dataset */ + hsize_t chunks[H5O_LAYOUT_NDIMS]; /* # of chunks in dataset dimensions */ + hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */ const struct H5D_chunk_ops_t *ops; /* Pointer to chunked layout operations */ union { H5O_layout_chunk_btree_t btree; /* Information for v1 B-tree index */ diff --git a/src/H5S.c b/src/H5S.c index 9de4e95..c723127 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -841,49 +841,46 @@ done: /*------------------------------------------------------------------------- - * Function: H5S_get_simple_extent_dims + * Function: H5S_extent_get_dims * * Purpose: Returns the size in each dimension of a dataspace. This * function may not be meaningful for all types of dataspaces. * * Return: Success: Number of dimensions. Zero implies scalar. - * * Failure: Negative * - * Programmer: Robb Matzke - * Thursday, December 11, 1997 - * - * Modifications: + * Programmer: Quincey Koziol + * Tuesday, June 30, 2009 * *------------------------------------------------------------------------- */ int -H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[]) +H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[]) { int i; /* Local index variable */ int ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5S_get_simple_extent_dims, FAIL) + FUNC_ENTER_NOAPI(H5S_extent_get_dims, FAIL) /* check args */ - HDassert(ds); + HDassert(ext); - switch(H5S_GET_EXTENT_TYPE(ds)) { + switch(ext->type) { case H5S_NULL: case H5S_SCALAR: ret_value = 0; break; case H5S_SIMPLE: - ret_value = (int)ds->extent.rank; + ret_value = (int)ext->rank; for(i = 0; i < ret_value; i++) { if(dims) - dims[i] = ds->extent.size[i]; + dims[i] = ext->size[i]; if(max_dims) { - if(ds->extent.max) - max_dims[i] = ds->extent.max[i]; + if(ext->max) + max_dims[i] = ext->max[i]; else - max_dims[i] = ds->extent.size[i]; + max_dims[i] = ext->size[i]; } /* end if */ } /* end for */ break; @@ -895,6 +892,42 @@ H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[]) done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_extent_get_dims() */ + + +/*------------------------------------------------------------------------- + * Function: H5S_get_simple_extent_dims + * + * Purpose: Returns the size in each dimension of a dataspace. This + * function may not be meaningful for all types of dataspaces. + * + * Return: Success: Number of dimensions. Zero implies scalar. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, December 11, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[]) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5S_get_simple_extent_dims, FAIL) + + /* check args */ + HDassert(ds); + + /* Get dims for extent */ + if((ret_value = H5S_extent_get_dims(&ds->extent, dims, max_dims)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve dataspace extent dims") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_get_simple_extent_dims() */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 3514670..fac5e1e 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -198,6 +198,7 @@ H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size); /* Operations on dataspace extents */ H5_DLL hsize_t H5S_extent_nelem(const H5S_extent_t *ext); +H5_DLL int H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[]); H5_DLL htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2); /* Operations on selections */ diff --git a/test/dsets.c b/test/dsets.c index bd02c24..2876dad 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -1401,8 +1401,8 @@ test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32, */ TESTING(" filters (uninitialized read)"); - if(H5Dread (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) - goto error; + if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0) + TEST_ERROR; for(i=0; i<(size_t)size[0]; i++) { for(j=0; j<(size_t)size[1]; j++) { -- cgit v0.12