summaryrefslogtreecommitdiffstats
path: root/src/H5Dchunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dchunk.c')
-rw-r--r--src/H5Dchunk.c1705
1 files changed, 953 insertions, 752 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 256b441..a3f20c5 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -67,11 +67,19 @@
/****************/
/* 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))
-#define H5D_CHUNK_GET_NODE_COUNT(map) (map->use_single ? (size_t)1 : H5SL_count(map->sel_chunks))
+#define H5D_CHUNK_GET_FIRST_NODE(dinfo) \
+ (dinfo->layout_io_info.chunk_map->use_single \
+ ? (H5SL_node_t *)(1) \
+ : H5SL_first(dinfo->layout_io_info.chunk_map->dset_sel_pieces))
+#define H5D_CHUNK_GET_NODE_INFO(dinfo, node) \
+ (dinfo->layout_io_info.chunk_map->use_single ? dinfo->layout_io_info.chunk_map->single_piece_info \
+ : (H5D_piece_info_t *)H5SL_item(node))
+#define H5D_CHUNK_GET_NEXT_NODE(dinfo, node) \
+ (dinfo->layout_io_info.chunk_map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
+#define H5D_CHUNK_GET_NODE_COUNT(dinfo) \
+ (dinfo->layout_io_info.chunk_map->use_single \
+ ? (size_t)1 \
+ : H5SL_count(dinfo->layout_io_info.chunk_map->dset_sel_pieces))
/* Sanity check on chunk index types: commonly used by a lot of routines in this file */
#define H5D_CHUNK_STORAGE_INDEX_CHK(storage) \
@@ -143,6 +151,7 @@ typedef struct H5D_chunk_it_ud1_t {
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
const H5D_chk_idx_info_t *idx_info; /* Chunked index info */
const H5D_io_info_t *io_info; /* I/O info for dataset operation */
+ const H5D_dset_io_info_t *dset_info; /* Dataset specific I/O info */
const hsize_t *space_dim; /* New dataset dimensions */
const hbool_t *shrunk_dim; /* Dimensions which have been shrunk */
H5S_t *chunk_space; /* Dataspace for a chunk */
@@ -231,14 +240,6 @@ typedef struct H5D_chunk_info_iter_ud_t {
hbool_t found; /* Whether the chunk was found */
} H5D_chunk_info_iter_ud_t;
-/* Callback info for file selection iteration */
-typedef struct H5D_chunk_file_iter_ud_t {
- H5D_chunk_map_t *fm; /* File->memory chunk mapping info */
-#ifdef H5_HAVE_PARALLEL
- const H5D_io_info_t *io_info; /* I/O info for operation */
-#endif /* H5_HAVE_PARALLEL */
-} H5D_chunk_file_iter_ud_t;
-
#ifdef H5_HAVE_PARALLEL
/* information to construct a collective I/O operation for filling chunks */
typedef struct H5D_chunk_coll_fill_info_t {
@@ -264,16 +265,13 @@ typedef struct H5D_chunk_iter_ud_t {
/* Chunked layout operation callbacks */
static herr_t H5D__chunk_construct(H5F_t *f, H5D_t *dset);
static herr_t H5D__chunk_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
-static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
-static herr_t H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm);
-static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
-static herr_t H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
+static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
+static herr_t H5D__chunk_io_init_selections(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
+static herr_t H5D__chunk_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
+static herr_t H5D__chunk_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
+static herr_t H5D__chunk_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
static herr_t H5D__chunk_flush(H5D_t *dset);
-static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm);
+static herr_t H5D__chunk_io_term(H5D_io_info_t *io_info, H5D_dset_io_info_t *di);
static herr_t H5D__chunk_dest(H5D_t *dset);
/* Chunk query operation callbacks */
@@ -283,8 +281,8 @@ static int H5D__get_chunk_info_by_coord_cb(const H5D_chunk_rec_t *chunk_rec, voi
static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata);
/* "Nonexistent" layout operation callback */
-static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq,
- size_t *chunk_curr_seq, size_t chunk_len_arr[],
+static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[],
hsize_t chunk_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
@@ -292,29 +290,28 @@ static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chun
static int H5D__chunk_format_convert_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata);
/* Helper routines */
-static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims,
- const hsize_t *max_dims);
-static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
-static herr_t H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata);
-static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udata);
-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_all(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_1d(const H5D_chunk_map_t *fm);
-static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm);
-static herr_t H5D__chunk_file_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
- void *fm);
-static herr_t H5D__chunk_mem_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
- void *fm);
-static htri_t H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info);
+static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims,
+ const hsize_t *max_dims);
+static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
+static herr_t H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata);
+static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udata);
+static herr_t H5D__create_piece_map_single(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
+static herr_t H5D__create_piece_file_map_all(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
+static herr_t H5D__create_piece_file_map_hyper(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
+static herr_t H5D__create_piece_mem_map_1d(const H5D_dset_io_info_t *di);
+static herr_t H5D__create_piece_mem_map_hyper(const H5D_dset_io_info_t *di);
+static herr_t H5D__piece_file_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
+ void *_opdata);
+static herr_t H5D__piece_mem_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
+ void *_opdata);
+static htri_t H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
static unsigned H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled);
static herr_t H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset);
static herr_t H5D__chunk_cache_evict(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t flush);
-static void *H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax,
- hbool_t prev_unfilt_chunk);
-static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty,
- void *chunk, uint32_t naccessed);
+static void *H5D__chunk_lock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
+ H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk);
+static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
+ const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk, uint32_t naccessed);
static herr_t H5D__chunk_cache_prune(const H5D_t *dset, size_t size);
static herr_t H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk);
#ifdef H5_HAVE_PARALLEL
@@ -337,17 +334,14 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
H5D__chunk_is_space_alloc, /* is_space_alloc */
H5D__chunk_is_data_cached, /* is_data_cached */
H5D__chunk_io_init, /* io_init */
+ H5D__chunk_mdio_init, /* mdio_init */
H5D__chunk_read, /* ser_read */
H5D__chunk_write, /* ser_write */
-#ifdef H5_HAVE_PARALLEL
- H5D__chunk_collective_read, /* par_read */
- H5D__chunk_collective_write, /* par_write */
-#endif
- NULL, /* readvv */
- NULL, /* writevv */
- H5D__chunk_flush, /* flush */
- H5D__chunk_io_term, /* io_term */
- H5D__chunk_dest /* dest */
+ NULL, /* readvv */
+ NULL, /* writevv */
+ H5D__chunk_flush, /* flush */
+ H5D__chunk_io_term, /* io_term */
+ H5D__chunk_dest /* dest */
}};
/*******************/
@@ -355,11 +349,8 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
/*******************/
/* "nonexistent" storage layout I/O ops */
-const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-#ifdef H5_HAVE_PARALLEL
- NULL, NULL,
-#endif /* H5_HAVE_PARALLEL */
- H5D__nonexistent_readvv, NULL, NULL, NULL, NULL}};
+const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, H5D__nonexistent_readvv, NULL, NULL, NULL, NULL}};
/* Declare a free list to manage the H5F_rdcc_ent_ptr_t sequence information */
H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t);
@@ -368,7 +359,10 @@ H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t);
H5FL_DEFINE_STATIC(H5D_rdcc_ent_t);
/* Declare a free list to manage the H5D_chunk_info_t struct */
-H5FL_DEFINE(H5D_chunk_info_t);
+H5FL_DEFINE(H5D_chunk_map_t);
+
+/* Declare a free list to manage the H5D_piece_info_t struct */
+H5FL_DEFINE(H5D_piece_info_t);
/* Declare a free list to manage the chunk sequence information */
H5FL_BLK_DEFINE_STATIC(chunk);
@@ -389,8 +383,7 @@ H5FL_EXTERN(H5S_sel_iter_t);
*-------------------------------------------------------------------------
*/
herr_t
-H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size,
- const void *buf)
+H5D__chunk_direct_write(H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size, const void *buf)
{
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
H5D_chunk_ud_t udata; /* User data for querying chunk info */
@@ -406,16 +399,9 @@ H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, ui
HDassert(layout->type == H5D_CHUNKED);
/* Allocate dataspace and initialize it if it hasn't been. */
- if (!H5D__chunk_is_space_alloc(&layout->storage)) {
- H5D_io_info_t io_info; /* to hold the dset info */
-
- io_info.dset = dset;
- io_info.f_sh = H5F_SHARED(dset->oloc.file);
-
- /* Allocate storage */
- if (H5D__alloc_storage(&io_info, H5D_ALLOC_WRITE, FALSE, NULL) < 0)
+ if (!H5D__chunk_is_space_alloc(&layout->storage))
+ if (H5D__alloc_storage(dset, H5D_ALLOC_WRITE, FALSE, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
- }
/* Calculate the index of this chunk */
H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, scaled);
@@ -1069,26 +1055,40 @@ H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset)
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
- H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm)
+H5D__chunk_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
{
- const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
- hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
- htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
- unsigned f_ndims; /* The number of dimensions of the file's dataspace */
- int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
- htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5D_t *dataset = dinfo->dset; /* Local pointer to dataset info */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
+ htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
+ unsigned f_ndims; /* The number of dimensions of the file's dataspace */
+ int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
+ htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
+ /* Allocate chunk map */
+ if (NULL == (dinfo->layout_io_info.chunk_map = H5FL_MALLOC(H5D_chunk_map_t)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk map")
+ fm = dinfo->layout_io_info.chunk_map;
+
/* Get layout for dataset */
- fm->layout = &(dataset->shared->layout);
- fm->nelmts = nelmts;
+ dinfo->layout = &(dataset->shared->layout);
+
+ /* Initialize "last chunk" information */
+ fm->last_index = (hsize_t)-1;
+ fm->last_piece_info = NULL;
+
+ /* Clear other fields */
+ fm->mchunk_tmpl = NULL;
+ fm->dset_sel_pieces = NULL;
+ fm->single_space = NULL;
+ fm->single_piece_info = NULL;
/* Check if the memory space is scalar & make equivalent memory space */
- if ((sm_ndims = H5S_GET_EXTENT_NDIMS(mem_space)) < 0)
+ if ((sm_ndims = H5S_GET_EXTENT_NDIMS(dinfo->mem_space)) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number")
/* Set the number of dimensions for the memory dataspace */
H5_CHECKED_ASSIGN(fm->m_ndims, unsigned, sm_ndims, int);
@@ -1102,49 +1102,28 @@ H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsi
* speed up hyperslab calculations by removing the extra checks and/or
* additions involving the offset and the hyperslab selection -QAK)
*/
- if ((file_space_normalized = H5S_hyper_normalize_offset(file_space, old_offset)) < 0)
+ if ((file_space_normalized = H5S_hyper_normalize_offset(dinfo->file_space, old_offset)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to normalize selection")
/* Decide the number of chunks in each dimension */
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];
-
-#ifdef H5_HAVE_PARALLEL
- /* Calculate total chunk in file map*/
- fm->select_chunk = NULL;
- if (io_info->using_mpi_vfd) {
- H5_CHECK_OVERFLOW(fm->layout->u.chunk.nchunks, hsize_t, size_t);
- if (fm->layout->u.chunk.nchunks)
- 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 */
-
- /* Initialize "last chunk" information */
- 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;
+ fm->chunk_dim[u] = dinfo->layout->u.chunk.dim[u];
- if (H5D__chunk_io_init_selections(io_info, type_info, fm) < 0)
+ if (H5D__chunk_io_init_selections(io_info, dinfo) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file and memory chunk selections")
- /* Check if we're performing selection I/O and save the result */
- if ((use_selection_io = H5D__chunk_may_use_select_io(io_info)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
- io_info->use_select_io = (hbool_t)use_selection_io;
+ /* Check if we're performing selection I/O and save the result if it hasn't
+ * been disabled already */
+ if (io_info->use_select_io) {
+ if ((use_selection_io = H5D__chunk_may_use_select_io(io_info, dinfo)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
+ io_info->use_select_io = (hbool_t)use_selection_io;
+ }
done:
- /* Reset the global dataspace info */
- fm->file_space = NULL;
- fm->mem_space = NULL;
-
if (file_space_normalized == TRUE)
- if (H5S_hyper_denormalize_offset(file_space, old_offset) < 0)
+ if (H5S_hyper_denormalize_offset(dinfo->file_space, old_offset) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't denormalize selection")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1163,34 +1142,44 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
- H5D_chunk_map_t *fm)
+H5D__chunk_io_init_selections(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
{
- const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
- const H5T_t *mem_type = type_info->mem_type; /* Local pointer to memory datatype */
- H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */
- H5T_t *file_type = NULL; /* Temporary copy of file datatype for iteration */
- hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
- char bogus; /* "bogus" buffer to pass to selection iterator */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ const H5D_t *dataset; /* Local pointer to dataset info */
+ const H5T_t *mem_type; /* Local pointer to memory datatype */
+ H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */
+ H5T_t *file_type = NULL; /* Temporary copy of file datatype for iteration */
+ hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
+ char bogus; /* "bogus" buffer to pass to selection iterator */
+ H5D_io_info_wrap_t io_info_wrap;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
+ HDassert(io_info);
+ HDassert(dinfo);
+
+ /* Set convenience pointers */
+ fm = dinfo->layout_io_info.chunk_map;
+ HDassert(fm);
+ dataset = dinfo->dset;
+ mem_type = dinfo->type_info.mem_type;
+
/* Special case for only one element in selection */
/* (usually appending a record) */
- if (fm->nelmts == 1
+ if (dinfo->nelmts == 1
#ifdef H5_HAVE_PARALLEL
&& !(io_info->using_mpi_vfd)
#endif /* H5_HAVE_PARALLEL */
- && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(fm->file_space)) {
+ && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(dinfo->file_space)) {
/* 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(fm->file_space, TRUE, FALSE)) == NULL)
+ if ((dataset->shared->cache.chunk.single_space = H5S_copy(dinfo->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 */
@@ -1205,17 +1194,17 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
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)))
+ if (NULL == dataset->shared->cache.chunk.single_piece_info)
+ if (NULL == (dataset->shared->cache.chunk.single_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
- fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info;
- HDassert(fm->single_chunk_info);
+ fm->single_piece_info = dataset->shared->cache.chunk.single_piece_info;
+ HDassert(fm->single_piece_info);
/* Reset chunk template information */
fm->mchunk_tmpl = NULL;
/* Set up chunk mapping for single element */
- if (H5D__create_chunk_map_single(fm, io_info) < 0)
+ if (H5D__create_piece_map_single(dinfo, io_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to create chunk selections for single element")
} /* end if */
@@ -1226,16 +1215,16 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
if (NULL == dataset->shared->cache.chunk.sel_chunks)
if (NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, NULL)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections")
- fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks;
- HDassert(fm->sel_chunks);
+ fm->dset_sel_pieces = dataset->shared->cache.chunk.sel_chunks;
+ HDassert(fm->dset_sel_pieces);
/* We are not using single element mode */
fm->use_single = FALSE;
/* Get type of selection on disk & in memory */
- if ((fm->fsel_type = H5S_GET_SELECT_TYPE(fm->file_space)) < H5S_SEL_NONE)
+ if ((fm->fsel_type = H5S_GET_SELECT_TYPE(dinfo->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(fm->mem_space)) < H5S_SEL_NONE)
+ if ((fm->msel_type = H5S_GET_SELECT_TYPE(dinfo->mem_space)) < H5S_SEL_NONE)
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
/* If the selection is NONE or POINTS, set the flag to FALSE */
@@ -1248,57 +1237,53 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
if (sel_hyper_flag) {
/* Build the file selection for each chunk */
if (H5S_SEL_ALL == fm->fsel_type) {
- if (H5D__create_chunk_file_map_all(fm, io_info) < 0)
+ if (H5D__create_piece_file_map_all(dinfo, io_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
} /* end if */
else {
/* Sanity check */
HDassert(fm->fsel_type == H5S_SEL_HYPERSLABS);
- if (H5D__create_chunk_file_map_hyper(fm, io_info) < 0)
+ if (H5D__create_piece_file_map_hyper(dinfo, io_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
} /* end else */
} /* end if */
else {
- H5S_sel_iter_op_t iter_op; /* Operator for iteration */
- H5D_chunk_file_iter_ud_t udata; /* User data for iteration */
+ H5S_sel_iter_op_t iter_op; /* Operator for iteration */
/* Create temporary datatypes for selection iteration */
if (NULL == (file_type = H5T_copy(dataset->shared->type, H5T_COPY_ALL)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
- /* Initialize the user data */
- udata.fm = fm;
-#ifdef H5_HAVE_PARALLEL
- udata.io_info = io_info;
-#endif /* H5_HAVE_PARALLEL */
-
- iter_op.op_type = H5S_SEL_ITER_OP_LIB;
- iter_op.u.lib_op = H5D__chunk_file_cb;
+ /* set opdata for H5D__piece_mem_cb */
+ io_info_wrap.io_info = io_info;
+ io_info_wrap.dinfo = dinfo;
+ iter_op.op_type = H5S_SEL_ITER_OP_LIB;
+ iter_op.u.lib_op = H5D__piece_file_cb;
/* Spaces might not be the same shape, iterate over the file selection directly */
- if (H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, &udata) < 0)
+ if (H5S_select_iterate(&bogus, file_type, dinfo->file_space, &iter_op, &io_info_wrap) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
- /* Reset "last chunk" info */
+ /* Reset "last piece" info */
fm->last_index = (hsize_t)-1;
- fm->last_chunk_info = NULL;
+ fm->last_piece_info = NULL;
} /* end else */
/* Build the memory selection for each chunk */
- if (sel_hyper_flag && H5S_SELECT_SHAPE_SAME(fm->file_space, fm->mem_space) == TRUE) {
+ if (sel_hyper_flag && H5S_SELECT_SHAPE_SAME(dinfo->file_space, dinfo->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 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)
+ if (H5D__create_piece_mem_map_hyper(dinfo) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
} /* end if */
else if (sel_hyper_flag && fm->f_ndims == 1 && fm->m_ndims == 1 &&
- H5S_SELECT_IS_REGULAR(fm->mem_space) && H5S_SELECT_IS_SINGLE(fm->mem_space)) {
- if (H5D__create_chunk_mem_map_1d(fm) < 0)
+ H5S_SELECT_IS_REGULAR(dinfo->mem_space) && H5S_SELECT_IS_SINGLE(dinfo->mem_space)) {
+ if (H5D__create_piece_mem_map_1d(dinfo) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
} /* end else-if */
else {
@@ -1306,7 +1291,7 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
size_t elmt_size; /* Memory datatype size */
/* Make a copy of equivalent memory space */
- if ((tmp_mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
+ if ((tmp_mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
/* De-select the mem space copy */
@@ -1324,15 +1309,18 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
/* Create selection iterator for memory selection */
if (0 == (elmt_size = H5T_get_size(mem_type)))
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
- if (H5S_select_iter_init(&(fm->mem_iter), fm->mem_space, elmt_size, 0) < 0)
+ if (H5S_select_iter_init(&(fm->mem_iter), dinfo->mem_space, elmt_size, 0) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
iter_init = TRUE; /* Selection iteration info has been initialized */
- iter_op.op_type = H5S_SEL_ITER_OP_LIB;
- iter_op.u.lib_op = H5D__chunk_mem_cb;
+ /* set opdata for H5D__piece_mem_cb */
+ io_info_wrap.io_info = io_info;
+ io_info_wrap.dinfo = dinfo;
+ iter_op.op_type = H5S_SEL_ITER_OP_LIB;
+ iter_op.u.lib_op = H5D__piece_mem_cb;
/* Spaces aren't the same shape, iterate over the memory selection directly */
- if (H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, fm) < 0)
+ if (H5S_select_iterate(&bogus, file_type, dinfo->file_space, &iter_op, &io_info_wrap) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
} /* end else */
} /* end else */
@@ -1344,7 +1332,7 @@ done:
if (H5S_close(tmp_mspace) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL,
"can't release memory chunk dataspace template")
- if (H5D__chunk_io_term(fm) < 0)
+ if (H5D__chunk_io_term(io_info, dinfo) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping")
} /* end if */
@@ -1466,14 +1454,17 @@ H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline)
/*--------------------------------------------------------------------------
NAME
- H5D__free_chunk_info
+ H5D__free_piece_info
PURPOSE
- Internal routine to destroy a chunk info node
+ Performs initialization before any sort of I/O on the raw data
+ This was derived from H5D__free_chunk_info for multi-dset work.
USAGE
- void H5D__free_chunk_info(chunk_info)
+ herr_t H5D__free_piece_info(chunk_info, key, opdata)
void *chunk_info; IN: Pointer to chunk info to destroy
+ void *key; Unused
+ void *opdata; Unused
RETURNS
- No return value
+ Non-negative on success, negative on failure
DESCRIPTION
Releases all the memory for a chunk info node. Called by H5SL_free
GLOBAL VARIABLES
@@ -1481,51 +1472,48 @@ H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static herr_t
-H5D__free_chunk_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *opdata)
+herr_t
+H5D__free_piece_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *opdata)
{
- H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item;
+ H5D_piece_info_t *piece_info = (H5D_piece_info_t *)item;
FUNC_ENTER_PACKAGE_NOERR
- HDassert(chunk_info);
+ HDassert(piece_info);
- /* Close the chunk's file dataspace, if it's not shared */
- if (!chunk_info->fspace_shared)
- (void)H5S_close(chunk_info->fspace);
+ /* Close the piece's file dataspace, if it's not shared */
+ if (!piece_info->fspace_shared)
+ (void)H5S_close(piece_info->fspace);
else
- H5S_select_all(chunk_info->fspace, TRUE);
+ H5S_select_all(piece_info->fspace, TRUE);
- /* Close the chunk's memory dataspace, if it's not shared */
- if (!chunk_info->mspace_shared && chunk_info->mspace)
- (void)H5S_close(chunk_info->mspace);
+ /* Close the piece's memory dataspace, if it's not shared */
+ if (!piece_info->mspace_shared && piece_info->mspace)
+ (void)H5S_close((H5S_t *)piece_info->mspace);
- /* Free the actual chunk info */
- chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
+ /* Free the actual piece info */
+ piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
FUNC_LEAVE_NOAPI(0)
-} /* H5D__free_chunk_info() */
+} /* H5D__free_piece_info() */
/*-------------------------------------------------------------------------
- * Function: H5D__create_chunk_map_single
+ * Function: H5D__create_piece_map_single
*
- * Purpose: Create chunk selections when appending a single record
+ * Purpose: Create piece selections when appending a single record
+ * This was derived from H5D__create_chunk_map_single for
+ * multi-dset work.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Tuesday, November 20, 2007
- *
+ * Programmer: Jonathan Kim Nov, 2013
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
-#ifndef H5_HAVE_PARALLEL
- H5_ATTR_UNUSED
-#endif /* H5_HAVE_PARALLEL */
- *io_info)
+H5D__create_piece_map_single(H5D_dset_io_info_t *di, H5D_io_info_t *io_info)
{
- H5D_chunk_info_t *chunk_info; /* Chunk information to insert into skip list */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5D_piece_info_t *piece_info; /* Piece information to insert into skip list */
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk */
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 */
@@ -1534,64 +1522,68 @@ H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
FUNC_ENTER_PACKAGE
- /* Sanity check */
+ /* Set convenience pointer */
+ fm = di->layout_io_info.chunk_map;
+
+ /* Sanity checks */
+ HDassert(fm);
HDassert(fm->f_ndims > 0);
/* Get coordinate for selection */
- if (H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
+ if (H5S_SELECT_BOUNDS(di->file_space, sel_start, sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
- /* Initialize the 'single chunk' file & memory chunk information */
- chunk_info = fm->single_chunk_info;
- chunk_info->chunk_points = 1;
+ /* Initialize the 'single piece' file & memory piece information */
+ piece_info = fm->single_piece_info;
+ piece_info->piece_points = 1;
/* Set chunk location & hyperslab size */
for (u = 0; u < fm->f_ndims; u++) {
/* Validate this chunk dimension */
- if (fm->layout->u.chunk.dim[u] == 0)
+ if (di->layout->u.chunk.dim[u] == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
HDassert(sel_start[u] == sel_end[u]);
- chunk_info->scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u];
- coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u];
+ piece_info->scaled[u] = sel_start[u] / di->layout->u.chunk.dim[u];
+ coords[u] = piece_info->scaled[u] * di->layout->u.chunk.dim[u];
} /* end for */
- chunk_info->scaled[fm->f_ndims] = 0;
+ piece_info->scaled[fm->f_ndims] = 0;
/* Calculate the index of this chunk */
- chunk_info->index =
- H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, chunk_info->scaled);
+ piece_info->index =
+ H5VM_array_offset_pre(fm->f_ndims, di->layout->u.chunk.down_chunks, piece_info->scaled);
/* Copy selection for file's dataspace into chunk dataspace */
- if (H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0)
+ if (H5S_select_copy(fm->single_space, di->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(fm->single_space, 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[chunk_info->index] = chunk_info;
-#endif /* H5_HAVE_PARALLEL */
-
/* Set the file dataspace for the chunk to the shared 'single' dataspace */
- chunk_info->fspace = fm->single_space;
+ piece_info->fspace = fm->single_space;
/* Indicate that the chunk's file dataspace is shared */
- chunk_info->fspace_shared = TRUE;
+ piece_info->fspace_shared = TRUE;
/* Just point at the memory dataspace & selection */
- chunk_info->mspace = fm->mem_space;
+ piece_info->mspace = di->mem_space;
/* Indicate that the chunk's memory dataspace is shared */
- chunk_info->mspace_shared = TRUE;
+ piece_info->mspace_shared = TRUE;
+
+ /* make connection to related dset info from this piece_info */
+ piece_info->dset_info = di;
+
+ /* Add piece to global piece_count */
+ io_info->piece_count++;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__create_chunk_map_single() */
+} /* end H5D__create_piece_map_single() */
/*-------------------------------------------------------------------------
- * Function: H5D__create_chunk_file_map_all
+ * Function: H5D__create_piece_file_map_all
*
* Purpose: Create all chunk selections in file, for an "all" selection.
*
@@ -1603,21 +1595,18 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
-#ifndef H5_HAVE_PARALLEL
- H5_ATTR_UNUSED
-#endif /* H5_HAVE_PARALLEL */
- *io_info)
+H5D__create_piece_file_map_all(H5D_dset_io_info_t *di, H5D_io_info_t *io_info)
{
- H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
- hsize_t file_dims[H5S_MAX_RANK]; /* File dataspace dims */
- hsize_t sel_points; /* Number of elements in file selection */
- hsize_t zeros[H5S_MAX_RANK]; /* All zero vector (for start parameter to setting hyperslab on partial
- chunks) */
- hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
- hsize_t end[H5S_MAX_RANK]; /* Final coordinates of chunk */
- hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
- hsize_t chunk_index; /* "Index" of chunk */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
+ hsize_t file_dims[H5S_MAX_RANK]; /* File dataspace dims */
+ hsize_t sel_points; /* Number of elements in file selection */
+ hsize_t zeros[H5S_MAX_RANK]; /* All zero vector (for start parameter to setting hyperslab on partial
+ chunks) */
+ hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
+ hsize_t end[H5S_MAX_RANK]; /* Final coordinates of chunk */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
+ hsize_t chunk_index; /* "Index" of chunk */
hsize_t curr_partial_clip[H5S_MAX_RANK]; /* Current partial dimension sizes to clip against */
hsize_t partial_dim_size[H5S_MAX_RANK]; /* Size of a partial dimension */
hbool_t is_partial_dim[H5S_MAX_RANK]; /* Whether a dimension is currently a partial chunk */
@@ -1627,14 +1616,18 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
FUNC_ENTER_PACKAGE
- /* Sanity check */
+ /* Set convenience pointer */
+ fm = di->layout_io_info.chunk_map;
+
+ /* Sanity checks */
+ HDassert(fm);
HDassert(fm->f_ndims > 0);
/* Get number of elements selected in file */
- sel_points = fm->nelmts;
+ sel_points = di->nelmts;
/* Get dataspace dimensions */
- if (H5S_get_simple_extent_dims(fm->file_space, file_dims, NULL) < 0)
+ if (H5S_get_simple_extent_dims(di->file_space, file_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Set initial chunk location, partial dimensions, etc */
@@ -1642,7 +1635,7 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
HDmemset(zeros, 0, sizeof(zeros));
for (u = 0; u < fm->f_ndims; u++) {
/* Validate this chunk dimension */
- if (fm->layout->u.chunk.dim[u] == 0)
+ if (di->layout->u.chunk.dim[u] == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
/* Set up start / end coordinates for first chunk */
@@ -1672,54 +1665,54 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
/* Iterate through each chunk in the dataset */
while (sel_points) {
- H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
+ H5D_piece_info_t *new_piece_info; /* Piece information to insert into skip list */
hsize_t chunk_points; /* Number of elements in chunk selection */
- /* Add temporary chunk to the list of chunks */
+ /* Add temporary chunk to the list of pieces */
/* Allocate the file & memory chunk information */
- if (NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info")
+ if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate piece info")
/* Initialize the chunk information */
/* Set the chunk index */
- new_chunk_info->index = chunk_index;
-
-#ifdef H5_HAVE_PARALLEL
- /* Store chunk selection information, for multi-chunk I/O */
- if (io_info->using_mpi_vfd)
- fm->select_chunk[chunk_index] = new_chunk_info;
-#endif /* H5_HAVE_PARALLEL */
+ new_piece_info->index = chunk_index;
/* Set the file chunk dataspace */
- if (NULL == (new_chunk_info->fspace = H5S_copy(tmp_fchunk, TRUE, FALSE)))
+ if (NULL == (new_piece_info->fspace = H5S_copy(tmp_fchunk, TRUE, FALSE)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy chunk dataspace")
- new_chunk_info->fspace_shared = FALSE;
+ new_piece_info->fspace_shared = FALSE;
/* If there are partial dimensions for this chunk, set the hyperslab for them */
if (num_partial_dims > 0)
- if (H5S_select_hyperslab(new_chunk_info->fspace, H5S_SELECT_SET, zeros, NULL, curr_partial_clip,
+ if (H5S_select_hyperslab(new_piece_info->fspace, H5S_SELECT_SET, zeros, NULL, curr_partial_clip,
NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk selection")
/* Set the memory chunk dataspace */
- new_chunk_info->mspace = NULL;
- new_chunk_info->mspace_shared = FALSE;
+ new_piece_info->mspace = NULL;
+ new_piece_info->mspace_shared = FALSE;
/* Copy the chunk's scaled coordinates */
- H5MM_memcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
- new_chunk_info->scaled[fm->f_ndims] = 0;
+ H5MM_memcpy(new_piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
+ new_piece_info->scaled[fm->f_ndims] = 0;
+
+ /* make connection to related dset info from this piece_info */
+ new_piece_info->dset_info = di;
/* Insert the new chunk into the skip list */
- if (H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) {
- H5D__free_chunk_info(new_chunk_info, NULL, NULL);
+ if (H5SL_insert(fm->dset_sel_pieces, new_piece_info, &new_piece_info->index) < 0) {
+ H5D__free_piece_info(new_piece_info, NULL, NULL);
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
} /* end if */
+ /* Add piece to global piece_count*/
+ io_info->piece_count++;
+
/* Get number of elements selected in chunk */
- chunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace);
- H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, chunk_points, hsize_t);
+ chunk_points = H5S_GET_SELECT_NPOINTS(new_piece_info->fspace);
+ new_piece_info->piece_points = chunk_points;
/* Decrement # of points left in file selection */
sel_points -= chunk_points;
@@ -1796,74 +1789,75 @@ done:
} /* end H5D__create_chunk_file_map_all() */
/*-------------------------------------------------------------------------
- * Function: H5D__create_chunk_file_map_hyper
+ * Function: H5D__create_piece_file_map_hyper
*
- * Purpose: Create all chunk selections in file, for a hyperslab selection.
+ * Purpose: Create all chunk selections in file.
+ * This was derived from H5D__create_chunk_file_map_hyper for
+ * multi-dset work.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Thursday, May 29, 2003
- *
+ * Programmer: Jonathan Kim Nov, 2013
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
-#ifndef H5_HAVE_PARALLEL
- H5_ATTR_UNUSED
-#endif /* H5_HAVE_PARALLEL */
- *io_info)
+H5D__create_piece_file_map_hyper(H5D_dset_io_info_t *dinfo, H5D_io_info_t *io_info)
{
- H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
- 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 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]; /* Final coordinates of chunk */
- hsize_t chunk_index; /* Index of chunk */
- hsize_t start_scaled[H5S_MAX_RANK]; /* Starting scaled coordinates of selection */
- hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
- int curr_dim; /* Current dimension to increment */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
+ 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 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]; /* Final coordinates of chunk */
+ hsize_t chunk_index; /* Index of chunk */
+ hsize_t start_scaled[H5S_MAX_RANK]; /* Starting scaled coordinates of selection */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
+ int curr_dim; /* Current dimension to increment */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
- /* Sanity check */
+ /* Set convenience pointer */
+ fm = dinfo->layout_io_info.chunk_map;
+
+ /* Sanity checks */
+ HDassert(fm);
HDassert(fm->f_ndims > 0);
/* Get number of elements selected in file */
- sel_points = fm->nelmts;
+ sel_points = dinfo->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)
+ if (H5S_SELECT_BOUNDS(dinfo->file_space, sel_start, sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Set initial chunk location & hyperslab size */
for (u = 0; u < fm->f_ndims; u++) {
/* Validate this chunk dimension */
- if (fm->layout->u.chunk.dim[u] == 0)
+ if (dinfo->layout->u.chunk.dim[u] == 0)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
- scaled[u] = start_scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u];
- coords[u] = start_coords[u] = scaled[u] * fm->layout->u.chunk.dim[u];
+ scaled[u] = start_scaled[u] = sel_start[u] / dinfo->layout->u.chunk.dim[u];
+ coords[u] = start_coords[u] = scaled[u] * dinfo->layout->u.chunk.dim[u];
end[u] = (coords[u] + fm->chunk_dim[u]) - 1;
} /* end for */
/* Calculate the index of this chunk */
- chunk_index = H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, scaled);
+ chunk_index = H5VM_array_offset_pre(fm->f_ndims, dinfo->layout->u.chunk.down_chunks, scaled);
/* Iterate through each chunk in the dataset */
while (sel_points) {
/* Check for intersection of current chunk and file selection */
- if (TRUE == H5S_SELECT_INTERSECT_BLOCK(fm->file_space, coords, end)) {
- H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
+ if (TRUE == H5S_SELECT_INTERSECT_BLOCK(dinfo->file_space, coords, end)) {
+ H5D_piece_info_t *new_piece_info; /* chunk information to insert into skip list */
hsize_t chunk_points; /* Number of elements in chunk selection */
/* Create dataspace for chunk, 'AND'ing the overall selection with
* the current chunk.
*/
- if (H5S_combine_hyperslab(fm->file_space, H5S_SELECT_AND, coords, NULL, fm->chunk_dim, NULL,
+ if (H5S_combine_hyperslab(dinfo->file_space, H5S_SELECT_AND, coords, NULL, fm->chunk_dim, NULL,
&tmp_fchunk) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL,
"unable to combine file space selection with chunk block")
@@ -1879,42 +1873,42 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
/* Add temporary chunk to the list of chunks */
/* Allocate the file & memory chunk information */
- if (NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
+ if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info")
/* Initialize the chunk information */
/* Set the chunk index */
- new_chunk_info->index = chunk_index;
-
-#ifdef H5_HAVE_PARALLEL
- /* Store chunk selection information, for multi-chunk I/O */
- if (io_info->using_mpi_vfd)
- fm->select_chunk[chunk_index] = new_chunk_info;
-#endif /* H5_HAVE_PARALLEL */
+ new_piece_info->index = chunk_index;
/* Set the file chunk dataspace */
- new_chunk_info->fspace = tmp_fchunk;
- new_chunk_info->fspace_shared = FALSE;
+ new_piece_info->fspace = tmp_fchunk;
+ new_piece_info->fspace_shared = FALSE;
tmp_fchunk = NULL;
/* Set the memory chunk dataspace */
- new_chunk_info->mspace = NULL;
- new_chunk_info->mspace_shared = FALSE;
+ new_piece_info->mspace = NULL;
+ new_piece_info->mspace_shared = FALSE;
/* Copy the chunk's scaled coordinates */
- H5MM_memcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
- new_chunk_info->scaled[fm->f_ndims] = 0;
+ H5MM_memcpy(new_piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
+ new_piece_info->scaled[fm->f_ndims] = 0;
- /* Insert the new chunk into the skip list */
- if (H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) {
- H5D__free_chunk_info(new_chunk_info, NULL, NULL);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
+ /* make connection to related dset info from this piece_info */
+ new_piece_info->dset_info = dinfo;
+
+ /* Add piece to global piece_count */
+ io_info->piece_count++;
+
+ /* Insert the new piece into the skip list */
+ if (H5SL_insert(fm->dset_sel_pieces, new_piece_info, &new_piece_info->index) < 0) {
+ H5D__free_piece_info(new_piece_info, NULL, NULL);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert piece into skip list")
} /* end if */
/* Get number of elements selected in chunk */
- chunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace);
- H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, chunk_points, hsize_t);
+ chunk_points = H5S_GET_SELECT_NPOINTS(new_piece_info->fspace);
+ new_piece_info->piece_points = chunk_points;
/* Decrement # of points left in file selection */
sel_points -= chunk_points;
@@ -1957,7 +1951,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
} while (curr_dim >= 0 && (coords[curr_dim] > sel_end[curr_dim]));
/* Re-calculate the index of this chunk */
- chunk_index = H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, scaled);
+ chunk_index = H5VM_array_offset_pre(fm->f_ndims, dinfo->layout->u.chunk.down_chunks, scaled);
} /* end if */
} /* end while */
@@ -1968,28 +1962,29 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't release temporary dataspace")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__create_chunk_file_map_hyper() */
+} /* end H5D__create_piece_file_map_hyper() */
/*-------------------------------------------------------------------------
- * Function: H5D__create_chunk_mem_map_hyper
+ * Function: H5D__create_piece_mem_map_hyper
*
- * Purpose: Create all chunk selections in memory by copying the file
+ * Purpose: Create all chunk selections in memory by copying the file
* chunk selections and adjusting their offsets to be correct
- * for the memory.
+ * or the memory.
+ * This was derived from H5D__create_chunk_mem_map_hyper for
+ * multi-dset work.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Thursday, May 29, 2003
+ * Programmer: Jonathan Kim Nov, 2013
*
* Assumptions: That the file and memory selections are the same shape.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
+H5D__create_piece_mem_map_hyper(const H5D_dset_io_info_t *dinfo)
{
- H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5D_piece_info_t *piece_info; /* Pointer to piece information */
H5SL_node_t *curr_node; /* Current node in skip list */
hsize_t file_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */
hsize_t file_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */
@@ -2002,30 +1997,33 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
FUNC_ENTER_PACKAGE
/* Sanity check */
- HDassert(fm->f_ndims > 0);
+ HDassert(dinfo->layout_io_info.chunk_map->f_ndims > 0);
+
+ /* Set convenience pointer */
+ fm = dinfo->layout_io_info.chunk_map;
/* Check for all I/O going to a single chunk */
- if (H5SL_count(fm->sel_chunks) == 1) {
+ if (H5SL_count(fm->dset_sel_pieces) == 1) {
/* Get the node */
- curr_node = H5SL_first(fm->sel_chunks);
+ curr_node = H5SL_first(fm->dset_sel_pieces);
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
+ /* Get pointer to piece's information */
+ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
+ HDassert(piece_info);
/* Just point at the memory dataspace & selection */
- chunk_info->mspace = fm->mem_space;
+ piece_info->mspace = dinfo->mem_space;
- /* Indicate that the chunk's memory space is shared */
- chunk_info->mspace_shared = TRUE;
+ /* Indicate that the piece's memory space is shared */
+ piece_info->mspace_shared = TRUE;
} /* end if */
else {
/* Get bounding box for file selection */
- if (H5S_SELECT_BOUNDS(fm->file_space, file_sel_start, file_sel_end) < 0)
+ if (H5S_SELECT_BOUNDS(dinfo->file_space, file_sel_start, file_sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Get bounding box for memory selection */
- if (H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0)
+ if (H5S_SELECT_BOUNDS(dinfo->mem_space, mem_sel_start, mem_sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Calculate the adjustment for memory selection from file selection */
@@ -2037,28 +2035,29 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
} /* end for */
/* Iterate over each chunk in the chunk list */
- curr_node = H5SL_first(fm->sel_chunks);
+ HDassert(fm->dset_sel_pieces);
+ curr_node = H5SL_first(fm->dset_sel_pieces);
while (curr_node) {
hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
- hssize_t chunk_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */
+ hssize_t piece_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */
H5S_sel_type chunk_sel_type; /* Chunk's selection type */
- /* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
+ /* Get pointer to piece's information */
+ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
+ HDassert(piece_info);
/* Compute the chunk coordinates from the scaled coordinates */
for (u = 0; u < fm->f_ndims; u++)
- coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u];
+ coords[u] = piece_info->scaled[u] * dinfo->layout->u.chunk.dim[u];
/* Copy the information */
/* Copy the memory dataspace */
- if ((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
+ if ((piece_info->mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
/* Get the chunk's selection type */
- if ((chunk_sel_type = H5S_GET_SELECT_TYPE(chunk_info->fspace)) < H5S_SEL_NONE)
+ if ((chunk_sel_type = H5S_GET_SELECT_TYPE(piece_info->fspace)) < H5S_SEL_NONE)
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
/* Set memory selection for "all" chunk selections */
@@ -2068,7 +2067,7 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
coords[u] = (hsize_t)((hssize_t)coords[u] - adjust[u]);
/* Set to same shape as chunk */
- if (H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, coords, NULL, fm->chunk_dim,
+ if (H5S_select_hyperslab(piece_info->mspace, H5S_SELECT_SET, coords, NULL, fm->chunk_dim,
NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection")
} /* end if */
@@ -2077,32 +2076,32 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
HDassert(H5S_SEL_HYPERSLABS == chunk_sel_type);
/* Copy the file chunk's selection */
- if (H5S_SELECT_COPY(chunk_info->mspace, chunk_info->fspace, FALSE) < 0)
+ if (H5S_SELECT_COPY(piece_info->mspace, piece_info->fspace, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection")
/* Compute the adjustment for this chunk */
for (u = 0; u < fm->f_ndims; u++) {
/* Compensate for the chunk offset */
H5_CHECK_OVERFLOW(coords[u], hsize_t, hssize_t);
- chunk_adjust[u] = adjust[u] - (hssize_t)coords[u];
+ piece_adjust[u] = adjust[u] - (hssize_t)coords[u];
} /* end for */
/* Adjust the selection */
- if (H5S_SELECT_ADJUST_S(chunk_info->mspace, chunk_adjust) < 0)
+ if (H5S_SELECT_ADJUST_S(piece_info->mspace, piece_adjust) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection")
} /* end else */
- /* Get the next chunk node in the skip list */
+ /* Get the next piece node in the skip list */
curr_node = H5SL_next(curr_node);
} /* end while */
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__create_chunk_mem_map_hyper() */
+} /* end H5D__create_piece_mem_map_hyper() */
/*-------------------------------------------------------------------------
- * Function: H5D__create_mem_map_1d
+ * Function: H5D__create_piece_mem_map_1d
*
* Purpose: Create all chunk selections for 1-dimensional regular memory space
* that has only one single block in the selection
@@ -2115,31 +2114,36 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
+H5D__create_piece_mem_map_1d(const H5D_dset_io_info_t *dinfo)
{
- H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5D_piece_info_t *piece_info; /* Pointer to chunk information */
H5SL_node_t *curr_node; /* Current node in skip list */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
- HDassert(fm->f_ndims > 0);
+ HDassert(dinfo->layout_io_info.chunk_map->f_ndims > 0);
+
+ /* Set convenience pointer */
+ fm = dinfo->layout_io_info.chunk_map;
+ HDassert(fm);
/* Check for all I/O going to a single chunk */
- if (H5SL_count(fm->sel_chunks) == 1) {
+ if (H5SL_count(fm->dset_sel_pieces) == 1) {
/* Get the node */
- curr_node = H5SL_first(fm->sel_chunks);
+ curr_node = H5SL_first(fm->dset_sel_pieces);
/* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
+ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
+ HDassert(piece_info);
/* Just point at the memory dataspace & selection */
- chunk_info->mspace = fm->mem_space;
+ piece_info->mspace = dinfo->mem_space;
/* Indicate that the chunk's memory space is shared */
- chunk_info->mspace_shared = TRUE;
+ piece_info->mspace_shared = TRUE;
} /* end if */
else {
hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */
@@ -2147,26 +2151,26 @@ H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
HDassert(fm->m_ndims == 1);
- if (H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0)
+ if (H5S_SELECT_BOUNDS(dinfo->mem_space, mem_sel_start, mem_sel_end) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Iterate over each chunk in the chunk list */
- curr_node = H5SL_first(fm->sel_chunks);
+ curr_node = H5SL_first(fm->dset_sel_pieces);
while (curr_node) {
hsize_t chunk_points; /* Number of elements in chunk selection */
hsize_t tmp_count = 1;
/* Get pointer to chunk's information */
- chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
- HDassert(chunk_info);
+ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
+ HDassert(piece_info);
/* Copy the memory dataspace */
- if ((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
+ if ((piece_info->mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
- chunk_points = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
+ chunk_points = H5S_GET_SELECT_NPOINTS(piece_info->fspace);
- if (H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, mem_sel_start, NULL, &tmp_count,
+ if (H5S_select_hyperslab(piece_info->mspace, H5S_SELECT_SET, mem_sel_start, NULL, &tmp_count,
&chunk_points) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection")
@@ -2179,177 +2183,187 @@ H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__create_chunk_mem_map_1d() */
+} /* end H5D__create_piece_mem_map_1d() */
/*-------------------------------------------------------------------------
- * Function: H5D__chunk_file_cb
+ * Function: H5D__piece_file_cb
*
- * Purpose: Callback routine for file selection iterator. Used when
+ * Purpose: Callback routine for file selection iterator. Used when
* creating selections in file for each point selected.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Wednesday, July 23, 2003
+ * Programmer: Jonathan Kim Nov, 2013
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
- const hsize_t *coords, void *_udata)
+H5D__piece_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
+ const hsize_t *coords, void *_opdata)
{
- H5D_chunk_file_iter_ud_t *udata = (H5D_chunk_file_iter_ud_t *)_udata; /* User data for operation */
- H5D_chunk_map_t *fm = udata->fm; /* File<->memory chunk mapping info */
- H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
- hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
- hsize_t chunk_index; /* Chunk index */
- hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_io_info_wrap_t *opdata = (H5D_io_info_wrap_t *)_opdata;
+ H5D_io_info_t *io_info = (H5D_io_info_t *)opdata->io_info; /* io info for multi dset */
+ H5D_dset_io_info_t *dinfo = (H5D_dset_io_info_t *)opdata->dinfo; /* File<->memory piece mapping info */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ H5D_piece_info_t *piece_info; /* Chunk information for current piece */
+ hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
+ hsize_t chunk_index; /* Chunk index */
+ hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
+ /* Set convenience pointer */
+ fm = dinfo->layout_io_info.chunk_map;
+
/* Calculate the index of this chunk */
- chunk_index = H5VM_chunk_index_scaled(ndims, coords, fm->layout->u.chunk.dim,
- fm->layout->u.chunk.down_chunks, scaled);
+ chunk_index = H5VM_chunk_index_scaled(ndims, coords, dinfo->layout->u.chunk.dim,
+ dinfo->layout->u.chunk.down_chunks, scaled);
/* Find correct chunk in file & memory skip list */
if (chunk_index == fm->last_index) {
/* If the chunk index is the same as the last chunk index we used,
* get the cached info to operate on.
*/
- chunk_info = fm->last_chunk_info;
+ piece_info = fm->last_piece_info;
} /* end if */
else {
/* If the chunk index is not the same as the last chunk index we used,
- * find the chunk in the skip list.
- */
- /* Get the chunk node from the skip list */
- if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index))) {
+ * find the chunk in the skip list. If we do not find it, create
+ * a new node. */
+ if (NULL == (piece_info = (H5D_piece_info_t *)H5SL_search(fm->dset_sel_pieces, &chunk_index))) {
H5S_t *fspace; /* Memory chunk's dataspace */
/* Allocate the file & memory chunk information */
- if (NULL == (chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
+ if (NULL == (piece_info = H5FL_MALLOC(H5D_piece_info_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
/* Initialize the chunk information */
/* Set the chunk index */
- chunk_info->index = chunk_index;
+ piece_info->index = chunk_index;
/* Create a dataspace for the chunk */
if ((fspace = H5S_create_simple(fm->f_ndims, fm->chunk_dim, NULL)) == NULL) {
- chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
+ piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace for chunk")
} /* end if */
/* De-select the chunk space */
if (H5S_select_none(fspace) < 0) {
(void)H5S_close(fspace);
- chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
+ piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select dataspace")
} /* end if */
/* Set the file chunk dataspace */
- chunk_info->fspace = fspace;
- chunk_info->fspace_shared = FALSE;
+ piece_info->fspace = fspace;
+ piece_info->fspace_shared = FALSE;
/* Set the memory chunk dataspace */
- chunk_info->mspace = NULL;
- chunk_info->mspace_shared = FALSE;
+ piece_info->mspace = NULL;
+ piece_info->mspace_shared = FALSE;
/* Set the number of selected elements in chunk to zero */
- chunk_info->chunk_points = 0;
+ piece_info->piece_points = 0;
/* Set the chunk's scaled coordinates */
- H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
- chunk_info->scaled[fm->f_ndims] = 0;
+ H5MM_memcpy(piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
+ piece_info->scaled[fm->f_ndims] = 0;
+
+ /* Make connection to related dset info from this piece_info */
+ piece_info->dset_info = dinfo;
/* Insert the new chunk into the skip list */
- if (H5SL_insert(fm->sel_chunks, chunk_info, &chunk_info->index) < 0) {
- H5D__free_chunk_info(chunk_info, NULL, NULL);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
+ if (H5SL_insert(fm->dset_sel_pieces, piece_info, &piece_info->index) < 0) {
+ H5D__free_piece_info(piece_info, NULL, NULL);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into dataset skip list")
} /* end if */
- } /* end if */
-#ifdef H5_HAVE_PARALLEL
- /* Store chunk selection information, for collective multi-chunk I/O */
- if (udata->io_info->using_mpi_vfd)
- fm->select_chunk[chunk_index] = chunk_info;
-#endif /* H5_HAVE_PARALLEL */
+ /* Add piece to global piece_count */
+ io_info->piece_count++;
+ } /* end if */
/* Update the "last chunk seen" information */
fm->last_index = chunk_index;
- fm->last_chunk_info = chunk_info;
+ fm->last_piece_info = piece_info;
} /* end else */
/* Get the offset of the element within the chunk */
for (u = 0; u < fm->f_ndims; u++)
- coords_in_chunk[u] = coords[u] - (scaled[u] * fm->layout->u.chunk.dim[u]);
+ coords_in_chunk[u] = coords[u] - (scaled[u] * dinfo->layout->u.chunk.dim[u]);
/* Add point to file selection for chunk */
- if (H5S_select_elements(chunk_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
+ if (H5S_select_elements(piece_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
/* Increment the number of elemented selected in chunk */
- chunk_info->chunk_points++;
+ piece_info->piece_points++;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__chunk_file_cb() */
+} /* end H5D__piece_file_cb */
/*-------------------------------------------------------------------------
- * Function: H5D__chunk_mem_cb
+ * Function: H5D__piece_mem_cb
*
- * Purpose: Callback routine for file selection iterator. Used when
- * creating selections in memory for each chunk.
+ * Purpose: Callback routine for file selection iterator. Used when
+ * creating selections in memory for each piece.
+ * This was derived from H5D__chunk_mem_cb for multi-dset
+ * work.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Raymond Lu
- * Thursday, April 10, 2003
+ * Programmer: Jonathan Kim Nov, 2013
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
- const hsize_t *coords, void *_fm)
+H5D__piece_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
+ const hsize_t *coords, void *_opdata)
{
- H5D_chunk_map_t *fm = (H5D_chunk_map_t *)_fm; /* File<->memory chunk mapping info */
- H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
- hsize_t coords_in_mem[H5S_MAX_RANK]; /* Coordinates of element in memory */
- hsize_t chunk_index; /* Chunk index */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5D_io_info_wrap_t *opdata = (H5D_io_info_wrap_t *)_opdata;
+ H5D_dset_io_info_t *dinfo = (H5D_dset_io_info_t *)opdata->dinfo; /* File<->memory chunk mapping info */
+ H5D_piece_info_t *piece_info; /* Chunk information for current chunk */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ hsize_t coords_in_mem[H5S_MAX_RANK]; /* Coordinates of element in memory */
+ hsize_t chunk_index; /* Chunk index */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
+ /* Set convenience pointer */
+ fm = dinfo->layout_io_info.chunk_map;
+
/* Calculate the index of this chunk */
- chunk_index = H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks);
+ chunk_index =
+ H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, dinfo->layout->u.chunk.down_chunks);
/* Find correct chunk in file & memory skip list */
if (chunk_index == fm->last_index) {
/* If the chunk index is the same as the last chunk index we used,
* get the cached spaces to operate on.
*/
- chunk_info = fm->last_chunk_info;
+ piece_info = fm->last_piece_info;
} /* end if */
else {
/* If the chunk index is not the same as the last chunk index we used,
- * find the chunk in the skip list.
+ * find the chunk in the dataset skip list.
*/
/* Get the chunk node from the skip list */
- if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, H5_ITER_ERROR, "can't locate chunk in skip list")
+ if (NULL == (piece_info = (H5D_piece_info_t *)H5SL_search(fm->dset_sel_pieces, &chunk_index)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, H5_ITER_ERROR, "can't locate piece in dataset skip list")
/* Check if the chunk already has a memory space */
- if (NULL == chunk_info->mspace)
+ if (NULL == piece_info->mspace)
/* Copy the template memory chunk dataspace */
- if (NULL == (chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)))
+ if (NULL == (piece_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy file space")
/* Update the "last chunk seen" information */
fm->last_index = chunk_index;
- fm->last_chunk_info = chunk_info;
+ fm->last_piece_info = piece_info;
} /* end else */
/* Get coordinates of selection iterator for memory */
@@ -2358,11 +2372,11 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u
/* Add point to memory selection for chunk */
if (fm->msel_type == H5S_SEL_POINTS) {
- if (H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
+ if (H5S_select_elements(piece_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select element")
} /* end if */
else {
- if (H5S_hyper_add_span_element(chunk_info->mspace, fm->m_ndims, coords_in_mem) < 0)
+ if (H5S_hyper_add_span_element(piece_info->mspace, fm->m_ndims, coords_in_mem) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select element")
} /* end else */
@@ -2372,7 +2386,62 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5D__chunk_mem_cb() */
+} /* end H5D__piece_mem_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__chunk_mdio_init
+ *
+ * Purpose: Performs second phase of initialization for multi-dataset
+ * I/O. Currently looks up chunk addresses and adds chunks to
+ * sel_pieces.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__chunk_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
+{
+ H5SL_node_t *piece_node; /* Current node in chunk skip list */
+ H5D_piece_info_t *piece_info; /* Piece information for current piece */
+ H5D_chunk_ud_t udata; /* Chunk data from index */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Get first node in skip list. Note we don't check for failure since NULL
+ * simply indicates an empty skip list. */
+ piece_node = H5D_CHUNK_GET_FIRST_NODE(dinfo);
+
+ /* Iterate over skip list */
+ while (piece_node) {
+ /* Get piece info */
+ if (NULL == (piece_info = (H5D_piece_info_t *)H5D_CHUNK_GET_NODE_INFO(dinfo, piece_node)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get piece info from list")
+
+ /* Get the info for the chunk in the file */
+ if (H5D__chunk_lookup(dinfo->dset, piece_info->scaled, &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
+
+ /* Save chunk file address */
+ piece_info->faddr = udata.chunk_block.offset;
+
+ /* Add piece to MDIO operation if it has a file address */
+ if (H5F_addr_defined(piece_info->faddr)) {
+ HDassert(io_info->sel_pieces);
+ HDassert(io_info->pieces_added < io_info->piece_count);
+
+ /* Add to sel_pieces and update pieces_added */
+ io_info->sel_pieces[io_info->pieces_added++] = piece_info;
+ }
+
+ /* Advance to next skip list node */
+ piece_node = H5D_CHUNK_GET_NEXT_NODE(dinfo, piece_node);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__chunk_mdio_init() */
/*-------------------------------------------------------------------------
* Function: H5D__chunk_cacheable
@@ -2388,16 +2457,19 @@ done:
*-------------------------------------------------------------------------
*/
htri_t
-H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op)
+H5D__chunk_cacheable(const H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, haddr_t caddr,
+ hbool_t write_op)
{
- const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
- hbool_t has_filters = FALSE; /* Whether there are filters on the chunk or not */
- htri_t ret_value = FAIL; /* Return value */
+ const H5D_t *dataset = NULL; /* Local pointer to dataset info */
+ hbool_t has_filters = FALSE; /* Whether there are filters on the chunk or not */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(io_info);
+ HDassert(dset_info);
+ dataset = dset_info->dset;
HDassert(dataset);
/* Must bring the whole chunk in if there are any filters on the chunk.
@@ -2405,9 +2477,9 @@ H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_
* chunk because it is a partial edge chunk. */
if (dataset->shared->dcpl_cache.pline.nused > 0) {
if (dataset->shared->layout.u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
- has_filters = !H5D__chunk_is_partial_edge_chunk(
- io_info->dset->shared->ndims, io_info->dset->shared->layout.u.chunk.dim,
- io_info->store->chunk.scaled, io_info->dset->shared->curr_dims);
+ has_filters =
+ !H5D__chunk_is_partial_edge_chunk(dataset->shared->ndims, dataset->shared->layout.u.chunk.dim,
+ dset_info->store->chunk.scaled, dataset->shared->curr_dims);
} /* end if */
else
has_filters = TRUE;
@@ -2478,7 +2550,7 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info)
+H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
{
const H5D_t *dataset = NULL; /* Local pointer to dataset info */
htri_t ret_value = FAIL; /* Return value */
@@ -2487,19 +2559,19 @@ H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info)
/* Sanity check */
HDassert(io_info);
+ HDassert(dset_info);
- dataset = io_info->dset;
+ dataset = dset_info->dset;
HDassert(dataset);
/* Don't use selection I/O if it's globally disabled, there is a type
* conversion, or if there are filters on the dataset (for now) */
- if (!H5_use_selection_io_g || io_info->io_ops.single_read != H5D__select_read ||
- dataset->shared->dcpl_cache.pline.nused > 0)
+ if (dset_info->io_ops.single_read != H5D__select_read || dataset->shared->dcpl_cache.pline.nused > 0)
ret_value = FALSE;
else {
hbool_t page_buf_enabled;
- HDassert(io_info->io_ops.single_write == H5D__select_write);
+ HDassert(dset_info->io_ops.single_write == H5D__select_write);
/* Check if the page buffer is enabled */
if (H5PB_enabled(io_info->f_sh, H5FD_MEM_DRAW, &page_buf_enabled) < 0)
@@ -2549,36 +2621,40 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
- H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
+H5D__chunk_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
{
- H5SL_node_t *chunk_node; /* Current node in chunk skip list */
- H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
- uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
- hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
- H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
- H5S_t *chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
- H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
- H5S_t *chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
- haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
- haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
- herr_t ret_value = SUCCEED; /*return value */
+ H5SL_node_t *chunk_node; /* Current node in chunk skip list */
+ H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
+ H5D_dset_io_info_t nonexistent_dset_info; /* "nonexistent" I/O dset info object */
+ H5D_dset_io_info_t ctg_dset_info; /* Contiguous I/O dset info object */
+ H5D_dset_io_info_t cpt_dset_info; /* Compact I/O dset info object */
+ uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
+ hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
+ H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
+ H5S_t *chunk_mem_spaces_local[8]; /* Local buffer for chunk_mem_spaces */
+ H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
+ H5S_t *chunk_file_spaces_local[8]; /* Local buffer for chunk_file_spaces */
+ haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
+ haddr_t chunk_addrs_local[8]; /* Local buffer for chunk_addrs */
+ herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(io_info);
- HDassert(io_info->u.rbuf);
- HDassert(type_info);
- HDassert(fm);
+ HDassert(dset_info);
+ HDassert(dset_info->buf.vp);
/* Set up "nonexistent" I/O info object */
H5MM_memcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info));
- nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT;
+ H5MM_memcpy(&nonexistent_dset_info, dset_info, sizeof(nonexistent_dset_info));
+ nonexistent_dset_info.layout_ops = *H5D_LOPS_NONEXISTENT;
+ nonexistent_io_info.dsets_info = &nonexistent_dset_info;
+ nonexistent_io_info.count = 1;
{
- const H5O_fill_t *fill = &(io_info->dset->shared->dcpl_cache.fill); /* Fill value info */
- H5D_fill_value_t fill_status; /* Fill value status */
+ const H5O_fill_t *fill = &(dset_info->dset->shared->dcpl_cache.fill); /* Fill value info */
+ H5D_fill_value_t fill_status; /* Fill value status */
/* Check the fill value status */
if (H5P_is_fill_value_defined(fill, &fill_status) < 0)
@@ -2596,48 +2672,53 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
/* Different blocks depending on whether we're using selection I/O */
if (io_info->use_select_io) {
size_t num_chunks;
- size_t element_sizes[2] = {type_info->dst_type_size, 0};
- void *bufs[2] = {io_info->u.rbuf, NULL};
-
- /* Cache number of chunks */
- num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
-
- /* Allocate arrays of dataspaces and offsets for use with selection I/O,
- * or point to static buffers */
- HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
- sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
- HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
- sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
- if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
- if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for memory space list")
- if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
- if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for chunk address list")
- } /* end if */
- else {
- chunk_mem_spaces = chunk_mem_spaces_static;
- chunk_file_spaces = chunk_file_spaces_static;
- chunk_addrs = chunk_addrs_static;
- } /* end else */
+ size_t element_sizes[2] = {dset_info->type_info.src_type_size, 0};
+ void *bufs[2] = {dset_info->buf.vp, NULL};
+
+ /* Only create selection I/O arrays if not performing multi dataset I/O,
+ * otherwise the higher level will handle it */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ /* Cache number of chunks */
+ num_chunks = H5D_CHUNK_GET_NODE_COUNT(dset_info);
+
+ /* Allocate arrays of dataspaces and offsets for use with selection I/O,
+ * or point to local buffers */
+ HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
+ sizeof(chunk_file_spaces_local) / sizeof(chunk_file_spaces_local[0]));
+ HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
+ sizeof(chunk_addrs_local) / sizeof(chunk_addrs_local[0]));
+ if (num_chunks > (sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]))) {
+ if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for memory space list")
+ if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for file space list")
+ if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for chunk address list")
+ } /* end if */
+ else {
+ chunk_mem_spaces = chunk_mem_spaces_local;
+ chunk_file_spaces = chunk_file_spaces_local;
+ chunk_addrs = chunk_addrs_local;
+ } /* end else */
- /* Reset num_chunks */
- num_chunks = 0;
+ /* Reset num_chunks */
+ num_chunks = 0;
+ } /* end if */
/* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
+ chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
while (chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
+ H5D_piece_info_t *chunk_info; /* Chunk information */
H5D_chunk_ud_t udata; /* Chunk index pass-through */
/* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
/* Get the info for the chunk in the file */
- if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
+ if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* There should be no chunks cached */
@@ -2649,45 +2730,66 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
/* Check for non-existent chunk & skip it if appropriate */
if (H5F_addr_defined(udata.chunk_block.offset)) {
- /* Add chunk to list for selection I/O */
- chunk_mem_spaces[num_chunks] = chunk_info->mspace;
- chunk_file_spaces[num_chunks] = chunk_info->fspace;
- chunk_addrs[num_chunks] = udata.chunk_block.offset;
- num_chunks++;
+ /* Add chunk to list for selection I/O, if not performing multi dataset I/O */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ chunk_mem_spaces[num_chunks] = chunk_info->mspace;
+ chunk_file_spaces[num_chunks] = chunk_info->fspace;
+ chunk_addrs[num_chunks] = udata.chunk_block.offset;
+ num_chunks++;
+ } /* end if */
+ else {
+ /* Add to mdset selection I/O arrays */
+ HDassert(io_info->mem_spaces);
+ HDassert(io_info->file_spaces);
+ HDassert(io_info->addrs);
+ HDassert(io_info->element_sizes);
+ HDassert(io_info->rbufs);
+ HDassert(io_info->pieces_added < io_info->piece_count);
+
+ io_info->mem_spaces[io_info->pieces_added] = chunk_info->mspace;
+ io_info->file_spaces[io_info->pieces_added] = chunk_info->fspace;
+ io_info->addrs[io_info->pieces_added] = udata.chunk_block.offset;
+ io_info->element_sizes[io_info->pieces_added] = element_sizes[0];
+ io_info->rbufs[io_info->pieces_added] = bufs[0];
+ io_info->pieces_added++;
+ }
} /* end if */
else if (!skip_missing_chunks) {
/* Perform the actual read operation from the nonexistent chunk
*/
- if ((io_info->io_ops.single_read)(&nonexistent_io_info, type_info,
- (hsize_t)chunk_info->chunk_points, chunk_info->fspace,
- chunk_info->mspace) < 0)
+ nonexistent_dset_info.file_space = chunk_info->fspace;
+ nonexistent_dset_info.mem_space = chunk_info->mspace;
+ nonexistent_dset_info.nelmts = chunk_info->piece_points;
+ if ((dset_info->io_ops.single_read)(&nonexistent_io_info, &nonexistent_dset_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
} /* end if */
/* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
} /* end while */
- /* Issue selection I/O call (we can skip the page buffer because we've
- * already verified it won't be used, and the metadata accumulator
- * because this is raw data) */
- if (H5F_shared_select_read(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
- chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes, bufs) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
-
- /* Clean up memory */
- if (chunk_mem_spaces != chunk_mem_spaces_static) {
- HDassert(chunk_mem_spaces);
- HDassert(chunk_file_spaces != chunk_file_spaces_static);
- HDassert(chunk_addrs != chunk_addrs_static);
- H5MM_free(chunk_mem_spaces);
- chunk_mem_spaces = NULL;
- H5MM_free(chunk_file_spaces);
- chunk_file_spaces = NULL;
- H5MM_free(chunk_addrs);
- chunk_addrs = NULL;
- } /* end if */
- } /* end if */
+ /* Only perform I/O if not performing multi dataset I/O, otherwise the
+ * higher level will handle it after all datasets have been processed */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ /* Issue selection I/O call (we can skip the page buffer because we've
+ * already verified it won't be used, and the metadata accumulator
+ * because this is raw data) */
+ H5_CHECK_OVERFLOW(num_chunks, size_t, uint32_t)
+ if (H5F_shared_select_read(H5F_SHARED(dset_info->dset->oloc.file), H5FD_MEM_DRAW,
+ (uint32_t)num_chunks, chunk_mem_spaces, chunk_file_spaces, chunk_addrs,
+ element_sizes, bufs) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
+
+ /* Clean up memory */
+ if (chunk_mem_spaces != chunk_mem_spaces_local) {
+ HDassert(chunk_file_spaces != chunk_file_spaces_local);
+ HDassert(chunk_addrs != chunk_addrs_local);
+ chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
+ chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
+ chunk_addrs = H5MM_xfree(chunk_addrs);
+ } /* end if */
+ } /* end if */
+ } /* end if */
else {
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
@@ -2697,33 +2799,39 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
/* Set up contiguous I/O info object */
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
- ctg_io_info.store = &ctg_store;
- ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
+ HDmemcpy(&ctg_dset_info, dset_info, sizeof(ctg_dset_info));
+ ctg_dset_info.store = &ctg_store;
+ ctg_dset_info.layout_ops = *H5D_LOPS_CONTIG;
+ ctg_io_info.dsets_info = &ctg_dset_info;
+ ctg_io_info.count = 1;
/* Initialize temporary contiguous storage info */
- H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
+ H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, dset_info->dset->shared->layout.u.chunk.size,
uint32_t);
/* Set up compact I/O info object */
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
- cpt_io_info.store = &cpt_store;
- cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
+ HDmemcpy(&cpt_dset_info, dset_info, sizeof(cpt_dset_info));
+ cpt_dset_info.store = &cpt_store;
+ cpt_dset_info.layout_ops = *H5D_LOPS_COMPACT;
+ cpt_io_info.dsets_info = &cpt_dset_info;
+ cpt_io_info.count = 1;
/* Initialize temporary compact storage info */
cpt_store.compact.dirty = &cpt_dirty;
/* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
+ chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
while (chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
+ H5D_piece_info_t *chunk_info; /* Chunk information */
H5D_chunk_ud_t udata; /* Chunk index pass-through */
htri_t cacheable; /* Whether the chunk is cacheable */
/* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
/* Get the info for the chunk in the file */
- if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
+ if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Sanity check */
@@ -2737,20 +2845,23 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
void *chunk = NULL; /* Pointer to locked chunk buffer */
/* Set chunk's [scaled] coordinates */
- io_info->store->chunk.scaled = chunk_info->scaled;
+ dset_info->store->chunk.scaled = chunk_info->scaled;
/* Determine if we should use the chunk cache */
- if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, FALSE)) < 0)
+ if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, FALSE)) <
+ 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
if (cacheable) {
/* Load the chunk into cache and lock it. */
/* Compute # of bytes accessed in chunk */
- H5_CHECK_OVERFLOW(type_info->src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
- src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size;
+ H5_CHECK_OVERFLOW(dset_info->type_info.src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
+ H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
+ src_accessed_bytes =
+ (uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.src_type_size;
/* Lock the chunk into the cache */
- if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE)))
+ if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, FALSE, FALSE)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -2772,35 +2883,39 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
} /* end else */
/* Perform the actual read operation */
- if ((io_info->io_ops.single_read)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
- chunk_info->fspace, chunk_info->mspace) < 0)
+ HDassert(chk_io_info->count == 1);
+ chk_io_info->dsets_info[0].file_space = chunk_info->fspace;
+ chk_io_info->dsets_info[0].mem_space = chunk_info->mspace;
+ chk_io_info->dsets_info[0].nelmts = chunk_info->piece_points;
+ if ((dset_info->io_ops.single_read)(chk_io_info, &chk_io_info->dsets_info[0]) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
/* Release the cache lock on the chunk. */
- if (chunk && H5D__chunk_unlock(io_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
+ if (chunk &&
+ H5D__chunk_unlock(io_info, dset_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
/* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
} /* end while */
} /* end else */
done:
/* Cleanup on failure */
if (ret_value < 0) {
- if (chunk_mem_spaces != chunk_mem_spaces_static)
+ if (chunk_mem_spaces != chunk_mem_spaces_local)
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
- if (chunk_file_spaces != chunk_file_spaces_static)
+ if (chunk_file_spaces != chunk_file_spaces_local)
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
- if (chunk_addrs != chunk_addrs_static)
+ if (chunk_addrs != chunk_addrs_local)
chunk_addrs = H5MM_xfree(chunk_addrs);
} /* end if */
/* Make sure we cleaned up */
- HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
- HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
- HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
+ HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_local);
+ HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_local);
+ HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_local);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D__chunk_read() */
@@ -2818,45 +2933,51 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
- H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
+H5D__chunk_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
{
- H5SL_node_t *chunk_node; /* Current node in chunk skip list */
- H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
- H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
- H5D_io_info_t cpt_io_info; /* Compact I/O info object */
- H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
- hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
- uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
- H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
- H5S_t *chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
- H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
- H5S_t *chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
- haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
- haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5SL_node_t *chunk_node; /* Current node in chunk skip list */
+ H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
+ H5D_dset_io_info_t ctg_dset_info; /* Contiguous I/O dset info object */
+ H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
+ H5D_io_info_t cpt_io_info; /* Compact I/O info object */
+ H5D_dset_io_info_t cpt_dset_info; /* Compact I/O dset info object */
+ H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
+ hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
+ uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
+ H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
+ H5S_t *chunk_mem_spaces_local[8]; /* Local buffer for chunk_mem_spaces */
+ H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
+ H5S_t *chunk_file_spaces_local[8]; /* Local buffer for chunk_file_spaces */
+ haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
+ haddr_t chunk_addrs_local[8]; /* Local buffer for chunk_addrs */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(io_info);
- HDassert(io_info->u.wbuf);
- HDassert(type_info);
- HDassert(fm);
+ HDassert(dset_info);
+ HDassert(dset_info->buf.cvp);
/* Set up contiguous I/O info object */
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
- ctg_io_info.store = &ctg_store;
- ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
+ HDmemcpy(&ctg_dset_info, dset_info, sizeof(ctg_dset_info));
+ ctg_dset_info.store = &ctg_store;
+ ctg_dset_info.layout_ops = *H5D_LOPS_CONTIG;
+ ctg_io_info.dsets_info = &ctg_dset_info;
+ ctg_io_info.count = 1;
/* Initialize temporary contiguous storage info */
- H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
+ H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, dset_info->dset->shared->layout.u.chunk.size,
uint32_t);
/* Set up compact I/O info object */
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
- cpt_io_info.store = &cpt_store;
- cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
+ HDmemcpy(&cpt_dset_info, dset_info, sizeof(cpt_dset_info));
+ cpt_dset_info.store = &cpt_store;
+ cpt_dset_info.layout_ops = *H5D_LOPS_COMPACT;
+ cpt_io_info.dsets_info = &cpt_dset_info;
+ cpt_io_info.count = 1;
/* Initialize temporary compact storage info */
cpt_store.compact.dirty = &cpt_dirty;
@@ -2864,51 +2985,56 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
/* Different blocks depending on whether we're using selection I/O */
if (io_info->use_select_io) {
size_t num_chunks;
- size_t element_sizes[2] = {type_info->dst_type_size, 0};
- const void *bufs[2] = {io_info->u.wbuf, NULL};
-
- /* Cache number of chunks */
- num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
-
- /* Allocate arrays of dataspaces and offsets for use with selection I/O,
- * or point to static buffers */
- HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
- sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
- HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
- sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
- if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
- if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for memory space list")
- if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
- if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
- "memory allocation failed for chunk address list")
- } /* end if */
- else {
- chunk_mem_spaces = chunk_mem_spaces_static;
- chunk_file_spaces = chunk_file_spaces_static;
- chunk_addrs = chunk_addrs_static;
- } /* end else */
+ size_t element_sizes[2] = {dset_info->type_info.dst_type_size, 0};
+ const void *bufs[2] = {dset_info->buf.cvp, NULL};
+
+ /* Only create selection I/O arrays if not performing multi dataset I/O,
+ * otherwise the higher level will handle it */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ /* Cache number of chunks */
+ num_chunks = H5D_CHUNK_GET_NODE_COUNT(dset_info);
+
+ /* Allocate arrays of dataspaces and offsets for use with selection I/O,
+ * or point to local buffers */
+ HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
+ sizeof(chunk_file_spaces_local) / sizeof(chunk_file_spaces_local[0]));
+ HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
+ sizeof(chunk_addrs_local) / sizeof(chunk_addrs_local[0]));
+ if (num_chunks > (sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]))) {
+ if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for memory space list")
+ if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for file space list")
+ if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
+ "memory allocation failed for chunk address list")
+ } /* end if */
+ else {
+ chunk_mem_spaces = chunk_mem_spaces_local;
+ chunk_file_spaces = chunk_file_spaces_local;
+ chunk_addrs = chunk_addrs_local;
+ } /* end else */
- /* Reset num_chunks */
- num_chunks = 0;
+ /* Reset num_chunks */
+ num_chunks = 0;
+ } /* end if */
/* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
+ chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
while (chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
+ H5D_piece_info_t *chunk_info; /* Chunk information */
H5D_chk_idx_info_t idx_info; /* Chunked index info */
H5D_chunk_ud_t udata; /* Index pass-through */
htri_t cacheable; /* Whether the chunk is cacheable */
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
/* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
/* Get the info for the chunk in the file */
- if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
+ if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* There should be no chunks cached */
@@ -2919,10 +3045,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
/* Set chunk's [scaled] coordinates */
- io_info->store->chunk.scaled = chunk_info->scaled;
+ dset_info->store->chunk.scaled = chunk_info->scaled;
/* Determine if we should use the chunk cache */
- if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
+ if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
if (cacheable) {
/* Load the chunk into cache. But if the whole chunk is written,
@@ -2931,42 +3057,47 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
/* Compute # of bytes accessed in chunk */
- H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
- dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
+ H5_CHECK_OVERFLOW(dset_info->type_info.dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
+ H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
+ dst_accessed_bytes =
+ (uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.dst_type_size;
/* Determine if we will access all the data in the chunk */
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
- (chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
- fm->fsel_type == H5S_SEL_POINTS)
+ (chunk_info->piece_points * dset_info->type_info.src_type_size) !=
+ ctg_store.contig.dset_size ||
+ dset_info->layout_io_info.chunk_map->fsel_type == H5S_SEL_POINTS)
entire_chunk = FALSE;
/* Lock the chunk into the cache */
- if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
+ if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, entire_chunk, FALSE)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
cpt_store.compact.buf = chunk;
/* Perform the actual write operation */
- if ((io_info->io_ops.single_write)(&cpt_io_info, type_info, (hsize_t)chunk_info->chunk_points,
- chunk_info->fspace, chunk_info->mspace) < 0)
+ cpt_dset_info.file_space = chunk_info->fspace;
+ cpt_dset_info.mem_space = chunk_info->mspace;
+ cpt_dset_info.nelmts = chunk_info->piece_points;
+ if ((dset_info->io_ops.single_write)(&cpt_io_info, &cpt_dset_info) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
/* Release the cache lock on the chunk */
- if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
+ if (H5D__chunk_unlock(io_info, dset_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
else {
/* If the chunk hasn't been allocated on disk, do so now. */
if (!H5F_addr_defined(udata.chunk_block.offset)) {
/* Compose chunked index info struct */
- idx_info.f = io_info->dset->oloc.file;
- idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
- idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
- idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
+ idx_info.f = dset_info->dset->oloc.file;
+ idx_info.pline = &(dset_info->dset->shared->dcpl_cache.pline);
+ idx_info.layout = &(dset_info->dset->shared->layout.u.chunk);
+ idx_info.storage = &(dset_info->dset->shared->layout.storage.u.chunk);
/* Set up the size of chunk for user data */
- udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
+ udata.chunk_block.length = dset_info->dset->shared->layout.u.chunk.size;
/* Allocate the chunk */
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
@@ -2979,53 +3110,72 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
/* Cache the new chunk information */
- H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
+ H5D__chunk_cinfo_cache_update(&dset_info->dset->shared->cache.chunk.last, &udata);
/* Insert chunk into index */
- if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
- if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
- NULL) < 0)
+ if (need_insert && dset_info->dset->shared->layout.storage.u.chunk.ops->insert)
+ if ((dset_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
+ NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
"unable to insert chunk addr into index")
} /* end if */
- /* Add chunk to list for selection I/O */
- chunk_mem_spaces[num_chunks] = chunk_info->mspace;
- chunk_file_spaces[num_chunks] = chunk_info->fspace;
- chunk_addrs[num_chunks] = udata.chunk_block.offset;
- num_chunks++;
+ /* Add chunk to list for selection I/O, if not performing multi dataset I/O */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ chunk_mem_spaces[num_chunks] = chunk_info->mspace;
+ chunk_file_spaces[num_chunks] = chunk_info->fspace;
+ chunk_addrs[num_chunks] = udata.chunk_block.offset;
+ num_chunks++;
+ } /* end if */
+ else {
+ /* Add to mdset selection I/O arrays */
+ HDassert(io_info->mem_spaces);
+ HDassert(io_info->file_spaces);
+ HDassert(io_info->addrs);
+ HDassert(io_info->element_sizes);
+ HDassert(io_info->wbufs);
+ HDassert(io_info->pieces_added < io_info->piece_count);
+
+ io_info->mem_spaces[io_info->pieces_added] = chunk_info->mspace;
+ io_info->file_spaces[io_info->pieces_added] = chunk_info->fspace;
+ io_info->addrs[io_info->pieces_added] = udata.chunk_block.offset;
+ io_info->element_sizes[io_info->pieces_added] = element_sizes[0];
+ io_info->wbufs[io_info->pieces_added] = bufs[0];
+ io_info->pieces_added++;
+ }
} /* end else */
/* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
} /* end while */
- /* Issue selection I/O call (we can skip the page buffer because we've
- * already verified it won't be used, and the metadata accumulator
- * because this is raw data) */
- if (H5F_shared_select_write(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
- chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes,
- bufs) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
-
- /* Clean up memory */
- if (chunk_mem_spaces != chunk_mem_spaces_static) {
- HDassert(chunk_mem_spaces);
- HDassert(chunk_file_spaces != chunk_file_spaces_static);
- HDassert(chunk_addrs != chunk_addrs_static);
- H5MM_free(chunk_mem_spaces);
- chunk_mem_spaces = NULL;
- H5MM_free(chunk_file_spaces);
- chunk_file_spaces = NULL;
- H5MM_free(chunk_addrs);
- chunk_addrs = NULL;
- } /* end if */
- } /* end if */
+ /* Only perform I/O if not performing multi dataset I/O, otherwise the
+ * higher level will handle it after all datasets have been processed */
+ if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
+ /* Issue selection I/O call (we can skip the page buffer because we've
+ * already verified it won't be used, and the metadata accumulator
+ * because this is raw data) */
+ H5_CHECK_OVERFLOW(num_chunks, size_t, uint32_t)
+ if (H5F_shared_select_write(H5F_SHARED(dset_info->dset->oloc.file), H5FD_MEM_DRAW,
+ (uint32_t)num_chunks, chunk_mem_spaces, chunk_file_spaces,
+ chunk_addrs, element_sizes, bufs) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "chunk selection write failed")
+
+ /* Clean up memory */
+ if (chunk_mem_spaces != chunk_mem_spaces_local) {
+ HDassert(chunk_file_spaces != chunk_file_spaces_local);
+ HDassert(chunk_addrs != chunk_addrs_local);
+ chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
+ chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
+ chunk_addrs = H5MM_xfree(chunk_addrs);
+ } /* end if */
+ } /* end if */
+ } /* end if */
else {
/* Iterate through nodes in chunk skip list */
- chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
+ chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
while (chunk_node) {
- H5D_chunk_info_t *chunk_info; /* Chunk information */
+ H5D_piece_info_t *chunk_info; /* Chunk information */
H5D_chk_idx_info_t idx_info; /* Chunked index info */
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
void *chunk; /* Pointer to locked chunk buffer */
@@ -3034,10 +3184,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
/* Get the actual chunk information from the skip list node */
- chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
+ chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
/* Look up the chunk */
- if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
+ if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Sanity check */
@@ -3045,10 +3195,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
/* Set chunk's [scaled] coordinates */
- io_info->store->chunk.scaled = chunk_info->scaled;
+ dset_info->store->chunk.scaled = chunk_info->scaled;
/* Determine if we should use the chunk cache */
- if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
+ if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
if (cacheable) {
/* Load the chunk into cache. But if the whole chunk is written,
@@ -3056,17 +3206,20 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
/* Compute # of bytes accessed in chunk */
- H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
- dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
+ H5_CHECK_OVERFLOW(dset_info->type_info.dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
+ H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
+ dst_accessed_bytes =
+ (uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.dst_type_size;
/* Determine if we will access all the data in the chunk */
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
- (chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
- fm->fsel_type == H5S_SEL_POINTS)
+ (chunk_info->piece_points * dset_info->type_info.src_type_size) !=
+ ctg_store.contig.dset_size ||
+ dset_info->layout_io_info.chunk_map->fsel_type == H5S_SEL_POINTS)
entire_chunk = FALSE;
/* Lock the chunk into the cache */
- if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
+ if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, entire_chunk, FALSE)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -3079,13 +3232,13 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
/* If the chunk hasn't been allocated on disk, do so now. */
if (!H5F_addr_defined(udata.chunk_block.offset)) {
/* Compose chunked index info struct */
- idx_info.f = io_info->dset->oloc.file;
- idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
- idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
- idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
+ idx_info.f = dset_info->dset->oloc.file;
+ idx_info.pline = &(dset_info->dset->shared->dcpl_cache.pline);
+ idx_info.layout = &(dset_info->dset->shared->layout.u.chunk);
+ idx_info.storage = &(dset_info->dset->shared->layout.storage.u.chunk);
/* Set up the size of chunk for user data */
- udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
+ udata.chunk_block.length = dset_info->dset->shared->layout.u.chunk.size;
/* Allocate the chunk */
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
@@ -3098,7 +3251,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
/* Cache the new chunk information */
- H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
+ H5D__chunk_cinfo_cache_update(&dset_info->dset->shared->cache.chunk.last, &udata);
} /* end if */
/* Set up the storage address information for this chunk */
@@ -3112,43 +3265,46 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
} /* end else */
/* Perform the actual write operation */
- if ((io_info->io_ops.single_write)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
- chunk_info->fspace, chunk_info->mspace) < 0)
+ HDassert(chk_io_info->count == 1);
+ chk_io_info->dsets_info[0].file_space = chunk_info->fspace;
+ chk_io_info->dsets_info[0].mem_space = chunk_info->mspace;
+ chk_io_info->dsets_info[0].nelmts = chunk_info->piece_points;
+ if ((dset_info->io_ops.single_write)(chk_io_info, &chk_io_info->dsets_info[0]) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
/* Release the cache lock on the chunk, or insert chunk into index. */
if (chunk) {
- if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
+ if (H5D__chunk_unlock(io_info, dset_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
else {
- if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
- if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata, NULL) <
- 0)
+ if (need_insert && dset_info->dset->shared->layout.storage.u.chunk.ops->insert)
+ if ((dset_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
+ NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
"unable to insert chunk addr into index")
} /* end else */
/* Advance to next chunk in list */
- chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
+ chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
} /* end while */
} /* end else */
done:
/* Cleanup on failure */
if (ret_value < 0) {
- if (chunk_mem_spaces != chunk_mem_spaces_static)
+ if (chunk_mem_spaces != chunk_mem_spaces_local)
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
- if (chunk_file_spaces != chunk_file_spaces_static)
+ if (chunk_file_spaces != chunk_file_spaces_local)
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
- if (chunk_addrs != chunk_addrs_static)
+ if (chunk_addrs != chunk_addrs_local)
chunk_addrs = H5MM_xfree(chunk_addrs);
} /* end if */
/* Make sure we cleaned up */
- HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
- HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
- HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
+ HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_local);
+ HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_local);
+ HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_local);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D__chunk_write() */
@@ -3199,44 +3355,56 @@ done:
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * Saturday, May 17, 2003
+ * Programmer: Jonathan Kim Nov, 2013
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_io_term(const H5D_chunk_map_t *fm)
+H5D__chunk_io_term(H5D_io_info_t H5_ATTR_UNUSED *io_info, H5D_dset_io_info_t *di)
{
- herr_t ret_value = SUCCEED; /*return value */
+ H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
+ herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_PACKAGE
+ HDassert(di);
+
+ /* Set convenience pointer */
+ fm = di->layout_io_info.chunk_map;
+
/* 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);
+ HDassert(fm->dset_sel_pieces == NULL);
+ HDassert(fm->last_piece_info == NULL);
+ HDassert(fm->single_piece_info);
+ HDassert(fm->single_piece_info->fspace_shared);
+ HDassert(fm->single_piece_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 */
+ /* Release the nodes on the list of selected pieces, or the last (only)
+ * piece if the skiplist is not available */
+ if (fm->dset_sel_pieces) {
+ if (H5SL_free(fm->dset_sel_pieces, H5D__free_piece_info, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTNEXT, FAIL, "can't free dataset skip list")
+ } /* end if */
+ else if (fm->last_piece_info) {
+ if (H5D__free_piece_info(fm->last_piece_info, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't free piece info")
+ fm->last_piece_info = NULL;
+ } /* end if */
+ } /* end else */
- /* Free the memory chunk dataspace template */
+ /* Free the memory piece dataspace template */
if (fm->mchunk_tmpl)
if (H5S_close(fm->mchunk_tmpl) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template")
-#ifdef H5_HAVE_PARALLEL
- if (fm->select_chunk)
- H5MM_xfree(fm->select_chunk);
-#endif /* H5_HAVE_PARALLEL */
+
+ /* Free chunk map */
+ di->layout_io_info.chunk_map = H5FL_FREE(H5D_chunk_map_t, di->layout_io_info.chunk_map);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -4099,20 +4267,19 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk)
+H5D__chunk_lock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, H5D_chunk_ud_t *udata,
+ hbool_t relax, hbool_t prev_unfilt_chunk)
{
- const H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
- H5O_pline_t *pline =
- &(dset->shared->dcpl_cache
- .pline); /* I/O pipeline info - always equal to the pline passed to H5D__chunk_mem_alloc */
- H5O_pline_t *old_pline = pline; /* Old pipeline, i.e. pipeline used to read the chunk */
- const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
- const H5O_fill_t *fill = &(dset->shared->dcpl_cache.fill); /* Fill value info */
- H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
- hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
- H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache*/
- H5D_rdcc_ent_t *ent; /*cache entry */
- size_t chunk_size; /*size of a chunk */
+ const H5D_t *dset; /* Convenience pointer to the dataset */
+ H5O_pline_t *pline; /* I/O pipeline info - always equal to the pline passed to H5D__chunk_mem_alloc */
+ H5O_pline_t *old_pline; /* Old pipeline, i.e. pipeline used to read the chunk */
+ const H5O_layout_t *layout; /* Dataset layout */
+ const H5O_fill_t *fill; /* Fill value info */
+ H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
+ hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
+ H5D_rdcc_t *rdcc; /*raw data chunk cache*/
+ H5D_rdcc_ent_t *ent; /*cache entry */
+ size_t chunk_size; /*size of a chunk */
hbool_t disable_filters = FALSE; /* Whether to disable filters (when adding to cache) */
void *chunk = NULL; /*the file chunk */
void *ret_value = NULL; /* Return value */
@@ -4121,10 +4288,20 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
/* Sanity checks */
HDassert(io_info);
- HDassert(io_info->store);
- HDassert(udata);
+ HDassert(dset_info);
+ HDassert(dset_info->store);
+ dset = dset_info->dset;
HDassert(dset);
+ HDassert(udata);
HDassert(!(udata->new_unfilt_chunk && prev_unfilt_chunk));
+
+ /* Set convenience pointers */
+ pline = &(dset->shared->dcpl_cache.pline);
+ old_pline = pline;
+ layout = &(dset->shared->layout);
+ fill = &(dset->shared->dcpl_cache.fill);
+ rdcc = &(dset->shared->cache.chunk);
+
HDassert(!rdcc->tmp_head);
/* Get the chunk's size */
@@ -4146,7 +4323,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
/* Make sure this is the right chunk */
for (u = 0; u < layout->u.chunk.ndims - 1; u++)
- HDassert(io_info->store->chunk.scaled[u] == ent->scaled[u]);
+ HDassert(dset_info->store->chunk.scaled[u] == ent->scaled[u]);
}
#endif /* NDEBUG */
@@ -4261,9 +4438,9 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
} /* end if */
else if (layout->u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
/* Check if this is an edge chunk */
- if (H5D__chunk_is_partial_edge_chunk(io_info->dset->shared->ndims, layout->u.chunk.dim,
- io_info->store->chunk.scaled,
- io_info->dset->shared->curr_dims)) {
+ if (H5D__chunk_is_partial_edge_chunk(dset->shared->ndims, layout->u.chunk.dim,
+ dset_info->store->chunk.scaled,
+ dset->shared->curr_dims)) {
/* Disable the filters for both writing and reading */
disable_filters = TRUE;
old_pline = NULL;
@@ -4388,17 +4565,17 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
/* See if the chunk can be cached */
if (rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max) {
/* Calculate the index */
- udata->idx_hint = H5D__chunk_hash_val(io_info->dset->shared, udata->common.scaled);
+ udata->idx_hint = H5D__chunk_hash_val(dset->shared, udata->common.scaled);
/* Add the chunk to the cache only if the slot is not already locked */
ent = rdcc->slot[udata->idx_hint];
if (!ent || !ent->locked) {
/* Preempt enough things from the cache to make room */
if (ent) {
- if (H5D__chunk_cache_evict(io_info->dset, ent, TRUE) < 0)
+ if (H5D__chunk_cache_evict(dset, ent, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk from cache")
} /* end if */
- if (H5D__chunk_cache_prune(io_info->dset, chunk_size) < 0)
+ if (H5D__chunk_cache_prune(dset, chunk_size) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache")
/* Create a new entry */
@@ -4498,19 +4675,26 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk,
- uint32_t naccessed)
+H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
+ const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk, uint32_t naccessed)
{
- const H5O_layout_t *layout = &(io_info->dset->shared->layout); /* Dataset layout */
- const H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);
+ const H5O_layout_t *layout; /* Dataset layout */
+ const H5D_rdcc_t *rdcc;
+ const H5D_t *dset; /* Local pointer to the dataset info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(io_info);
+ HDassert(dset_info);
HDassert(udata);
+ /* Set convenience pointers */
+ layout = &(dset_info->dset->shared->layout);
+ rdcc = &(dset_info->dset->shared->cache.chunk);
+ dset = dset_info->dset;
+
if (UINT_MAX == udata->idx_hint) {
/*
* It's not in the cache, probably because it's too big. If it's
@@ -4526,9 +4710,9 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbo
} /* end if */
else if (layout->u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
/* Check if the chunk is an edge chunk, and disable filters if so */
- is_unfiltered_edge_chunk = H5D__chunk_is_partial_edge_chunk(
- io_info->dset->shared->ndims, layout->u.chunk.dim, io_info->store->chunk.scaled,
- io_info->dset->shared->curr_dims);
+ is_unfiltered_edge_chunk =
+ H5D__chunk_is_partial_edge_chunk(dset->shared->ndims, layout->u.chunk.dim,
+ dset_info->store->chunk.scaled, dset->shared->curr_dims);
} /* end if */
if (dirty) {
@@ -4547,13 +4731,13 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbo
fake_ent.chunk_block.length = udata->chunk_block.length;
fake_ent.chunk = (uint8_t *)chunk;
- if (H5D__chunk_flush_entry(io_info->dset, &fake_ent, TRUE) < 0)
+ if (H5D__chunk_flush_entry(dset, &fake_ent, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
} /* end if */
else {
if (chunk)
chunk = H5D__chunk_mem_xfree(
- chunk, (is_unfiltered_edge_chunk ? NULL : &(io_info->dset->shared->dcpl_cache.pline)));
+ chunk, (is_unfiltered_edge_chunk ? NULL : &(dset->shared->dcpl_cache.pline)));
} /* end else */
} /* end if */
else {
@@ -4676,9 +4860,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const hsize_t old_dim[])
+H5D__chunk_allocate(const H5D_t *dset, hbool_t full_overwrite, const hsize_t old_dim[])
{
- const H5D_t *dset = io_info->dset; /* the dataset pointer */
H5D_chk_idx_info_t idx_info; /* Chunked index info */
const H5D_chunk_ops_t *ops = dset->shared->layout.storage.u.chunk.ops; /* Chunk operations */
hsize_t min_unalloc[H5O_LAYOUT_NDIMS]; /* First chunk in each dimension that is unallocated (in scaled
@@ -5170,6 +5353,7 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
H5D_io_info_t chk_io_info; /* Chunked I/O info object */
H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
H5D_storage_t chk_store; /* Chunk storage information */
+ H5D_dset_io_info_t chk_dset_info; /* Chunked I/O dset info object */
void *chunk; /* The file chunk */
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
herr_t ret_value = SUCCEED; /* Return value */
@@ -5203,7 +5387,13 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
* Note that we only need to set chunk_offset once, as the array's address
* will never change. */
chk_store.chunk.scaled = chunk_sc;
- H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, &chk_store, NULL);
+
+ chk_io_info.op_type = H5D_IO_OP_READ;
+
+ chk_dset_info.dset = dset;
+ chk_dset_info.store = &chk_store;
+ chk_dset_info.buf.vp = NULL;
+ chk_io_info.dsets_info = &chk_dset_info;
/*
* Determine the edges of the dataset which need to be modified
@@ -5268,11 +5458,12 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
if (H5F_addr_defined(chk_udata.chunk_block.offset) || (UINT_MAX != chk_udata.idx_hint)) {
/* Lock the chunk into cache. H5D__chunk_lock will take care of
* updating the chunk to no longer be an edge chunk. */
- if (NULL == (chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_udata, FALSE, TRUE)))
+ if (NULL ==
+ (chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_dset_info, &chk_udata, FALSE, TRUE)))
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
/* Unlock the chunk */
- if (H5D__chunk_unlock(&chk_io_info, &chk_udata, TRUE, chunk, (uint32_t)0) < 0)
+ if (H5D__chunk_unlock(&chk_io_info, &chk_dset_info, &chk_udata, TRUE, chunk, (uint32_t)0) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
@@ -5603,7 +5794,7 @@ static herr_t
H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
{
const H5D_io_info_t *io_info = udata->io_info; /* Local pointer to I/O info */
- const H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
+ const H5D_t *dset = udata->dset_info->dset; /* Local pointer to the dataset info */
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
unsigned rank = udata->common.layout->ndims - 1; /* Dataset rank */
const hsize_t *scaled = udata->common.scaled; /* Scaled chunk offset */
@@ -5658,7 +5849,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab")
/* Lock the chunk into the cache, to get a pointer to the chunk buffer */
- if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, &chk_udata, FALSE, FALSE)))
+ if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, udata->dset_info, &chk_udata, FALSE, FALSE)))
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
/* Fill the selection in the memory buffer */
@@ -5695,7 +5886,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
bytes_accessed = (uint32_t)sel_nelmts * layout->u.chunk.dim[rank];
/* Release lock on chunk */
- if (H5D__chunk_unlock(io_info, &chk_udata, TRUE, chunk, bytes_accessed) < 0)
+ if (H5D__chunk_unlock(io_info, udata->dset_info, &chk_udata, TRUE, chunk, bytes_accessed) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
done:
@@ -5822,6 +6013,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
unfiltered */
H5D_chk_idx_info_t idx_info; /* Chunked index info */
H5D_io_info_t chk_io_info; /* Chunked I/O info object */
+ H5D_dset_io_info_t chk_dset_info; /* Chunked I/O dset info object */
H5D_storage_t chk_store; /* Chunk storage information */
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
@@ -5889,7 +6081,14 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
* Note that we only need to set scaled once, as the array's address
* will never change. */
chk_store.chunk.scaled = scaled;
- H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, &chk_store, NULL);
+
+ chk_io_info.op_type = H5D_IO_OP_READ;
+
+ chk_dset_info.dset = dset;
+ chk_dset_info.store = &chk_store;
+ chk_dset_info.buf.vp = NULL;
+ chk_io_info.dsets_info = &chk_dset_info;
+ chk_io_info.count = 1;
/* Compose chunked index info struct */
idx_info.f = dset->oloc.file;
@@ -5903,6 +6102,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
udata.common.storage = sc;
udata.common.scaled = scaled;
udata.io_info = &chk_io_info;
+ udata.dset_info = &chk_dset_info;
udata.idx_info = &idx_info;
udata.space_dim = space_dim;
udata.shrunk_dim = shrunk_dim;
@@ -6183,18 +6383,18 @@ H5D__chunk_addrmap_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
*-------------------------------------------------------------------------
*/
herr_t
-H5D__chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[])
+H5D__chunk_addrmap(const H5D_t *dset, haddr_t chunk_addr[])
{
- H5D_chk_idx_info_t idx_info; /* Chunked index info */
- const H5D_t *dset = io_info->dset; /* Local pointer to dataset info */
- H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
- H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk);
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
+ H5O_storage_chunk_t *sc;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
HDassert(dset);
HDassert(dset->shared);
+ sc = &(dset->shared->layout.storage.u.chunk);
H5D_CHUNK_STORAGE_INDEX_CHK(sc);
HDassert(chunk_addr);
@@ -7254,9 +7454,10 @@ done:
*-------------------------------------------------------------------------
*/
static ssize_t
-H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq, size_t *chunk_curr_seq,
- size_t chunk_len_arr[], hsize_t chunk_off_arr[], size_t mem_max_nseq,
- size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
+H5D__nonexistent_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[],
+ hsize_t chunk_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
+ size_t mem_len_arr[], hsize_t mem_off_arr[])
{
H5D_chunk_readvv_ud_t udata; /* User data for H5VM_opvv() operator */
ssize_t ret_value = -1; /* Return value */
@@ -7273,8 +7474,8 @@ H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq, siz
HDassert(mem_off_arr);
/* Set up user data for H5VM_opvv() */
- udata.rbuf = (unsigned char *)io_info->u.rbuf;
- udata.dset = io_info->dset;
+ udata.rbuf = (unsigned char *)dset_info->buf.vp;
+ udata.dset = dset_info->dset;
/* Call generic sequence operation routine */
if ((ret_value = H5VM_opvv(chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_off_arr, mem_max_nseq,