diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2014-12-29 20:35:31 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2014-12-29 20:35:31 (GMT) |
commit | 7d60047a2a8cfe5df186f0c2f44820f858710dd7 (patch) | |
tree | 87caa79f6311467b2e2b15ef2466b08ffa82209a /src | |
parent | c8d45ef69354b59f05fcdcf4f6c2976b03cae032 (diff) | |
download | hdf5-7d60047a2a8cfe5df186f0c2f44820f858710dd7.zip hdf5-7d60047a2a8cfe5df186f0c2f44820f858710dd7.tar.gz hdf5-7d60047a2a8cfe5df186f0c2f44820f858710dd7.tar.bz2 |
[svn-r25930] refactor I/O path to merge multi-dataset and single-dataset I/O.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dchunk.c | 1294 | ||||
-rw-r--r-- | src/H5Dcompact.c | 27 | ||||
-rw-r--r-- | src/H5Dcontig.c | 260 | ||||
-rw-r--r-- | src/H5Defl.c | 30 | ||||
-rw-r--r-- | src/H5Dint.c | 36 | ||||
-rw-r--r-- | src/H5Dio.c | 1254 | ||||
-rw-r--r-- | src/H5Dmpio.c | 365 | ||||
-rw-r--r-- | src/H5Dpkg.h | 162 | ||||
-rw-r--r-- | src/H5Dscatgath.c | 26 | ||||
-rw-r--r-- | src/H5Dselect.c | 14 |
10 files changed, 807 insertions, 2661 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 97e16df..d832900 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -67,8 +67,8 @@ /****************/ /* Macros for iterating over chunks to operate on */ -#define H5D_CHUNK_GET_FIRST_NODE(map) (map->use_single ? (H5SL_node_t *)(1) : H5SL_first(map->sel_chunks)) -#define H5D_CHUNK_GET_NODE_INFO(map, node) (map->use_single ? map->single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node)) +#define H5D_CHUNK_GET_FIRST_NODE(map) (map->use_single ? (H5SL_node_t *)(1) : H5SL_first(map->dset_sel_pieces)) +#define H5D_CHUNK_GET_NODE_INFO(map, node) (map->use_single ? map->single_piece_info : (H5D_piece_info_t *)H5SL_item(node)) #define H5D_CHUNK_GET_NEXT_NODE(map, node) (map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node)) /* @@ -168,14 +168,6 @@ typedef struct H5D_chunk_readvv_ud_t { hid_t dxpl_id; /* DXPL for operation */ } H5D_chunk_readvv_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_info_t { @@ -190,20 +182,16 @@ typedef struct H5D_chunk_coll_info_t { /* Chunked layout operation callbacks */ static herr_t H5D__chunk_construct(H5F_t *f, H5D_t *dset); -static herr_t H5D__chunk_io_init(const H5D_io_info_t *io_info, - const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, - const H5S_t *mem_space, H5D_chunk_map_t *fm); -static herr_t H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, +static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_dset_info_t *dinfo); static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *fm); + H5D_dset_info_t *dinfo); static herr_t H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *fm); + H5D_dset_info_t *dinfo); static herr_t H5D__chunk_flush(H5D_t *dset, hid_t dxpl_id); -static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm); static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last); /* "Nonexistent" layout operation callback */ @@ -223,25 +211,13 @@ 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__free_piece_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_piece_map_single(H5D_dset_info_t *di, - const H5D_io_info_md_t* io_info_md); -static herr_t H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, +static herr_t H5D__create_piece_map_single(H5D_dset_info_t *di, + const H5D_io_info_t* io_info); +static herr_t H5D__create_piece_file_map_hyper(H5D_dset_info_t *di, const H5D_io_info_t *io_info); -static herr_t -H5D__create_piece_file_map_hyper(H5D_dset_info_t *di, - const H5D_io_info_md_t *io_info_md); -static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm); -static herr_t H5D__create_piece_mem_map_hyper(const H5D_io_info_md_t *io_info_md, +static herr_t H5D__create_piece_mem_map_hyper(const H5D_io_info_t *io_info, const H5D_dset_info_t *dinfo); -static herr_t H5D__chunk_file_cb(void *elem, hid_t type_id, unsigned ndims, - const hsize_t *coords, void *fm); -static herr_t H5D__chunk_mem_cb(void *elem, hid_t type_id, unsigned ndims, - const hsize_t *coords, void *fm); static herr_t H5D__piece_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_opdata); static herr_t H5D__piece_mem_cb(void *elem, hid_t type_id, unsigned ndims, @@ -268,18 +244,16 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{ H5D__chunk_init, H5D__chunk_is_space_alloc, H5D__chunk_io_init, - H5D__chunk_io_init_mdset, H5D__chunk_read, H5D__chunk_write, #ifdef H5_HAVE_PARALLEL - H5D__mdset_collective_read, - H5D__mdset_collective_write, + H5D__collective_read, + H5D__collective_write, #endif /* H5_HAVE_PARALLEL */ NULL, NULL, H5D__chunk_flush, - H5D__chunk_io_term, - H5D__piece_io_term_mdset + H5D__piece_io_term }}; @@ -295,7 +269,6 @@ const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{ NULL, NULL, NULL, - NULL, #ifdef H5_HAVE_PARALLEL NULL, NULL, @@ -303,7 +276,6 @@ const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{ H5D__nonexistent_readvv, NULL, NULL, - NULL, NULL }}; @@ -313,9 +285,6 @@ H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t); /* Declare a free list to manage H5D_rdcc_ent_t objects */ 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); - /* Declare a free list to manage the H5D_piece_info_t struct */ H5FL_DEFINE(H5D_piece_info_t); @@ -359,7 +328,6 @@ H5D__chunk_direct_write(const H5D_t *dset, hid_t dxpl_id, uint32_t filters, hsiz HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") } /* end if */ - /* Retrieve the dataset dimensions */ if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info") @@ -706,290 +674,10 @@ H5D__chunk_is_space_alloc(const H5O_storage_t *storage) FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_is_space_alloc() */ - /*------------------------------------------------------------------------- * Function: H5D__chunk_io_init * * Purpose: Performs initialization before any sort of I/O on the raw data - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, March 20, 2008 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *fm) -{ - 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 */ - hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */ - htri_t file_space_normalized = FALSE; /* File dataspace was normalized */ - hid_t f_tid = (-1); /* Temporary copy of file datatype for iteration */ - hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ - 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) */ - H5SL_node_t *curr_node; /* Current node in skip list */ - H5S_sel_type fsel_type; /* Selection type on disk */ - char bogus; /* "bogus" buffer to pass to selection iterator */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Get layout for dataset */ - fm->layout = &(dataset->shared->layout); - fm->nelmts = nelmts; - - /* Check if the memory space is scalar & make equivalent memory space */ - if((sm_ndims = H5S_GET_EXTENT_NDIMS(mem_space)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number") - /* Set the number of dimensions for the memory dataspace */ - H5_ASSIGN_OVERFLOW(fm->m_ndims, sm_ndims, int, unsigned); - - /* Get dim number and dimensionality for each dataspace */ - fm->f_ndims = f_ndims = dataset->shared->layout.u.chunk.ndims - 1; - if(H5S_get_simple_extent_dims(file_space, fm->f_dims, NULL) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality") - - /* Normalize hyperslab selections by adjusting them by the offset */ - /* (It might be worthwhile to normalize both the file and memory dataspaces - * before any (contiguous, chunked, etc) file I/O operation, in order to - * 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((H5S_t *)file_space, old_offset)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") - - /* 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]; - } /* end for */ - - /* 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; - - /* Special case for only one element in selection */ - /* (usually appending a record) */ - if(nelmts == 1 -#ifdef H5_HAVE_PARALLEL - && !(io_info->using_mpi_vfd) -#endif /* H5_HAVE_PARALLEL */ - && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(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(file_space, TRUE, FALSE)) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space") - - /* Resize chunk's dataspace dimensions to size of chunk */ - if(H5S_set_extent_real(dataset->shared->cache.chunk.single_space, fm->chunk_dim) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust chunk dimensions") - - /* Set the single chunk dataspace to 'all' selection */ - if(H5S_select_all(dataset->shared->cache.chunk.single_space, TRUE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to set all selection") - } /* end if */ - fm->single_space = dataset->shared->cache.chunk.single_space; - HDassert(fm->single_space); - - /* Allocate the single chunk information */ - if(NULL == dataset->shared->cache.chunk.single_chunk_info) { - if(NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") - } /* end if */ - fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info; - HDassert(fm->single_chunk_info); - - /* Reset chunk template information */ - fm->mchunk_tmpl = NULL; - - /* Set up chunk mapping for single element */ - if(H5D__create_chunk_map_single(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk selections for single element") - } /* end if */ - else { - hbool_t sel_hyper_flag; /* Whether file selection is a hyperslab */ - - /* Initialize skip list for chunk selections */ - if(NULL == dataset->shared->cache.chunk.sel_chunks) { - if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, NULL))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections") - } /* end if */ - fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks; - HDassert(fm->sel_chunks); - - /* We are not using single element mode */ - fm->use_single = FALSE; - - /* Get type of selection on disk & in memory */ - if((fsel_type = H5S_GET_SELECT_TYPE(file_space)) < H5S_SEL_NONE) - HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") - if((fm->msel_type = H5S_GET_SELECT_TYPE(mem_space)) < H5S_SEL_NONE) - HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection") - - /* If the selection is NONE or POINTS, set the flag to FALSE */ - if(fsel_type == H5S_SEL_POINTS || fsel_type == H5S_SEL_NONE) - sel_hyper_flag = FALSE; - else - sel_hyper_flag = TRUE; - - /* Check if file selection is a not a hyperslab selection */ - if(sel_hyper_flag) { - /* Build the file selection for each chunk */ - if(H5D__create_chunk_file_map_hyper(fm, io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - - /* Clean file chunks' hyperslab span "scratch" information */ - curr_node = H5SL_first(fm->sel_chunks); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->fspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") - - /* Get the next chunk node in the skip list */ - curr_node = H5SL_next(curr_node); - } /* end while */ - } /* end if */ - else { - H5D_chunk_file_iter_ud_t udata; /* User data for iteration */ - - /* Create temporary datatypes for selection iteration */ - if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") - - /* Initialize the user data */ - udata.fm = fm; -#ifdef H5_HAVE_PARALLEL - udata.io_info = io_info; -#endif /* H5_HAVE_PARALLEL */ - - /* Spaces might not be the same shape, iterate over the file selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__chunk_file_cb, &udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") - - /* Reset "last chunk" info */ - fm->last_index = (hsize_t)-1; - fm->last_chunk_info = NULL; - } /* end else */ - - /* Build the memory selection for each chunk */ - if(sel_hyper_flag && H5S_select_shape_same(file_space, mem_space) == TRUE) { - /* Reset chunk template information */ - fm->mchunk_tmpl = NULL; - - /* If the selections are the same shape, use the file chunk information - * to generate the memory chunk information quickly. - */ - if(H5D__create_chunk_mem_map_hyper(fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") - } /* end if */ - else { - size_t elmt_size; /* Memory datatype size */ - - /* Make a copy of equivalent memory space */ - if((tmp_mspace = H5S_copy(mem_space, TRUE, FALSE)) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - - /* De-select the mem space copy */ - if(H5S_select_none(tmp_mspace) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space") - - /* Save chunk template information */ - fm->mchunk_tmpl = tmp_mspace; - - /* Create temporary datatypes for selection iteration */ - if(f_tid < 0) { - if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->shared->type, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") - } /* end if */ - - /* 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), mem_space, elmt_size) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator") - iter_init = TRUE; /* Selection iteration info has been initialized */ - - /* Spaces aren't the same shape, iterate over the memory selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__chunk_mem_cb, fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") - - /* Clean up hyperslab stuff, if necessary */ - if(fm->msel_type != H5S_SEL_POINTS) { - /* Clean memory chunks' hyperslab span "scratch" information */ - curr_node = H5SL_first(fm->sel_chunks); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer chunk information */ - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Clean hyperslab span's "scratch" information */ - if(H5S_hyper_reset_scratch(chunk_info->mspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") - - /* Get the next chunk node in the skip list */ - curr_node = H5SL_next(curr_node); - } /* end while */ - } /* end if */ - } /* end else */ - } /* end else */ - -done: - /* Release the [potentially partially built] chunk mapping information if an error occurs */ - if(ret_value < 0) { - if(tmp_mspace && !fm->mchunk_tmpl) { - if(H5S_close(tmp_mspace) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template") - } /* end if */ - - if(H5D__chunk_io_term(fm) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping") - } /* end if */ - - /* Reset the global dataspace info */ - fm->file_space = NULL; - fm->mem_space = NULL; - - if(iter_init && H5S_SELECT_ITER_RELEASE(&(fm->mem_iter)) < 0) - HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator") - if(f_tid != (-1) && H5I_dec_ref(f_tid) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") - if(file_space_normalized) { - /* (Casting away const OK -QAK) */ - if(H5S_hyper_denormalize_offset((H5S_t *)file_space, old_offset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_io_init() */ - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_io_init_mdset - * - * Purpose: Performs initialization before any sort of I/O on the raw data * This was derived from H5D__chunk_io_init for multi-dset work. * * Return: Non-negative on success/Negative on failure @@ -998,7 +686,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *type_info, +H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_dset_info_t *dinfo) { @@ -1015,7 +703,7 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty H5S_sel_type fsel_type; /* Selection type on disk */ char bogus; /* "bogus" buffer to pass to selection iterator */ unsigned u; /* Local index variable */ - H5D_io_info_md_wrap_t io_info_md_wrap; + H5D_io_info_wrap_t io_info_wrap; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1062,11 +750,11 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty /* (usually appending a record) */ if(nelmts == 1 #ifdef H5_HAVE_PARALLEL - && !(io_info_md->using_mpi_vfd) + && !(io_info->using_mpi_vfd) #endif /* H5_HAVE_PARALLEL */ && H5S_SEL_ALL != H5S_GET_SELECT_TYPE(file_space)) { /* Initialize skip list for chunk selections */ - io_info_md->sel_pieces = NULL; + //io_info->sel_pieces = NULL; dinfo->use_single = TRUE; /* Initialize single chunk dataspace */ @@ -1098,7 +786,7 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty dinfo->mchunk_tmpl = NULL; /* Set up chunk mapping for single element */ - if(H5D__create_piece_map_single(dinfo, io_info_md) < 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 */ else { @@ -1111,7 +799,7 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty } /* end if */ dinfo->dset_sel_pieces = dataset->shared->cache.chunk.sel_chunks; HDassert(dinfo->dset_sel_pieces); - HDassert(io_info_md->sel_pieces); + HDassert(io_info->sel_pieces); /* We are not using single element mode */ dinfo->use_single = FALSE; @@ -1131,19 +819,18 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty /* Check if file selection is a not a hyperslab selection */ if(sel_hyper_flag) { /* Build the file selection for each chunk */ - if(H5D__create_piece_file_map_hyper(dinfo, io_info_md) < 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") /* Clean file chunks' hyperslab span "scratch" information */ - curr_node = H5SL_first(io_info_md->sel_pieces); - + curr_node = H5SL_first(dinfo->dset_sel_pieces); while(curr_node) { H5D_piece_info_t *piece_info; /* Pointer piece information */ /* Get pointer to piece's information */ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node); HDassert(piece_info); - + /* only for current dset */ if (piece_info->dset_info == dinfo) { /* Clean hyperslab span's "scratch" information */ @@ -1161,10 +848,10 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype") /* set opdata for H5D__piece_mem_cb */ - io_info_md_wrap.io_info_md = io_info_md; - io_info_md_wrap.dinfo = dinfo; + io_info_wrap.io_info = io_info; + io_info_wrap.dinfo = dinfo; /* Spaces might not be the same shape, iterate over the file selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__piece_file_cb, &io_info_md_wrap) < 0) + if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__piece_file_cb, &io_info_wrap) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections") /* Reset "last chunk" info */ @@ -1180,7 +867,7 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty /* If the selections are the same shape, use the file chunk * information to generate the memory chunk information quickly. */ - if(H5D__create_piece_mem_map_hyper(io_info_md, dinfo) < 0) + if(H5D__create_piece_mem_map_hyper(io_info, dinfo) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") } /* end if */ else { @@ -1211,17 +898,18 @@ H5D__chunk_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *ty iter_init = TRUE; /* Selection iteration info has been initialized */ /* set opdata for H5D__piece_mem_cb */ - io_info_md_wrap.io_info_md = io_info_md; - io_info_md_wrap.dinfo = dinfo; + io_info_wrap.io_info = io_info; + io_info_wrap.dinfo = dinfo; /* Spaces aren't the same shape, iterate over the memory selection directly */ - if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__piece_mem_cb, &io_info_md_wrap) < 0) + if(H5S_select_iterate(&bogus, f_tid, file_space, H5D__piece_mem_cb, &io_info_wrap) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections") /* Clean up hyperslab stuff, if necessary */ if(dinfo->msel_type != H5S_SEL_POINTS) { /* Clean memory pieces' hyperslab span "scratch" information */ curr_node = H5SL_first(dinfo->dset_sel_pieces); + while(curr_node) { H5D_piece_info_t *piece_info; /* Pointer piece information */ @@ -1247,7 +935,7 @@ done: if(H5S_close(tmp_mspace) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template") - if(H5D__piece_io_term_mdset(dinfo) < 0) + if(H5D__piece_io_term(io_info, dinfo) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping") } /* end if */ @@ -1262,7 +950,7 @@ done: HDONE_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_io_init_mdset() */ +} /* end H5D__chunk_io_init() */ /*------------------------------------------------------------------------- @@ -1363,49 +1051,6 @@ H5D__chunk_realloc(void *chk, size_t size, const H5O_pline_t *pline) } /* H5D__chunk_realloc() */ -/*-------------------------------------------------------------------------- - NAME - H5D__free_chunk_info - PURPOSE - Internal routine to destroy a chunk info node - USAGE - void H5D__free_chunk_info(chunk_info) - void *chunk_info; IN: Pointer to chunk info to destroy - RETURNS - No return value - DESCRIPTION - Releases all the memory for a chunk info node. Called by H5SL_free - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -static herr_t -H5D__free_chunk_info(void *item, void UNUSED *key, void UNUSED *opdata) -{ - H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item; - - FUNC_ENTER_STATIC_NOERR - - HDassert(chunk_info); - - /* Close the chunk's file dataspace, if it's not shared */ - if(!chunk_info->fspace_shared) - (void)H5S_close(chunk_info->fspace); - else - H5S_select_all(chunk_info->fspace, TRUE); - - /* Close the chunk's memory dataspace, if it's not shared */ - if(!chunk_info->mspace_shared && chunk_info->mspace) - (void)H5S_close(chunk_info->mspace); - - /* Free the actual chunk info */ - chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info); - - FUNC_LEAVE_NOAPI(0) -} /* H5D__free_chunk_info() */ - - /*------------------------------------------------------------------------- * Function: H5D__free_piece_info * @@ -1449,82 +1094,6 @@ H5D__free_piece_info(void *item, void UNUSED *key, void UNUSED *opdata) FUNC_LEAVE_NOAPI(0) } /* H5D__free_piece_info() */ - -/*------------------------------------------------------------------------- - * Function: H5D__create_chunk_map_single - * - * Purpose: Create chunk selections when appending a single record - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, November 20, 2007 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t -#ifndef H5_HAVE_PARALLEL - UNUSED -#endif /* H5_HAVE_PARALLEL */ - *io_info) -{ - H5D_chunk_info_t *chunk_info; /* Chunk information to insert into skip list */ - hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Sanity check */ - HDassert(fm->f_ndims > 0); - - /* Get coordinate for selection */ - if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") - - /* Initialize the 'single chunk' file & memory chunk information */ - chunk_info = fm->single_chunk_info; - chunk_info->chunk_points = 1; - - /* Set chunk location & hyperslab size */ - for(u = 0; u < fm->f_ndims; u++) { - HDassert(sel_start[u] == sel_end[u]); - chunk_info->coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u]; - } /* end for */ - chunk_info->coords[fm->f_ndims] = 0; - - /* Calculate the index of this chunk */ - if(H5VM_chunk_index(fm->f_ndims, chunk_info->coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_info->index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") - - /* Copy selection for file's dataspace into chunk dataspace */ - if(H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file selection") - - /* Move selection back to have correct offset in chunk */ - if(H5S_SELECT_ADJUST_U(fm->single_space, chunk_info->coords) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") - - /* Set the file dataspace for the chunk to the shared 'single' dataspace */ - chunk_info->fspace = fm->single_space; - - /* Indicate that the chunk's file dataspace is shared */ - chunk_info->fspace_shared = TRUE; - - /* Just point at the memory dataspace & selection */ - /* (Casting away const OK -QAK) */ - chunk_info->mspace = (H5S_t *)fm->mem_space; - - /* Indicate that the chunk's memory dataspace is shared */ - chunk_info->mspace_shared = TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__create_chunk_map_single() */ - - /*------------------------------------------------------------------------- * Function: H5D__create_piece_map_single * @@ -1539,7 +1108,7 @@ done: */ static herr_t H5D__create_piece_map_single(H5D_dset_info_t *di, - const H5D_io_info_md_t *io_info_md) + const H5D_io_info_t *io_info) { H5D_piece_info_t *piece_info; /* Piece information to insert into skip list */ hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ @@ -1548,7 +1117,7 @@ H5D__create_piece_map_single(H5D_dset_info_t *di, H5D_chunk_ud_t udata; /* User data for querying piece info */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_TAG(io_info_md->dxpl_id, di->dset->oloc.addr, FAIL) + FUNC_ENTER_STATIC_TAG(io_info->dxpl_id, di->dset->oloc.addr, FAIL) /* Sanity check */ HDassert(di->f_ndims > 0); @@ -1569,7 +1138,8 @@ H5D__create_piece_map_single(H5D_dset_info_t *di, piece_info->coords[di->f_ndims] = 0; /* Calculate the index of this chunk */ - if(H5VM_chunk_index(di->f_ndims, piece_info->coords, di->layout->u.chunk.dim, di->layout->u.chunk.down_chunks, &piece_info->index) < 0) + if(H5VM_chunk_index(di->f_ndims, piece_info->coords, di->layout->u.chunk.dim, + di->layout->u.chunk.down_chunks, &piece_info->index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Copy selection for file's dataspace into chunk dataspace */ @@ -1597,192 +1167,19 @@ H5D__create_piece_map_single(H5D_dset_info_t *di, piece_info->dset_info = di; /* get piece file address */ - if(H5D__chunk_lookup(piece_info->dset_info->dset, io_info_md->dxpl_id, + if(H5D__chunk_lookup(piece_info->dset_info->dset, io_info->dxpl_id, piece_info->coords, piece_info->index, &udata) < 0) - HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list") + HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skip list") piece_info->faddr = udata.addr; /* Insert piece into global piece skiplist */ - if(H5SL_insert(io_info_md->sel_pieces, piece_info, &piece_info->faddr) < 0) + if(H5SL_insert(io_info->sel_pieces, piece_info, &piece_info->faddr) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") done: FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) } /* end H5D__create_piece_map_single() */ - -/*------------------------------------------------------------------------- - * Function: H5D__create_chunk_file_map_hyper - * - * Purpose: Create all chunk selections in file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, May 29, 2003 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t -#ifndef H5_HAVE_PARALLEL - UNUSED -#endif /* H5_HAVE_PARALLEL */ - *io_info) -{ - 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]; /* Current coordinates of chunk */ - hsize_t chunk_index; /* Index of chunk */ - int curr_dim; /* Current dimension to increment */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Sanity check */ - HDassert(fm->f_ndims>0); - - /* Get number of elements selected in file */ - sel_points = fm->nelmts; - - /* Get bounding box for selection (to reduce the number of chunks to iterate over) */ - if(H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0) - 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++) { - start_coords[u] = (sel_start[u] / fm->layout->u.chunk.dim[u]) * fm->layout->u.chunk.dim[u]; - coords[u] = start_coords[u]; - end[u] = (coords[u] + fm->chunk_dim[u]) - 1; - } /* end for */ - - /* Calculate the index of this chunk */ - if(H5VM_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") - - /* Iterate through each chunk in the dataset */ - while(sel_points) { - /* Check for intersection of temporary chunk and file selection */ - /* (Casting away const OK - QAK) */ - if(TRUE == H5S_hyper_intersect_block((H5S_t *)fm->file_space, coords, end)) { - H5S_t *tmp_fchunk; /* Temporary file dataspace */ - H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */ - hssize_t schunk_points; /* Number of elements in chunk selection */ - - /* Create "temporary" chunk for selection operations (copy file space) */ - if(NULL == (tmp_fchunk = H5S_copy(fm->file_space, TRUE, FALSE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - - /* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */ - if(H5S_hyper_convert(tmp_fchunk) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") - } /* end if */ - - /* "AND" temporary chunk and current chunk */ - if(H5S_select_hyperslab(tmp_fchunk,H5S_SELECT_AND,coords,NULL,fm->chunk_dim,NULL) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create chunk selection") - } /* end if */ - - /* Resize chunk's dataspace dimensions to size of chunk */ - if(H5S_set_extent_real(tmp_fchunk,fm->chunk_dim) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk dimensions") - } /* end if */ - - /* Move selection back to have correct offset in chunk */ - if(H5S_SELECT_ADJUST_U(tmp_fchunk, coords) < 0) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") - } /* end if */ - - /* 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))) { - (void)H5S_close(tmp_fchunk); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") - } /* end if */ - - /* Initialize the chunk information */ - - /* Set the chunk index */ - new_chunk_info->index=chunk_index; - - /* Set the file chunk dataspace */ - new_chunk_info->fspace = tmp_fchunk; - new_chunk_info->fspace_shared = FALSE; - - /* Set the memory chunk dataspace */ - new_chunk_info->mspace=NULL; - new_chunk_info->mspace_shared = FALSE; - - /* Copy the chunk's coordinates */ - for(u=0; u<fm->f_ndims; u++) - new_chunk_info->coords[u]=coords[u]; - new_chunk_info->coords[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") - } /* end if */ - - /* Get number of elements selected in chunk */ - if((schunk_points = H5S_GET_SELECT_NPOINTS(tmp_fchunk)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements") - H5_ASSIGN_OVERFLOW(new_chunk_info->chunk_points, schunk_points, hssize_t, uint32_t); - - /* Decrement # of points left in file selection */ - sel_points -= (hsize_t)schunk_points; - - /* Leave if we are done */ - if(sel_points == 0) - HGOTO_DONE(SUCCEED) - } /* end if */ - - /* Increment chunk index */ - chunk_index++; - - /* Set current increment dimension */ - curr_dim=(int)fm->f_ndims-1; - - /* Increment chunk location in fastest changing dimension */ - H5_CHECK_OVERFLOW(fm->chunk_dim[curr_dim],hsize_t,hssize_t); - coords[curr_dim]+=fm->chunk_dim[curr_dim]; - end[curr_dim]+=fm->chunk_dim[curr_dim]; - - /* Bring chunk location back into bounds, if necessary */ - if(coords[curr_dim] > sel_end[curr_dim]) { - do { - /* Reset current dimension's location to 0 */ - coords[curr_dim] = start_coords[curr_dim]; /*lint !e771 The start_coords will always be initialized */ - end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1; - - /* Decrement current dimension */ - curr_dim--; - - /* Increment chunk location in current dimension */ - coords[curr_dim] += fm->chunk_dim[curr_dim]; - end[curr_dim] = (coords[curr_dim] + fm->chunk_dim[curr_dim]) - 1; - } while(coords[curr_dim] > sel_end[curr_dim]); - - /* Re-calculate the index of this chunk */ - if(H5VM_chunk_index(fm->f_ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") - } /* end if */ - } /* end while */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__create_chunk_file_map_hyper() */ - - /*------------------------------------------------------------------------- * Function: H5D__create_piece_file_map_hyper * @@ -1796,8 +1193,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_md_t - *io_info_md) +H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_t *io_info) { 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 */ @@ -1810,7 +1206,7 @@ H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_md_t unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_TAG(io_info_md->dxpl_id, dinfo->dset->oloc.addr, FAIL) + FUNC_ENTER_STATIC_TAG(io_info->dxpl_id, dinfo->dset->oloc.addr, FAIL) /* Sanity check */ HDassert(dinfo->f_ndims > 0); @@ -1830,7 +1226,8 @@ H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_md_t } /* end for */ /* Calculate the index of this chunk */ - if(H5VM_chunk_index(dinfo->f_ndims, coords, dinfo->layout->u.chunk.dim, dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) + if(H5VM_chunk_index(dinfo->f_ndims, coords, dinfo->layout->u.chunk.dim, + dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Iterate through each chunk in the dataset */ @@ -1875,7 +1272,7 @@ H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_md_t /* Add temporary chunk to the list of chunks */ /* Allocate the file & memory chunk information */ - if (NULL==(new_piece_info = H5FL_MALLOC(H5D_piece_info_t))) { + if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t))) { (void)H5S_close(tmp_fchunk); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") } /* end if */ @@ -1902,18 +1299,19 @@ H5D__create_piece_file_map_hyper(H5D_dset_info_t *dinfo, const H5D_io_info_md_t new_piece_info->dset_info = dinfo; /* get chunk file address */ - if(H5D__chunk_lookup(new_piece_info->dset_info->dset, io_info_md->dxpl_id, + if(H5D__chunk_lookup(new_piece_info->dset_info->dset, io_info->dxpl_id, new_piece_info->coords, new_piece_info->index, &udata) < 0) HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list") new_piece_info->faddr = udata.addr; + if(HADDR_UNDEF != udata.addr) { + /* Insert the new piece into the global skip list */ + if(H5SL_insert(io_info->sel_pieces, new_piece_info, &new_piece_info->faddr) < 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 */ + } - /* Insert the new piece into the global skip list */ - if(H5SL_insert(io_info_md->sel_pieces, new_piece_info, &new_piece_info->faddr) < 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 */ - /* Insert the new piece into the dataset skip list */ if(H5SL_insert(dinfo->dset_sel_pieces, new_piece_info, &new_piece_info->index) < 0) { H5D__free_piece_info(new_piece_info, NULL, NULL); @@ -1969,119 +1367,6 @@ done: FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) } /* end H5D__create_piece_file_map_hyper() */ - -/*------------------------------------------------------------------------- - * Function: H5D__create_chunk_mem_map_hyper - * - * Purpose: Create all chunk selections in memory by copying the file - * chunk selections and adjusting their offsets to be correct - * for the memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, May 29, 2003 - * - * 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) -{ - H5SL_node_t *curr_node; /* Current node in skip list */ - hsize_t file_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t file_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - hsize_t mem_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ - hsize_t mem_sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */ - hssize_t adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to all file chunks */ - hssize_t chunk_adjust[H5O_LAYOUT_NDIMS]; /* Adjustment to make to a particular chunk */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Sanity check */ - HDassert(fm->f_ndims>0); - - /* Check for all I/O going to a single chunk */ - if(H5SL_count(fm->sel_chunks)==1) { - H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ - - /* Get the node */ - curr_node=H5SL_first(fm->sel_chunks); - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Just point at the memory dataspace & selection */ - /* (Casting away const OK -QAK) */ - chunk_info->mspace = (H5S_t *)fm->mem_space; - - /* Indicate that the chunk's memory space is shared */ - chunk_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) - 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) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info") - - /* Calculate the adjustment for memory selection from file selection */ - HDassert(fm->m_ndims==fm->f_ndims); - for(u=0; u<fm->f_ndims; u++) { - H5_CHECK_OVERFLOW(file_sel_start[u],hsize_t,hssize_t); - H5_CHECK_OVERFLOW(mem_sel_start[u],hsize_t,hssize_t); - adjust[u]=(hssize_t)file_sel_start[u]-(hssize_t)mem_sel_start[u]; - } /* end for */ - - /* Iterate over each chunk in the chunk list */ - curr_node=H5SL_first(fm->sel_chunks); - while(curr_node) { - H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */ - - /* Get pointer to chunk's information */ - chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node); - HDassert(chunk_info); - - /* Copy the information */ - - /* Copy the memory dataspace */ - if((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - - /* Release the current selection */ - if(H5S_SELECT_RELEASE(chunk_info->mspace) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection") - - /* Copy the file chunk's selection */ - if(H5S_select_copy(chunk_info->mspace,chunk_info->fspace,FALSE) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection") - - /* Compensate for the chunk offset */ - for(u=0; u<fm->f_ndims; u++) { - H5_CHECK_OVERFLOW(chunk_info->coords[u],hsize_t,hssize_t); - chunk_adjust[u]=adjust[u]-(hssize_t)chunk_info->coords[u]; /*lint !e771 The adjust array will always be initialized */ - } /* end for */ - - /* Adjust the selection */ - if(H5S_hyper_adjust_s(chunk_info->mspace,chunk_adjust) < 0) /*lint !e772 The chunk_adjust array will always be initialized */ - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection") - - /* Get the next chunk 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() */ - - /*------------------------------------------------------------------------- * Function: H5D__create_piece_mem_map_hyper * @@ -2099,7 +1384,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__create_piece_mem_map_hyper(const H5D_io_info_md_t *io_info_md, const H5D_dset_info_t *dinfo) +H5D__create_piece_mem_map_hyper(const H5D_io_info_t *io_info, const H5D_dset_info_t *dinfo) { H5SL_node_t *curr_node; /* Current node in skip list */ hsize_t file_sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */ @@ -2117,11 +1402,13 @@ H5D__create_piece_mem_map_hyper(const H5D_io_info_md_t *io_info_md, const H5D_ds assert(dinfo->f_ndims>0); /* Check for all I/O going to a single chunk */ - if(H5SL_count(io_info_md->sel_pieces)==1) { + //if(H5SL_count(io_info->sel_pieces) == 1) { + if(H5SL_count(dinfo->dset_sel_pieces) == 1) { H5D_piece_info_t *piece_info; /* Pointer to piece information */ /* Get the node */ - curr_node=H5SL_first(io_info_md->sel_pieces); + //curr_node=H5SL_first(io_info->sel_pieces); + curr_node=H5SL_first(dinfo->dset_sel_pieces); /* Get pointer to piece's information */ piece_info = (H5D_piece_info_t *)H5SL_item(curr_node); @@ -2154,6 +1441,7 @@ H5D__create_piece_mem_map_hyper(const H5D_io_info_md_t *io_info_md, const H5D_ds /* Iterate over each piece in the dataset's piece skiplist */ assert(dinfo->dset_sel_pieces); curr_node=H5SL_first(dinfo->dset_sel_pieces); + while(curr_node) { H5D_piece_info_t *piece_info; /* Pointer to piece information */ @@ -2192,126 +1480,11 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__create_piece_mem_map_hyper() */ - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_file_cb - * - * 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 - * - * Programmer: Quincey Koziol - * Wednesday, July 23, 2003 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__chunk_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_udata) -{ - 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 */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Calculate the index of this chunk */ - if(H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") - - /* Find correct chunk in file & memory skip list */ - 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; - } /* 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))) { - H5S_t *fspace; /* Memory chunk's dataspace */ - - /* Allocate the file & memory chunk information */ - if (NULL==(chunk_info = H5FL_MALLOC (H5D_chunk_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; - - /* 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); - 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); - 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; - - /* Set the memory chunk dataspace */ - chunk_info->mspace = NULL; - chunk_info->mspace_shared = FALSE; - - /* Set the number of selected elements in chunk to zero */ - chunk_info->chunk_points = 0; - - /* Compute the chunk's coordinates */ - for(u = 0; u < fm->f_ndims; u++) { - H5_CHECK_OVERFLOW(fm->layout->u.chunk.dim[u], hsize_t, hssize_t); - chunk_info->coords[u] = (coords[u] / (hssize_t)fm->layout->u.chunk.dim[u]) * (hssize_t)fm->layout->u.chunk.dim[u]; - } /* end for */ - chunk_info->coords[fm->f_ndims] = 0; - - /* 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") - } /* end if */ - } /* end if */ - - /* Update the "last chunk seen" information */ - fm->last_index = chunk_index; - fm->last_chunk_info = chunk_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] - chunk_info->coords[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) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element") - - /* Increment the number of elemented selected in chunk */ - chunk_info->chunk_points++; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_file_cb() */ - - /*------------------------------------------------------------------------- * Function: H5D__piece_file_cb * * Purpose: Callback routine for file selection iterator. Used when - * creating selections in file for each point selected. - * This was derived from H5D__chunk_file_cb for multi-dset work. + * creating selections in file for each point selected. * * Return: Non-negative on success/Negative on failure * @@ -2321,8 +1494,8 @@ done: static herr_t H5D__piece_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_opdata) { - H5D_io_info_md_wrap_t *opdata = (H5D_io_info_md_wrap_t *)_opdata; - H5D_io_info_md_t *io_info_md = (H5D_io_info_md_t *) opdata->io_info_md; /* io info for mumti dset */ + 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 mumti dset */ H5D_dset_info_t *dinfo = (H5D_dset_info_t *) opdata->dinfo; /* File<->memory piece mapping info */ H5D_piece_info_t *piece_info; /* Chunk information for current piece */ @@ -2334,11 +1507,12 @@ H5D__piece_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, cons FUNC_ENTER_STATIC /* Calculate the index of this chunk */ - if(H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) + if(H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, + dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Find correct chunk in file & memory skip list */ - if(chunk_index==dinfo->last_index) { + if(chunk_index == dinfo->last_index) { /* If the chunk index is the same as the last chunk index we used, * get the cached info to operate on. */ @@ -2364,7 +1538,7 @@ H5D__piece_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, cons piece_info->index = chunk_index; /* Create a dataspace for the chunk */ - if((fspace = H5S_create_simple(dinfo->f_ndims,dinfo->chunk_dim,NULL))==NULL) { + if((fspace = H5S_create_simple(dinfo->f_ndims, dinfo->chunk_dim, NULL)) == NULL) { 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 */ @@ -2390,36 +1564,39 @@ H5D__piece_file_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, cons /* Compute the chunk's coordinates */ for(u = 0; u < dinfo->f_ndims; u++) { H5_CHECK_OVERFLOW(dinfo->layout->u.chunk.dim[u], hsize_t, hssize_t); - piece_info->coords[u] = (coords[u] / (hssize_t)dinfo->layout->u.chunk.dim[u]) * (hssize_t)dinfo->layout->u.chunk.dim[u]; + piece_info->coords[u] = + (coords[u] / (hssize_t)dinfo->layout->u.chunk.dim[u]) * (hssize_t)dinfo->layout->u.chunk.dim[u]; } /* end for */ piece_info->coords[dinfo->f_ndims] = 0; /* make connection to related dset info from this piece_info */ piece_info->dset_info = dinfo; + /* Insert the new piece into the dataset skip list */ + if(H5SL_insert(dinfo->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 */ + /* set metadata tagging with dset oheader addr for H5D__chunk_lookup */ - if(H5AC_tag(io_info_md->dxpl_id, piece_info->dset_info->dset->oloc.addr, &prev_tag) < 0) + if(H5AC_tag(io_info->dxpl_id, piece_info->dset_info->dset->oloc.addr, &prev_tag) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") /* get chunk file address */ - if(H5D__chunk_lookup(piece_info->dset_info->dset, io_info_md->dxpl_id, + if(H5D__chunk_lookup(piece_info->dset_info->dset, io_info->dxpl_id, piece_info->coords, piece_info->index, &udata) < 0) - HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list") + HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skip list") piece_info->faddr = udata.addr; /* Reset metadata tagging */ - if(H5AC_tag(io_info_md->dxpl_id, prev_tag, NULL) < 0) + if(H5AC_tag(io_info->dxpl_id, prev_tag, NULL) < 0) HDONE_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") - /* Insert the new piece into the global skip list */ - if(H5SL_insert(io_info_md->sel_pieces,piece_info,&piece_info->faddr) < 0) { + if(HADDR_UNDEF != udata.addr) { + /* Insert the new piece into the global skip list */ + if(H5SL_insert(io_info->sel_pieces, piece_info, &piece_info->faddr) < 0) { H5D__free_piece_info(piece_info,NULL,NULL); - HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list") - } /* end if */ - - /* Insert the new piece into the dataset skip list */ - if(H5SL_insert(dinfo->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 */ + HGOTO_ERROR(H5E_DATASPACE,H5E_CANTINSERT,FAIL,"can't insert chunk into skip list") + } /* end if */ + } } /* end if */ /* Update the "last chunk seen" information */ @@ -2442,86 +1619,6 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__piece_file_cb */ - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_mem_cb - * - * Purpose: Callback routine for file selection iterator. Used when - * creating selections in memory for each chunk. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Thursday, April 10, 2003 - * - *------------------------------------------------------------------------- - */ -/* ARGSUSED */ -static herr_t -H5D__chunk_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_fm) -{ - 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[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */ - hsize_t chunk_index; /* Chunk index */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* Calculate the index of this chunk */ - if(H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks, &chunk_index) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") - - /* Find correct chunk in file & memory skip list */ - 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; - } /* 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))) - HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "can't locate chunk in skip list") - - /* Check if the chunk already has a memory space */ - if(NULL == chunk_info->mspace) { - /* Copy the template memory chunk dataspace */ - if(NULL == (chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space") - } /* end else */ - - /* Update the "last chunk seen" information */ - fm->last_index = chunk_index; - fm->last_chunk_info = chunk_info; - } /* end else */ - - /* Get coordinates of selection iterator for memory */ - if(H5S_SELECT_ITER_COORDS(&fm->mem_iter, coords_in_mem) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator coordinates") - - /* 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) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element") - } /* end if */ - else { - if(H5S_hyper_add_span_element(chunk_info->mspace, fm->m_ndims, coords_in_mem) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element") - } /* end else */ - - /* Move memory selection iterator to next element in selection */ - if(H5S_SELECT_ITER_NEXT(&fm->mem_iter, (size_t)1) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to move to next iterator location") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_mem_cb() */ - - /*------------------------------------------------------------------------- * Function: H5D__piece_mem_cb * @@ -2537,7 +1634,8 @@ done: static herr_t H5D__piece_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const hsize_t *coords, void *_opdata) { - H5D_io_info_md_wrap_t *opdata = (H5D_io_info_md_wrap_t *)_opdata; + 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 mumti dset */ H5D_dset_info_t *dinfo = (H5D_dset_info_t *) opdata->dinfo; /* File<->memory chunk mapping info */ H5D_piece_info_t *piece_info; /* Chunk information for current piece */ hsize_t coords_in_mem[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */ @@ -2547,7 +1645,8 @@ H5D__piece_mem_cb(void UNUSED *elem, hid_t UNUSED type_id, unsigned ndims, const FUNC_ENTER_STATIC /* Calculate the index of this chunk */ - if(H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) + if(H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, + dinfo->layout->u.chunk.down_chunks, &chunk_index) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index") /* Find correct chunk in file & memory skip list */ @@ -2615,12 +1714,13 @@ done: htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op) { - const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */ + const H5D_t *dataset = NULL; /* Local pointer to dataset */ htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_PACKAGE HDassert(io_info); + dataset = io_info->dsets_info[0].dset; HDassert(dataset); /* Must bring the whole chunk in if there are any filters */ @@ -2689,15 +1789,22 @@ done: static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, - H5D_chunk_map_t *fm) + H5D_dset_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 */ + + H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */ + H5D_dset_info_t nonexistent_dset_info; /* "nonexistent" I/O dset info object */ + H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */ + H5D_dset_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_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 src_accessed_bytes = 0; /* Total accessed size in a chunk */ hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */ herr_t ret_value = SUCCEED; /*return value */ @@ -2706,32 +1813,38 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Sanity check */ HDassert(io_info); - HDassert(io_info->u.rbuf); + HDassert(dset_info); + HDassert(dset_info->u.rbuf); HDassert(type_info); - HDassert(fm); /* Set up "nonexistent" I/O info object */ HDmemcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info)); - nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT; + HDmemcpy(&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; /* Set up contiguous I/O info object */ HDmemcpy(&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; /* Initialize temporary contiguous storage info */ - H5_ASSIGN_OVERFLOW(ctg_store.contig.dset_size, io_info->dset->shared->layout.u.chunk.size, uint32_t, hsize_t); + H5_ASSIGN_OVERFLOW(ctg_store.contig.dset_size, dset_info->dset->shared->layout.u.chunk.size, uint32_t, hsize_t); /* Set up compact I/O info object */ HDmemcpy(&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; /* Initialize temporary compact storage info */ cpt_store.compact.dirty = &cpt_dirty; { - const H5O_fill_t *fill = &(io_info->dset->shared->dcpl_cache.fill); /* Fill value info */ + 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 */ @@ -2749,19 +1862,20 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, } /* 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_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */ void *chunk; /* Pointer to locked chunk buffer */ H5D_chunk_ud_t udata; /* B-tree 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, io_info->dxpl_id, chunk_info->coords, chunk_info->index, &udata) < 0) + if(H5D__chunk_lookup(dset_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->index, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") /* Check for non-existant chunk & skip it if appropriate */ @@ -2772,12 +1886,12 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable") if(cacheable) { /* Pass in chunk's coordinates in a union. */ - io_info->store->chunk.offset = chunk_info->coords; - io_info->store->chunk.index = chunk_info->index; + dset_info->store->chunk.offset = chunk_info->coords; + dset_info->store->chunk.index = chunk_info->index; /* 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; + src_accessed_bytes = chunk_info->piece_points * (uint32_t)type_info->src_type_size; /* Lock the chunk into the cache */ if(NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE))) @@ -2809,7 +1923,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* 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) + (hsize_t)chunk_info->piece_points, chunk_info->fspace, chunk_info->mspace) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed") /* Release the cache lock on the chunk. */ @@ -2818,7 +1932,7 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, } /* 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 */ done: @@ -2841,12 +1955,14 @@ done: static herr_t H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, - H5D_chunk_map_t *fm) + H5D_dset_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_dset_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_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 */ @@ -2856,41 +1972,47 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Sanity check */ HDassert(io_info); - HDassert(io_info->u.wbuf); + HDassert(dset_info); + HDassert(dset_info->u.wbuf); HDassert(type_info); - HDassert(fm); /* Set up contiguous I/O info object */ HDmemcpy(&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; /* Initialize temporary contiguous storage info */ - H5_ASSIGN_OVERFLOW(ctg_store.contig.dset_size, io_info->dset->shared->layout.u.chunk.size, uint32_t, hsize_t); + H5_ASSIGN_OVERFLOW(ctg_store.contig.dset_size, dset_info->dset->shared->layout.u.chunk.size, uint32_t, hsize_t); /* Set up compact I/O info object */ HDmemcpy(&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; /* 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_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */ void *chunk; /* Pointer to locked chunk buffer */ H5D_chunk_ud_t udata; /* 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); /* Load the chunk into cache. But if the whole chunk is written, * simply allocate space instead of load the chunk. */ - if(H5D__chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords, chunk_info->index, &udata) < 0) + if(H5D__chunk_lookup(dset_info->dset, io_info->dxpl_id, chunk_info->coords, + chunk_info->index, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") if((cacheable = H5D__chunk_cacheable(io_info, udata.addr, TRUE)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable") @@ -2898,16 +2020,16 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */ /* Pass in chunk's coordinates in a union. */ - io_info->store->chunk.offset = chunk_info->coords; - io_info->store->chunk.index = chunk_info->index; + dset_info->store->chunk.offset = chunk_info->coords; + dset_info->store->chunk.index = chunk_info->index; /* 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; + dst_accessed_bytes = chunk_info->piece_points * (uint32_t)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) + (chunk_info->piece_points * type_info->src_type_size) != ctg_store.contig.dset_size) entire_chunk = FALSE; /* Lock the chunk into the cache */ @@ -2926,17 +2048,17 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chk_idx_info_t idx_info; /* Chunked index info */ /* Compose chunked index info struct */ - idx_info.f = io_info->dset->oloc.file; + idx_info.f = dset_info->dset->oloc.file; idx_info.dxpl_id = io_info->dxpl_id; - 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.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.nbytes = io_info->dset->shared->layout.u.chunk.size; + udata.nbytes = dset_info->dset->shared->layout.u.chunk.size; /* Create the chunk */ - if((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata) < 0) + if((dset_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert/resize chunk") /* Make sure the address of the chunk is returned. */ @@ -2944,7 +2066,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, 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 */ @@ -2957,9 +2079,13 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, chk_io_info = &ctg_io_info; } /* end else */ + HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER)); + HDassert(TRUE == H5P_isa_class(ctg_io_info.dxpl_id, H5P_DATASET_XFER)); + HDassert(TRUE == H5P_isa_class(chk_io_info->dxpl_id, H5P_DATASET_XFER)); + /* 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) + (hsize_t)chunk_info->piece_points, chunk_info->fspace, chunk_info->mspace) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed") /* Release the cache lock on the chunk. */ @@ -2967,7 +2093,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk") /* 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 */ done: @@ -3025,59 +2151,10 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_flush() */ - -/*------------------------------------------------------------------------- - * Function: H5D__chunk_io_term - * - * Purpose: Destroy I/O operation information. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Saturday, May 17, 2003 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__chunk_io_term(const H5D_chunk_map_t *fm) -{ - herr_t ret_value = SUCCEED; /*return value */ - - FUNC_ENTER_STATIC - - /* Single element I/O vs. multiple element I/O cleanup */ - if(fm->use_single) { - /* Sanity checks */ - HDassert(fm->sel_chunks == NULL); - HDassert(fm->single_chunk_info); - HDassert(fm->single_chunk_info->fspace_shared); - HDassert(fm->single_chunk_info->mspace_shared); - - /* Reset the selection for the single element I/O */ - H5S_select_all(fm->single_space, TRUE); - } /* end if */ - else { - /* Release the nodes on the list of selected chunks */ - if(fm->sel_chunks) - if(H5SL_free(fm->sel_chunks, H5D__free_chunk_info, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks") - } /* end else */ - - /* Free the memory chunk dataspace template */ - if(fm->mchunk_tmpl) - if(H5S_close(fm->mchunk_tmpl) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__chunk_io_term() */ - - /*------------------------------------------------------------------------- - * Function: H5D__piece_io_term_mdset + * Function: H5D__piece_io_term * * Purpose: Destroy I/O operation information. - * This was derived from H5D__chunk_io_term for multi-dset work. * * Return: Non-negative on success/Negative on failure * @@ -3085,7 +2162,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__piece_io_term_mdset(H5D_dset_info_t *di) +H5D__piece_io_term(H5D_io_info_t *io_info, H5D_dset_info_t *di) { herr_t ret_value = SUCCEED; /*return value */ @@ -3124,7 +2201,7 @@ H5D__piece_io_term_mdset(H5D_dset_info_t *di) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__piece_io_term_mdset() */ +} /* end H5D__piece_io_term() */ /*------------------------------------------------------------------------- @@ -3772,7 +2849,7 @@ void * H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax) { - const H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */ + const H5D_t *dset = io_info->dsets_info[0].dset; /* Local pointer to the dataset info */ const H5O_pline_t *pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info - always equal to the pline passed to H5D__chunk_alloc */ const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */ const H5O_fill_t *fill = &(dset->shared->dcpl_cache.fill); /* Fill value info */ @@ -3790,7 +2867,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, HDassert(io_info); HDassert(io_info->dxpl_cache); - HDassert(io_info->store); + HDassert(io_info->dsets_info[0].store); HDassert(udata); HDassert(dset); HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER)); @@ -3811,7 +2888,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, #ifndef NDEBUG /* Make sure this is the right chunk */ for(u = 0; u < layout->u.chunk.ndims; u++) - HDassert(io_info->store->chunk.offset[u] == ent->offset[u]); + HDassert(io_info->dsets_info[0].store->chunk.offset[u] == ent->offset[u]); #endif /* NDEBUG */ /* @@ -3939,17 +3016,17 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, } /* end if */ else if(rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max) { /* Calculate the index */ - udata->idx_hint = H5D_CHUNK_HASH(dset->shared, io_info->store->chunk.index); + udata->idx_hint = H5D_CHUNK_HASH(dset->shared, io_info->dsets_info[0].store->chunk.index); /* 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, io_info->dxpl_id, io_info->dxpl_cache, ent, TRUE) < 0) + if(H5D__chunk_cache_evict(io_info->dsets_info[0].dset, io_info->dxpl_id, io_info->dxpl_cache, 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, io_info->dxpl_id, io_info->dxpl_cache, chunk_size) < 0) + if(H5D__chunk_cache_prune(io_info->dsets_info[0].dset, io_info->dxpl_id, io_info->dxpl_cache, chunk_size) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache") /* Create a new entry */ @@ -3961,7 +3038,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, ent->deleted = FALSE; ent->chunk_addr = chunk_addr; for(u = 0; u < layout->u.chunk.ndims; u++) - ent->offset[u] = io_info->store->chunk.offset[u]; + ent->offset[u] = io_info->dsets_info[0].store->chunk.offset[u]; H5_ASSIGN_OVERFLOW(ent->rd_count, chunk_size, size_t, uint32_t); H5_ASSIGN_OVERFLOW(ent->wr_count, chunk_size, size_t, uint32_t); ent->chunk = (uint8_t *)chunk; @@ -4048,8 +3125,8 @@ 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) { - 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 = &(io_info->dsets_info[0].dset->shared->layout); /* Dataset layout */ + const H5D_rdcc_t *rdcc = &(io_info->dsets_info[0].dset->shared->cache.chunk); herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -4069,17 +3146,17 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, HDmemset(&fake_ent, 0, sizeof(fake_ent)); fake_ent.dirty = TRUE; - HDmemcpy(fake_ent.offset, io_info->store->chunk.offset, layout->u.chunk.ndims * sizeof(fake_ent.offset[0])); + HDmemcpy(fake_ent.offset, io_info->dsets_info[0].store->chunk.offset, layout->u.chunk.ndims * sizeof(fake_ent.offset[0])); HDassert(layout->u.chunk.size > 0); fake_ent.chunk_addr = udata->addr; fake_ent.chunk = (uint8_t *)chunk; - if(H5D__chunk_flush_entry(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, &fake_ent, TRUE) < 0) + if(H5D__chunk_flush_entry(io_info->dsets_info[0].dset, io_info->dxpl_id, io_info->dxpl_cache, &fake_ent, TRUE) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer") } /* end if */ else { if(chunk) - chunk = H5D__chunk_xfree(chunk, &(io_info->dset->shared->dcpl_cache.pline)); + chunk = H5D__chunk_xfree(chunk, &(io_info->dsets_info[0].dset->shared->dcpl_cache.pline)); } /* end else */ } /* end if */ else { @@ -4733,10 +3810,10 @@ static herr_t H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata) { 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 = io_info->dsets_info[0].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 *chunk_offset = io_info->store->chunk.offset; /* Chunk offset */ + const hsize_t *chunk_offset = io_info->dsets_info[0].store->chunk.offset; /* Chunk offset */ H5S_sel_iter_t chunk_iter; /* Memory selection iteration info */ hssize_t sel_nelmts; /* Number of elements in selection */ hsize_t count[H5O_LAYOUT_NDIMS]; /* Element count of hyperslab */ @@ -4755,7 +3832,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata) H5_ASSIGN_OVERFLOW(chunk_size, layout->u.chunk.size, uint32_t, size_t); /* Get the info for the chunk in the file */ - if(H5D__chunk_lookup(dset, io_info->dxpl_id, chunk_offset, io_info->store->chunk.index, &chk_udata) < 0) + if(H5D__chunk_lookup(dset, io_info->dxpl_id, chunk_offset, io_info->dsets_info[0].store->chunk.index, &chk_udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") /* If this chunk does not exist in cache or on disk, no need to do anything @@ -4949,6 +4026,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) hbool_t has_fill = FALSE; /* Whether there are chunks that must be filled */ H5D_chk_idx_info_t idx_info; /* Chunked index info */ H5D_io_info_t chk_io_info; /* Chunked I/O info object */ + H5D_dset_info_t chk_dset_info; /* Chunked I/O dset info object */ H5D_storage_t chk_store; /* Chunk storage information */ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ @@ -5025,7 +4103,13 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const 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.offset = chunk_offset; - H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, dxpl_cache, dxpl_id, &chk_store, NULL); + chk_io_info.dxpl_cache = dxpl_cache; + chk_io_info.dxpl_id = dxpl_id; + chk_io_info.op_type = H5D_IO_OP_READ; + chk_dset_info.dset = dset; + chk_dset_info.store = &chk_store; + chk_dset_info.u.rbuf = NULL; + chk_io_info.dsets_info = &chk_dset_info; /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; @@ -5137,7 +4221,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) /* Calculate the index of this chunk */ if(H5VM_chunk_index((unsigned)space_ndims, chunk_offset, layout->u.chunk.dim, layout->u.chunk.down_chunks, - &(chk_io_info.store->chunk.index)) < 0) + &(chk_dset_info.store->chunk.index)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index") if(0 == ndims_outside_fill) { @@ -5164,7 +4248,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) #endif /* NDEBUG */ /* Check if the chunk exists in cache or on disk */ - if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, chk_io_info.store->chunk.index, &chk_udata) < 0) + if(H5D__chunk_lookup(dset, dxpl_id, chunk_offset, chk_dset_info.store->chunk.index, &chk_udata) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk") /* Evict the entry from the cache if present, but do not flush @@ -6215,8 +5299,8 @@ H5D__nonexistent_readvv(const H5D_io_info_t *io_info, 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 *)io_info->dsets_info[0].u.rbuf; + udata.dset = io_info->dsets_info[0].dset; udata.dxpl_id = io_info->dxpl_id; /* Call generic sequence operation routine */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index 412c9db..a6d321f 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -60,9 +60,9 @@ /* Layout operation callbacks */ static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset); static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage); -static herr_t H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *cm); +static herr_t H5D__compact_io_init(H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, + const H5S_t *mem_space, H5D_dset_info_t *dinfo); static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]); @@ -82,7 +82,6 @@ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{ NULL, H5D__compact_is_space_alloc, H5D__compact_io_init, - NULL, H5D__contig_read, H5D__contig_write, #ifdef H5_HAVE_PARALLEL @@ -92,7 +91,6 @@ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{ H5D__compact_readvv, H5D__compact_writevv, H5D__compact_flush, - NULL, NULL }}; @@ -256,14 +254,14 @@ H5D__compact_is_space_alloc(const H5O_storage_t UNUSED *storage) *------------------------------------------------------------------------- */ static herr_t -H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *type_info, +H5D__compact_io_init(H5D_io_info_t UNUSED *io_info, const H5D_type_info_t UNUSED *type_info, hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, - H5D_chunk_map_t UNUSED *cm) + H5D_dset_info_t *dinfo) { FUNC_ENTER_STATIC_NOERR - io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf; - io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty; + dinfo->store->compact.buf = dinfo->dset->shared->layout.storage.u.compact.buf; + dinfo->store->compact.dirty = &dinfo->dset->shared->layout.storage.u.compact.dirty; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__compact_io_init() */ @@ -299,7 +297,9 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, HDassert(io_info); /* Use the vectorized memory copy routine to do actual work */ - if((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0) + if((ret_value = H5VM_memcpyvv(io_info->dsets_info[0].u.rbuf, mem_max_nseq, mem_curr_seq, + mem_size_arr, mem_offset_arr, io_info->dsets_info[0].store->compact.buf, + dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed") done: @@ -340,11 +340,14 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, HDassert(io_info); /* Use the vectorized memory copy routine to do actual work */ - if((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0) + if((ret_value = H5VM_memcpyvv(io_info->dsets_info[0].store->compact.buf, dset_max_nseq, + dset_curr_seq, dset_size_arr, dset_offset_arr, + io_info->dsets_info[0].u.wbuf, mem_max_nseq, mem_curr_seq, + mem_size_arr, mem_offset_arr)) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed") /* Mark the compact dataset's buffer as dirty */ - *io_info->store->compact.dirty = TRUE; + *io_info->dsets_info[0].store->compact.dirty = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 5333723..f997674 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -96,10 +96,8 @@ typedef struct H5D_contig_writevv_ud_t { /* Layout operation callbacks */ static herr_t H5D__contig_construct(H5F_t *f, H5D_t *dset); -static herr_t H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *cm); -static herr_t H5D__contig_io_init_mdset(H5D_io_info_md_t *io_info_md, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_dset_info_t *dinfo); +static herr_t H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, + hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_dset_info_t *dinfo); static ssize_t H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]); @@ -123,18 +121,16 @@ const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{ NULL, H5D__contig_is_space_alloc, H5D__contig_io_init, - H5D__contig_io_init_mdset, H5D__contig_read, H5D__contig_write, #ifdef H5_HAVE_PARALLEL - H5D__mdset_collective_read, - H5D__mdset_collective_write, + H5D__collective_read, + H5D__collective_write, #endif /* H5_HAVE_PARALLEL */ H5D__contig_readvv, H5D__contig_writevv, H5D__contig_flush, - NULL, - H5D__piece_io_term_mdset + H5D__piece_io_term }}; @@ -200,6 +196,7 @@ herr_t H5D__contig_fill(const H5D_t *dset, hid_t dxpl_id) { H5D_io_info_t ioinfo; /* Dataset I/O info */ + H5D_dset_info_t dset_info; /* Dset info */ H5D_storage_t store; /* Union of storage info for dataset */ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ @@ -278,7 +275,13 @@ H5D__contig_fill(const H5D_t *dset, hid_t dxpl_id) offset = 0; /* Simple setup for dataset I/O info struct */ - H5D_BUILD_IO_INFO_WRT(&ioinfo, dset, dxpl_cache, my_dxpl_id, &store, fb_info.fill_buf); + ioinfo.dxpl_cache = dxpl_cache; + ioinfo.dxpl_id = my_dxpl_id; + ioinfo.op_type = H5D_IO_OP_WRITE; + dset_info.dset = (H5D_t *)dset; + dset_info.store = &store; + dset_info.u.wbuf = fb_info.fill_buf; + ioinfo.dsets_info = &dset_info; /* * Fill the entire current extent with the fill value. We can do @@ -496,39 +499,11 @@ H5D__contig_is_space_alloc(const H5O_storage_t *storage) * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, March 20, 2008 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *type_info, - hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, - H5D_chunk_map_t UNUSED *cm) -{ - FUNC_ENTER_STATIC_NOERR - - io_info->store->contig.dset_addr = io_info->dset->shared->layout.storage.u.contig.addr; - io_info->store->contig.dset_size = io_info->dset->shared->layout.storage.u.contig.size; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5D__contig_io_init() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__contig_io_init_mdset - * - * Purpose: Performs initialization before any sort of I/O on the raw data - * - * This was referred from H5D__contig_io_init for multi-dset work. - * - * Return: Non-negative on success/Negative on failure - * * Programmer: Jonathan Kim *------------------------------------------------------------------------- */ static herr_t -H5D__contig_io_init_mdset(H5D_io_info_md_t *io_info_md, +H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_dset_info_t *dinfo) { @@ -547,6 +522,9 @@ H5D__contig_io_init_mdset(H5D_io_info_md_t *io_info_md, FUNC_ENTER_STATIC + dinfo->store->contig.dset_addr = dataset->shared->layout.storage.u.contig.addr; + dinfo->store->contig.dset_size = dataset->shared->layout.storage.u.contig.size; + /* Get layout for dataset */ dinfo->layout = &(dataset->shared->layout); /* num of element selected */ @@ -585,23 +563,23 @@ H5D__contig_io_init_mdset(H5D_io_info_md_t *io_info_md, /* Only need single skip list point over multiple read/write IO * and multiple dsets until H5D_close. Thus check both - * since io_info_md->sel_pieces only lives single write/read IO, + * since io_info->sel_pieces only lives single write/read IO, * even cache.sel_pieces lives until Dclose */ if(NULL == dataset->shared->cache.sel_pieces && - NULL == io_info_md->sel_pieces) { + NULL == io_info->sel_pieces) { if(NULL == (dataset->shared->cache.sel_pieces = H5SL_create(H5SL_TYPE_HADDR, NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for piece selections") /* keep the skip list in cache, so do not need to recreate until close */ - io_info_md->sel_pieces = dataset->shared->cache.sel_pieces; + io_info->sel_pieces = dataset->shared->cache.sel_pieces; } /* end if */ /* this is need when multiple write/read occurs on the same dsets, * just pass the previously created pointer */ - if (NULL == io_info_md->sel_pieces) - io_info_md->sel_pieces = dataset->shared->cache.sel_pieces; + if (NULL == io_info->sel_pieces) + io_info->sel_pieces = dataset->shared->cache.sel_pieces; - HDassert(io_info_md->sel_pieces); + HDassert(io_info->sel_pieces); /* We are not using single element mode */ dinfo->use_single = FALSE; @@ -625,99 +603,91 @@ H5D__contig_io_init_mdset(H5D_io_info_md_t *io_info_md, else sel_hyper_flag = TRUE; - /* - * This block is referred from H5D__create_piece_file_map_hyper as part of - * multi-dset work - * Note: may be able to make a seperate function as a seperate task later. - */ - { + /* if selected elements exist */ + if (dinfo->nelmts) { unsigned u; - - /* if selected elements exist */ - if (dinfo->nelmts) { - H5D_piece_info_t *new_piece_info; /* piece information to insert into skip list */ - - /* Get copy of dset file_space, so it can be changed temporarily - * purpose - * This tmp_fspace allows multiple write before close dset */ - H5S_t *tmp_fspace; /* Temporary file dataspace */ - /* Create "temporary" chunk for selection operations (copy file space) */ - if(NULL == (tmp_fspace = H5S_copy(dinfo->file_space, TRUE, FALSE))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") - - /* Actions specific to hyperslab selections */ - if(sel_hyper_flag) { - /* Sanity check */ - HDassert(dinfo->f_ndims > 0); - - /* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */ - if(H5S_hyper_convert(tmp_fspace) < 0) { - (void)H5S_close(tmp_fspace); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") - } /* end if */ - } /* end if */ - - /* Add temporary chunk to the list of pieces */ - /* collect piece_info into Skip List */ - /* Allocate the file & memory chunk information */ - if (NULL==(new_piece_info = H5FL_MALLOC (H5D_piece_info_t))) { + H5D_piece_info_t *new_piece_info; /* piece information to insert into skip list */ + + /* Get copy of dset file_space, so it can be changed temporarily + * purpose + * This tmp_fspace allows multiple write before close dset */ + H5S_t *tmp_fspace; /* Temporary file dataspace */ + /* Create "temporary" chunk for selection operations (copy file space) */ + if(NULL == (tmp_fspace = H5S_copy(dinfo->file_space, TRUE, FALSE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space") + + /* Actions specific to hyperslab selections */ + if(sel_hyper_flag) { + /* Sanity check */ + HDassert(dinfo->f_ndims > 0); + + /* Make certain selections are stored in span tree form (not "optimized hyperslab" or "all") */ + if(H5S_hyper_convert(tmp_fspace) < 0) { (void)H5S_close(tmp_fspace); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to convert selection to span trees") } /* end if */ + } /* end if */ - /* Set the piece index */ - new_piece_info->index = 0; + /* Add temporary chunk to the list of pieces */ + /* collect piece_info into Skip List */ + /* Allocate the file & memory chunk information */ + if (NULL==(new_piece_info = H5FL_MALLOC (H5D_piece_info_t))) { + (void)H5S_close(tmp_fspace); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info") + } /* end if */ - /* Set the file chunk dataspace */ - new_piece_info->fspace = tmp_fspace; - new_piece_info->fspace_shared = FALSE; + /* Set the piece index */ + new_piece_info->index = 0; - /* Set the memory chunk dataspace */ - /* same as one chunk, just use dset mem space */ - new_piece_info->mspace = mem_space; + /* Set the file chunk dataspace */ + new_piece_info->fspace = tmp_fspace; + new_piece_info->fspace_shared = FALSE; - /* set true for sharing mem space with dset, which means - * fspace gets free by applicaton H5Sclose(), and - * doesn't require providing layout_ops.io_term() for H5D_LOPS_CONTIG. - */ - new_piece_info->mspace_shared = TRUE; + /* Set the memory chunk dataspace */ + /* same as one chunk, just use dset mem space */ + new_piece_info->mspace = mem_space; - /* Copy the piece's coordinates */ - for(u = 0; u < dinfo->f_ndims; u++) - new_piece_info->coords[u] = 0; - new_piece_info->coords[dinfo->f_ndims] = 0; + /* set true for sharing mem space with dset, which means + * fspace gets free by applicaton H5Sclose(), and + * doesn't require providing layout_ops.io_term() for H5D_LOPS_CONTIG. + */ + new_piece_info->mspace_shared = TRUE; - /* make connection to related dset info from this piece_info */ - new_piece_info->dset_info = dinfo; + /* Copy the piece's coordinates */ + for(u = 0; u < dinfo->f_ndims; u++) + new_piece_info->coords[u] = 0; + new_piece_info->coords[dinfo->f_ndims] = 0; - /* get dset file address for piece */ - new_piece_info->faddr = dinfo->dset->shared->layout.storage.u.contig.addr; + /* make connection to related dset info from this piece_info */ + new_piece_info->dset_info = dinfo; - /* Save piece to last_piece_info so it is freed at the end of the - * operation */ - dinfo->last_piece_info = new_piece_info; + /* get dset file address for piece */ + new_piece_info->faddr = dinfo->dset->shared->layout.storage.u.contig.addr; - /* insert piece info */ - if(H5SL_insert(io_info_md->sel_pieces, new_piece_info, &new_piece_info->faddr) < 0) { - /* mimic H5D__free_piece_info */ - H5S_select_all(new_piece_info->fspace, TRUE); - H5FL_FREE(H5D_piece_info_t, new_piece_info); - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") - } /* end if */ + /* Save piece to last_piece_info so it is freed at the end of the + * operation */ + dinfo->last_piece_info = new_piece_info; - H5_ASSIGN_OVERFLOW(new_piece_info->piece_points, nelmts, hssize_t, uint32_t); - - /* only scratch for this dset */ - /* Clean hyperslab span's "scratch" information */ - if(sel_hyper_flag) - if(H5S_hyper_reset_scratch(new_piece_info->fspace) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") + /* insert piece info */ + if(H5SL_insert(io_info->sel_pieces, new_piece_info, &new_piece_info->faddr) < 0) { + /* mimic H5D__free_piece_info */ + H5S_select_all(new_piece_info->fspace, TRUE); + H5FL_FREE(H5D_piece_info_t, new_piece_info); + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list") } /* end if */ - } /* end block referred from H5D__create_piece_file_map_hyper */ + + H5_ASSIGN_OVERFLOW(new_piece_info->piece_points, nelmts, hssize_t, uint32_t); + + /* only scratch for this dset */ + /* Clean hyperslab span's "scratch" information */ + if(sel_hyper_flag) + if(H5S_hyper_reset_scratch(new_piece_info->fspace) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info") + } /* end if */ done: if(ret_value < 0) { - if(H5D__piece_io_term_mdset(dinfo) < 0) + if(H5D__piece_io_term(io_info, dinfo) < 0) HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping") } /* end if */ @@ -728,7 +698,7 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__contig_io_init_mdset() */ +} /* end H5D__contig_io_init() */ /*------------------------------------------------------------------------- @@ -746,7 +716,7 @@ done: herr_t H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t UNUSED *fm) + H5D_dset_info_t *dinfo) { herr_t ret_value = SUCCEED; /*return value */ @@ -754,7 +724,7 @@ H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Sanity check */ HDassert(io_info); - HDassert(io_info->u.rbuf); + HDassert(dinfo->u.rbuf); HDassert(type_info); HDassert(mem_space); HDassert(file_space); @@ -783,7 +753,7 @@ done: herr_t H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t UNUSED *fm) + H5D_dset_info_t *dinfo) { herr_t ret_value = SUCCEED; /*return value */ @@ -791,7 +761,7 @@ H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, /* Sanity check */ HDassert(io_info); - HDassert(io_info->u.wbuf); + HDassert(dinfo->u.wbuf); HDassert(type_info); HDassert(mem_space); HDassert(file_space); @@ -1063,6 +1033,7 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[]) { + H5D_dset_info_t dset_info; ssize_t ret_value; /* Return value */ FUNC_ENTER_STATIC @@ -1076,15 +1047,17 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, HDassert(mem_len_arr); HDassert(mem_off_arr); + dset_info = io_info->dsets_info[0]; + /* Check if data sieving is enabled */ - if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_DATA_SIEVE)) { + if(H5F_HAS_FEATURE(dset_info.dset->oloc.file, H5FD_FEAT_DATA_SIEVE)) { H5D_contig_readvv_sieve_ud_t udata; /* User data for H5VM_opvv() operator */ /* Set up user data for H5VM_opvv() */ - udata.file = io_info->dset->oloc.file; - udata.dset_contig = &(io_info->dset->shared->cache.contig); - udata.store_contig = &(io_info->store->contig); - udata.rbuf = (unsigned char *)io_info->u.rbuf; + udata.file = dset_info.dset->oloc.file; + udata.dset_contig = &(dset_info.dset->shared->cache.contig); + udata.store_contig = &(dset_info.store->contig); + udata.rbuf = (unsigned char *)dset_info.u.rbuf; udata.dxpl_id = io_info->dxpl_id; /* Call generic sequence operation routine */ @@ -1097,9 +1070,9 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, H5D_contig_readvv_ud_t udata; /* User data for H5VM_opvv() operator */ /* Set up user data for H5VM_opvv() */ - udata.file = io_info->dset->oloc.file; - udata.dset_addr = io_info->store->contig.dset_addr; - udata.rbuf = (unsigned char *)io_info->u.rbuf; + udata.file = dset_info.dset->oloc.file; + udata.dset_addr = dset_info.store->contig.dset_addr; + udata.rbuf = (unsigned char *)dset_info.u.rbuf; udata.dxpl_id = io_info->dxpl_id; /* Call generic sequence operation routine */ @@ -1384,6 +1357,7 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[]) { + H5D_dset_info_t dset_info; ssize_t ret_value; /* Return value (Size of sequence in bytes) */ FUNC_ENTER_STATIC @@ -1397,15 +1371,17 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, HDassert(mem_len_arr); HDassert(mem_off_arr); + dset_info = io_info->dsets_info[0]; + /* Check if data sieving is enabled */ - if(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_DATA_SIEVE)) { + if(H5F_HAS_FEATURE(dset_info.dset->oloc.file, H5FD_FEAT_DATA_SIEVE)) { H5D_contig_writevv_sieve_ud_t udata; /* User data for H5VM_opvv() operator */ /* Set up user data for H5VM_opvv() */ - udata.file = io_info->dset->oloc.file; - udata.dset_contig = &(io_info->dset->shared->cache.contig); - udata.store_contig = &(io_info->store->contig); - udata.wbuf = (const unsigned char *)io_info->u.wbuf; + udata.file = dset_info.dset->oloc.file; + udata.dset_contig = &(dset_info.dset->shared->cache.contig); + udata.store_contig = &(dset_info.store->contig); + udata.wbuf = (const unsigned char *)dset_info.u.wbuf; udata.dxpl_id = io_info->dxpl_id; /* Call generic sequence operation routine */ @@ -1418,9 +1394,9 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, H5D_contig_writevv_ud_t udata; /* User data for H5VM_opvv() operator */ /* Set up user data for H5VM_opvv() */ - udata.file = io_info->dset->oloc.file; - udata.dset_addr = io_info->store->contig.dset_addr; - udata.wbuf = (const unsigned char *)io_info->u.wbuf; + udata.file = dset_info.dset->oloc.file; + udata.dset_addr = dset_info.store->contig.dset_addr; + udata.wbuf = (const unsigned char *)dset_info.u.wbuf; udata.dxpl_id = io_info->dxpl_id; /* Call generic sequence operation routine */ diff --git a/src/H5Defl.c b/src/H5Defl.c index 9e060c3..613699f 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -64,9 +64,9 @@ typedef struct H5D_efl_writevv_ud_t { /* Layout operation callbacks */ static herr_t H5D__efl_construct(H5F_t *f, H5D_t *dset); -static herr_t H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, - hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *cm); +static herr_t H5D__efl_io_init(H5D_io_info_t *io_info, + const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, + const H5S_t *mem_space, H5D_dset_info_t *dinfo); static ssize_t H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]); @@ -91,7 +91,6 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{ NULL, H5D__efl_is_space_alloc, H5D__efl_io_init, - NULL, H5D__contig_read, H5D__contig_write, #ifdef H5_HAVE_PARALLEL @@ -101,7 +100,6 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{ H5D__efl_readvv, H5D__efl_writevv, NULL, - NULL, NULL }}; @@ -225,13 +223,13 @@ H5D__efl_is_space_alloc(const H5O_storage_t UNUSED *storage) *------------------------------------------------------------------------- */ static herr_t -H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t UNUSED *type_info, +H5D__efl_io_init(H5D_io_info_t UNUSED *io_info, const H5D_type_info_t UNUSED *type_info, hsize_t UNUSED nelmts, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space, - H5D_chunk_map_t UNUSED *cm) + H5D_dset_info_t *dinfo) { FUNC_ENTER_STATIC_NOERR - HDmemcpy(&io_info->store->efl, &(io_info->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t)); + HDmemcpy(&dinfo->store->efl, &(dinfo->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t)); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__efl_io_init() */ @@ -468,8 +466,8 @@ H5D__efl_readvv(const H5D_io_info_t *io_info, /* Check args */ HDassert(io_info); - HDassert(io_info->store->efl.nused > 0); - HDassert(io_info->u.rbuf); + HDassert(io_info->dsets_info[0].store->efl.nused > 0); + HDassert(io_info->dsets_info[0].u.rbuf); HDassert(dset_curr_seq); HDassert(dset_len_arr); HDassert(dset_off_arr); @@ -478,8 +476,8 @@ H5D__efl_readvv(const H5D_io_info_t *io_info, HDassert(mem_off_arr); /* Set up user data for H5VM_opvv() */ - udata.efl = &(io_info->store->efl); - udata.rbuf = (unsigned char *)io_info->u.rbuf; + udata.efl = &(io_info->dsets_info[0].store->efl); + udata.rbuf = (unsigned char *)io_info->dsets_info[0].u.rbuf; /* Call generic sequence operation routine */ if((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, @@ -548,8 +546,8 @@ H5D__efl_writevv(const H5D_io_info_t *io_info, /* Check args */ HDassert(io_info); - HDassert(io_info->store->efl.nused > 0); - HDassert(io_info->u.wbuf); + HDassert(io_info->dsets_info[0].store->efl.nused > 0); + HDassert(io_info->dsets_info[0].u.wbuf); HDassert(dset_curr_seq); HDassert(dset_len_arr); HDassert(dset_off_arr); @@ -558,8 +556,8 @@ H5D__efl_writevv(const H5D_io_info_t *io_info, HDassert(mem_off_arr); /* Set up user data for H5VM_opvv() */ - udata.efl = &(io_info->store->efl); - udata.wbuf = (const unsigned char *)io_info->u.wbuf; + udata.efl = &(io_info->dsets_info[0].store->efl); + udata.wbuf = (const unsigned char *)io_info->dsets_info[0].u.wbuf; /* Call generic sequence operation routine */ if((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, diff --git a/src/H5Dint.c b/src/H5Dint.c index 15c65e5..04b4e5d 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -100,9 +100,6 @@ H5FL_DEFINE_STATIC(H5D_shared_t); /* Declare the external PQ free list for the sieve buffer information */ H5FL_BLK_EXTERN(sieve_buf); -/* Declare the external free list to manage the H5D_chunk_info_t struct */ -H5FL_EXTERN(H5D_chunk_info_t); - /* Declare the external free list to manage the H5D_piece_info_t struct */ H5FL_EXTERN(H5D_piece_info_t); @@ -1437,12 +1434,9 @@ H5D_close(H5D_t *dataset) } /* end if */ /* Check for cached single element chunk info */ - if(dataset->shared->cache.chunk.single_chunk_info) - dataset->shared->cache.chunk.single_chunk_info = H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info); - - /* Check for cached single element piece info */ if(dataset->shared->cache.chunk.single_piece_info) - dataset->shared->cache.chunk.single_piece_info = H5FL_FREE(H5D_piece_info_t, dataset->shared->cache.chunk.single_piece_info); + dataset->shared->cache.chunk.single_piece_info = + H5FL_FREE(H5D_piece_info_t, dataset->shared->cache.chunk.single_piece_info); /* Flush and destroy chunks in the cache. Continue to close even if * it fails. */ @@ -2074,6 +2068,7 @@ herr_t H5D__vlen_get_buf_size(void UNUSED *elem, hid_t type_id, unsigned UNUSED ndim, const hsize_t *point, void *op_data) { H5D_vlen_bufsize_t *vlen_bufsize = (H5D_vlen_bufsize_t *)op_data; + H5D_dset_info_t *dset_info = NULL; /* Internal multi-dataset info placeholder */ H5T_t *dt; /* Datatype for operation */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2094,11 +2089,30 @@ H5D__vlen_get_buf_size(void UNUSED *elem, hid_t type_id, unsigned UNUSED ndim, c if(H5S_select_elements(vlen_bufsize->fspace, H5S_SELECT_SET, (size_t)1, point) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't select point") - /* Read in the point (with the custom VL memory allocator) */ - if(H5D__read(vlen_bufsize->dset, type_id, vlen_bufsize->mspace, vlen_bufsize->fspace, vlen_bufsize->xfer_pid, vlen_bufsize->fl_tbuf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read point") + { + hid_t file_id; /* File ID for operation */ + + /* Alloc dset_info */ + if(NULL == (dset_info = (H5D_dset_info_t *)H5MM_calloc(sizeof(H5D_dset_info_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dset info array buffer") + + dset_info->dset = vlen_bufsize->dset; + dset_info->mem_space = vlen_bufsize->mspace; + dset_info->file_space = vlen_bufsize->fspace; + dset_info->u.rbuf = vlen_bufsize->fl_tbuf; + dset_info->mem_type_id = type_id; + + /* Retrieve file_id */ + file_id = H5F_FILE_ID(dset_info->dset->oloc.file); + + /* Read in the point (with the custom VL memory allocator) */ + if(H5D__read(file_id, vlen_bufsize->xfer_pid, 1, dset_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + } done: + if(dset_info) + H5MM_xfree(dset_info); FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__vlen_get_buf_size() */ diff --git a/src/H5Dio.c b/src/H5Dio.c index 5bae705..f4c997a 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -56,14 +56,9 @@ static herr_t H5D__pre_read(hid_t file_id, hid_t dxpl_id, size_t count, H5D_dset_info_t *dset_info); static herr_t H5D__pre_write(hid_t file_id, hid_t dxpl_id, size_t count, H5D_dset_info_t *dset_info); -static herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, - const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, - const void *buf); /* Internal I/O routines for multi-dset */ -static herr_t H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, - H5D_dset_info_t *dset_info); -static herr_t H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, +static herr_t H5D__write(hid_t file_id, hid_t dxpl_id, size_t count, H5D_dset_info_t *dset_info); /* Setup/teardown routines */ @@ -71,25 +66,14 @@ static herr_t H5D__ioinfo_init(H5D_t *dset, #ifndef H5_HAVE_PARALLEL const #endif /* H5_HAVE_PARALLEL */ - H5D_dxpl_cache_t *dxpl_cache, - hid_t dxpl_id, const H5D_type_info_t *type_info, H5D_storage_t *store, - H5D_io_info_t *io_info); -static herr_t H5D__ioinfo_init_mdset(H5D_t *dset, -#ifndef H5_HAVE_PARALLEL - const -#endif /* H5_HAVE_PARALLEL */ H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, H5D_dset_info_t *dset_info, - H5D_storage_t *store, H5D_io_info_md_t *io_info_md); + H5D_storage_t *store, H5D_io_info_t *io_info); static herr_t H5D__typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, hid_t mem_type_id, hbool_t do_write, H5D_type_info_t *type_info); #ifdef H5_HAVE_PARALLEL -static herr_t H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, - hid_t dxpl_id, const H5S_t *file_space, const H5S_t *mem_space, - const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm); -static herr_t H5D__ioinfo_adjust_mdset(const size_t count, H5D_io_info_md_t *io_info_md, hid_t dxpl_id); +static herr_t H5D__ioinfo_adjust(const size_t count, H5D_io_info_t *io_info, hid_t dxpl_id); static herr_t H5D__ioinfo_term(H5D_io_info_t *io_info); -static herr_t H5D__ioinfo_term_mdset(H5D_io_info_md_t *io_info_md); #endif /* H5_HAVE_PARALLEL */ static herr_t H5D__typeinfo_term(const H5D_type_info_t *type_info); @@ -121,7 +105,7 @@ H5FL_BLK_DEFINE(type_conv); * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5D__init_dset_info(H5D_dset_info_t *dset_info, hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t dset_space_id, const H5D_dset_buf_t *u_buf) @@ -253,14 +237,8 @@ done: /*------------------------------------------------------------------------- * Function: H5Dread_multi * - * Purpose: Reads multiple (part of) DSETs from a file into application - * memory BUFs. The part of the dataset to read is defined with - * MEM_SPACE_IDs and FILE_SPACE_IDs. The data points are - * converted from their file type to the MEM_TYPE_ID specified. - * Additional miscellaneous data transfer properties can be - * passed to this function with the PLIST_ID argument. - * - * This was referred from H5Dread for multi-dset work. + * Purpose: Multi-version of H5Dread(), which reads selections from + * multiple datasets from a file into application memory BUFS. * * Return: Non-negative on success/Negative on failure * @@ -292,8 +270,6 @@ H5Dread_multi(hid_t file_id, hid_t dxpl_id, size_t count, H5D_rw_multi_t *info) /* Translate public multi-dataset info to internal structure */ /* (And check parameters) */ for(u = 0; u < count; u++) { - /* Translate public multi-dataset info to internal structure */ - /* (And check parameters) */ if(H5D__init_dset_info(&dset_info[u], info[u].dset_id, info[u].mem_type_id, info[u].mem_space_id, info[u].dset_space_id, &(info[u].u.rbuf)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't init dataset info") @@ -303,7 +279,7 @@ H5Dread_multi(hid_t file_id, hid_t dxpl_id, size_t count, H5D_rw_multi_t *info) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset's file ID doesn't match file_id parameter") } /* end for */ - /* Call common pre-write routine */ + /* Call common pre-read routine */ if(H5D__pre_read(file_id, dxpl_id, count, dset_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't prepare for reading data") @@ -332,7 +308,7 @@ H5D__pre_read(hid_t file_id, hid_t dxpl_id, size_t count, { H5P_genplist_t *plist; /* DXPL property list pointer */ H5FD_mpio_xfer_t xfer_mode; /* Parallel I/O transfer mode */ - hbool_t broke_mdset = FALSE; /* Whether to break collective */ + hbool_t broke_mdset = FALSE; /* Whether to break multi-dataset option */ size_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -351,88 +327,47 @@ H5D__pre_read(hid_t file_id, hid_t dxpl_id, size_t count, if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") -/***********************************************/ -/* QAK: Does not seem to be in H5D__pre_write? */ -/***********************************************/ - /* Check for unsupported layouts */ - for(u = 0; u < count; u++) { + /* In independent mode or with an unsupported layout, for now just + read each dataset individually */ + if(xfer_mode == H5FD_MPIO_INDEPENDENT) + broke_mdset = TRUE; + else { /* Multi-dset I/O currently supports CHUNKED and internal CONTIGUOUS * only, not external CONTIGUOUS (EFL) or COMPACT. Fall back to * individual dataset reads if any dataset uses an unsupported layout. */ - if(!(dset_info[u].dset->shared->layout.type == H5D_CHUNKED || - (dset_info[u].dset->shared->layout.type == H5D_CONTIGUOUS && - dset_info[u].dset->shared->layout.ops != H5D_LOPS_EFL))) - broke_mdset = TRUE; - } /* end for */ + for(u = 0; u < count; u++) { + if(!(dset_info[u].dset->shared->layout.type == H5D_CHUNKED || + (dset_info[u].dset->shared->layout.type == H5D_CONTIGUOUS && + dset_info[u].dset->shared->layout.ops != H5D_LOPS_EFL))) { + broke_mdset = TRUE; + break; + } + } /* end for */ + } - if((xfer_mode == H5FD_MPIO_INDEPENDENT) || broke_mdset) { - /* In independent mode or with an unsupported layout, for now just read - * each dataset individually */ + if(broke_mdset) { + /* Read raw data from each dataset by iteself */ for(u = 0; u < count; u++) - /* Read raw data */ - if(H5D__read(dset_info[u].dset, dset_info[u].mem_type_id, dset_info[u].mem_space, dset_info[u].file_space, dxpl_id, dset_info[u].u.rbuf) < 0) + if(H5D__read(file_id, dxpl_id, 1, &dset_info[u]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") } /* end if */ else { HDassert(xfer_mode == H5FD_MPIO_COLLECTIVE); if(count > 0) { - if(H5D__read_mdset(file_id, dxpl_id, count, dset_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") + if(H5D__read(file_id, dxpl_id, count, dset_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") } /* end if */ #ifdef H5_HAVE_PARALLEL + /* MSC - I do not think we should allow for this. I think we + should make the multi dataset APIs enforce a uniform list + of datasets among all processes, and users would enter a + NULL selection when a process does not have anything to + write to a particulat dataset. */ else { - /* Case for the current process without any dset to work on, thus doing - * nothing but has participate to prevent hanging, since all process - * have to participate collective MPI funcs (below). - */ - int local_cause = 0; - int global_cause = 0; - int mpi_code; - H5F_t *file; - H5FD_mpio_collective_opt_t para_io_mode; - - HDassert(file_id > 0); - - /* get parallel io mode */ - if(H5P_get(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, ¶_io_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") - - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - - /* just to match up with MPI_Allreduce from H5D__mpio_opt_possible_mdset() */ - if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, MPI_INT, MPI_BOR, H5F_mpi_get_comm(file)))) - HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) - - /* if collective mode is not broken according to the - * H5D__mpio_opt_possible_mdset, since the below MPI funcs will be - * called only in collective mode */ - if(!global_cause) { - MPI_Status mpi_stat; - MPI_File mpi_fh_p; - MPI_File mpi_fh; - - if(H5F_get_mpi_handle(file, (MPI_File **)&mpi_fh_p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle") - mpi_fh = *(MPI_File*)mpi_fh_p; - - /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_read() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) - - /* just to match up with MPI_File_write_at_all from H5FD_mpio_read() */ - if(para_io_mode == H5FD_MPIO_COLLECTIVE_IO) { - HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); - if(MPI_SUCCESS != (mpi_code = MPI_File_read_at_all(mpi_fh, 0, NULL, 0, MPI_BYTE, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at_all failed", mpi_code) - } /* end if */ - - /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_read() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) - } /* end if !global_cause */ + if(H5D__match_coll_calls(file_id, plist, TRUE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "failed in matching collective MPI calls") } /* end else */ #endif /* H5_HAVE_PARALLEL */ } /* end if */ @@ -521,15 +456,8 @@ done: /*------------------------------------------------------------------------- * Function: H5Dwrite_multi * - * Purpose: Writes multiple (part of) DSETs from application memory BUFs to the - * file. The part of the datasets to write is defined with the - * MEM_SPACE_IDs and FILE_SPACE_IDs arguments. The data points - * are converted from their current type (MEM_TYPE_ID) to their - * file datatype. Additional miscellaneous data transfer - * properties can be passed to this function with the - * PLIST_ID argument. - * - * This was referred from H5Dwrite for multi-dset work. + * Purpose: Multi-version of H5Dwrite(), which writes selections from + * application memory BUFs into multiple datasets in a file. * * Return: Non-negative on success/Negative on failure * @@ -561,8 +489,6 @@ H5Dwrite_multi(hid_t file_id, hid_t dxpl_id, size_t count, const H5D_rw_multi_t /* Translate public multi-dataset info to internal structure */ /* (And check parameters) */ for(u = 0; u < count; u++) { - /* Translate public multi-dataset info to internal structure */ - /* (And check parameters) */ if(H5D__init_dset_info(&dset_info[u], info[u].dset_id, info[u].mem_type_id, info[u].mem_space_id, info[u].dset_space_id, &(info[u].u.wbuf)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't init dataset info") @@ -672,85 +598,56 @@ H5D__pre_write(hid_t file_id, hid_t dxpl_id, size_t count, HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write chunk directly") } /* end if */ else { + size_t u; /* Local index variable */ + hbool_t broke_mdset = FALSE; /* Whether to break multi-dataset option */ H5FD_mpio_xfer_t xfer_mode; /* Parallel I/O transfer mode */ /* Get the transfer mode */ if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") - if(xfer_mode == H5FD_MPIO_INDEPENDENT) { - size_t u; /* Local index variable */ - - /* In independent mode, for now just write each dataset individually */ + /* In independent mode or with an unsupported layout, for now + just write each dataset individually */ + if(xfer_mode == H5FD_MPIO_INDEPENDENT) + broke_mdset = TRUE; + else { + /* Multi-dset I/O currently supports CHUNKED and internal CONTIGUOUS + * only, not external CONTIGUOUS (EFL) or COMPACT. Fall back to + * individual dataset writes if any dataset uses an unsupported layout. + */ + for(u = 0; u < count; u++) { + if(!(dset_info[u].dset->shared->layout.type == H5D_CHUNKED || + (dset_info[u].dset->shared->layout.type == H5D_CONTIGUOUS && + dset_info[u].dset->shared->layout.ops != H5D_LOPS_EFL))) { + broke_mdset = TRUE; + break; + } + } /* end for */ + } + + if(broke_mdset) { + /* Write raw data to each dataset by iteself */ for(u = 0; u < count; u++) - /* Write raw data */ - if(H5D__write(dset_info[u].dset, dset_info[u].mem_type_id, dset_info[u].mem_space, - dset_info[u].file_space, dxpl_id, dset_info[u].u.wbuf) < 0) + if(H5D__write(file_id, dxpl_id, 1, &dset_info[u]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") } /* end if */ else { HDassert(xfer_mode == H5FD_MPIO_COLLECTIVE); if(count > 0) { - if(H5D__write_mdset(file_id, dxpl_id, count, dset_info) < 0) + if(H5D__write(file_id, dxpl_id, count, dset_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") } /* end if */ + #ifdef H5_HAVE_PARALLEL + /* MSC - I do not think we should allow for this. I think we + should make the multi dataset APIs enforce a uniform list + of datasets among all processes, and users would enter a + NULL selection when a process does not have anything to + write to a particulat dataset. */ else { - /* Case for the current process without any dset to work on, thus doing - * nothing but has participate to prevent hanging, since all process - * have to participate collective MPI funcs (below). - */ - int local_cause = 0; - int global_cause = 0; - int mpi_code; - H5F_t *file; - H5FD_mpio_collective_opt_t para_io_mode; - - HDassert(file_id > 0); - - /* get parallel io mode */ - if(H5P_get(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, ¶_io_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") - - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - - /* just to match up with MPI_Allreduce from H5D__mpio_opt_possible_mdset() */ - if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, - MPI_INT, MPI_BOR, H5F_mpi_get_comm(file)))) - HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) - - /* if collective mode is not broken according to the - * H5D__mpio_opt_possible_mdset, since the below MPI funcs will be - * called only in collective mode */ - if(!global_cause) { - MPI_Status mpi_stat; - MPI_File mpi_fh_p; - MPI_File mpi_fh; - - if(H5F_get_mpi_handle(file, (MPI_File **)&mpi_fh_p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle") - mpi_fh = *(MPI_File*)mpi_fh_p; - - /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, - MPI_BYTE, "native", MPI_INFO_NULL))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) - - /* just to match up with MPI_File_write_at_all from H5FD_mpio_write() */ - if(para_io_mode == H5FD_MPIO_COLLECTIVE_IO) { - HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); - if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, 0, NULL, 0, - MPI_BYTE, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) - } /* end if */ - - /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_write() */ - if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, - MPI_BYTE, "native", MPI_INFO_NULL))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) - } /* end if !global_cause */ + if(H5D__match_coll_calls(file_id, plist, FALSE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "failed in matching collective MPI calls") } /* end else */ #endif /* H5_HAVE_PARALLEL */ } /* end else */ @@ -764,221 +661,6 @@ done: /*------------------------------------------------------------------------- * Function: H5D__read * - * Purpose: Reads (part of) a DATASET into application memory BUF. See - * H5Dread() for complete details. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, - const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/) -{ - H5D_chunk_map_t fm; /* Chunk file<->memory mapping */ - H5D_io_info_t io_info; /* Dataset I/O info */ - H5D_type_info_t type_info; /* Datatype info for operation */ - hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */ - H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */ - /* projection of the supplied mem_space to a new */ - /* dataspace with rank equal to that of */ - /* file_space. */ - /* */ - /* This field is only used if */ - /* H5S_select_shape_same() returns TRUE when */ - /* comparing the mem_space and the data_space, */ - /* and the mem_space have different rank. */ - /* */ - /* Note that if this variable is used, the */ - /* projected mem space must be discarded at the */ - /* end of the function to avoid a memory leak. */ - H5D_storage_t store; /*union of EFL and chunk pointer in file space */ - hssize_t snelmts; /*total number of elmts (signed) */ - hsize_t nelmts; /*total number of elmts */ -#ifdef H5_HAVE_PARALLEL - hbool_t io_info_init = FALSE; /* Whether the I/O info has been initialized */ -#endif /*H5_HAVE_PARALLEL*/ - hbool_t io_op_init = FALSE; /* Whether the I/O op has been initialized */ - H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ - H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - char fake_char; /* Temporary variable for NULL buffer pointers */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE_TAG(dxpl_id, dataset->oloc.addr, FAIL) - - /* check args */ - HDassert(dataset && dataset->oloc.file); - - if(!file_space) - file_space = dataset->shared->space; - if(!mem_space) - mem_space = file_space; - if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dst dataspace has invalid selection") - H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t); - - /* Fill the DXPL cache values for later use */ - if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") - - /* Set up datatype info for operation */ - if(H5D__typeinfo_init(dataset, dxpl_cache, dxpl_id, mem_type_id, FALSE, &type_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info") - type_info_init = TRUE; - -#ifdef H5_HAVE_PARALLEL - /* Collective access is not permissible without a MPI based VFD */ - if(dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE && - !(H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI))) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based drivers only") -#endif /*H5_HAVE_PARALLEL*/ - - /* Make certain that the number of elements in each selection is the same */ - if(nelmts != (hsize_t)H5S_GET_SELECT_NPOINTS(file_space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspace have different sizes") - - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ - if(NULL == buf) { - /* Check for any elements selected (which is invalid) */ - if(nelmts > 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") - - /* If the buffer is nil, and 0 element is selected, make a fake buffer. - * This is for some MPI package like ChaMPIon on NCSA's tungsten which - * doesn't support this feature. - */ - buf = &fake_char; - } /* end if */ - - /* Make sure that both selections have their extents set */ - if(!(H5S_has_extent(file_space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set") - if(!(H5S_has_extent(mem_space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") - - /* H5S_select_shape_same() has been modified to accept topologically identical - * selections with different rank as having the same shape (if the most - * rapidly changing coordinates match up), but the I/O code still has - * difficulties with the notion. - * - * To solve this, we check to see if H5S_select_shape_same() returns true, - * and if the ranks of the mem and file spaces are different. If the are, - * construct a new mem space that is equivalent to the old mem space, and - * use that instead. - * - * Note that in general, this requires us to touch up the memory buffer as - * well. - */ - if(TRUE == H5S_select_shape_same(mem_space, file_space) && - H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ - /* to the beginning of the projected mem space. */ - - /* Attempt to construct projected dataspace for memory dataspace */ - if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.dst_type_size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") - HDassert(projected_mem_space); - HDassert(adj_buf); - - /* Switch to using projected memory dataspace & adjusted buffer */ - mem_space = projected_mem_space; - buf = (void *)adj_buf; - } /* end if */ - - /* Retrieve dataset properties */ - /* <none needed in the general case> */ - - /* If space hasn't been allocated and not using external storage, - * return fill value to buffer if fill time is upon allocation, or - * do nothing if fill time is never. If the dataset is compact and - * fill time is NEVER, there is no way to tell whether part of data - * has been overwritten. So just proceed in reading. - */ - if(nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 && - !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) { - H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */ - - /* Retrieve dataset's fill-value properties */ - if(H5P_is_fill_value_defined(&dataset->shared->dcpl_cache.fill, &fill_status) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined") - - /* Should be impossible, but check anyway... */ - if(fill_status == H5D_FILL_VALUE_UNDEFINED && - (dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC || dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET)) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "read failed: dataset doesn't exist, no data can be read") - - /* If we're never going to fill this dataset, just leave the junk in the user's buffer */ - if(dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_NEVER) - HGOTO_DONE(SUCCEED) - - /* Go fill the user's selection with the dataset's fill value */ - if(H5D__fill(dataset->shared->dcpl_cache.fill.buf, dataset->shared->type, buf, type_info.mem_type, mem_space, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed") - else - HGOTO_DONE(SUCCEED) - } /* end if */ - - /* Set up I/O operation */ - io_info.op_type = H5D_IO_OP_READ; - io_info.u.rbuf = buf; - if(H5D__ioinfo_init(dataset, dxpl_cache, dxpl_id, &type_info, &store, &io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation") -#ifdef H5_HAVE_PARALLEL - io_info_init = TRUE; -#endif /*H5_HAVE_PARALLEL*/ - - /* Sanity check that space is allocated, if there are elements */ - if(nelmts > 0) - HDassert((*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) - || dataset->shared->dcpl_cache.efl.nused > 0 - || dataset->shared->layout.type == H5D_COMPACT); - - /* Call storage method's I/O initialization routine */ - HDmemset(&fm, 0, sizeof(H5D_chunk_map_t)); - if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info") - io_op_init = TRUE; - -#ifdef H5_HAVE_PARALLEL - /* Adjust I/O info for any parallel I/O */ - if(H5D__ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O") -#endif /*H5_HAVE_PARALLEL*/ - - /* Invoke correct "high level" I/O routine */ - if((*io_info.io_ops.multi_read)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") - -done: - /* Shut down the I/O op information */ - if(io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(&fm) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") -#ifdef H5_HAVE_PARALLEL - /* Shut down io_info struct */ - if(io_info_init) - if(H5D__ioinfo_term(&io_info) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't shut down io_info") -#endif /*H5_HAVE_PARALLEL*/ - /* Shut down datatype info for operation */ - if(type_info_init && H5D__typeinfo_term(&type_info) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info") - - /* discard projected mem space if it was created */ - if(NULL != projected_mem_space) - if(H5S_close(projected_mem_space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* end H5D__read() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__read_mdset - * * Purpose: Reads multiple (part of) DATASETs into application memory BUFs. * See H5Dread_multi() for complete details. * @@ -988,11 +670,11 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, +herr_t +H5D__read(hid_t file_id, hid_t dxpl_id, size_t count, H5D_dset_info_t *dset_info) { - H5D_io_info_md_t io_info_md; /* Dataset I/O info for multi dsets */ + H5D_io_info_t io_info; /* Dataset I/O info for multi dsets */ size_t type_info_init = 0; /* Number of datatype info structs that have been initialized */ H5S_t ** projected_mem_space; /* If not NULL, ptr to dataspace containing a */ /* projection of the supplied mem_space to a new */ @@ -1007,7 +689,6 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, /* Note that if this variable is used, the */ /* projected mem space must be discarded at the */ /* end of the function to avoid a memory leak. */ - const H5S_t **ori_mem_space = NULL; /* Original memory space */ H5D_storage_t *store = NULL; /* Union of EFL and chunk pointer in file space */ hssize_t snelmts; /* Total number of elmts (signed) */ hsize_t nelmts; /* Total number of elmts */ @@ -1017,61 +698,56 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, size_t io_op_init = 0; /* Number I/O ops that have been initialized */ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - void ** info_rbuf_ori; /* Save original rbuf */ size_t i; /* Local index variable */ char fake_char; /* Temporary variable for NULL buffer pointers */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - /* init io_info_md */ - io_info_md.sel_pieces = NULL; - io_info_md.store_faddr = 0; - io_info_md.base_maddr_r = NULL; + /* init io_info */ + io_info.sel_pieces = NULL; + io_info.store_faddr = 0; + io_info.base_maddr_r = NULL; /* Create global piece skiplist */ - if(NULL == (io_info_md.sel_pieces = H5SL_create(H5SL_TYPE_HADDR, NULL))) + if(NULL == (io_info.sel_pieces = H5SL_create(H5SL_TYPE_HADDR, NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for piece selections") /* Use provided dset_info */ - io_info_md.dsets_info = dset_info; + io_info.dsets_info = dset_info; /* Allocate other buffers */ if(NULL == (projected_mem_space = (H5S_t **)H5MM_calloc(count * sizeof(H5S_t*)))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dset space array ptr") - if(NULL == (ori_mem_space = (const H5S_t **)H5MM_calloc(count * sizeof(H5S_t*)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dset space array ptr") if(NULL == (store = (H5D_storage_t *)H5MM_malloc(count * sizeof(H5D_storage_t)))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTALLOC, FAIL, "couldn't allocate dset storage info array buffer") - /* allocate rbuf ptr array to save original rbuf ptr */ - if(NULL == (info_rbuf_ori = (void **)H5MM_calloc(count * sizeof(void*)))) - HGOTO_ERROR(H5E_STORAGE, H5E_CANTALLOC, FAIL, "couldn't allocate ori buf array") - /* Get the default dataset transfer property list if the user didn't provide one */ if(H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - /* iterate dsets */ + /* iterate over all dsets and construct I/O information necessary to do I/O */ for(i = 0; i < count; i++) { /* check args */ if(NULL == dset_info[i].dset) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(NULL == dset_info[i].dset->oloc.file) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + /* Fill the DXPL cache values for later use */ if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") /* Set up datatype info for operation */ - if(H5D__typeinfo_init(dset_info[i].dset, dxpl_cache, dxpl_id, dset_info[i].mem_type_id, TRUE, &(dset_info[i].type_info)) < 0) + if(H5D__typeinfo_init(dset_info[i].dset, dxpl_cache, dxpl_id, dset_info[i].mem_type_id, + FALSE, &(dset_info[i].type_info)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info") type_info_init++; #ifdef H5_HAVE_PARALLEL /* Collective access is not permissible without a MPI based VFD */ if(dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE && - !(H5F_HAS_FEATURE(dset_info[i].dset->oloc.file, H5FD_FEAT_HAS_MPI))) + !(H5F_HAS_FEATURE(dset_info[i].dset->oloc.file, H5FD_FEAT_HAS_MPI))) HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based drivers only") #endif /*H5_HAVE_PARALLEL*/ @@ -1115,19 +791,16 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, * Note that in general, this requires us to touch up the memory buffer * as well. */ - - /* Save original read buf pointer and memory space */ - info_rbuf_ori[i] = dset_info[i].u.rbuf; - ori_mem_space[i] = dset_info[i].mem_space; - if(TRUE == H5S_select_shape_same(dset_info[i].mem_space, dset_info[i].file_space) && - H5S_GET_EXTENT_NDIMS(dset_info[i].mem_space) != H5S_GET_EXTENT_NDIMS(dset_info[i].file_space)) { + H5S_GET_EXTENT_NDIMS(dset_info[i].mem_space) != H5S_GET_EXTENT_NDIMS(dset_info[i].file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ /* Attempt to construct projected dataspace for memory dataspace */ if(H5S_select_construct_projection(dset_info[i].mem_space, &(projected_mem_space[i]), - (unsigned)H5S_GET_EXTENT_NDIMS(dset_info[i].file_space), dset_info[i].u.rbuf, (const void **)&adj_buf, (hsize_t)dset_info[i].type_info.dst_type_size) < 0) + (unsigned)H5S_GET_EXTENT_NDIMS(dset_info[i].file_space), dset_info[i].u.rbuf, + (const void **)&adj_buf, + (hsize_t)dset_info[i].type_info.dst_type_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") HDassert(projected_mem_space[i]); HDassert(adj_buf); @@ -1147,7 +820,7 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, * has been overwritten. So just proceed in reading. */ if(nelmts > 0 && dset_info[i].dset->shared->dcpl_cache.efl.nused == 0 && - !(*dset_info[i].dset->shared->layout.ops->is_space_alloc)(&dset_info[i].dset->shared->layout.storage)) { + !(*dset_info[i].dset->shared->layout.ops->is_space_alloc)(&dset_info[i].dset->shared->layout.storage)) { H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */ /* Retrieve dataset's fill-value properties */ @@ -1156,7 +829,8 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, /* Should be impossible, but check anyway... */ if(fill_status == H5D_FILL_VALUE_UNDEFINED && - (dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC || dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET)) + (dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC || + dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET)) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "read failed: dataset doesn't exist, no data can be read") /* If we're never going to fill this dataset, just leave the junk in the user's buffer */ @@ -1164,15 +838,17 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, HGOTO_DONE(SUCCEED) /* Go fill the user's selection with the dataset's fill value */ - if(H5D__fill(dset_info[i].dset->shared->dcpl_cache.fill.buf, dset_info[i].dset->shared->type, dset_info[i].u.rbuf, dset_info[i].type_info.mem_type, dset_info[i].mem_space, dxpl_id) < 0) + if(H5D__fill(dset_info[i].dset->shared->dcpl_cache.fill.buf, dset_info[i].dset->shared->type, + dset_info[i].u.rbuf, dset_info[i].type_info.mem_type, dset_info[i].mem_space, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed") else HGOTO_DONE(SUCCEED) } /* end if */ /* Set up I/O operation */ - io_info_md.op_type = H5D_IO_OP_READ; - if(H5D__ioinfo_init_mdset(dset_info[i].dset, dxpl_cache, dxpl_id, &(dset_info[i]), &(store[i]), &io_info_md) < 0) + io_info.op_type = H5D_IO_OP_READ; + if(H5D__ioinfo_init(dset_info[i].dset, dxpl_cache, dxpl_id, &(dset_info[i]), + &(store[i]), &io_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation") #ifdef H5_HAVE_PARALLEL io_info_init = TRUE; @@ -1180,23 +856,30 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, /* Sanity check that space is allocated, if there are elements */ if(nelmts > 0) - HDassert((*dset_info[i].dset->shared->layout.ops->is_space_alloc)(&dset_info[i].dset->shared->layout.storage) - || dset_info[i].dset->shared->dcpl_cache.efl.nused > 0 - || dset_info[i].dset->shared->layout.type == H5D_COMPACT); - + HDassert((*dset_info[i].dset->shared->layout.ops->is_space_alloc) + (&dset_info[i].dset->shared->layout.storage) + || dset_info[i].dset->shared->dcpl_cache.efl.nused > 0 + || dset_info[i].dset->shared->layout.type == H5D_COMPACT); + /* Call storage method's I/O initialization routine */ - /* Init io_info_md.dset_info[] and generate piece_info in skip list */ - if(dset_info[i].layout_ops.io_init_md && (*dset_info[i].layout_ops.io_init_md)(&io_info_md, &(dset_info[i].type_info), nelmts, dset_info[i].file_space, dset_info[i].mem_space, &(dset_info[i])) < 0) + /* Init io_info.dset_info[] and generate piece_info in skip list */ + if(dset_info[i].layout_ops.io_init && + (*dset_info[i].layout_ops.io_init)(&io_info, &(dset_info[i].type_info), nelmts, + dset_info[i].file_space, dset_info[i].mem_space, + &(dset_info[i])) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info") io_op_init++; } /* end of for loop */ + assert(type_info_init == count); assert(io_op_init == count); #ifdef H5_HAVE_PARALLEL /* Adjust I/O info for any parallel I/O */ - if(H5D__ioinfo_adjust_mdset(count, &io_info_md, dxpl_id) < 0) + if(H5D__ioinfo_adjust(count, &io_info, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O") +#else + io_info.is_coll_broken = TRUE; #endif /*H5_HAVE_PARALLEL*/ /* Invoke correct "high level" I/O routine */ @@ -1204,35 +887,37 @@ H5D__read_mdset(hid_t file_id, hid_t dxpl_id, size_t count, * single-dset path with looping. * Multiple-dset path can not be called since it is not supported, so make * detour through single-dset path */ - if(TRUE == io_info_md.is_coll_broken) { - /* Shut down any I/O op information that was created for the multi - * dataset operation. Iterate in reverse order so io_op_init remains - * valid. */ - while(io_op_init > 0) { - io_op_init--; - if(dset_info[io_op_init].layout_ops.io_term_md && (*dset_info[io_op_init].layout_ops.io_term_md)(&(dset_info[io_op_init])) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") - } /* end while */ + if(TRUE == io_info.is_coll_broken) { + haddr_t prev_tag = HADDR_UNDEF; /* Loop with serial & single-dset read IO path */ - for(i = 0; i < count; i++) - /* Use original rbuf as initial state for single-dset path */ - if(H5D__read(dset_info[i].dset, dset_info[i].mem_type_id, ori_mem_space[i], dset_info[i].file_space, dxpl_id, info_rbuf_ori[i]) < 0) + for(i = 0; i < count; i++) { + /* set metadata tagging with dset oheader addr */ + if(H5AC_tag(dxpl_id, dset_info->dset->oloc.addr, &prev_tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") + + if((*io_info.io_ops.multi_read)(&io_info, &(dset_info[i].type_info), nelmts, dset_info[i].file_space, + dset_info[i].mem_space, &dset_info[i]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + + /* Reset metadata tagging */ + if(H5AC_tag(dxpl_id, prev_tag, NULL) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") + } } /* end if */ else - if((*io_info_md.io_ops.multi_read_md)(file_id, count, &io_info_md) < 0) + if((*io_info.io_ops.multi_read_md)(file_id, count, &io_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") done: /* Shut down the I/O op information */ for(i = 0; i < io_op_init; i++) - if(dset_info[i].layout_ops.io_term_md && (*dset_info[i].layout_ops.io_term_md)(&(dset_info[i])) < 0) + if(dset_info[i].layout_ops.io_term && (*dset_info[i].layout_ops.io_term)(&io_info, &(dset_info[i])) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") #ifdef H5_HAVE_PARALLEL /* Shut down io_info struct */ - if(io_info_init && H5D__ioinfo_term_mdset(&io_info_md) < 0) + if(io_info_init && H5D__ioinfo_term(&io_info) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't shut down io_info") #endif /*H5_HAVE_PARALLEL*/ @@ -1248,283 +933,23 @@ done: HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") /* Free global piece skiplist */ - if(io_info_md.sel_pieces) - if(H5SL_close(io_info_md.sel_pieces) < 0) + if(io_info.sel_pieces) + if(H5SL_close(io_info.sel_pieces) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't close dataset skip list") - /* Free other buffers */ - if (info_rbuf_ori) - H5MM_xfree(info_rbuf_ori); - /* io_info_md.dsets_info was allocated in calling function */ + /* io_info.dsets_info was allocated in calling function */ if(projected_mem_space) H5MM_xfree(projected_mem_space); - if(ori_mem_space) - H5MM_xfree(ori_mem_space); if(store) H5MM_xfree(store); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__read_mdset() */ +} /* end H5D__read() */ /*------------------------------------------------------------------------- * Function: H5D__write * - * Purpose: Writes (part of) a DATASET to a file from application memory - * BUF. See H5Dwrite() for complete details. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, - const H5S_t *file_space, hid_t dxpl_id, const void *buf) -{ - H5D_chunk_map_t fm; /* Chunk file<->memory mapping */ - H5D_io_info_t io_info; /* Dataset I/O info */ - H5D_type_info_t type_info; /* Datatype info for operation */ - hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */ - H5S_t * projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */ - /* projection of the supplied mem_space to a new */ - /* dataspace with rank equal to that of */ - /* file_space. */ - /* */ - /* This field is only used if */ - /* H5S_select_shape_same() returns TRUE when */ - /* comparing the mem_space and the data_space, */ - /* and the mem_space have different rank. */ - /* */ - /* Note that if this variable is used, the */ - /* projected mem space must be discarded at the */ - /* end of the function to avoid a memory leak. */ - H5D_storage_t store; /*union of EFL and chunk pointer in file space */ - hssize_t snelmts; /*total number of elmts (signed) */ - hsize_t nelmts; /*total number of elmts */ -#ifdef H5_HAVE_PARALLEL - hbool_t io_info_init = FALSE; /* Whether the I/O info has been initialized */ -#endif /*H5_HAVE_PARALLEL*/ - hbool_t io_op_init = FALSE; /* Whether the I/O op has been initialized */ - H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ - H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - char fake_char; /* Temporary variable for NULL buffer pointers */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC_TAG(dxpl_id, dataset->oloc.addr, FAIL) - - /* check args */ - HDassert(dataset && dataset->oloc.file); - - /* All filters in the DCPL must have encoding enabled. */ - if(!dataset->shared->checked_filters) { - if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) < 0) - HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters") - - dataset->shared->checked_filters = TRUE; - } /* end if */ - - /* Check if we are allowed to write to this file */ - if(0 == (H5F_INTENT(dataset->oloc.file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file") - - /* Fill the DXPL cache values for later use */ - if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") - - /* Set up datatype info for operation */ - if(H5D__typeinfo_init(dataset, dxpl_cache, dxpl_id, mem_type_id, TRUE, &type_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info") - type_info_init = TRUE; - - /* Various MPI based checks */ -#ifdef H5_HAVE_PARALLEL - if H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI) { - /* If MPI based VFD is used, no VL datatype support yet. */ - /* This is because they use the global heap in the file and we don't */ - /* support parallel access of that yet */ - if(H5T_detect_class(type_info.mem_type, H5T_VLEN, FALSE) > 0) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet") - - /* If MPI based VFD is used, no VL datatype support yet. */ - /* This is because they use the global heap in the file and we don't */ - /* support parallel access of that yet */ - /* We should really use H5T_detect_class() here, but it will be difficult - * to detect the type of the reference if it is nested... -QAK - */ - if(H5T_get_class(type_info.mem_type, TRUE) == H5T_REFERENCE && - H5T_get_ref_type(type_info.mem_type) == H5R_DATASET_REGION) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing region reference datatypes yet") - - /* Can't write to chunked datasets with filters, in parallel */ - if(dataset->shared->layout.type == H5D_CHUNKED && - dataset->shared->dcpl_cache.pline.nused > 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot write to chunked storage with filters in parallel") - } /* end if */ - else { - /* Collective access is not permissible without a MPI based VFD */ - if(dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based driver only") - } /* end else */ -#endif /*H5_HAVE_PARALLEL*/ - - /* Initialize dataspace information */ - if(!file_space) - file_space = dataset->shared->space; - if(!mem_space) - mem_space = file_space; - - if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t); - - /* Make certain that the number of elements in each selection is the same */ - if(nelmts != (hsize_t)H5S_GET_SELECT_NPOINTS(file_space)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspace have different sizes") - - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ - if(NULL == buf) { - /* Check for any elements selected (which is invalid) */ - if(nelmts > 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") - - /* If the buffer is nil, and 0 element is selected, make a fake buffer. - * This is for some MPI package like ChaMPIon on NCSA's tungsten which - * doesn't support this feature. - */ - buf = &fake_char; - } /* end if */ - - /* Make sure that both selections have their extents set */ - if(!(H5S_has_extent(file_space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set") - if(!(H5S_has_extent(mem_space))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set") - - /* H5S_select_shape_same() has been modified to accept topologically - * identical selections with different rank as having the same shape - * (if the most rapidly changing coordinates match up), but the I/O - * code still has difficulties with the notion. - * - * To solve this, we check to see if H5S_select_shape_same() returns - * true, and if the ranks of the mem and file spaces are different. - * If the are, construct a new mem space that is equivalent to the - * old mem space, and use that instead. - * - * Note that in general, this requires us to touch up the memory buffer - * as well. - */ - if(TRUE == H5S_select_shape_same(mem_space, file_space) && - H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { - const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ - /* to the beginning of the projected mem space. */ - - /* Attempt to construct projected dataspace for memory dataspace */ - if(H5S_select_construct_projection(mem_space, &projected_mem_space, - (unsigned)H5S_GET_EXTENT_NDIMS(file_space), buf, (const void **)&adj_buf, type_info.src_type_size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace") - HDassert(projected_mem_space); - HDassert(adj_buf); - - /* Switch to using projected memory dataspace & adjusted buffer */ - mem_space = projected_mem_space; - buf = adj_buf; - } /* end if */ - - /* Retrieve dataset properties */ - /* <none needed currently> */ - - /* Allocate dataspace and initialize it if it hasn't been. */ - if(nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 && - !(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage)) { - hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */ - hbool_t full_overwrite; /* Whether we are over-writing all the elements */ - - /* Get the number of elements in file dataset's dataspace */ - if((file_nelmts = H5S_GET_EXTENT_NPOINTS(file_space)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset") - - /* Always allow fill values to be written if the dataset has a VL datatype */ - if(H5T_detect_class(dataset->shared->type, H5T_VLEN, FALSE)) - full_overwrite = FALSE; - else - full_overwrite = (hbool_t)((hsize_t)file_nelmts == nelmts ? TRUE : FALSE); - - /* Allocate storage */ - if(H5D__alloc_storage(dataset, dxpl_id, H5D_ALLOC_WRITE, full_overwrite, NULL) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") - } /* end if */ - - /* Set up I/O operation */ - io_info.op_type = H5D_IO_OP_WRITE; - io_info.u.wbuf = buf; - if(H5D__ioinfo_init(dataset, dxpl_cache, dxpl_id, &type_info, &store, &io_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up I/O operation") -#ifdef H5_HAVE_PARALLEL - io_info_init = TRUE; -#endif /*H5_HAVE_PARALLEL*/ - - /* Call storage method's I/O initialization routine */ - HDmemset(&fm, 0, sizeof(H5D_chunk_map_t)); - if(io_info.layout_ops.io_init && (*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info") - io_op_init = TRUE; - -#ifdef H5_HAVE_PARALLEL - /* Adjust I/O info for any parallel I/O */ - if(H5D__ioinfo_adjust(&io_info, dataset, dxpl_id, file_space, mem_space, &type_info, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O") -#endif /*H5_HAVE_PARALLEL*/ - - /* Invoke correct "high level" I/O routine */ - if((*io_info.io_ops.multi_write)(&io_info, &type_info, nelmts, file_space, mem_space, &fm) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") - -#ifdef OLD_WAY -/* - * This was taken out because it can be called in a parallel program with - * independent access, causing the metadata cache to get corrupted. Its been - * disabled for all types of access (serial as well as parallel) to make the - * modification time consistent for all programs. -QAK - * - * We should set a value in the dataset's shared information instead and flush - * it to the file when the dataset is being closed. -QAK - */ - /* - * Update modification time. We have to do this explicitly because - * writing to a dataset doesn't necessarily change the object header. - */ - if(H5O_touch(&(dataset->oloc), FALSE, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time") -#endif /* OLD_WAY */ - -done: - /* Shut down the I/O op information */ - if(io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(&fm) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") -#ifdef H5_HAVE_PARALLEL - /* Shut down io_info struct */ - if(io_info_init && H5D__ioinfo_term(&io_info) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't shut down io_info") -#endif /*H5_HAVE_PARALLEL*/ - /* Shut down datatype info for operation */ - if(type_info_init && H5D__typeinfo_term(&type_info) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info") - - /* discard projected mem space if it was created */ - if(NULL != projected_mem_space) - if(H5S_close(projected_mem_space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* end H5D__write() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__write_mdset - * * Purpose: Writes multiple (part of) DATASETs to a file from application * memory BUFs. See H5Dwrite_multi() for complete details. * @@ -1537,14 +962,14 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, +H5D__write(hid_t file_id, hid_t dxpl_id, size_t count, H5D_dset_info_t *dset_info) { - H5D_io_info_md_t io_info_md; /* Dataset I/O info for multi dsets */ + H5D_io_info_t io_info; /* Dataset I/O info for multi dsets */ size_t type_info_init = 0; /* Number of datatype info structs that have been initialized */ H5S_t **projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */ /* projection of the supplied mem_space to a new */ - /* dataspace with rank equal to that of */ + /* dataspace with rank equal to that of */ /* file_space. */ /* */ /* This field is only used if */ @@ -1555,7 +980,6 @@ H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, /* Note that if this variable is used, the */ /* projected mem space must be discarded at the */ /* end of the function to avoid a memory leak. */ - const H5S_t **ori_mem_space = NULL; /* Original memory space */ H5D_storage_t *store = NULL; /* Union of EFL and chunk pointer in file space */ hssize_t snelmts; /* Total number of elmts (signed) */ hsize_t nelmts; /* Total number of elmts */ @@ -1565,45 +989,44 @@ H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, size_t io_op_init = 0; /* Number I/O ops that have been initialized */ H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ - const void **info_wbuf_ori = NULL; /* save original wbuf */ size_t i; /* Local index variable */ char fake_char; /* Temporary variable for NULL buffer pointers */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC - /* Init io_info_md */ - io_info_md.sel_pieces = NULL; - io_info_md.store_faddr = 0; - io_info_md.base_maddr_w = NULL; + /* Init io_info */ + io_info.sel_pieces = NULL; + io_info.store_faddr = 0; + io_info.base_maddr_w = NULL; /* Create global piece skiplist */ - if(NULL == (io_info_md.sel_pieces = H5SL_create(H5SL_TYPE_HADDR, NULL))) + if(NULL == (io_info.sel_pieces = H5SL_create(H5SL_TYPE_HADDR, NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for piece selections") /* Use provided dset_info */ - io_info_md.dsets_info = dset_info; + io_info.dsets_info = dset_info; /* Allocate other buffers */ if(NULL == (projected_mem_space = (H5S_t **)H5MM_calloc(count * sizeof(H5S_t*)))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dset space array ptr") - if(NULL == (ori_mem_space = (const H5S_t **)H5MM_calloc(count * sizeof(H5S_t*)))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "couldn't allocate dset space array ptr") if(NULL == (store = (H5D_storage_t *)H5MM_malloc(count * sizeof(H5D_storage_t)))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTALLOC, FAIL, "couldn't allocate dset storage info array buffer") - /* allocate wbuf ptr array to save original wbuf ptr */ - if(NULL == (info_wbuf_ori = (const void **)H5MM_calloc(count * sizeof(void*)))) - HGOTO_ERROR(H5E_STORAGE, H5E_CANTALLOC, FAIL, "couldn't allocate ori buf array") - - /* iterate dsets */ + /* iterate over all dsets and construct I/O information */ for(i = 0; i < count; i++) { + haddr_t prev_tag = HADDR_UNDEF; + /* check args */ if(NULL == dset_info[i].dset) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(NULL == dset_info[i].dset->oloc.file) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + /* set metadata tagging with dset oheader addr */ + if(H5AC_tag(dxpl_id, dset_info->dset->oloc.addr, &prev_tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") + /* All filters in the DCPL must have encoding enabled. */ if(!dset_info[i].dset->shared->checked_filters) { if(H5Z_can_apply(dset_info[i].dset->shared->dcpl_id, dset_info[i].dset->shared->type_id) < 0) @@ -1697,10 +1120,6 @@ H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, * Note that in general, this requires us to touch up the memory buffer * as well. */ - /* Save original write buf pointer and memory space */ - info_wbuf_ori[i] = dset_info[i].u.wbuf; - ori_mem_space[i] = dset_info[i].mem_space; - if(TRUE == H5S_select_shape_same(dset_info[i].mem_space, dset_info[i].file_space) && H5S_GET_EXTENT_NDIMS(dset_info[i].mem_space) != H5S_GET_EXTENT_NDIMS(dset_info[i].file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ @@ -1745,56 +1164,62 @@ H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, } /* end if */ /* Set up I/O operation */ - io_info_md.op_type = H5D_IO_OP_WRITE; - if(H5D__ioinfo_init_mdset(dset_info[i].dset, dxpl_cache, dxpl_id, &(dset_info[i]), - &(store[i]), &io_info_md) < 0) + io_info.op_type = H5D_IO_OP_WRITE; + if(H5D__ioinfo_init(dset_info[i].dset, dxpl_cache, dxpl_id, &(dset_info[i]), + &(store[i]), &io_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up I/O operation") #ifdef H5_HAVE_PARALLEL io_info_init = TRUE; #endif /*H5_HAVE_PARALLEL*/ /* Call storage method's I/O initialization routine */ - /* Init io_info_md.dset_info[] and generate piece_info in skip list */ - if(dset_info[i].layout_ops.io_init_md && - (*dset_info[i].layout_ops.io_init_md)(&io_info_md, &(dset_info[i].type_info), nelmts, - dset_info[i].file_space, dset_info[i].mem_space, - &(dset_info[i])) < 0) + /* Init io_info.dset_info[] and generate piece_info in skip list */ + if(dset_info[i].layout_ops.io_init && + (*dset_info[i].layout_ops.io_init)(&io_info, &(dset_info[i].type_info), nelmts, + dset_info[i].file_space, dset_info[i].mem_space, + &(dset_info[i])) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info") io_op_init++; + + /* Reset metadata tagging */ + if(H5AC_tag(dxpl_id, prev_tag, NULL) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") } /* end of Count for loop */ assert(type_info_init == count); assert(io_op_init == count); #ifdef H5_HAVE_PARALLEL /* Adjust I/O info for any parallel I/O */ - if(H5D__ioinfo_adjust_mdset(count, &io_info_md, dxpl_id) < 0) + if(H5D__ioinfo_adjust(count, &io_info, dxpl_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O") +#else + io_info.is_coll_broken = TRUE; #endif /*H5_HAVE_PARALLEL*/ /* If collective mode is broken, perform write IO in independent mode via * single-dset path with looping. * Multiple-dset path can not be called since it is not supported, so make * detour through single-dset path */ - if(TRUE == io_info_md.is_coll_broken) { - /* Shut down any I/O op information that was created for the multi - * dataset operation. Iterate in reverse order so io_op_init remains - * valid. */ - while(io_op_init > 0) { - io_op_init--; - if(dset_info[io_op_init].layout_ops.io_term_md && - (*dset_info[io_op_init].layout_ops.io_term_md)(&(dset_info[io_op_init])) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") - } /* end while */ + if(TRUE == io_info.is_coll_broken) { + haddr_t prev_tag = HADDR_UNDEF; /* loop with serial & single-dset write IO path */ - for(i = 0; i < count; i++) - /* Use original wbuf as initial state for single-dset path */ - if(H5D__write(dset_info[i].dset, dset_info[i].mem_type_id, ori_mem_space[i], dset_info[i].file_space, dxpl_id, info_wbuf_ori[i]) < 0) + for(i = 0; i < count; i++) { + /* set metadata tagging with dset oheader addr */ + if(H5AC_tag(dxpl_id, dset_info->dset->oloc.addr, &prev_tag) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") + /* Invoke correct "high level" I/O routine */ + if((*io_info.io_ops.multi_write)(&io_info, &(dset_info[i].type_info), nelmts, dset_info[i].file_space, + dset_info[i].mem_space, &dset_info[i]) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") + /* Reset metadata tagging */ + if(H5AC_tag(dxpl_id, prev_tag, NULL) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to apply metadata tag") + } } /* end if */ else /* Invoke correct "high level" I/O routine */ - if((*io_info_md.io_ops.multi_write_md)(file_id, count, &io_info_md) < 0) + if((*io_info.io_ops.multi_write_md)(file_id, count, &io_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") #ifdef OLD_WAY @@ -1818,12 +1243,12 @@ H5D__write_mdset(hid_t file_id, hid_t dxpl_id, size_t count, done: /* Shut down the I/O op information */ for(i = 0; i < io_op_init; i++) - if(dset_info[i].layout_ops.io_term_md && (*dset_info[i].layout_ops.io_term_md)(&(dset_info[i])) < 0) + if(dset_info[i].layout_ops.io_term && (*dset_info[i].layout_ops.io_term)(&io_info, &(dset_info[i])) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info") #ifdef H5_HAVE_PARALLEL /* Shut down io_info struct */ - if(io_info_init && H5D__ioinfo_term_mdset(&io_info_md) < 0) + if(io_info_init && H5D__ioinfo_term(&io_info) < 0) HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't shut down io_info") #endif /*H5_HAVE_PARALLEL*/ @@ -1839,97 +1264,23 @@ done: HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace") /* Free global piece skiplist */ - if(io_info_md.sel_pieces) - if(H5SL_close(io_info_md.sel_pieces) < 0) + if(io_info.sel_pieces) + if(H5SL_close(io_info.sel_pieces) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't close dataset skip list") - /* Free other buffers */ - if(info_wbuf_ori) - H5MM_xfree(info_wbuf_ori); - /* io_info_md.dsets_info was allocated in calling function */ + /* io_info.dsets_info was allocated in calling function */ if(projected_mem_space) H5MM_xfree(projected_mem_space); - if(ori_mem_space) - H5MM_xfree(ori_mem_space); if(store) H5MM_xfree(store); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__write_mdset */ +} /* end H5D__write */ /*------------------------------------------------------------------------- * Function: H5D__ioinfo_init * - * Purpose: Routine for determining correct I/O operations for - * each I/O action. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, September 30, 2004 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__ioinfo_init(H5D_t *dset, -#ifndef H5_HAVE_PARALLEL - const -#endif /* H5_HAVE_PARALLEL */ - H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, - const H5D_type_info_t *type_info, H5D_storage_t *store, H5D_io_info_t *io_info) -{ - FUNC_ENTER_STATIC_NOERR - - /* check args */ - HDassert(dset); - HDassert(dset->oloc.file); - HDassert(type_info); - HDassert(type_info->tpath); - HDassert(io_info); - - /* Set up "normal" I/O fields */ - io_info->dset = dset; - io_info->dxpl_cache = dxpl_cache; - io_info->dxpl_id = dxpl_id; - io_info->store = store; - - /* Set I/O operations to initial values */ - io_info->layout_ops = *dset->shared->layout.ops; - - /* Set the "high-level" I/O operations for the dataset */ - io_info->io_ops.multi_read = dset->shared->layout.ops->ser_read; - io_info->io_ops.multi_write = dset->shared->layout.ops->ser_write; - - /* Set the I/O operations for reading/writing single blocks on disk */ - if(type_info->is_xform_noop && type_info->is_conv_noop) { - /* - * If there is no data transform or type conversion then read directly into - * the application's buffer. This saves at least one mem-to-mem copy. - */ - io_info->io_ops.single_read = H5D__select_read; - io_info->io_ops.single_write = H5D__select_write; - } /* end if */ - else { - /* - * This is the general case (type conversion, usually). - */ - io_info->io_ops.single_read = H5D__scatgath_read; - io_info->io_ops.single_write = H5D__scatgath_write; - } /* end else */ - -#ifdef H5_HAVE_PARALLEL - /* Determine if the file was opened with an MPI VFD */ - io_info->using_mpi_vfd = H5F_HAS_FEATURE(dset->oloc.file, H5FD_FEAT_HAS_MPI); -#endif /* H5_HAVE_PARALLEL */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5D__ioinfo_init() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__ioinfo_init_mdset - * * Purpose: Routine for determining correct I/O operations for each I/O action. * * This was derived from H5D__ioinfo_init for multi-dset work. @@ -1940,38 +1291,35 @@ H5D__ioinfo_init(H5D_t *dset, *------------------------------------------------------------------------- */ static herr_t -H5D__ioinfo_init_mdset(H5D_t *dset, +H5D__ioinfo_init(H5D_t *dset, #ifndef H5_HAVE_PARALLEL const #endif /* H5_HAVE_PARALLEL */ H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, - H5D_dset_info_t *dset_info, H5D_storage_t *store, H5D_io_info_md_t *io_info_md) + H5D_dset_info_t *dset_info, H5D_storage_t *store, H5D_io_info_t *io_info) { FUNC_ENTER_STATIC_NOERR /* check args */ HDassert(dset); HDassert(dset->oloc.file); - HDassert(&(dset_info->type_info)); + //HDassert(&(dset_info->type_info)); HDassert(dset_info->type_info.tpath); - HDassert(io_info_md); + HDassert(io_info); /* Set up "normal" I/O fields */ dset_info->dset = dset; - io_info_md->dxpl_cache = dxpl_cache; - io_info_md->dxpl_id = dxpl_id; - io_info_md->is_coll_broken = FALSE; /* is collective broken? */ + io_info->dxpl_cache = dxpl_cache; + io_info->dxpl_id = dxpl_id; + io_info->is_coll_broken = FALSE; /* is collective broken? */ dset_info->store = store; /* Set I/O operations to initial values */ dset_info->layout_ops = *dset->shared->layout.ops; - /* - * these are SERIAL setting, so not effect for PARALLE - */ /* Set the "high-level" I/O operations for the dataset */ - io_info_md->io_ops.multi_read = dset->shared->layout.ops->ser_read; - io_info_md->io_ops.multi_write = dset->shared->layout.ops->ser_write; + io_info->io_ops.multi_read = dset->shared->layout.ops->ser_read; + io_info->io_ops.multi_write = dset->shared->layout.ops->ser_write; /* Set the I/O operations for reading/writing single blocks on disk */ if(dset_info->type_info.is_xform_noop && dset_info->type_info.is_conv_noop) { @@ -1980,24 +1328,24 @@ H5D__ioinfo_init_mdset(H5D_t *dset, * into the application's buffer. * This saves at least one mem-to-mem copy. */ - io_info_md->io_ops.single_read = H5D__select_read; - io_info_md->io_ops.single_write = H5D__select_write; + io_info->io_ops.single_read = H5D__select_read; + io_info->io_ops.single_write = H5D__select_write; } /* end if */ else { /* * This is the general case (type conversion, usually). */ - io_info_md->io_ops.single_read = H5D__scatgath_read; - io_info_md->io_ops.single_write = H5D__scatgath_write; + io_info->io_ops.single_read = H5D__scatgath_read; + io_info->io_ops.single_write = H5D__scatgath_write; } /* end else */ #ifdef H5_HAVE_PARALLEL /* Determine if the file was opened with an MPI VFD */ - io_info_md->using_mpi_vfd = H5F_HAS_FEATURE(dset->oloc.file, H5FD_FEAT_HAS_MPI); + io_info->using_mpi_vfd = H5F_HAS_FEATURE(dset->oloc.file, H5FD_FEAT_HAS_MPI); #endif /* H5_HAVE_PARALLEL */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5D__ioinfo_init_mdset() */ +} /* end H5D__ioinfo_init() */ /*------------------------------------------------------------------------- @@ -2162,100 +1510,6 @@ done: * * Purpose: Adjust operation's I/O info for any parallel I/O * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, March 27, 2008 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, hid_t dxpl_id, - const H5S_t *file_space, const H5S_t *mem_space, - const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm) -{ - H5P_genplist_t *dx_plist; /* Data transer property list */ - int global_no_collective_cause; - H5D_mpio_actual_chunk_opt_mode_t actual_chunk_opt_mode; /* performed chunk optimization */ - H5D_mpio_actual_io_mode_t actual_io_mode; /* performed io mode */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC - - /* check args */ - HDassert(dset); - HDassert(dset->oloc.file); - HDassert(mem_space); - HDassert(file_space); - HDassert(type_info); - HDassert(type_info->tpath); - HDassert(io_info); - - /* Get the dataset transfer property list */ - if(NULL == (dx_plist = (H5P_genplist_t *)H5I_object(dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") - - if(H5P_get(dx_plist, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, &global_no_collective_cause) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get global value") - - /* Reset the actual io mode properties to the default values in case - * the dxpl was previously used in a collective I/O operation. - */ - actual_chunk_opt_mode = H5D_MPIO_NO_CHUNK_OPTIMIZATION; - actual_io_mode = H5D_MPIO_NO_COLLECTIVE; - if(H5P_set(dx_plist, H5D_MPIO_ACTUAL_CHUNK_OPT_MODE_NAME, &actual_chunk_opt_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set actual chunk opt mode property") - if(H5P_set(dx_plist, H5D_MPIO_ACTUAL_IO_MODE_NAME, &actual_io_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set actual io mode property") - - /* Make any parallel I/O adjustments */ - if(io_info->using_mpi_vfd) { - htri_t opt; /* Flag whether a selection is optimizable */ - - /* Record the original state of parallel I/O transfer options */ - io_info->orig.xfer_mode = io_info->dxpl_cache->xfer_mode; - io_info->orig.coll_opt_mode = io_info->dxpl_cache->coll_opt_mode; - io_info->orig.io_ops.single_read = io_info->io_ops.single_read; - io_info->orig.io_ops.single_write = io_info->io_ops.single_write; - - /* Get MPI communicator */ - if(MPI_COMM_NULL == (io_info->comm = H5F_mpi_get_comm(dset->oloc.file))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator") - - /* if collective broken cause already calculated, no need to do again */ - if (global_no_collective_cause > 0) - opt = FALSE; - else - /* Check if we can set direct MPI-IO read/write functions */ - if((opt = H5D__mpio_opt_possible(io_info, file_space, mem_space, type_info, fm, dx_plist)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid check for direct IO dataspace ") - - /* All collective operations should have gone through the multi dataset - * path */ - HDassert(!opt); - - /* If we won't be doing collective I/O, but the user asked for - * collective I/O, change the request to use independent I/O, but - * mark it so that we remember to revert the change. - */ - if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE) { - /* Change the xfer_mode to independent for handling the I/O */ - io_info->dxpl_cache->xfer_mode = H5FD_MPIO_INDEPENDENT; - if(H5P_set(dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &io_info->dxpl_cache->xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode") - } /* end if */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__ioinfo_adjust() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__ioinfo_adjust_mdset - * - * Purpose: Adjust operation's I/O info for any parallel I/O - * * This was derived from H5D__ioinfo_adjust for multi-dset work. * * Return: Non-negative on success/Negative on failure @@ -2264,7 +1518,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5D__ioinfo_adjust_mdset(const size_t count, H5D_io_info_md_t *io_info_md, hid_t dxpl_id) +H5D__ioinfo_adjust(const size_t count, H5D_io_info_t *io_info, hid_t dxpl_id) { H5D_t *dset0; /* only the first dset , also for single dsets case */ H5P_genplist_t *dx_plist; /* Data transer property list */ @@ -2276,11 +1530,11 @@ H5D__ioinfo_adjust_mdset(const size_t count, H5D_io_info_md_t *io_info_md, hid_t /* check args */ HDassert(count > 0); - HDassert(io_info_md); + HDassert(io_info); /* check the first dset, should exist either single or multi dset cases */ - HDassert(io_info_md->dsets_info[0].dset); - dset0 = io_info_md->dsets_info[0].dset; + HDassert(io_info->dsets_info[0].dset); + dset0 = io_info->dsets_info[0].dset; HDassert(dset0->oloc.file); /* Get the dataset transfer property list */ @@ -2298,54 +1552,54 @@ H5D__ioinfo_adjust_mdset(const size_t count, H5D_io_info_md_t *io_info_md, hid_t HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set actual io mode property") /* Make any parallel I/O adjustments */ - if(io_info_md->using_mpi_vfd) { + if(io_info->using_mpi_vfd) { htri_t opt; /* Flag whether a selection is optimizable */ /* Record the original state of parallel I/O transfer options */ - io_info_md->orig.xfer_mode = io_info_md->dxpl_cache->xfer_mode; - io_info_md->orig.coll_opt_mode = io_info_md->dxpl_cache->coll_opt_mode; + io_info->orig.xfer_mode = io_info->dxpl_cache->xfer_mode; + io_info->orig.coll_opt_mode = io_info->dxpl_cache->coll_opt_mode; /* single-dset */ - io_info_md->orig.io_ops.single_read = io_info_md->io_ops.single_read; - io_info_md->orig.io_ops.single_write = io_info_md->io_ops.single_write; + io_info->orig.io_ops.single_read = io_info->io_ops.single_read; + io_info->orig.io_ops.single_write = io_info->io_ops.single_write; /* multi-dset */ - io_info_md->orig.io_ops.single_read_md = io_info_md->io_ops.single_read_md; - io_info_md->orig.io_ops.single_write_md = io_info_md->io_ops.single_write_md; + io_info->orig.io_ops.single_read_md = io_info->io_ops.single_read_md; + io_info->orig.io_ops.single_write_md = io_info->io_ops.single_write_md; /* Get MPI communicator from the first dset */ - if(MPI_COMM_NULL == (io_info_md->comm = H5F_mpi_get_comm(dset0->oloc.file))) + if(MPI_COMM_NULL == (io_info->comm = H5F_mpi_get_comm(dset0->oloc.file))) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator") /* Check if we can set direct MPI-IO read/write functions */ - if((opt = H5D__mpio_opt_possible_mdset(count, io_info_md, dx_plist)) < 0) + if((opt = H5D__mpio_opt_possible(count, io_info, dx_plist)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid check for direct IO dataspace ") /* Check if we can use the optimized parallel I/O routines */ if(opt == TRUE) { /* Override the I/O op pointers to the MPI-specific routines */ - /* Single dset case: only first dset exist */ - io_info_md->io_ops.multi_read = NULL; - io_info_md->io_ops.multi_write = NULL; - /* Multi dset case: still first dset can be used since same function is - * shared for both Chunked and Contiguous dset */ - io_info_md->io_ops.multi_read_md = dset0->shared->layout.ops->par_read; - io_info_md->io_ops.multi_write_md = dset0->shared->layout.ops->par_write; - io_info_md->io_ops.single_read_md = H5D__mpio_select_read_mdset; - io_info_md->io_ops.single_write_md = H5D__mpio_select_write_mdset; + io_info->io_ops.multi_read = NULL; + io_info->io_ops.multi_write = NULL; + io_info->io_ops.multi_read_md = dset0->shared->layout.ops->par_read; + io_info->io_ops.multi_write_md = dset0->shared->layout.ops->par_write; + io_info->io_ops.single_read_md = H5D__mpio_select_read; + io_info->io_ops.single_write_md = H5D__mpio_select_write; } /* end if */ else { /* If we won't be doing collective I/O, but the user asked for * collective I/O, change the request to use independent I/O, but * mark it so that we remember to revert the change. */ - if(io_info_md->dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE) { + if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_COLLECTIVE) { /* Change the xfer_mode to independent for handling the I/O */ - io_info_md->dxpl_cache->xfer_mode = H5FD_MPIO_INDEPENDENT; - if(H5P_set(dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &io_info_md->dxpl_cache->xfer_mode) < 0) + io_info->dxpl_cache->xfer_mode = H5FD_MPIO_INDEPENDENT; + if(H5P_set(dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &io_info->dxpl_cache->xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode") - io_info_md->is_coll_broken = TRUE; + io_info->is_coll_broken = TRUE; } /* end if */ + else if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT) + io_info->is_coll_broken = TRUE; } /* end else */ } /* end if */ - + else + io_info->is_coll_broken = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__ioinfo_adjust() */ @@ -2355,13 +1609,13 @@ done: * Function: H5D__ioinfo_term * * Purpose: Common logic for terminating an I/O info object - * (Only used for restoring MPI transfer mode currently) + * (Only used for restoring MPI transfer mode currently) * - * Return: Non-negative on success/Negative on failure + * This was derived from H5D__ioinfo_term for multi-dset work. * - * Programmer: Quincey Koziol - * Friday, February 6, 2004 + * Return: Non-negative on success/Negative on failure * + * Programmer: Jonathan Kim Nov, 2013 *------------------------------------------------------------------------- */ static herr_t @@ -2403,60 +1657,6 @@ H5D__ioinfo_term(H5D_io_info_t *io_info) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__ioinfo_term() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__ioinfo_term_mdset - * - * Purpose: Common logic for terminating an I/O info object - * (Only used for restoring MPI transfer mode currently) - * - * This was derived from H5D__ioinfo_term for multi-dset work. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Jonathan Kim Nov, 2013 - *------------------------------------------------------------------------- - */ -static herr_t -H5D__ioinfo_term_mdset(H5D_io_info_md_t *io_info_md) -{ - herr_t ret_value = SUCCEED; /*return value */ - - FUNC_ENTER_STATIC - - /* Check if we used the MPI VFD for the I/O */ - if(io_info_md->using_mpi_vfd) { - /* Check if we need to revert the change to the xfer mode */ - if(io_info_md->orig.xfer_mode != io_info_md->dxpl_cache->xfer_mode) { - H5P_genplist_t *dx_plist; /* Data transer property list */ - - /* Get the dataset transfer property list */ - if(NULL == (dx_plist = (H5P_genplist_t *)H5I_object(io_info_md->dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") - - /* Restore the original parallel I/O mode */ - if(H5P_set(dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &io_info_md->orig.xfer_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode") - } /* end if */ - - /* Check if we need to revert the change to the collective opt mode */ - if(io_info_md->orig.coll_opt_mode != io_info_md->dxpl_cache->coll_opt_mode) { - H5P_genplist_t *dx_plist; /* Data transer property list */ - - /* Get the dataset transfer property list */ - if(NULL == (dx_plist = (H5P_genplist_t *)H5I_object(io_info_md->dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") - - /* Restore the original parallel I/O mode */ - if(H5P_set(dx_plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, &io_info_md->orig.coll_opt_mode) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set collective option mode") - } /* end if */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__ioinfo_term_mdset() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index e5d7387..f2d4a33 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -89,9 +89,6 @@ /* Combine chunk/piece address and chunk/piece info into a struct for * better performance. */ typedef struct H5D_chunk_addr_info_t { - /* chunk for single-dset */ - haddr_t chunk_addr; - H5D_chunk_info_t chunk_info; /* piece for multi-dset */ haddr_t piece_addr; H5D_piece_info_t piece_info; @@ -102,13 +99,13 @@ typedef struct H5D_chunk_addr_info_t { /* Local Prototypes */ /********************/ /* multi-dset IO */ -static herr_t H5D__piece_mdset_io(const hid_t file_id, const size_t count, - H5D_io_info_md_t *io_info_md); -static herr_t H5D__final_collective_io_mdset(H5D_io_info_md_t *io_info_md, +static herr_t H5D__piece_io(const hid_t file_id, const size_t count, + H5D_io_info_t *io_info); +static herr_t H5D__final_collective_io(H5D_io_info_t *io_info, hsize_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type); static herr_t H5D__all_piece_collective_io(const hid_t file_id, const size_t count, - H5D_io_info_md_t *io_info_md, H5P_genplist_t *dx_plist); + H5D_io_info_t *io_info, H5P_genplist_t *dx_plist); /*********************/ @@ -125,111 +122,6 @@ static herr_t H5D__all_piece_collective_io(const hid_t file_id, const size_t cou * Function: H5D__mpio_opt_possible * * Purpose: Checks if an direct I/O transfer is possible between memory and - * the file. - * - * Return: Sauccess: Non-negative: TRUE or FALSE - * Failure: Negative - * - * Programmer: Quincey Koziol - * Wednesday, April 3, 2002 - * - *------------------------------------------------------------------------- - */ -htri_t -H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space, - const H5S_t *mem_space, const H5D_type_info_t *type_info, - UNUSED const H5D_chunk_map_t *fm, H5P_genplist_t *dx_plist) -{ - int local_cause = 0; /* Local reason(s) for breaking collective mode */ - int global_cause = 0; /* Global reason(s) for breaking collective mode */ - htri_t ret_value; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* Check args */ - HDassert(io_info); - HDassert(mem_space); - HDassert(file_space); - HDassert(type_info); - - - /* For independent I/O, get out quickly and don't try to form consensus */ - if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT) - local_cause |= H5D_MPIO_SET_INDEPENDENT; - - /* Optimized MPI types flag must be set */ - /* (based on 'HDF5_MPI_OPT_TYPES' environment variable) */ - if(!H5FD_mpi_opt_types_g) - local_cause |= H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED; - - /* Don't allow collective operations if datatype conversions need to happen */ - if(!type_info->is_conv_noop) - local_cause |= H5D_MPIO_DATATYPE_CONVERSION; - - /* Don't allow collective operations if data transform operations should occur */ - if(!type_info->is_xform_noop) - local_cause |= H5D_MPIO_DATA_TRANSFORMS; - - /* Check whether these are both simple or scalar dataspaces */ - if(!((H5S_SIMPLE == H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(mem_space)) - && (H5S_SIMPLE == H5S_GET_EXTENT_TYPE(file_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(file_space)))) - local_cause |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES; - - /* Dataset storage must be contiguous or chunked */ - if(!(io_info->dset->shared->layout.type == H5D_CONTIGUOUS || - io_info->dset->shared->layout.type == H5D_CHUNKED)) - local_cause |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; - - /* check if external-file storage is used */ - if(io_info->dset->shared->dcpl_cache.efl.nused > 0) - local_cause |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET; - - /* The handling of memory space is different for chunking and contiguous - * storage. For contiguous storage, mem_space and file_space won't change - * when it it is doing disk IO. For chunking storage, mem_space will - * change for different chunks. So for chunking storage, whether we can - * use collective IO will defer until each chunk IO is reached. - */ - - /* Don't allow collective operations if filters need to be applied */ - if(io_info->dset->shared->layout.type == H5D_CHUNKED && - io_info->dset->shared->dcpl_cache.pline.nused > 0) - local_cause |= H5D_MPIO_FILTERS; - - /* Check for independent I/O */ - if(local_cause & H5D_MPIO_SET_INDEPENDENT) - global_cause = local_cause; - else { - int mpi_code; /* MPI error code */ - - /* Form consensus opinion among all processes about whether to perform - * collective I/O - */ - if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, - MPI_INT, MPI_BOR, io_info->comm))) - HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) - } /* end else */ - - /* Write the local value of no-collective-cause to the DXPL. */ - if(H5P_set(dx_plist, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME, &local_cause) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set local no collective cause property") - - /* Write the global value of no-collective-cause to the DXPL. */ - if(H5P_set(dx_plist, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, &global_cause) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "couldn't set global no collective cause property") - - /* Set the return value, based on the global cause */ - ret_value = global_cause > 0 ? FALSE : TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__mpio_opt_possible() */ - - -/*------------------------------------------------------------------------- - * Function: H5D__mpio_opt_possible_mdset - * - * Purpose: Checks if an direct I/O transfer is possible between memory and * the file. * * This was derived from H5D__mpio_opt_possible for @@ -238,11 +130,10 @@ done: * Return: Sauccess: Non-negative: TRUE or FALSE * Failure: Negative * - * Programmer: JOnathan Kim *------------------------------------------------------------------------- */ htri_t -H5D__mpio_opt_possible_mdset(const size_t count, H5D_io_info_md_t *io_info_md, H5P_genplist_t *dx_plist) +H5D__mpio_opt_possible(const size_t count, H5D_io_info_t *io_info, H5P_genplist_t *dx_plist) { int i; H5D_t *dset; @@ -259,24 +150,24 @@ H5D__mpio_opt_possible_mdset(const size_t count, H5D_io_info_md_t *io_info_md, H FUNC_ENTER_PACKAGE /* Check args */ - HDassert(io_info_md); + HDassert(io_info); HDassert(dx_plist); for (i = 0; i < count; i++) { - HDassert(io_info_md->dsets_info[i].file_space); - HDassert(io_info_md->dsets_info[i].mem_space); + HDassert(io_info->dsets_info[i].file_space); + HDassert(io_info->dsets_info[i].mem_space); } /* For independent I/O, get out quickly and don't try to form consensus */ - if(io_info_md->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT) + if(io_info->dxpl_cache->xfer_mode == H5FD_MPIO_INDEPENDENT) local_cause |= H5D_MPIO_SET_INDEPENDENT; for (i = 0; i < count; i++) { - dset = io_info_md->dsets_info[i].dset; - file_space = io_info_md->dsets_info[i].file_space; - mem_space = io_info_md->dsets_info[i].mem_space; - type_info = io_info_md->dsets_info[i].type_info; + dset = io_info->dsets_info[i].dset; + file_space = io_info->dsets_info[i].file_space; + mem_space = io_info->dsets_info[i].mem_space; + type_info = io_info->dsets_info[i].type_info; /* Optimized MPI types flag must be set */ /* (based on 'HDF5_MPI_OPT_TYPES' environment variable) */ @@ -322,13 +213,11 @@ H5D__mpio_opt_possible_mdset(const size_t count, H5D_io_info_md_t *io_info_md, H if(local_cause & H5D_MPIO_SET_INDEPENDENT) global_cause = local_cause; else { - int mpi_code; /* MPI error code */ - /* Form consensus opinion among all processes about whether to perform * collective I/O */ if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, MPI_INT, - MPI_BOR, io_info_md->comm))) + MPI_BOR, io_info->comm))) HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) } /* end else */ @@ -346,11 +235,11 @@ H5D__mpio_opt_possible_mdset(const size_t count, H5D_io_info_md_t *io_info_md, H done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5D__mpio_opt_possible_mdset() */ +} /* H5D__mpio_opt_possible() */ /*------------------------------------------------------------------------- - * Function: H5D__mpio_select_read_mdset + * Function: H5D__mpio_select_read * * Purpose: MPI-IO function to read directly from app buffer to file. * @@ -359,39 +248,35 @@ done: * * Return: non-negative on success, negative on failure. * - * Modification: Jonathan Kim Nov, 2013 - * Modified from the previous H5D__mpio_select_read. - * This is part multi-dset work. - * *------------------------------------------------------------------------- */ herr_t -H5D__mpio_select_read_mdset(const H5D_io_info_md_t *io_info_md, hsize_t mpi_buf_count, +H5D__mpio_select_read(const H5D_io_info_t *io_info, hsize_t mpi_buf_count, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space) { /* all dsets are in the same file, so just get it from the first dset */ - const H5F_t *file = io_info_md->dsets_info[0].dset->oloc.file; + const H5F_t *file = io_info->dsets_info[0].dset->oloc.file; void *rbuf = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE /* memory addr from a piece with lowest file addr */ - rbuf = io_info_md->base_maddr_r; + rbuf = io_info->base_maddr_r; /*OKAY: CAST DISCARDS CONST QUALIFIER*/ H5_CHECK_OVERFLOW(mpi_buf_count, hsize_t, size_t); - if(H5F_block_read(file, H5FD_MEM_DRAW, io_info_md->store_faddr, (size_t)mpi_buf_count, - io_info_md->dxpl_id, rbuf) < 0) + if(H5F_block_read(file, H5FD_MEM_DRAW, io_info->store_faddr, (size_t)mpi_buf_count, + io_info->dxpl_id, rbuf) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't finish collective parallel write") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__mpio_select_read_mdset() */ +} /* end H5D__mpio_select_read() */ /*------------------------------------------------------------------------- - * Function: H5D__mpio_select_write_mdset + * Function: H5D__mpio_select_write * * Purpose: MPI-IO function to write directly from app buffer to file. * @@ -400,38 +285,35 @@ done: * * Return: non-negative on success, negative on failure. * - * Modification: Jonathan Kim Nov, 2013 - * Modified from the previous H5D__mpio_select_write. - * This is part multi-dset work. *------------------------------------------------------------------------- */ herr_t -H5D__mpio_select_write_mdset(const H5D_io_info_md_t *io_info_md, hsize_t mpi_buf_count, +H5D__mpio_select_write(const H5D_io_info_t *io_info, hsize_t mpi_buf_count, const H5S_t UNUSED *file_space, const H5S_t UNUSED *mem_space) { /* all dsets are in the same file, so just get it from the first dset */ - const H5F_t *file = io_info_md->dsets_info[0].dset->oloc.file; + const H5F_t *file = io_info->dsets_info[0].dset->oloc.file; const void *wbuf = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE /* memory addr from a piece with lowest file addr */ - wbuf = io_info_md->base_maddr_w; + wbuf = io_info->base_maddr_w; /*OKAY: CAST DISCARDS CONST QUALIFIER*/ H5_CHECK_OVERFLOW(mpi_buf_count, hsize_t, size_t); - if(H5F_block_write(file, H5FD_MEM_DRAW, io_info_md->store_faddr, (size_t)mpi_buf_count, - io_info_md->dxpl_id, wbuf) < 0) + if(H5F_block_write(file, H5FD_MEM_DRAW, io_info->store_faddr, (size_t)mpi_buf_count, + io_info->dxpl_id, wbuf) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't finish collective parallel write") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__mpio_select_write_mdset() */ +} /* end H5D__mpio_select_write() */ /*------------------------------------------------------------------------- - * Function: H5D__piece_mdset_io + * Function: H5D__piece_io * * Purpose: Routine for choosing an IO option: * a) Single collective IO defined by one MPI derived datatype @@ -440,21 +322,10 @@ done: * * Return: Non-negative on success/Negative on failure * - * programmer: Jonathan Kim Nov, 2013 - * Refactored from the previous H5D__chunk_collective_io. - * This is part multi-dset work. - * - * Modification: - * - Refctore to remove multi-chunk-without-opimization feature and update for - * multi-chunk-io accordingly - * Programmer: Jonathan Kim - * Date: 2012-10-10 - * - * Original Programmer: Muqun Yang Monday, Feb. 13th, 2006 *------------------------------------------------------------------------- */ static herr_t -H5D__piece_mdset_io(const hid_t file_id, const size_t count, H5D_io_info_md_t *io_info_md) +H5D__piece_io(const hid_t file_id, const size_t count, H5D_io_info_t *io_info) { H5P_genplist_t *dx_plist; /* Pointer to DXPL */ H5FD_mpio_chunk_opt_t chunk_opt_mode; @@ -464,11 +335,11 @@ H5D__piece_mdset_io(const hid_t file_id, const size_t count, H5D_io_info_md_t *i FUNC_ENTER_STATIC /* Sanity checks */ - HDassert(io_info_md); - HDassert(io_info_md->using_mpi_vfd); + HDassert(io_info); + HDassert(io_info->using_mpi_vfd); /* Obtain the data transfer properties */ - if(NULL == (dx_plist = H5I_object(io_info_md->dxpl_id))) + if(NULL == (dx_plist = H5I_object(io_info->dxpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") /* Check the optional property list on what to do with collective chunk IO. */ @@ -482,11 +353,11 @@ H5D__piece_mdset_io(const hid_t file_id, const size_t count, H5D_io_info_md_t *i int new_value; /*** Test collective chunk user-input optimization APIs. ***/ - check_prop = H5Pexist(io_info_md->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME); + check_prop = H5Pexist(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME); if(check_prop > 0) { if(H5D_ONE_LINK_CHUNK_IO == io_option) { new_value = 0; - if(H5Pset(io_info_md->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &new_value) < 0) + if(H5Pset(io_info->dxpl_id, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &new_value) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTSET, FAIL, "unable to set property value") } /* end if */ } /* end if */ @@ -495,16 +366,16 @@ H5D__piece_mdset_io(const hid_t file_id, const size_t count, H5D_io_info_md_t *i /* step 2: Go ahead to do IO.*/ if(H5D_ONE_LINK_CHUNK_IO == io_option) { - if(H5D__all_piece_collective_io(file_id, count, io_info_md, dx_plist) < 0) + if(H5D__all_piece_collective_io(file_id, count, io_info, dx_plist) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO") } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__piece_mdset_io */ +} /* end H5D__piece_io */ /*------------------------------------------------------------------------- - * Function: H5D__mdset_collective_read + * Function: H5D__collective_read * * Purpose: Read directly from pieces (chunks/contig) in file into * application memory using collective I/O. @@ -514,30 +385,26 @@ done: * Programmer: Quincey Koziol * Tuesday, March 4, 2008 * - * Modification: Jonathan Kim Nov, 2013 - * Modified from the previous H5D__chunk/contig_collective_read. - * This is part multi-dset work. - * *------------------------------------------------------------------------- */ herr_t -H5D__mdset_collective_read(const hid_t file_id, const size_t count, H5D_io_info_md_t *io_info_md) +H5D__collective_read(const hid_t file_id, const size_t count, H5D_io_info_t *io_info) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Call generic selection operation */ - if(H5D__piece_mdset_io(file_id, count, io_info_md) < 0) + if(H5D__piece_io(file_id, count, io_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__mdset_collective_read() */ +} /* end H5D__collective_read() */ /*------------------------------------------------------------------------- - * Function: H5D__mdset_collective_write + * Function: H5D__collective_write * * Purpose: Write directly to pieces (chunks/contig) in file into * application memory using collective I/O. @@ -547,25 +414,22 @@ done: * Programmer: Quincey Koziol * Tuesday, March 4, 2008 * - * Modification: Jonathan Kim Nov, 2013 - * Modified from the previous H5D__chunk/contig_collective_write. - * This is part multi-dset work. *------------------------------------------------------------------------- */ herr_t -H5D__mdset_collective_write(const hid_t file_id, const size_t count, H5D_io_info_md_t *io_info_md) +H5D__collective_write(const hid_t file_id, const size_t count, H5D_io_info_t *io_info) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Call generic selection operation */ - if(H5D__piece_mdset_io(file_id, count, io_info_md) < 0) + if(H5D__piece_io(file_id, count, io_info) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__mdset_collective_write() */ +} /* end H5D__collective_write() */ /*------------------------------------------------------------------------- @@ -581,14 +445,11 @@ done: * * Return: Non-negative on success/Negative on failure * - * Programmer: Jonathan Kim Nov, 2013 - * Refactored from the previous H5D__link_chunk_collective_io (Muqun Yang Feb. 2006). - * This is part multi-dset work. *------------------------------------------------------------------------- */ static herr_t H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, - H5D_io_info_md_t *io_info_md, H5P_genplist_t *dx_plist) + H5D_io_info_t *io_info, H5P_genplist_t *dx_plist) { MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with seletion */ hbool_t chunk_final_mtype_is_derived = FALSE; @@ -613,9 +474,9 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, /* set actual_io_mode */ for (i=0; i < count; i++) { - if (io_info_md->dsets_info[i].layout->type == H5D_CHUNKED) + if (io_info->dsets_info[i].layout->type == H5D_CHUNKED) actual_io_mode |= H5D_MPIO_CHUNK_COLLECTIVE; - else if (io_info_md->dsets_info[i].layout->type == H5D_CONTIGUOUS) { + else if (io_info->dsets_info[i].layout->type == H5D_CONTIGUOUS) { actual_io_mode |= H5D_MPIO_CONTIGUOUS_COLLECTIVE; /* if only single-dset */ @@ -649,7 +510,7 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, void * base_rbuf_addr = NULL; /* Get the number of chunks with a selection */ - num_chunk = H5SL_count(io_info_md->sel_pieces); + num_chunk = H5SL_count(io_info->sel_pieces); H5_CHECK_OVERFLOW(num_chunk, size_t, int); /* Set up MPI datatype for chunks selected */ @@ -673,7 +534,7 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file is derived datatype flags buffer") /* get first piece, which is sorted in skiplist */ - if(NULL == (piece_node = H5SL_first(io_info_md->sel_pieces))) + if(NULL == (piece_node = H5SL_first(io_info->sel_pieces))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get piece node from skipped list") if(NULL == (piece_info = (H5D_piece_info_t *)H5SL_item(piece_node))) HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL,"couldn't get piece info from skipped list") @@ -755,10 +616,10 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, * (assume MPI_Aint big enough to hold it) */ chunk_file_disp_array[u] = (MPI_Aint)piece_info->faddr - (MPI_Aint)ctg_store.contig.dset_addr; - if(io_info_md->op_type == H5D_IO_OP_WRITE) { + if(io_info->op_type == H5D_IO_OP_WRITE) { chunk_mem_disp_array[u] = (MPI_Aint)piece_info->dset_info->u.wbuf - (MPI_Aint)base_wbuf_addr; } - else if (io_info_md->op_type == H5D_IO_OP_READ) { + else if (io_info->op_type == H5D_IO_OP_READ) { chunk_mem_disp_array[u] = (MPI_Aint)piece_info->dset_info->u.rbuf - (MPI_Aint)base_rbuf_addr; } @@ -806,11 +667,11 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, * at this point dset object hear address is availbe to any * process, so just pass it. 0x0 also work fine */ ctg_store.contig.dset_addr = 0x0; - /* or ctg_store.contig.dset_addr = io_info_md->dsets_info[0].dset->oloc.addr; */ + /* or ctg_store.contig.dset_addr = io_info->dsets_info[0].dset->oloc.addr; */ /* just provide a valid mem address. no actual IO occur */ - base_wbuf_addr = io_info_md->dsets_info[0].u.wbuf; - base_rbuf_addr = io_info_md->dsets_info[0].u.rbuf; + base_wbuf_addr = io_info->dsets_info[0].u.wbuf; + base_rbuf_addr = io_info->dsets_info[0].u.rbuf; /* Set the MPI datatype to just participate */ chunk_final_ftype = MPI_BYTE; @@ -823,12 +684,12 @@ H5D__all_piece_collective_io(UNUSED const hid_t file_id, const size_t count, HDfprintf(H5DEBUG(D),"before coming to final collective IO\n"); #endif /* Set up the base storage address for this piece */ - io_info_md->store_faddr = ctg_store.contig.dset_addr; - io_info_md->base_maddr_w = base_wbuf_addr; - io_info_md->base_maddr_r = base_rbuf_addr; + io_info->store_faddr = ctg_store.contig.dset_addr; + io_info->base_maddr_w = base_wbuf_addr; + io_info->base_maddr_r = base_rbuf_addr; /* Perform final collective I/O operation */ - if(H5D__final_collective_io_mdset(io_info_md, mpi_buf_count, &chunk_final_ftype, &chunk_final_mtype) < 0) + if(H5D__final_collective_io(io_info, mpi_buf_count, &chunk_final_ftype, &chunk_final_mtype) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO") } @@ -866,7 +727,7 @@ if(H5DEBUG(D)) /*------------------------------------------------------------------------- - * Function: H5D__final_collective_io_mdset + * Function: H5D__final_collective_io * * Purpose: Routine for the common part of collective IO with different storages. * @@ -875,13 +736,10 @@ if(H5DEBUG(D)) * Programmer: Muqun Yang * Monday, Feb. 13th, 2006 * - * Modification: Jonathan Kim Nov, 2013 - * Modified from the previous H5D__final_collective_io. - * This is part multi-dset work. *------------------------------------------------------------------------- */ static herr_t -H5D__final_collective_io_mdset(H5D_io_info_md_t *io_info_md, +H5D__final_collective_io(H5D_io_info_t *io_info, hsize_t mpi_buf_count, MPI_Datatype *mpi_file_type, MPI_Datatype *mpi_buf_type) { herr_t ret_value = SUCCEED; @@ -889,15 +747,15 @@ H5D__final_collective_io_mdset(H5D_io_info_md_t *io_info_md, FUNC_ENTER_STATIC /* Pass buf type, file type to the file driver. */ - if(H5FD_mpi_setup_collective(io_info_md->dxpl_id, mpi_buf_type, mpi_file_type) < 0) + if(H5FD_mpi_setup_collective(io_info->dxpl_id, mpi_buf_type, mpi_file_type) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI-I/O properties") - if(io_info_md->op_type == H5D_IO_OP_WRITE) { - if((io_info_md->io_ops.single_write_md)(io_info_md, mpi_buf_count, NULL, NULL) < 0) + if(io_info->op_type == H5D_IO_OP_WRITE) { + if((io_info->io_ops.single_write_md)(io_info, mpi_buf_count, NULL, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed") } /* end if */ else { - if((io_info_md->io_ops.single_read_md)(io_info_md, mpi_buf_count, NULL, NULL) < 0) + if((io_info->io_ops.single_read_md)(io_info, mpi_buf_count, NULL, NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed") } /* end else */ @@ -907,7 +765,7 @@ if(H5DEBUG(D)) HDfprintf(H5DEBUG(D),"ret_value before leaving final_collective_io=%d\n",ret_value); #endif FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__final_collective_io_mdset */ +} /* end H5D__final_collective_io */ /*------------------------------------------------------------------------- @@ -931,11 +789,96 @@ H5D__cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2) FUNC_ENTER_STATIC_NOERR - addr1 = ((const H5D_chunk_addr_info_t *)chunk_addr_info1)->chunk_addr; - addr2 = ((const H5D_chunk_addr_info_t *)chunk_addr_info2)->chunk_addr; + addr1 = ((const H5D_chunk_addr_info_t *)chunk_addr_info1)->piece_addr; + addr2 = ((const H5D_chunk_addr_info_t *)chunk_addr_info2)->piece_addr; FUNC_LEAVE_NOAPI(H5F_addr_cmp(addr1, addr2)) } /* end H5D__cmp_chunk_addr() */ + +/*------------------------------------------------------------------------- + * Function: H5D_match_coll_calls + * + * Purpose: For processes that are not reading/writing to a particular + * datasets through the multi-dataset interface, but are participating + * in the collective call, match the collective I/O calls from the + * other processes. + * + * Return: non-negative on success, negative on failure. + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__match_coll_calls(hid_t file_id, H5P_genplist_t *plist, hbool_t do_read) +{ + int local_cause = 0; + int global_cause = 0; + int mpi_code; + H5F_t *file; + H5FD_mpio_collective_opt_t para_io_mode; + H5FD_mpio_xfer_t xfer_mode; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + HDassert(file_id > 0); + + /* Get the transfer mode */ + if(H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") + HDassert(xfer_mode == H5FD_MPIO_COLLECTIVE); + + /* get parallel io mode */ + if(H5P_get(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, ¶_io_mode) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to get value") + + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + + /* just to match up with MPI_Allreduce from H5D__mpio_opt_possible() */ + if(MPI_SUCCESS != (mpi_code = MPI_Allreduce(&local_cause, &global_cause, 1, + MPI_INT, MPI_BOR, H5F_mpi_get_comm(file)))) + HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) + + /* if collective mode is not broken according to the + * H5D__mpio_opt_possible, since the below MPI funcs will be + * called only in collective mode */ + if(!global_cause) { + MPI_Status mpi_stat; + MPI_File mpi_fh_p; + MPI_File mpi_fh; + + if(H5F_get_mpi_handle(file, (MPI_File **)&mpi_fh_p) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get mpi file handle") + mpi_fh = *(MPI_File*)mpi_fh_p; + + /* just to match up with the 1st MPI_File_set_view from H5FD_mpio_read() */ + if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, + MPI_BYTE, "native", MPI_INFO_NULL))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + + /* just to match up with MPI_File_write_at_all from H5FD_mpio_read() */ + if(para_io_mode == H5FD_MPIO_COLLECTIVE_IO) { + HDmemset(&mpi_stat, 0, sizeof(MPI_Status)); + if(do_read) { + if(MPI_SUCCESS != (mpi_code = MPI_File_read_at_all(mpi_fh, 0, NULL, 0, MPI_BYTE, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at_all failed", mpi_code) + } + else { + if(MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(mpi_fh, 0, NULL, 0, MPI_BYTE, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) + } + } /* end if */ + + /* just to match up with the 2nd MPI_File_set_view (reset) in H5FD_mpio_read() */ + if(MPI_SUCCESS != (mpi_code = MPI_File_set_view(mpi_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, + "native", MPI_INFO_NULL))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + } /* end if !global_cause */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FD_match_coll_calls */ + #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 1d94450..bc69e5a 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -52,13 +52,6 @@ (io_info)->store = str; \ (io_info)->op_type = H5D_IO_OP_WRITE; \ (io_info)->u.wbuf = buf -#define H5D_BUILD_IO_INFO_RD(io_info, ds, dxpl_c, dxpl_i, str, buf) \ - (io_info)->dset = ds; \ - (io_info)->dxpl_cache = dxpl_c; \ - (io_info)->dxpl_id = dxpl_i; \ - (io_info)->store = str; \ - (io_info)->op_type = H5D_IO_OP_READ; \ - (io_info)->u.rbuf = buf #define H5D_CHUNK_HASH(D, ADDR) H5F_addr_hash(ADDR, (D)->cache.chunk.nslots) @@ -97,8 +90,6 @@ typedef struct H5D_type_info_t { /* Forward declaration of structs used below */ struct H5D_io_info_t; -struct H5D_chunk_map_t; -struct H5D_io_info_md_t; struct H5D_dset_info_t; /* Function pointers for I/O on particular types of dataset layouts */ @@ -106,22 +97,20 @@ typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset); typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id); typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage); -typedef herr_t (*H5D_layout_io_init_func_t)(const struct H5D_io_info_t *io_info, - const H5D_type_info_t *type_info, - hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - struct H5D_chunk_map_t *cm); -typedef herr_t (*H5D_layout_io_init_md_func_t)(struct H5D_io_info_md_t *io_info_md, +typedef herr_t (*H5D_layout_io_init_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, struct H5D_dset_info_t *dinfo); typedef herr_t (*H5D_layout_read_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, - const H5S_t *mem_space, struct H5D_chunk_map_t *fm); + const H5S_t *mem_space, struct H5D_dset_info_t *dinfo); typedef herr_t (*H5D_layout_write_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, - const H5S_t *mem_space, struct H5D_chunk_map_t *fm); -typedef herr_t (*H5D_layout_read_md_func_t)(const hid_t file_id, const size_t count, struct H5D_io_info_md_t *io_info_md); -typedef herr_t (*H5D_layout_write_md_func_t)(const hid_t file_id, const size_t count, struct H5D_io_info_md_t *io_info_md); + const H5S_t *mem_space, struct H5D_dset_info_t *dinfo); +typedef herr_t (*H5D_layout_read_md_func_t)(const hid_t file_id, const size_t count, + struct H5D_io_info_t *io_info); +typedef herr_t (*H5D_layout_write_md_func_t)(const hid_t file_id, const size_t count, + struct H5D_io_info_t *io_info); typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]); @@ -129,8 +118,7 @@ typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t *io_info size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]); typedef herr_t (*H5D_layout_flush_func_t)(H5D_t *dataset, hid_t dxpl_id); -typedef herr_t (*H5D_layout_io_term_func_t)(const struct H5D_chunk_map_t *cm); -typedef herr_t (*H5D_layout_io_term_md_func_t)(struct H5D_dset_info_t *di); +typedef herr_t (*H5D_layout_io_term_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_info_t *di); /* Typedef for grouping layout I/O routines */ typedef struct H5D_layout_ops_t { @@ -138,18 +126,16 @@ typedef struct H5D_layout_ops_t { H5D_layout_init_func_t init; /* Layout initializer for dataset */ H5D_layout_is_space_alloc_func_t is_space_alloc; /* Query routine to determine if storage is allocated */ H5D_layout_io_init_func_t io_init; /* I/O initialization routine */ - H5D_layout_io_init_md_func_t io_init_md; /* I/O initialization routine */ H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */ H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */ #ifdef H5_HAVE_PARALLEL - H5D_layout_read_md_func_t par_read; /* High-level I/O routine for reading data in parallel */ + H5D_layout_read_md_func_t par_read; /* High-level I/O routine for reading data in parallel */ H5D_layout_write_md_func_t par_write; /* High-level I/O routine for writing data in parallel */ #endif /* H5_HAVE_PARALLEL */ H5D_layout_readvv_func_t readvv; /* Low-level I/O routine for reading data */ H5D_layout_writevv_func_t writevv; /* Low-level I/O routine for writing data */ H5D_layout_flush_func_t flush; /* Low-level I/O routine for flushing raw data */ - H5D_layout_io_term_func_t io_term; /* I/O shutdown routine */ - H5D_layout_io_term_md_func_t io_term_md; /* I/O shutdown routine for multi-dset */ + H5D_layout_io_term_func_t io_term; /* I/O shutdown routine for multi-dset */ } H5D_layout_ops_t; /* Function pointers for either multiple or single block I/O access */ @@ -160,8 +146,10 @@ typedef herr_t (*H5D_io_single_write_func_t)(const struct H5D_io_info_t *io_info const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); -typedef herr_t (*H5D_io_single_read_md_func_t)(const struct H5D_io_info_md_t *io_info_md, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); -typedef herr_t (*H5D_io_single_write_md_func_t)(const struct H5D_io_info_md_t *io_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); +typedef herr_t (*H5D_io_single_read_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts, + const H5S_t *file_space, const H5S_t *mem_space); +typedef herr_t (*H5D_io_single_write_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts, + const H5S_t *file_space, const H5S_t *mem_space); /* Typedef for raw data I/O framework info */ typedef struct H5D_io_ops_t { @@ -204,34 +192,7 @@ typedef enum H5D_io_op_type_t { H5D_IO_OP_WRITE /* Write operation */ } H5D_io_op_type_t; -typedef struct H5D_io_info_t { - const H5D_t *dset; /* Pointer to dataset being operated on */ -#ifndef H5_HAVE_PARALLEL - const -#endif /* H5_HAVE_PARALLEL */ - H5D_dxpl_cache_t *dxpl_cache; /* Pointer to cached DXPL info */ - hid_t dxpl_id; /* Original DXPL ID */ -#ifdef H5_HAVE_PARALLEL - MPI_Comm comm; /* MPI communicator for file */ - hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */ - struct { - H5FD_mpio_xfer_t xfer_mode; /* Parallel transfer for this request (H5D_XFER_IO_XFER_MODE_NAME) */ - H5FD_mpio_collective_opt_t coll_opt_mode; /* Parallel transfer with independent IO or collective IO with this mode */ - H5D_io_ops_t io_ops; /* I/O operation function pointers */ - } orig; -#endif /* H5_HAVE_PARALLEL */ - H5D_storage_t *store; /* Dataset storage info */ - H5D_layout_ops_t layout_ops; /* Dataset layout I/O operation function pointers */ - H5D_io_ops_t io_ops; /* I/O operation function pointers */ - H5D_io_op_type_t op_type; - union { - void *rbuf; /* Pointer to buffer for read */ - const void *wbuf; /* Pointer to buffer to write */ - } u; -} H5D_io_info_t; - -/* piece info for multiple dsets. - * referred from H5D_chunk_info_t for single-dset */ +/* piece info for multiple dsets. */ typedef struct H5D_piece_info_t { haddr_t faddr; /* file addr. key of skip list */ hsize_t index; /* "Index" of chunk in dataset */ @@ -270,6 +231,8 @@ typedef struct H5D_dset_info_t { unsigned m_ndims; /* Number of dimensions for memory dataspace */ H5S_sel_type msel_type; /* Selection type in memory */ + H5SL_t *dset_sel_pieces; /* Skiplist of selected pieces in this dataset, indexed by index */ + H5S_t *single_space; /* Dataspace for single chunk */ H5D_piece_info_t *single_piece_info; hbool_t use_single; /* Whether I/O is on a single element */ @@ -277,8 +240,6 @@ typedef struct H5D_dset_info_t { hsize_t last_index; /* Index of last chunk operated on */ H5D_piece_info_t *last_piece_info; /* Pointer to last piece's info */ - H5SL_t *dset_sel_pieces; /* Skiplist of selected pieces in this dataset, indexed by index */ - hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */ hid_t mem_type_id; /* memory datatype ID */ @@ -286,7 +247,7 @@ typedef struct H5D_dset_info_t { hbool_t type_info_init; } H5D_dset_info_t; -typedef struct H5D_io_info_md_t { +typedef struct H5D_io_info_t { #ifndef H5_HAVE_PARALLEL const #endif /* H5_HAVE_PARALLEL */ @@ -304,7 +265,7 @@ typedef struct H5D_io_info_md_t { H5D_io_ops_t io_ops; /* I/O operation function pointers */ H5D_io_op_type_t op_type; - H5D_dset_info_t *dsets_info; /* multiple dsets info */ + H5D_dset_info_t *dsets_info; /* dsets info where I/O is done to/from */ H5SL_t *sel_pieces; /* Skip list containing information for each piece selected */ haddr_t store_faddr; /* lowest file addr for read/write */ @@ -312,13 +273,13 @@ typedef struct H5D_io_info_md_t { void * base_maddr_r; /* start mem addr for read */ hbool_t is_coll_broken; /* is collective mode broken? */ -} H5D_io_info_md_t; +} H5D_io_info_t; /* created to pass both at once for callback func */ -typedef struct H5D_io_info_md_wrap_t { - H5D_io_info_md_t *io_info_md; +typedef struct H5D_io_info_wrap_t { + H5D_io_info_t *io_info; H5D_dset_info_t *dinfo; -} H5D_io_info_md_wrap_t; +} H5D_io_info_wrap_t; /******************/ @@ -427,44 +388,6 @@ typedef struct H5D_chunk_ops_t { H5D_chunk_dest_func_t dest; /* Routine to destroy indexing information in memory */ } H5D_chunk_ops_t; -/* Structure holding information about a chunk's selection for mapping */ -typedef struct H5D_chunk_info_t { - hsize_t index; /* "Index" of chunk in dataset */ - uint32_t chunk_points; /* Number of elements selected in chunk */ - hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk in file dataset's dataspace */ - H5S_t *fspace; /* Dataspace describing chunk & selection in it */ - unsigned fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */ - H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */ - unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */ -} H5D_chunk_info_t; - -/* Main structure holding the mapping between file chunks and memory */ -typedef struct H5D_chunk_map_t { - H5O_layout_t *layout; /* Dataset layout information*/ - hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */ - - const H5S_t *file_space; /* Pointer to the file dataspace */ - unsigned f_ndims; /* Number of dimensions for file dataspace */ - hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* File dataspace dimensions */ - - const H5S_t *mem_space; /* Pointer to the memory dataspace */ - H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */ - H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */ - unsigned m_ndims; /* Number of dimensions for memory dataspace */ - H5S_sel_type msel_type; /* Selection type in memory */ - - H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ - - H5S_t *single_space; /* Dataspace for single chunk */ - H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */ - hbool_t use_single; /* Whether I/O is on a single element */ - - hsize_t last_index; /* Index of last chunk operated on */ - H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */ - - hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */ -} H5D_chunk_map_t; - /* Cached information about a particular chunk */ typedef struct H5D_chunk_cached_t{ hbool_t valid; /*whether cache info is valid*/ @@ -493,7 +416,6 @@ typedef struct H5D_rdcc_t { struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/ H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */ H5S_t *single_space; /* Dataspace for single element I/O on chunks */ - H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */ H5D_piece_info_t *single_piece_info; /* Pointer to single piece's info */ } H5D_rdcc_t; @@ -654,11 +576,13 @@ H5_DLL herr_t H5D__get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache); H5_DLL herr_t H5D__flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id); H5_DLL herr_t H5D__mark(const H5D_t *dataset, hid_t dxpl_id, unsigned flags); H5_DLL herr_t H5D__flush_real(H5D_t *dataset, hid_t dxpl_id); +H5_DLL herr_t H5D__init_dset_info(H5D_dset_info_t *dset_info, hid_t dset_id, + hid_t mem_type_id, hid_t mem_space_id, hid_t dset_space_id, + const H5D_dset_buf_t *u_buf); -/* Internal I/O routines */ -H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, - const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, - void *buf/*out*/); +/* Functions to do I/O */ +H5_DLL herr_t H5D__read(hid_t file_id, hid_t dxpl_id, size_t count, + H5D_dset_info_t *dset_info); /* Functions that perform direct serial I/O operations */ H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, @@ -697,10 +621,10 @@ H5_DLL hbool_t H5D__contig_is_space_alloc(const H5O_storage_t *storage); H5_DLL herr_t H5D__contig_fill(const H5D_t *dset, hid_t dxpl_id); H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *fm); + H5D_dset_info_t *dinfo); H5_DLL herr_t H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, - H5D_chunk_map_t *fm); + H5D_dset_info_t *dinfo); H5_DLL herr_t H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, H5F_t *f_dst, H5O_storage_contig_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); @@ -781,33 +705,31 @@ H5_DLL herr_t H5D__fill_term(H5D_fill_buf_info_t *fb_info); /* MPI-IO function to read multi-dsets (Chunk, Contig), it will select either * regular or irregular read */ -H5_DLL herr_t H5D__mpio_select_read_mdset(const H5D_io_info_md_t *io_info_md, +H5_DLL herr_t H5D__mpio_select_read(const H5D_io_info_t *io_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); /* MPI-IO function to write multi-dsets (Chunk, Contig), it will select either * regular or irregular write */ -H5_DLL herr_t H5D__mpio_select_write_mdset(const H5D_io_info_md_t *io_info_md, +H5_DLL herr_t H5D__mpio_select_write(const H5D_io_info_t *io_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space); /* MPI-IO functions to handle collective IO for multiple dsets (CONTIG, CHUNK) */ -H5_DLL herr_t H5D__mdset_collective_read(const hid_t file_id, const size_t count, H5D_io_info_md_t *io_info_md); -H5_DLL herr_t H5D__mdset_collective_write(const hid_t file_id, const size_t count, H5D_io_info_md_t *io_info_md); +H5_DLL herr_t H5D__collective_read(const hid_t file_id, const size_t count, H5D_io_info_t *io_info); +H5_DLL herr_t H5D__collective_write(const hid_t file_id, const size_t count, H5D_io_info_t *io_info); /* MPI-IO function to check if a direct I/O transfer is possible between * memory and the file */ -H5_DLL htri_t H5D__mpio_opt_possible(const H5D_io_info_t *io_info, - const H5S_t *file_space, const H5S_t *mem_space, - const H5D_type_info_t *type_info, const H5D_chunk_map_t *fm, - H5P_genplist_t *dx_plist); +H5_DLL htri_t H5D__mpio_opt_possible(const size_t count, H5D_io_info_t *io_info, + H5P_genplist_t *dx_plist); -/* MPI-IO function to check if a direct I/O transfer is possible between - * memory and the file for multi-dset */ -H5_DLL htri_t H5D__mpio_opt_possible_mdset(const size_t count, H5D_io_info_md_t *io_info_md, H5P_genplist_t *dx_plist); +/* function to invoke collective I/O calls for ranks that have no I/O + on a dataset to match other ranks' collective calls */ +H5_DLL herr_t H5D__match_coll_calls(hid_t file_id, H5P_genplist_t *plist, hbool_t do_read); #endif /* H5_HAVE_PARALLEL */ -/* for both CHUNK and CONTIG dset skiplist free (sel_pieces) for layout_ops.io_term_md. */ -H5_DLL herr_t H5D__piece_io_term_mdset(H5D_dset_info_t *di); +/* for both CHUNK and CONTIG dset skiplist free (sel_pieces) for layout_ops.io_term. */ +H5_DLL herr_t H5D__piece_io_term(H5D_io_info_t *io_info, H5D_dset_info_t *di); /* Testing functions */ #ifdef H5D_TESTING diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 4b0846f..317ba4a 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -97,6 +97,7 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, const void *_buf) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ + H5D_dset_info_t tmp_dset_info; /* Temporary I/O info object */ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off = NULL; /* Pointer to sequence offsets */ hsize_t mem_off; /* Offset in memory */ @@ -120,8 +121,10 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, /* Set up temporary I/O info object */ HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); + HDmemcpy(&tmp_dset_info, &(_io_info->dsets_info[0]), sizeof(tmp_dset_info)); tmp_io_info.op_type = H5D_IO_OP_WRITE; - tmp_io_info.u.wbuf = _buf; + tmp_dset_info.u.wbuf = _buf; + tmp_io_info.dsets_info = &tmp_dset_info; /* Allocate the vector I/O arrays */ if(tmp_io_info.dxpl_cache->vec_size > H5D_IO_VECTOR_SIZE) { @@ -147,12 +150,12 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, mem_off = 0; /* Write sequence list out */ - if((*tmp_io_info.layout_ops.writevv)(&tmp_io_info, nseq, &dset_curr_seq, + if((*tmp_dset_info.layout_ops.writevv)(&tmp_io_info, nseq, &dset_curr_seq, len, off, (size_t)1, &mem_curr_seq, &mem_len, &mem_off) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error") /* Update buffer */ - tmp_io_info.u.wbuf = (const uint8_t *)tmp_io_info.u.wbuf + orig_mem_len; + tmp_dset_info.u.wbuf = (const uint8_t *)tmp_dset_info.u.wbuf + orig_mem_len; /* Decrement number of elements left to process */ nelmts -= nelem; @@ -196,6 +199,7 @@ H5D__gather_file(const H5D_io_info_t *_io_info, void *_buf/*out*/) { H5D_io_info_t tmp_io_info; /* Temporary I/O info object */ + H5D_dset_info_t tmp_dset_info; /* Temporary I/O info object */ hsize_t _off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */ hsize_t *off = NULL; /* Pointer to sequence offsets */ hsize_t mem_off; /* Offset in memory */ @@ -212,8 +216,8 @@ H5D__gather_file(const H5D_io_info_t *_io_info, /* Check args */ HDassert(_io_info); - HDassert(_io_info->dset); - HDassert(_io_info->store); + HDassert(_io_info->dsets_info[0].dset); + HDassert(_io_info->dsets_info[0].store); HDassert(space); HDassert(iter); HDassert(nelmts > 0); @@ -221,8 +225,10 @@ H5D__gather_file(const H5D_io_info_t *_io_info, /* Set up temporary I/O info object */ HDmemcpy(&tmp_io_info, _io_info, sizeof(*_io_info)); + HDmemcpy(&tmp_dset_info, &(_io_info->dsets_info[0]), sizeof(tmp_dset_info)); tmp_io_info.op_type = H5D_IO_OP_READ; - tmp_io_info.u.rbuf = _buf; + tmp_dset_info.u.rbuf = _buf; + tmp_io_info.dsets_info = &tmp_dset_info; /* Allocate the vector I/O arrays */ if(tmp_io_info.dxpl_cache->vec_size > H5D_IO_VECTOR_SIZE) { @@ -248,12 +254,12 @@ H5D__gather_file(const H5D_io_info_t *_io_info, mem_off = 0; /* Read sequence list in */ - if((*tmp_io_info.layout_ops.readvv)(&tmp_io_info, nseq, &dset_curr_seq, + if((*tmp_dset_info.layout_ops.readvv)(&tmp_io_info, nseq, &dset_curr_seq, len, off, (size_t)1, &mem_curr_seq, &mem_len, &mem_off) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error") /* Update buffer */ - tmp_io_info.u.rbuf = (uint8_t *)tmp_io_info.u.rbuf + orig_mem_len; + tmp_dset_info.u.rbuf = (uint8_t *)tmp_dset_info.u.rbuf + orig_mem_len; /* Decrement number of elements left to process */ nelmts -= nelem; @@ -459,7 +465,7 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space) { const H5D_dxpl_cache_t *dxpl_cache = io_info->dxpl_cache; /* Local pointer to dataset transfer info */ - void *buf = io_info->u.rbuf; /* Local pointer to application buffer */ + void *buf = io_info->dsets_info[0].u.rbuf; /* Local pointer to application buffer */ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/ hbool_t mem_iter_init = FALSE; /*memory selection iteration info has been initialized */ H5S_sel_iter_t bkg_iter; /*background iteration info*/ @@ -591,7 +597,7 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space) { const H5D_dxpl_cache_t *dxpl_cache = io_info->dxpl_cache; /* Local pointer to dataset transfer info */ - const void *buf = io_info->u.wbuf; /* Local pointer to application buffer */ + const void *buf = io_info->dsets_info[0].u.wbuf; /* Local pointer to application buffer */ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/ hbool_t mem_iter_init = FALSE; /*memory selection iteration info has been initialized */ H5S_sel_iter_t bkg_iter; /*background iteration info*/ diff --git a/src/H5Dselect.c b/src/H5Dselect.c index 38f8bc4..8414b8b 100644 --- a/src/H5Dselect.c +++ b/src/H5Dselect.c @@ -109,10 +109,10 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, /* Check args */ HDassert(io_info); - HDassert(io_info->dset); - HDassert(io_info->store); + HDassert(io_info->dsets_info[0].dset); + HDassert(io_info->dsets_info[0].store); HDassert(TRUE == H5P_isa_class(io_info->dxpl_id, H5P_DATASET_XFER)); - HDassert(io_info->u.rbuf); + HDassert(io_info->dsets_info[0].u.rbuf); /* Allocate the vector I/O arrays */ if(io_info->dxpl_cache->vec_size > H5D_IO_VECTOR_SIZE) { @@ -149,14 +149,14 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, /* Perform I/O on memory and file sequences */ if(io_info->op_type == H5D_IO_OP_READ) { - if((tmp_file_len = (*io_info->layout_ops.readvv)(io_info, + if((tmp_file_len = (*io_info->dsets_info[0].layout_ops.readvv)(io_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, &curr_mem_seq, mem_len, mem_off)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error") } /* end if */ else { HDassert(io_info->op_type == H5D_IO_OP_WRITE); - if((tmp_file_len = (*io_info->layout_ops.writevv)(io_info, + if((tmp_file_len = (*io_info->dsets_info[0].layout_ops.writevv)(io_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, &curr_mem_seq, mem_len, mem_off)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error") @@ -207,14 +207,14 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, /* Perform I/O on memory and file sequences */ if(io_info->op_type == H5D_IO_OP_READ) { - if((tmp_file_len = (*io_info->layout_ops.readvv)(io_info, + if((tmp_file_len = (*io_info->dsets_info[0].layout_ops.readvv)(io_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, &curr_mem_seq, mem_len, mem_off)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error") } /* end if */ else { HDassert(io_info->op_type == H5D_IO_OP_WRITE); - if((tmp_file_len = (*io_info->layout_ops.writevv)(io_info, + if((tmp_file_len = (*io_info->dsets_info[0].layout_ops.writevv)(io_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq, &curr_mem_seq, mem_len, mem_off)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error") |