From 66addd2d2c56c31137b2e50f66134e66c0bb746d Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 10 Dec 2007 16:38:03 -0500 Subject: [svn-r14334] Description: - Avoid trying to update 1-D dataset's chunk indices (they can't change) - Cache a copy of a dataspace describing a chunk, when doing single element I/O - Keep a 'chunk info' struct around, for single element I/O - Avoid creating a skip list for chunk infos when performing I/O on single element Also, minor formatting cleanups to testing code 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/H5Dint.c | 15 +++++ src/H5Dio.c | 188 +++++++++++++++++++++++++++++++++++--------------------- src/H5Distore.c | 45 ++++++++------ src/H5Dpkg.h | 28 +++++---- test/tselect.c | 26 ++++---- 5 files changed, 188 insertions(+), 114 deletions(-) diff --git a/src/H5Dint.c b/src/H5Dint.c index d344d41..4ee6c19 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -98,6 +98,9 @@ H5FL_DEFINE_STATIC(H5D_shared_t); /* Declare the external PQ free list for the sieve buffer information */ H5FL_BLK_EXTERN(sieve_buf); +/* Declare the external free list to manage the H5D_chunk_info_t struct */ +H5FL_EXTERN(H5D_chunk_info_t); + /* Define a static "default" dataset structure to use to initialize new datasets */ static H5D_shared_t H5D_def_dset; @@ -1517,6 +1520,18 @@ H5D_close(H5D_t *dataset) dataset->shared->cache.chunk.sel_chunks = NULL; } /* end if */ + /* Check for cached single chunk dataspace */ + if(dataset->shared->cache.chunk.single_space) { + (void)H5S_close(dataset->shared->cache.chunk.single_space); + dataset->shared->cache.chunk.single_space = NULL; + } /* end if */ + + /* Check for cached single element chunk info */ + if(dataset->shared->cache.chunk.single_chunk_info) { + (void)H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info); + dataset->shared->cache.chunk.single_chunk_info = NULL; + } /* end if */ + /* Flush and destroy chunks in the cache */ if(H5D_istore_dest(dataset, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to destroy chunk cache") diff --git a/src/H5Dio.c b/src/H5Dio.c index 189d9f1..bcb90a0 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -44,6 +44,12 @@ #define H5D_DEFAULT_SKIPLIST_HEIGHT 8 +/* Macros for iterating over chunks to operate on */ +#define H5D_CHUNK_GET_FIRST_NODE(map) (map.use_single ? (H5SL_node_t *)(1) : H5SL_first(map.sel_chunks)) +#define H5D_CHUNK_GET_NODE_INFO(map, node) (map.use_single ? map.single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node)) +#define H5D_CHUNK_GET_NEXT_NODE(map, node) (map.use_single ? (H5SL_node_t *)NULL : H5SL_next(node)) + + /******************/ /* Local Typedefs */ /******************/ @@ -119,7 +125,7 @@ static herr_t H5D_chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims, H5FL_BLK_DEFINE(type_conv); /* Declare a free list to manage the H5D_chunk_info_t struct */ -H5FL_DEFINE_STATIC(H5D_chunk_info_t); +H5FL_DEFINE(H5D_chunk_info_t); /* Declare a free list to manage sequences of size_t */ H5FL_SEQ_DEFINE_STATIC(size_t); @@ -1412,13 +1418,13 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, else {/* sequential or independent read */ #endif /* Get first node in chunk skip list */ - chunk_node = H5SL_first(fm.sel_chunks); + chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm); while(chunk_node) { H5D_chunk_info_t *chunk_info; /* chunk information */ /* Get the actual chunk information from the skip list node */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node); + chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node); /* Pass in chunk's coordinates in a union. */ store.chunk.offset = chunk_info->coords; @@ -1446,7 +1452,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, } /* end if */ /* Advance to next chunk in list */ - chunk_node = H5SL_next(chunk_node); + chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node); } /* end while */ #ifdef H5_HAVE_PARALLEL } @@ -1521,14 +1527,14 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, /* Loop over all the chunks, performing I/O on each */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.sel_chunks); + chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm); /* Iterate through chunks to be operated on */ while(chunk_node) { H5D_chunk_info_t *chunk_info; /* chunk information */ /* Get the actual chunk information from the skip list nodes */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node); + chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node); /* initialize selection iterator */ if (H5S_select_iter_init(&file_iter, chunk_info->fspace, src_type_size) < 0) @@ -1671,7 +1677,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts, } /* end if */ /* Get the next chunk node in the skip list */ - chunk_node=H5SL_next(chunk_node); + chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node); } /* end while */ done: @@ -1810,13 +1816,13 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, else {/* sequential or independent write */ #endif /* H5_HAVE_PARALLEL */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.sel_chunks); + chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm); while(chunk_node) { H5D_chunk_info_t *chunk_info; /* Chunk information */ /* Get the actual chunk information from the skip list node */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node); + chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node); /* Pass in chunk's coordinates in a union. */ store.chunk.offset = chunk_info->coords; @@ -1850,7 +1856,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, relax = TRUE; /* Advance to next chunk in list */ - chunk_node = H5SL_next(chunk_node); + chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node); } /* end while */ #ifdef H5_HAVE_PARALLEL } @@ -1928,14 +1934,14 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, /* Loop over all the chunks, performing I/O on each */ /* Get first node in chunk skip list */ - chunk_node=H5SL_first(fm.sel_chunks); + chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm); /* Iterate through chunks to be operated on */ while(chunk_node) { H5D_chunk_info_t *chunk_info; /* chunk information */ /* Get the actual chunk information from the skip list node */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node); + chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node); /* initialize selection iterator */ if (H5S_select_iter_init(&file_iter, chunk_info->fspace, dst_type_size) < 0) @@ -2083,7 +2089,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts, } /* end if */ /* Get the next chunk node in the skip list */ - chunk_node=H5SL_next(chunk_node); + chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node); } /* end while */ done: @@ -2412,14 +2418,6 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, #endif /* H5_HAVE_PARALLEL */ - /* Initialize skip list for chunk selections */ - if(NULL == dataset->shared->cache.chunk.sel_chunks) { - if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_DEFAULT_SKIPLIST_HEIGHT))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections") - } /* end if */ - fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks; - HDassert(fm->sel_chunks); - /* Initialize "last chunk" information */ fm->last_index = (hsize_t)-1; fm->last_chunk_info = NULL; @@ -2430,7 +2428,40 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, /* Special case for only one element in selection */ /* (usually appending a record) */ - if(nelmts == 1) { + if(nelmts == 1 +#ifdef H5_HAVE_PARALLEL + && !(io_info->using_mpi_vfd) +#endif /* H5_HAVE_PARALLEL */ + ) { + /* Initialize skip list for chunk selections */ + fm->sel_chunks = NULL; + fm->use_single = TRUE; + + /* Initialize single chunk dataspace */ + if(NULL == dataset->shared->cache.chunk.single_space) { + /* Make a copy of the dataspace for the dataset */ + if((dataset->shared->cache.chunk.single_space = H5S_copy(file_space, TRUE, FALSE)) == NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space") + + /* Resize chunk's dataspace dimensions to size of chunk */ + if(H5S_set_extent_real(dataset->shared->cache.chunk.single_space, fm->chunk_dim) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust chunk dimensions") + + /* Set the single chunk dataspace to 'all' selection */ + if(H5S_select_all(dataset->shared->cache.chunk.single_space, TRUE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to set all selection") + } /* end if */ + fm->single_space = dataset->shared->cache.chunk.single_space; + HDassert(fm->single_space); + + /* Allocate the single chunk information */ + if(NULL == dataset->shared->cache.chunk.single_chunk_info) { + if(NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") + } /* end if */ + fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info; + HDassert(fm->single_chunk_info); + /* Reset chunk template information */ fm->mchunk_tmpl = NULL; @@ -2439,6 +2470,17 @@ H5D_create_chunk_map(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk selections for single element") } /* end if */ else { + /* Initialize skip list for chunk selections */ + if(NULL == dataset->shared->cache.chunk.sel_chunks) { + if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, 0.5, (size_t)H5D_DEFAULT_SKIPLIST_HEIGHT))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections") + } /* end if */ + fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks; + HDassert(fm->sel_chunks); + + /* We are not using single element mode */ + fm->use_single = FALSE; + /* 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") @@ -2596,7 +2638,7 @@ done: RETURNS No return value DESCRIPTION - Releases all the memory for a chunk info node. Called by H5SL_iterate + Releases all the memory for a chunk info node. Called by H5SL_free GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES @@ -2605,21 +2647,24 @@ done: static herr_t H5D_free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata) { - H5D_chunk_info_t *chunk_info=(H5D_chunk_info_t *)item; + H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_free_chunk_info) - assert(chunk_info); + HDassert(chunk_info); - /* Close the chunk's file dataspace */ - (void)H5S_close(chunk_info->fspace); + /* Close the chunk's file dataspace, if it's not shared */ + if(!chunk_info->fspace_shared) + (void)H5S_close(chunk_info->fspace); + else + H5S_select_all(chunk_info->fspace, TRUE); /* Close the chunk's memory dataspace, if it's not shared */ if(!chunk_info->mspace_shared) (void)H5S_close(chunk_info->mspace); /* Free the actual chunk info */ - H5FL_FREE(H5D_chunk_info_t,chunk_info); + H5FL_FREE(H5D_chunk_info_t, chunk_info); FUNC_LEAVE_NOAPI(0); } /* H5D_free_chunk_info() */ @@ -2644,10 +2689,23 @@ H5D_destroy_chunk_map(const H5D_chunk_map_t *fm) FUNC_ENTER_NOAPI_NOINIT(H5D_destroy_chunk_map) - /* Release the nodes on the list of selected chunks */ - if(fm->sel_chunks) - if(H5SL_free(fm->sel_chunks, H5D_free_chunk_info, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks") + /* Single element I/O vs. multiple element I/O cleanup */ + if(fm->use_single) { + /* Sanity checks */ + HDassert(fm->sel_chunks == NULL); + HDassert(fm->single_chunk_info); + HDassert(fm->single_chunk_info->fspace_shared); + HDassert(fm->single_chunk_info->mspace_shared); + + /* Reset the selection for the single element I/O */ + H5S_select_all(fm->single_space, TRUE); + } /* end if */ + else { + /* Release the nodes on the list of selected chunks */ + if(fm->sel_chunks) + if(H5SL_free(fm->sel_chunks, H5D_free_chunk_info, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks") + } /* end else */ /* Free the memory chunk dataspace template */ if(fm->mchunk_tmpl) @@ -2682,8 +2740,7 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t #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 */ + H5D_chunk_info_t *chunk_info; /* 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 */ @@ -2698,62 +2755,49 @@ H5D_create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t 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; + /* Initialize the 'single chunk' file & memory chunk information */ + chunk_info = fm->single_chunk_info; + 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]; + 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; + 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) + if(H5V_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->down_chunks, &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") + /* Copy selection for file's dataspace into chunk dataspace */ + if(H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file selection") /* Move selection back to have correct offset in chunk */ - if(H5S_SELECT_ADJUST_U(tmp_fchunk, new_chunk_info->coords) < 0) + if(H5S_SELECT_ADJUST_U(fm->single_space, 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; + fm->select_chunk[chunk_info->index] = TRUE; #endif /* H5_HAVE_PARALLEL */ - /* Set the file chunk dataspace */ - new_chunk_info->fspace = tmp_fchunk; + /* Set the file dataspace for the chunk to the shared 'single' dataspace */ + chunk_info->fspace = fm->single_space; + + /* Indicate that the chunk's file dataspace is shared */ + chunk_info->fspace_shared = TRUE; /* Just point at the memory dataspace & selection */ /* (Casting away const OK -QAK) */ - new_chunk_info->mspace = (H5S_t *)fm->mem_space; + 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->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") + /* Indicate that the chunk's memory dataspace is shared */ + chunk_info->mspace_shared = TRUE; 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() */ @@ -2870,11 +2914,12 @@ H5D_create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t #endif /* H5_HAVE_PARALLEL */ /* Set the file chunk dataspace */ - new_chunk_info->fspace=tmp_fchunk; + new_chunk_info->fspace = tmp_fchunk; + new_chunk_info->fspace_shared = FALSE; /* Set the memory chunk dataspace */ new_chunk_info->mspace=NULL; - new_chunk_info->mspace_shared=0; + new_chunk_info->mspace_shared = FALSE; /* Copy the chunk's coordinates */ for(u=0; uf_ndims; u++) @@ -2988,7 +3033,7 @@ H5D_create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) chunk_info->mspace=(H5S_t *)fm->mem_space; /* Indicate that the chunk's memory space is shared */ - chunk_info->mspace_shared=1; + chunk_info->mspace_shared = TRUE; } /* end if */ else { /* Get bounding box for file selection */ @@ -3117,11 +3162,12 @@ H5D_chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const } /* end if */ /* Set the file chunk dataspace */ - chunk_info->fspace=fspace; + chunk_info->fspace = fspace; + chunk_info->fspace_shared = FALSE; /* Set the memory chunk dataspace */ chunk_info->mspace=NULL; - chunk_info->mspace_shared=0; + chunk_info->mspace_shared = FALSE; /* Set the number of selected elements in chunk to zero */ chunk_info->chunk_points=0; diff --git a/src/H5Distore.c b/src/H5Distore.c index 1efe049..47e4cab 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -3689,39 +3689,46 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id) H5D_rdcc_ent_t *ent, *next; /*cache entry */ H5D_rdcc_ent_t *old_ent; /* Old cache entry */ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ - H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */ - unsigned rank; /*current # of dimensions */ + H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ + unsigned rank; /*current # of dimensions */ hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace 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 */ - unsigned u; /*counters */ - herr_t ret_value=SUCCEED; /* Return value */ + unsigned u; /*counters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5D_istore_update_cache, FAIL) /* Check args */ - assert(dset && H5D_CHUNKED == dset->shared->layout.type); - assert(dset->shared->layout.u.chunk.ndims > 0 && dset->shared->layout.u.chunk.ndims <= H5O_LAYOUT_NDIMS); + HDassert(dset && H5D_CHUNKED == dset->shared->layout.type); + HDassert(dset->shared->layout.u.chunk.ndims > 0 && dset->shared->layout.u.chunk.ndims <= H5O_LAYOUT_NDIMS); - /* Go get the rank & dimensions */ + /* Get the rank */ rank = dset->shared->layout.u.chunk.ndims-1; + HDassert(rank > 0); + + /* 1-D dataset's chunks can't have their index change */ + if(rank == 1) + HGOTO_DONE(SUCCEED) + + /* Go get the dimensions */ if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions") /* Round up to the next integer # of chunks, to accomodate partial chunks */ for(u = 0; u < rank; u++) - chunks[u] = ((curr_dims[u]+dset->shared->layout.u.chunk.dim[u])-1) / dset->shared->layout.u.chunk.dim[u]; + chunks[u] = ((curr_dims[u] + dset->shared->layout.u.chunk.dim[u]) - 1) / dset->shared->layout.u.chunk.dim[u]; /* Get the "down" sizes for each dimension */ - if(H5V_array_down(rank,chunks,down_chunks) < 0) + if(H5V_array_down(rank, chunks, down_chunks) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes") /* Fill the DXPL cache values for later use */ - if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache) < 0) + if(H5D_get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") /* Construct dataset I/O info */ - H5D_BUILD_IO_INFO(&io_info,dset,dxpl_cache,dxpl_id,NULL); + H5D_BUILD_IO_INFO(&io_info, dset, dxpl_cache, dxpl_id, NULL); /* Recompute the index for each cached chunk that is in a dataset */ for(ent = rdcc->head; ent; ent = next) { @@ -3739,26 +3746,26 @@ H5D_istore_update_cache(H5D_t *dset, hid_t dxpl_id) old_idx=ent->idx; /* Save for later */ ent->idx=H5D_HASH(dset->shared,idx); - if(old_idx!=ent->idx) { + if(old_idx != ent->idx) { /* Check if there is already a chunk at this chunk's new location */ old_ent = rdcc->slot[ent->idx]; - if(old_ent!=NULL) { - assert(old_ent->locked==0); + if(old_ent != NULL) { + HDassert(old_ent->locked == 0); /* Check if we are removing the entry we would walk to next */ - if(old_ent==next) - next=old_ent->next; + if(old_ent == next) + next = old_ent->next; /* Remove the old entry from the cache */ - if (H5D_istore_preempt(&io_info, old_ent, TRUE )<0) + if(H5D_istore_preempt(&io_info, old_ent, TRUE) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush one or more raw data chunks") } /* end if */ /* Insert this chunk into correct location in hash table */ - rdcc->slot[ent->idx]=ent; + rdcc->slot[ent->idx] = ent; /* Null out previous location */ - rdcc->slot[old_idx]=NULL; + rdcc->slot[old_idx] = NULL; } /* end if */ } /* end for */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 4f4bc35..aec5e19 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -119,6 +119,17 @@ typedef struct H5D_io_info_t { #endif /* H5S_DEBUG */ } H5D_io_info_t; +/* Structure holding information about a chunk's selection for mapping */ +typedef struct H5D_chunk_info_t { + hsize_t index; /* "Index" of chunk in dataset */ + size_t chunk_points; /* Number of elements selected in chunk */ + hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */ + H5S_t *fspace; /* Dataspace describing chunk & selection in it */ + unsigned fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */ + H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */ + unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */ +} H5D_chunk_info_t; + /* Cached information about a particular chunk */ typedef struct { hbool_t valid; /*whether cache info is valid*/ @@ -143,7 +154,9 @@ typedef struct H5D_rdcc_t { int nused; /* Number of chunk slots in use */ H5D_chunk_cached_t last; /* Cached copy of last chunk information */ struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/ - H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ + H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ + H5S_t *single_space; /* Dataspace for single element I/O on chunks */ + H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */ } H5D_rdcc_t; /* The raw data contiguous data cache */ @@ -200,16 +213,6 @@ typedef enum { } H5D_time_alloc_t; -/* Structure holding information about a chunk's selection for mapping */ -typedef struct H5D_chunk_info_t { - hsize_t index; /* "Index" of chunk in dataset */ - size_t chunk_points; /* Number of elements selected in chunk */ - H5S_t *fspace; /* Dataspace describing chunk & selection in it */ - hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */ - H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */ - unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */ -} 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*/ @@ -226,6 +229,9 @@ typedef struct H5D_chunk_map_t { H5S_sel_type msel_type; /* Selection type in memory */ H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ + H5S_t *single_space; /* Dataspace for single chunk */ + H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */ + hbool_t use_single; /* Whether I/O is on a single element */ 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 */ diff --git a/test/tselect.c b/test/tselect.c index 3f18eb9..661226e 100644 --- a/test/tselect.c +++ b/test/tselect.c @@ -7629,35 +7629,35 @@ test_select_hyper_chunk_offset(void) wbuf[i]=i; /* Create file */ - fid = H5Fcreate (FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK(fid, FAIL, "H5Fcreate"); /* Create a dataset creation property list */ - dcpl = H5Pcreate (H5P_DATASET_CREATE); + dcpl = H5Pcreate(H5P_DATASET_CREATE); CHECK(dcpl, FAIL, "H5Pcreate"); /* Set to chunked storage layout */ - ret=H5Pset_layout (dcpl, H5D_CHUNKED); + ret = H5Pset_layout(dcpl, H5D_CHUNKED); CHECK(ret, FAIL, "H5Pset_layout"); /* Set the chunk size */ - ret=H5Pset_chunk (dcpl, 1, chunks); + ret = H5Pset_chunk(dcpl, 1, chunks); CHECK(ret, FAIL, "H5Pset_chunk"); /* Create dataspace for memory */ - msid = H5Screate_simple (1, mem_dims, NULL); + msid = H5Screate_simple(1, mem_dims, NULL); CHECK(msid, FAIL, "H5Screate_simple"); /* Select the correct chunk in the memory dataspace */ - ret=H5Sselect_hyperslab (msid, H5S_SELECT_SET, start, NULL, count, NULL); + ret = H5Sselect_hyperslab(msid, H5S_SELECT_SET, start, NULL, count, NULL); CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* Create dataspace for dataset */ - sid = H5Screate_simple (1, dims, maxdims); + sid = H5Screate_simple(1, dims, maxdims); CHECK(sid, FAIL, "H5Screate_simple"); /* Create the dataset */ - did = H5Dcreate2 (fid, "fooData", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + did = H5Dcreate2(fid, "fooData", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); CHECK(did, FAIL, "H5Dcreate2"); /* Close the dataspace */ @@ -7684,7 +7684,7 @@ test_select_hyper_chunk_offset(void) CHECK(fsid, FAIL, "H5Dget_space"); /* Select the correct chunk in the dataset */ - ret = H5Sselect_hyperslab (fsid, H5S_SELECT_SET, start, NULL, count, NULL); + ret = H5Sselect_hyperslab(fsid, H5S_SELECT_SET, start, NULL, count, NULL); CHECK(ret, FAIL, "H5Sselect_hyperslab"); /* Set the selection offset for the file dataspace */ @@ -7693,13 +7693,13 @@ test_select_hyper_chunk_offset(void) CHECK(ret, FAIL, "H5Soffset_simple"); /* Set the selection offset for the memory dataspace */ - offset[0] = SPACE10_DIM1-i; + offset[0] = SPACE10_DIM1 - i; ret = H5Soffset_simple(msid, offset); CHECK(ret, FAIL, "H5Soffset_simple"); /* Write the data to the chunk */ ret = H5Dwrite(did, H5T_NATIVE_INT, msid, fsid, H5P_DEFAULT, wbuf); - CHECK(ret, FAIL, "H5Soffset_simple"); + CHECK(ret, FAIL, "H5Dwrite"); /* Close the file dataspace copy */ ret = H5Sclose(fsid); @@ -7707,8 +7707,8 @@ test_select_hyper_chunk_offset(void) } /* Read the data back in */ - ret=H5Dread (did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); - CHECK(ret, FAIL, "H5Soffset_simple"); + ret = H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf); + CHECK(ret, FAIL, "H5Dread"); /* Verify the information read in */ for(i=0; i