mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
Merge initial version of selection I/O feature into develop (#1367)
This commit is contained in:
parent
25ef608e2f
commit
42b767fc67
@ -171,4 +171,4 @@
|
||||
*
|
||||
* <b>See also: <a href="http://hdfgroup.org/HDF5/"> http://hdfgroup.org/HDF5"</a></b>
|
||||
**/
|
||||
package hdf.hdf5lib;
|
||||
package hdf.hdf5lib;
|
||||
|
13
src/H5.c
13
src/H5.c
@ -83,6 +83,8 @@ hbool_t H5_libinit_g = FALSE; /* Library hasn't been initialized */
|
||||
hbool_t H5_libterm_g = FALSE; /* Library isn't being shutdown */
|
||||
#endif
|
||||
|
||||
hbool_t H5_use_selection_io_g = FALSE;
|
||||
|
||||
#ifdef H5_HAVE_MPE
|
||||
hbool_t H5_MPEinit_g = FALSE; /* MPE Library hasn't been initialized */
|
||||
#endif
|
||||
@ -144,7 +146,8 @@ herr_t
|
||||
H5_init_library(void)
|
||||
{
|
||||
size_t i;
|
||||
herr_t ret_value = SUCCEED;
|
||||
char * env_use_select_io = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
@ -288,6 +291,14 @@ H5_init_library(void)
|
||||
}
|
||||
/* clang-format on */
|
||||
|
||||
/* Check for HDF5_USE_SELECTION_IO env variable */
|
||||
env_use_select_io = HDgetenv("HDF5_USE_SELECTION_IO");
|
||||
if (NULL != env_use_select_io && HDstrcmp(env_use_select_io, "") && HDstrcmp(env_use_select_io, "0") &&
|
||||
HDstrcmp(env_use_select_io, "no") && HDstrcmp(env_use_select_io, "No") &&
|
||||
HDstrcmp(env_use_select_io, "NO") && HDstrcmp(env_use_select_io, "false") &&
|
||||
HDstrcmp(env_use_select_io, "False") && HDstrcmp(env_use_select_io, "FALSE"))
|
||||
H5_use_selection_io_g = TRUE;
|
||||
|
||||
/* Debugging? */
|
||||
H5__debug_mask("-all");
|
||||
H5__debug_mask(HDgetenv("HDF5_DEBUG"));
|
||||
|
787
src/H5Dchunk.c
787
src/H5Dchunk.c
@ -59,6 +59,7 @@
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
#include "H5MFprivate.h" /* File memory management */
|
||||
#include "H5PBprivate.h" /* Page Buffer */
|
||||
#include "H5VMprivate.h" /* Vector and array functions */
|
||||
|
||||
/****************/
|
||||
@ -70,6 +71,7 @@
|
||||
#define H5D_CHUNK_GET_NODE_INFO(map, node) \
|
||||
(map->use_single ? map->single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node))
|
||||
#define H5D_CHUNK_GET_NEXT_NODE(map, node) (map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
|
||||
#define H5D_CHUNK_GET_NODE_COUNT(map) (map->use_single ? (size_t)1 : H5SL_count(map->sel_chunks))
|
||||
|
||||
/* Sanity check on chunk index types: commonly used by a lot of routines in this file */
|
||||
#define H5D_CHUNK_STORAGE_INDEX_CHK(storage) \
|
||||
@ -261,8 +263,8 @@ typedef struct H5D_chunk_iter_ud_t {
|
||||
/* Chunked layout operation callbacks */
|
||||
static herr_t H5D__chunk_construct(H5F_t *f, H5D_t *dset);
|
||||
static herr_t H5D__chunk_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
@ -304,6 +306,7 @@ static herr_t H5D__chunk_file_cb(void *elem, const H5T_t *type, unsigned ndims
|
||||
void *fm);
|
||||
static herr_t H5D__chunk_mem_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
|
||||
void *fm);
|
||||
static htri_t H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info);
|
||||
static unsigned H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled);
|
||||
static herr_t H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset);
|
||||
static herr_t H5D__chunk_cache_evict(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t flush);
|
||||
@ -1065,16 +1068,17 @@ H5D__chunk_is_data_cached(const H5D_shared_t *shared_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,
|
||||
H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm)
|
||||
{
|
||||
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
|
||||
hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
|
||||
htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
|
||||
unsigned f_ndims; /* The number of dimensions of the file's dataspace */
|
||||
int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
@ -1128,6 +1132,11 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
if (H5D__chunk_io_init_selections(io_info, type_info, fm) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file and memory chunk selections")
|
||||
|
||||
/* Check if we're performing selection I/O and save the result */
|
||||
if ((use_selection_io = H5D__chunk_may_use_select_io(io_info)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
|
||||
done:
|
||||
/* Reset the global dataspace info */
|
||||
fm->file_space = NULL;
|
||||
@ -2458,6 +2467,78 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_cacheable() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_may_use_select_io
|
||||
*
|
||||
* Purpose: A small internal function to if it may be possible to use
|
||||
* selection I/O.
|
||||
*
|
||||
* Return: TRUE or FALSE
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 4 May 2021
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static htri_t
|
||||
H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info)
|
||||
{
|
||||
const H5D_t *dataset = NULL; /* Local pointer to dataset info */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
|
||||
dataset = io_info->dset;
|
||||
HDassert(dataset);
|
||||
|
||||
/* Don't use selection I/O if it's globally disabled, there is a type
|
||||
* conversion, or if there are filters on the dataset (for now) */
|
||||
if (!H5_use_selection_io_g || io_info->io_ops.single_read != H5D__select_read ||
|
||||
dataset->shared->dcpl_cache.pline.nused > 0)
|
||||
ret_value = FALSE;
|
||||
else {
|
||||
hbool_t page_buf_enabled;
|
||||
|
||||
HDassert(io_info->io_ops.single_write == H5D__select_write);
|
||||
|
||||
/* Check if the page buffer is enabled */
|
||||
if (H5PB_enabled(io_info->f_sh, H5FD_MEM_DRAW, &page_buf_enabled) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if page buffer is enabled")
|
||||
if (page_buf_enabled)
|
||||
ret_value = FALSE;
|
||||
else {
|
||||
/* Check if chunks in this dataset may be cached, if so don't use
|
||||
* selection I/O (for now). Note that chunks temporarily cached for
|
||||
* the purpose of writing the fill value don't count, since they are
|
||||
* immediately evicted. */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* If MPI based VFD is used and the file is opened for write access,
|
||||
* must bypass the chunk-cache scheme because other MPI processes
|
||||
* could be writing to other elements in the same chunk.
|
||||
*/
|
||||
if (io_info->using_mpi_vfd && (H5F_ACC_RDWR & H5F_INTENT(dataset->oloc.file)))
|
||||
ret_value = TRUE;
|
||||
else {
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
/* Check if the chunk is too large to keep in the cache */
|
||||
H5_CHECK_OVERFLOW(dataset->shared->layout.u.chunk.size, uint32_t, size_t);
|
||||
if ((size_t)dataset->shared->layout.u.chunk.size > dataset->shared->cache.chunk.nbytes_max)
|
||||
ret_value = TRUE;
|
||||
else
|
||||
ret_value = FALSE;
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
} /* end else */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_may_use_select_io() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_read
|
||||
*
|
||||
@ -2474,16 +2555,17 @@ static herr_t
|
||||
H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
|
||||
H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
{
|
||||
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 ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint32_t 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 */
|
||||
H5SL_node_t * chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
|
||||
uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
|
||||
H5S_t ** chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t * chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
|
||||
H5S_t ** chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t * chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
|
||||
haddr_t * chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
@ -2497,23 +2579,6 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
H5MM_memcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info));
|
||||
nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT;
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
|
||||
uint32_t);
|
||||
|
||||
/* Set up compact I/O info object */
|
||||
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
|
||||
cpt_io_info.store = &cpt_store;
|
||||
cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
|
||||
/* 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 */
|
||||
H5D_fill_value_t fill_status; /* Fill value status */
|
||||
@ -2531,80 +2596,215 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
skip_missing_chunks = TRUE;
|
||||
}
|
||||
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chunk_ud_t udata; /* Chunk index pass-through */
|
||||
/* Different blocks depending on whether we're using selection I/O */
|
||||
if (io_info->use_select_io) {
|
||||
size_t num_chunks;
|
||||
size_t element_sizes[2] = {type_info->dst_type_size, 0};
|
||||
void * bufs[2] = {io_info->u.rbuf, NULL};
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Check for non-existent chunk & skip it if appropriate */
|
||||
if (H5F_addr_defined(udata.chunk_block.offset) || UINT_MAX != udata.idx_hint ||
|
||||
!skip_missing_chunks) {
|
||||
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
|
||||
void * chunk = NULL; /* Pointer to locked chunk buffer */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, FALSE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache and lock it. */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Point I/O info at contiguous I/O info for this chunk */
|
||||
chk_io_info = &cpt_io_info;
|
||||
} /* end if */
|
||||
else if (H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Set up the storage address information for this chunk */
|
||||
ctg_store.contig.dset_addr = udata.chunk_block.offset;
|
||||
|
||||
/* Point I/O info at temporary I/O info for this chunk */
|
||||
chk_io_info = &ctg_io_info;
|
||||
} /* end else if */
|
||||
else {
|
||||
/* Point I/O info at "nonexistent" I/O info for this chunk */
|
||||
chk_io_info = &nonexistent_io_info;
|
||||
} /* end else */
|
||||
|
||||
/* Perform the actual read operation */
|
||||
if ((io_info->io_ops.single_read)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
|
||||
|
||||
/* Release the cache lock on the chunk. */
|
||||
if (chunk && H5D__chunk_unlock(io_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to static buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
} /* end if */
|
||||
else {
|
||||
chunk_mem_spaces = chunk_mem_spaces_static;
|
||||
chunk_file_spaces = chunk_file_spaces_static;
|
||||
chunk_addrs = chunk_addrs_static;
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chunk_ud_t udata; /* Chunk index pass-through */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* There should be no chunks cached */
|
||||
HDassert(UINT_MAX == udata.idx_hint);
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Check for non-existent chunk & skip it if appropriate */
|
||||
if (H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Add chunk to list for selection I/O */
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
} /* end if */
|
||||
else if (!skip_missing_chunks) {
|
||||
/* Perform the actual read operation from the nonexistent chunk
|
||||
*/
|
||||
if ((io_info->io_ops.single_read)(&nonexistent_io_info, type_info,
|
||||
(hsize_t)chunk_info->chunk_points, chunk_info->fspace,
|
||||
chunk_info->mspace) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
|
||||
} /* end if */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_read(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
|
||||
chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
|
||||
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static) {
|
||||
HDassert(chunk_mem_spaces);
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_static);
|
||||
HDassert(chunk_addrs != chunk_addrs_static);
|
||||
H5MM_free(chunk_mem_spaces);
|
||||
chunk_mem_spaces = NULL;
|
||||
H5MM_free(chunk_file_spaces);
|
||||
chunk_file_spaces = NULL;
|
||||
H5MM_free(chunk_addrs);
|
||||
chunk_addrs = NULL;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
|
||||
uint32_t);
|
||||
|
||||
/* Set up compact I/O info object */
|
||||
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
|
||||
cpt_io_info.store = &cpt_store;
|
||||
cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
|
||||
/* 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);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chunk_ud_t udata; /* Chunk index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Check for non-existent chunk & skip it if appropriate */
|
||||
if (H5F_addr_defined(udata.chunk_block.offset) || UINT_MAX != udata.idx_hint ||
|
||||
!skip_missing_chunks) {
|
||||
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
|
||||
void * chunk = NULL; /* Pointer to locked chunk buffer */
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, FALSE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache and lock it. */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Point I/O info at contiguous I/O info for this chunk */
|
||||
chk_io_info = &cpt_io_info;
|
||||
} /* end if */
|
||||
else if (H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Set up the storage address information for this chunk */
|
||||
ctg_store.contig.dset_addr = udata.chunk_block.offset;
|
||||
|
||||
/* Point I/O info at temporary I/O info for this chunk */
|
||||
chk_io_info = &ctg_io_info;
|
||||
} /* end else if */
|
||||
else {
|
||||
/* Point I/O info at "nonexistent" I/O info for this chunk */
|
||||
chk_io_info = &nonexistent_io_info;
|
||||
} /* end else */
|
||||
|
||||
/* Perform the actual read operation */
|
||||
if ((io_info->io_ops.single_read)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
|
||||
|
||||
/* Release the cache lock on the chunk. */
|
||||
if (chunk && H5D__chunk_unlock(io_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
/* Cleanup on failure */
|
||||
if (ret_value < 0) {
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static)
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
if (chunk_file_spaces != chunk_file_spaces_static)
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
if (chunk_addrs != chunk_addrs_static)
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
|
||||
/* Make sure we cleaned up */
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5D__chunk_read() */
|
||||
|
||||
@ -2624,14 +2824,20 @@ static herr_t
|
||||
H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
|
||||
H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
{
|
||||
H5SL_node_t * chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5SL_node_t * chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
H5S_t ** chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t * chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
|
||||
H5S_t ** chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t * chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
|
||||
haddr_t * chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
@ -2658,116 +2864,295 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
/* 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);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t * chunk_info; /* Chunk information */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_io_info_t * chk_io_info; /* Pointer to I/O info object for this chunk */
|
||||
void * chunk; /* Pointer to locked chunk buffer */
|
||||
H5D_chunk_ud_t udata; /* Index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
|
||||
/* Different blocks depending on whether we're using selection I/O */
|
||||
if (io_info->use_select_io) {
|
||||
size_t num_chunks;
|
||||
size_t element_sizes[2] = {type_info->dst_type_size, 0};
|
||||
const void *bufs[2] = {io_info->u.wbuf, NULL};
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
|
||||
|
||||
/* Look up the chunk */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache. But if the whole chunk is written,
|
||||
* simply allocate space instead of load the chunk. */
|
||||
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
|
||||
|
||||
/* Determine if we will access all the data in the chunk */
|
||||
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
|
||||
(chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
|
||||
fm->fsel_type == H5S_SEL_POINTS)
|
||||
entire_chunk = FALSE;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Point I/O info at main I/O info for this chunk */
|
||||
chk_io_info = &cpt_io_info;
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to static buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk hasn't been allocated on disk, do so now. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = io_info->dset->oloc.file;
|
||||
idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
|
||||
chunk_mem_spaces = chunk_mem_spaces_static;
|
||||
chunk_file_spaces = chunk_file_spaces_static;
|
||||
chunk_addrs = chunk_addrs_static;
|
||||
} /* end else */
|
||||
|
||||
/* Set up the size of chunk for user data */
|
||||
udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
|
||||
/* Allocate the chunk */
|
||||
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
|
||||
chunk_info->scaled) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert/resize chunk on chunk level")
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t * chunk_info; /* Chunk information */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_chunk_ud_t udata; /* Index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
|
||||
|
||||
/* Make sure the address of the chunk is returned. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
|
||||
/* Cache the new chunk information */
|
||||
H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* There should be no chunks cached */
|
||||
HDassert(UINT_MAX == udata.idx_hint);
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache. But if the whole chunk is written,
|
||||
* simply allocate space instead of load the chunk. */
|
||||
void * chunk; /* Pointer to locked chunk buffer */
|
||||
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
|
||||
|
||||
/* Determine if we will access all the data in the chunk */
|
||||
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
|
||||
(chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
|
||||
fm->fsel_type == H5S_SEL_POINTS)
|
||||
entire_chunk = FALSE;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Perform the actual write operation */
|
||||
if ((io_info->io_ops.single_write)(&cpt_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
|
||||
|
||||
/* Release the cache lock on the chunk */
|
||||
if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk hasn't been allocated on disk, do so now. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = io_info->dset->oloc.file;
|
||||
idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
|
||||
|
||||
/* Set up the storage address information for this chunk */
|
||||
ctg_store.contig.dset_addr = udata.chunk_block.offset;
|
||||
/* Set up the size of chunk for user data */
|
||||
udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* No chunk cached */
|
||||
chunk = NULL;
|
||||
/* Allocate the chunk */
|
||||
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
|
||||
chunk_info->scaled) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert/resize chunk on chunk level")
|
||||
|
||||
/* Point I/O info at temporary I/O info for this chunk */
|
||||
chk_io_info = &ctg_io_info;
|
||||
} /* end else */
|
||||
/* Make sure the address of the chunk is returned. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
|
||||
|
||||
/* 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)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
|
||||
/* Cache the new chunk information */
|
||||
H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
|
||||
|
||||
/* Release the cache lock on the chunk, or insert chunk into index. */
|
||||
if (chunk) {
|
||||
if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
/* Insert chunk into index */
|
||||
if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert chunk addr into index")
|
||||
} /* end if */
|
||||
|
||||
/* Add chunk to list for selection I/O */
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_write(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
|
||||
chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
|
||||
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static) {
|
||||
HDassert(chunk_mem_spaces);
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_static);
|
||||
HDassert(chunk_addrs != chunk_addrs_static);
|
||||
H5MM_free(chunk_mem_spaces);
|
||||
chunk_mem_spaces = NULL;
|
||||
H5MM_free(chunk_file_spaces);
|
||||
chunk_file_spaces = NULL;
|
||||
H5MM_free(chunk_addrs);
|
||||
chunk_addrs = NULL;
|
||||
} /* end if */
|
||||
else {
|
||||
if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk addr into index")
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else {
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t * chunk_info; /* Chunk information */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_io_info_t * chk_io_info; /* Pointer to I/O info object for this chunk */
|
||||
void * chunk; /* Pointer to locked chunk buffer */
|
||||
H5D_chunk_ud_t udata; /* Index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
|
||||
/* Look up the chunk */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length > 0) ||
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache. But if the whole chunk is written,
|
||||
* simply allocate space instead of load the chunk. */
|
||||
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
|
||||
|
||||
/* Determine if we will access all the data in the chunk */
|
||||
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
|
||||
(chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
|
||||
fm->fsel_type == H5S_SEL_POINTS)
|
||||
entire_chunk = FALSE;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Point I/O info at main I/O info for this chunk */
|
||||
chk_io_info = &cpt_io_info;
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk hasn't been allocated on disk, do so now. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = io_info->dset->oloc.file;
|
||||
idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
|
||||
|
||||
/* Set up the size of chunk for user data */
|
||||
udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Allocate the chunk */
|
||||
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
|
||||
chunk_info->scaled) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert/resize chunk on chunk level")
|
||||
|
||||
/* Make sure the address of the chunk is returned. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset))
|
||||
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);
|
||||
} /* end if */
|
||||
|
||||
/* Set up the storage address information for this chunk */
|
||||
ctg_store.contig.dset_addr = udata.chunk_block.offset;
|
||||
|
||||
/* No chunk cached */
|
||||
chunk = NULL;
|
||||
|
||||
/* Point I/O info at temporary I/O info for this chunk */
|
||||
chk_io_info = &ctg_io_info;
|
||||
} /* end else */
|
||||
|
||||
/* Perform the actual write operation */
|
||||
if ((io_info->io_ops.single_write)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
|
||||
|
||||
/* Release the cache lock on the chunk, or insert chunk into index. */
|
||||
if (chunk) {
|
||||
if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata, NULL) <
|
||||
0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert chunk addr into index")
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
/* Cleanup on failure */
|
||||
if (ret_value < 0) {
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static)
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
if (chunk_file_spaces != chunk_file_spaces_static)
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
if (chunk_addrs != chunk_addrs_static)
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
|
||||
/* Make sure we cleaned up */
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5D__chunk_write() */
|
||||
|
||||
|
@ -63,8 +63,8 @@ typedef struct H5D_compact_iovv_memmanage_ud_t {
|
||||
/* 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, H5S_t *file_space, 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,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static herr_t H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata);
|
||||
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,
|
||||
@ -247,7 +247,7 @@ H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__compact_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
H5D__compact_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
{
|
||||
|
110
src/H5Dcontig.c
110
src/H5Dcontig.c
@ -43,6 +43,7 @@
|
||||
#include "H5FOprivate.h" /* File objects */
|
||||
#include "H5Oprivate.h" /* Object headers */
|
||||
#include "H5Pprivate.h" /* Property lists */
|
||||
#include "H5PBprivate.h" /* Page Buffer */
|
||||
#include "H5VMprivate.h" /* Vector and array functions */
|
||||
|
||||
/****************/
|
||||
@ -90,8 +91,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_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static herr_t H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
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[]);
|
||||
@ -102,6 +103,7 @@ static herr_t H5D__contig_flush(H5D_t *dset);
|
||||
|
||||
/* Helper routines */
|
||||
static herr_t H5D__contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size_t size);
|
||||
static htri_t H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, H5D_io_op_type_t op_type);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@ -566,18 +568,80 @@ H5D__contig_is_data_cached(const H5D_shared_t *shared_dset)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__contig_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
{
|
||||
FUNC_ENTER_STATIC_NOERR
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
htri_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
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)
|
||||
/* Check if we're performing selection I/O */
|
||||
if ((use_selection_io = H5D__contig_may_use_select_io(io_info, H5D_IO_OP_READ)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_io_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_may_use_select_io
|
||||
*
|
||||
* Purpose: A small internal function to if it may be possible to use
|
||||
* selection I/O.
|
||||
*
|
||||
* Return: TRUE/FALSE/FAIL
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* 3 August 2021
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static htri_t
|
||||
H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, H5D_io_op_type_t op_type)
|
||||
{
|
||||
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_STATIC
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(dataset);
|
||||
HDassert(op_type == H5D_IO_OP_READ || op_type == H5D_IO_OP_WRITE);
|
||||
|
||||
/* Don't use selection I/O if it's globally disabled, if there is a type
|
||||
* conversion, or if it's not a contiguous dataset, or if the sieve buffer
|
||||
* exists (write) or is dirty (read) */
|
||||
if (!H5_use_selection_io_g || io_info->io_ops.single_read != H5D__select_read ||
|
||||
io_info->layout_ops.readvv != H5D__contig_readvv ||
|
||||
(op_type == H5D_IO_OP_READ && io_info->dset->shared->cache.contig.sieve_dirty) ||
|
||||
(op_type == H5D_IO_OP_WRITE && io_info->dset->shared->cache.contig.sieve_buf))
|
||||
ret_value = FALSE;
|
||||
else {
|
||||
hbool_t page_buf_enabled;
|
||||
|
||||
HDassert(io_info->io_ops.single_write == H5D__select_write);
|
||||
HDassert(io_info->layout_ops.writevv == H5D__contig_writevv);
|
||||
|
||||
/* Check if the page buffer is enabled */
|
||||
if (H5PB_enabled(io_info->f_sh, H5FD_MEM_DRAW, &page_buf_enabled) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if page buffer is enabled")
|
||||
if (page_buf_enabled)
|
||||
ret_value = FALSE;
|
||||
else
|
||||
ret_value = TRUE;
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_may_use_select_io() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_read
|
||||
*
|
||||
@ -594,7 +658,7 @@ herr_t
|
||||
H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@ -605,8 +669,20 @@ H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
|
||||
/* Read data */
|
||||
if ((io_info->io_ops.single_read)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
if (io_info->use_select_io) {
|
||||
size_t dst_type_size = type_info->dst_type_size;
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_read(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, nelmts > 0 ? 1 : 0,
|
||||
&mem_space, &file_space, &(io_info->store->contig.dset_addr),
|
||||
&dst_type_size, &(io_info->u.rbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "contiguous selection read failed")
|
||||
} /* end if */
|
||||
else
|
||||
/* Read data through legacy (non-selection I/O) pathway */
|
||||
if ((io_info->io_ops.single_read)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "contiguous read failed")
|
||||
|
||||
done:
|
||||
@ -629,7 +705,7 @@ herr_t
|
||||
H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@ -640,8 +716,20 @@ H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
|
||||
/* Write data */
|
||||
if ((io_info->io_ops.single_write)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
if (io_info->use_select_io) {
|
||||
size_t dst_type_size = type_info->dst_type_size;
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_write(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, nelmts > 0 ? 1 : 0,
|
||||
&mem_space, &file_space, &(io_info->store->contig.dset_addr),
|
||||
&dst_type_size, &(io_info->u.wbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "contiguous selection write failed")
|
||||
} /* end if */
|
||||
else
|
||||
/* Write data through legacy (non-selection I/O) pathway */
|
||||
if ((io_info->io_ops.single_write)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "contiguous write failed")
|
||||
|
||||
done:
|
||||
|
@ -60,9 +60,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,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static herr_t H5D__efl_construct(H5F_t *f, H5D_t *dset);
|
||||
static herr_t H5D__efl_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
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[]);
|
||||
@ -209,7 +209,7 @@ H5D__efl_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
H5D__efl_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
{
|
||||
|
21
src/H5Dio.c
21
src/H5Dio.c
@ -576,6 +576,10 @@ H5D__ioinfo_init(H5D_t *dset, const H5D_type_info_t *type_info, H5D_storage_t *s
|
||||
io_info->io_ops.single_write = H5D__scatgath_write;
|
||||
} /* end else */
|
||||
|
||||
/* Start with selection I/O off, layout callback will turn it on if
|
||||
* appropriate */
|
||||
io_info->use_select_io = FALSE;
|
||||
|
||||
#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);
|
||||
@ -814,12 +818,17 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_
|
||||
|
||||
/* 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 */
|
||||
io_info->io_ops.multi_read = dset->shared->layout.ops->par_read;
|
||||
io_info->io_ops.multi_write = dset->shared->layout.ops->par_write;
|
||||
io_info->io_ops.single_read = H5D__mpio_select_read;
|
||||
io_info->io_ops.single_write = H5D__mpio_select_write;
|
||||
} /* end if */
|
||||
/* Override the I/O op pointers to the MPI-specific routines, unless
|
||||
* selection I/O is to be used - in this case the file driver will
|
||||
* handle collective I/O */
|
||||
/* Check for selection/vector support in file driver? -NAF */
|
||||
if (!io_info->use_select_io) {
|
||||
io_info->io_ops.multi_read = dset->shared->layout.ops->par_read;
|
||||
io_info->io_ops.multi_write = dset->shared->layout.ops->par_write;
|
||||
io_info->io_ops.single_read = H5D__mpio_select_read;
|
||||
io_info->io_ops.single_write = H5D__mpio_select_write;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
/* Check if there are any filters in the pipeline. If there are,
|
||||
* we cannot break to independent I/O if this is a write operation
|
||||
|
@ -121,9 +121,9 @@ 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, const H5D_t *dset, hid_t dapl_id);
|
||||
typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage);
|
||||
typedef hbool_t (*H5D_layout_is_data_cached_func_t)(const H5D_shared_t *shared_dset);
|
||||
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,
|
||||
H5S_t *file_space, H5S_t *mem_space, struct H5D_chunk_map_t *cm);
|
||||
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, H5S_t *file_space, H5S_t *mem_space,
|
||||
struct H5D_chunk_map_t *cm);
|
||||
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, H5S_t *file_space, H5S_t *mem_space,
|
||||
struct H5D_chunk_map_t *fm);
|
||||
@ -222,6 +222,7 @@ typedef struct H5D_io_info_t {
|
||||
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;
|
||||
hbool_t use_select_io; /* Whether to use selection I/O */
|
||||
union {
|
||||
void * rbuf; /* Pointer to buffer for read */
|
||||
const void *wbuf; /* Pointer to buffer to write */
|
||||
|
368
src/H5FD.c
368
src/H5FD.c
@ -214,6 +214,8 @@ H5FDregister(const H5FD_class_t *cls)
|
||||
/* Check arguments */
|
||||
if (!cls)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null class pointer is disallowed")
|
||||
if (cls->version != H5FD_CLASS_VERSION)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_VERSION, H5I_INVALID_HID, "wrong file driver version #")
|
||||
if (!cls->open || !cls->close)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
|
||||
"'open' and/or 'close' methods are not defined")
|
||||
@ -1479,6 +1481,370 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5FDwrite() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FDread_vector
|
||||
*
|
||||
* Purpose: Perform count reads from the specified file at the offsets
|
||||
* provided in the addrs array, with the lengths and memory
|
||||
* types provided in the sizes and types arrays. Data read
|
||||
* is returned in the buffers provided in the bufs array.
|
||||
*
|
||||
* All reads are done according to the data transfer property
|
||||
* list dxpl_id (which may be the constant H5P_DEFAULT).
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* All reads have completed successfully, and
|
||||
* the results havce been into the supplied
|
||||
* buffers.
|
||||
*
|
||||
* Failure: FAIL
|
||||
* The contents of supplied buffers are undefined.
|
||||
*
|
||||
* Programmer: JRM -- 6/10/20
|
||||
*
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5FDread_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], void *bufs[] /* out */)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE7("e", "*#iIu*Mt*a*zx", file, dxpl_id, count, types, addrs, sizes, bufs);
|
||||
|
||||
/* Check arguments */
|
||||
if (!file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
|
||||
|
||||
if (!file->cls)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
|
||||
|
||||
if ((!types) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!addrs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!sizes) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!bufs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((count > 0) && (sizes[0] == 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
|
||||
|
||||
if ((count > 0) && (types[0] == H5FD_MEM_NOLIST))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count[0] can't be H5FD_MEM_NOLIST")
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else {
|
||||
if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
|
||||
}
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Call private function */
|
||||
/* (Note compensating for base addresses addition in internal routine) */
|
||||
if (H5FD_read_vector(file, count, types, addrs, sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file vector read request failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5FDread_vector() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FDwrite_vector
|
||||
*
|
||||
* Purpose: Perform count writes to the specified file at the offsets
|
||||
* provided in the addrs array, with the lengths and memory
|
||||
* types provided in the sizes and types arrays. Data to be
|
||||
* written is in the buffers provided in the bufs array.
|
||||
*
|
||||
* All writes are done according to the data transfer property
|
||||
* list dxpl_id (which may be the constant H5P_DEFAULT).
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* All writes have completed successfully
|
||||
*
|
||||
* Failure: FAIL
|
||||
* One or more of the writes failed.
|
||||
*
|
||||
* Programmer: JRM -- 6/10/20
|
||||
*
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5FDwrite_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], const void *bufs[] /* in */)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE7("e", "*#iIu*Mt*a*z**x", file, dxpl_id, count, types, addrs, sizes, bufs);
|
||||
|
||||
/* Check arguments */
|
||||
if (!file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
|
||||
|
||||
if (!file->cls)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
|
||||
|
||||
if ((!types) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!addrs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!sizes) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!bufs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((count > 0) && (sizes[0] == 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
|
||||
|
||||
if ((count > 0) && (types[0] == H5FD_MEM_NOLIST))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count[0] can't be H5FD_MEM_NOLIST")
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else {
|
||||
if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
|
||||
}
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Call private function */
|
||||
/* (Note compensating for base address addition in internal routine) */
|
||||
if (H5FD_write_vector(file, count, types, addrs, sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file vector write request failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5FDwrite_vector() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FDread_selection
|
||||
*
|
||||
* Purpose: Perform count reads from the specified file at the
|
||||
* locations selected in the dataspaces in the file_spaces
|
||||
* array, with each of those dataspaces starting at the file
|
||||
* address specified by the corresponding element of the
|
||||
* offsets array, and with the size of each element in the
|
||||
* dataspace specified by the corresponding element of the
|
||||
* element_sizes array. The memory type provided by type is
|
||||
* the same for all selections. Data read is returned in
|
||||
* the locations selected in the dataspaces in the
|
||||
* mem_spaces array, within the buffers provided in the
|
||||
* corresponding elements of the bufs array.
|
||||
*
|
||||
* If i > 0 and element_sizes[i] == 0, presume
|
||||
* element_sizes[n] = element_sizes[i-1] for all n >= i and
|
||||
* < count.
|
||||
*
|
||||
* If the underlying VFD supports selection reads, pass the
|
||||
* call through directly.
|
||||
*
|
||||
* If it doesn't, convert the selection read into a sequence
|
||||
* of individual reads.
|
||||
*
|
||||
* All reads are done according to the data transfer property
|
||||
* list dxpl_id (which may be the constant H5P_DEFAULT).
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* All reads have completed successfully, and
|
||||
* the results havce been into the supplied
|
||||
* buffers.
|
||||
*
|
||||
* Failure: FAIL
|
||||
* The contents of supplied buffers are undefined.
|
||||
*
|
||||
* Programmer: NAF -- 5/19/21
|
||||
*
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[],
|
||||
hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE9("e", "*#MtiIu*i*i*a*zx", file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets,
|
||||
element_sizes, bufs);
|
||||
|
||||
/* Check arguments */
|
||||
if (!file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
|
||||
|
||||
if (!file->cls)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
|
||||
|
||||
if ((!mem_space_ids) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_spaces parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!file_space_ids) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_spaces parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!offsets) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offsets parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!element_sizes) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"element_sizes parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!bufs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((count > 0) && (element_sizes[0] == 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
|
||||
|
||||
if ((count > 0) && (bufs[0] == NULL))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs[0] can't be NULL")
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else {
|
||||
if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
|
||||
}
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Call private function */
|
||||
/* (Note compensating for base address addition in internal routine) */
|
||||
if (H5FD_read_selection_id(file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file selection read request failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5FDread_selection() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FDwrite_selection
|
||||
*
|
||||
* Purpose: Perform count writes to the specified file at the
|
||||
* locations selected in the dataspaces in the file_spaces
|
||||
* array, with each of those dataspaces starting at the file
|
||||
* address specified by the corresponding element of the
|
||||
* offsets array, and with the size of each element in the
|
||||
* dataspace specified by the corresponding element of the
|
||||
* element_sizes array. The memory type provided by type is
|
||||
* the same for all selections. Data write is from
|
||||
* the locations selected in the dataspaces in the
|
||||
* mem_spaces array, within the buffers provided in the
|
||||
* corresponding elements of the bufs array.
|
||||
*
|
||||
* If i > 0 and element_sizes[i] == 0, presume
|
||||
* element_sizes[n] = element_sizes[i-1] for all n >= i and
|
||||
* < count.
|
||||
*
|
||||
* If the underlying VFD supports selection writes, pass the
|
||||
* call through directly.
|
||||
*
|
||||
* If it doesn't, convert the selection write into a sequence
|
||||
* of individual writes.
|
||||
*
|
||||
* All writes are done according to the data transfer property
|
||||
* list dxpl_id (which may be the constant H5P_DEFAULT).
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* All writes have completed successfully
|
||||
*
|
||||
* Failure: FAIL
|
||||
* One or more of the writes failed.
|
||||
*
|
||||
* Programmer: NAF -- 5/14/21
|
||||
*
|
||||
* Changes: None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[],
|
||||
hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], const void *bufs[])
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE9("e", "*#MtiIu*i*i*a*z**x", file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets,
|
||||
element_sizes, bufs);
|
||||
|
||||
/* Check arguments */
|
||||
if (!file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
|
||||
|
||||
if (!file->cls)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
|
||||
|
||||
if ((!mem_space_ids) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_spaces parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!file_space_ids) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_spaces parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!offsets) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offsets parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!element_sizes) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"element_sizes parameter can't be NULL if count is positive")
|
||||
|
||||
if ((!bufs) && (count > 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
|
||||
|
||||
if ((count > 0) && (element_sizes[0] == 0))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
|
||||
|
||||
if ((count > 0) && (bufs[0] == NULL))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs[0] can't be NULL")
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else {
|
||||
if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
|
||||
}
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Call private function */
|
||||
/* (Note compensating for base address addition in internal routine) */
|
||||
if (H5FD_write_selection_id(file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file selection write request failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5FDwrite_selection() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FDflush
|
||||
*
|
||||
@ -1827,7 +2193,7 @@ H5FD_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void
|
||||
else if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) {
|
||||
|
||||
HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL,
|
||||
"VFD ctl request failed (no ctl callback and fail if unknown flag is set)")
|
||||
"VFD ctl request failed (no ctl and fail if unknown flag is set)")
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -152,6 +152,7 @@ static herr_t H5FD__core_delete(const char *filename, hid_t fapl_id);
|
||||
static inline const H5FD_core_fapl_t *H5FD__core_get_default_config(void);
|
||||
|
||||
static const H5FD_class_t H5FD_core_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_CORE_VALUE, /* value */
|
||||
"core", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -180,6 +181,10 @@ static const H5FD_class_t H5FD_core_g = {
|
||||
H5FD__core_get_handle, /* get_handle */
|
||||
H5FD__core_read, /* read */
|
||||
H5FD__core_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
H5FD__core_flush, /* flush */
|
||||
H5FD__core_truncate, /* truncate */
|
||||
H5FD__core_lock, /* lock */
|
||||
|
@ -25,6 +25,9 @@
|
||||
/* Public Macros */
|
||||
/*****************/
|
||||
|
||||
/* H5FD_class_t struct version */
|
||||
#define H5FD_CLASS_VERSION 0x01 /* File driver struct version */
|
||||
|
||||
/* Map "fractal heap" header blocks to 'ohdr' type file memory, since its
|
||||
* a fair amount of work to add a new kind of file memory and they are similar
|
||||
* enough to object headers and probably too minor to deserve their own type.
|
||||
@ -160,6 +163,7 @@ typedef struct H5FD_t H5FD_t;
|
||||
|
||||
/* Class information for each file driver */
|
||||
typedef struct H5FD_class_t {
|
||||
unsigned version; /**< File driver class struct version # */
|
||||
H5FD_class_value_t value;
|
||||
const char * name;
|
||||
haddr_t maxaddr;
|
||||
@ -188,6 +192,16 @@ typedef struct H5FD_class_t {
|
||||
herr_t (*get_handle)(H5FD_t *file, hid_t fapl, void **file_handle);
|
||||
herr_t (*read)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, void *buffer);
|
||||
herr_t (*write)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl, haddr_t addr, size_t size, const void *buffer);
|
||||
herr_t (*read_vector)(H5FD_t *file, hid_t dxpl, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], void *bufs[]);
|
||||
herr_t (*write_vector)(H5FD_t *file, hid_t dxpl, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], const void *bufs[]);
|
||||
herr_t (*read_selection)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, size_t count, hid_t mem_spaces[],
|
||||
hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[],
|
||||
void *bufs[] /*out*/);
|
||||
herr_t (*write_selection)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, size_t count, hid_t mem_spaces[],
|
||||
hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[],
|
||||
const void *bufs[] /*in*/);
|
||||
herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
|
||||
herr_t (*truncate)(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
|
||||
herr_t (*lock)(H5FD_t *file, hbool_t rw);
|
||||
@ -257,6 +271,16 @@ H5_DLL herr_t H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t ad
|
||||
void *buf /*out*/);
|
||||
H5_DLL herr_t H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
|
||||
const void *buf);
|
||||
H5_DLL herr_t H5FDread_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[],
|
||||
haddr_t addrs[], size_t sizes[], void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FDwrite_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[],
|
||||
haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */);
|
||||
H5_DLL herr_t H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count,
|
||||
hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[],
|
||||
size_t element_sizes[], void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count,
|
||||
hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[],
|
||||
size_t element_sizes[], const void *bufs[]);
|
||||
H5_DLL herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
|
||||
H5_DLL herr_t H5FDtruncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
|
||||
H5_DLL herr_t H5FDlock(H5FD_t *file, hbool_t rw);
|
||||
|
@ -142,6 +142,7 @@ static herr_t H5FD__direct_unlock(H5FD_t *_file);
|
||||
static herr_t H5FD__direct_delete(const char *filename, hid_t fapl_id);
|
||||
|
||||
static const H5FD_class_t H5FD_direct_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_DIRECT_VALUE, /* value */
|
||||
"direct", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -170,6 +171,10 @@ static const H5FD_class_t H5FD_direct_g = {
|
||||
H5FD__direct_get_handle, /* get_handle */
|
||||
H5FD__direct_read, /* read */
|
||||
H5FD__direct_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__direct_truncate, /* truncate */
|
||||
H5FD__direct_lock, /* lock */
|
||||
|
@ -112,6 +112,7 @@ static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id);
|
||||
|
||||
/* The class struct */
|
||||
static const H5FD_class_t H5FD_family_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_FAMILY_VALUE, /* value */
|
||||
"family", /* name */
|
||||
HADDR_MAX, /* maxaddr */
|
||||
@ -140,6 +141,10 @@ static const H5FD_class_t H5FD_family_g = {
|
||||
H5FD__family_get_handle, /* get_handle */
|
||||
H5FD__family_read, /* read */
|
||||
H5FD__family_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
H5FD__family_flush, /* flush */
|
||||
H5FD__family_truncate, /* truncate */
|
||||
H5FD__family_lock, /* lock */
|
||||
|
@ -278,6 +278,7 @@ static herr_t H5FD__hdfs_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
|
||||
static herr_t H5FD__hdfs_validate_config(const H5FD_hdfs_fapl_t *fa);
|
||||
|
||||
static const H5FD_class_t H5FD_hdfs_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_HDFS_VALUE, /* value */
|
||||
"hdfs", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -306,6 +307,10 @@ static const H5FD_class_t H5FD_hdfs_g = {
|
||||
H5FD__hdfs_get_handle, /* get_handle */
|
||||
H5FD__hdfs_read, /* read */
|
||||
H5FD__hdfs_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__hdfs_truncate, /* truncate */
|
||||
NULL, /* lock */
|
||||
|
1977
src/H5FDint.c
1977
src/H5FDint.c
File diff suppressed because it is too large
Load Diff
@ -180,41 +180,46 @@ static herr_t H5FD__log_unlock(H5FD_t *_file);
|
||||
static herr_t H5FD__log_delete(const char *filename, hid_t fapl_id);
|
||||
|
||||
static const H5FD_class_t H5FD_log_g = {
|
||||
H5FD_LOG_VALUE, /* value */
|
||||
"log", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
H5FD__log_term, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
sizeof(H5FD_log_fapl_t), /* fapl_size */
|
||||
H5FD__log_fapl_get, /* fapl_get */
|
||||
H5FD__log_fapl_copy, /* fapl_copy */
|
||||
H5FD__log_fapl_free, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD__log_open, /* open */
|
||||
H5FD__log_close, /* close */
|
||||
H5FD__log_cmp, /* cmp */
|
||||
H5FD__log_query, /* query */
|
||||
NULL, /* get_type_map */
|
||||
H5FD__log_alloc, /* alloc */
|
||||
H5FD__log_free, /* free */
|
||||
H5FD__log_get_eoa, /* get_eoa */
|
||||
H5FD__log_set_eoa, /* set_eoa */
|
||||
H5FD__log_get_eof, /* get_eof */
|
||||
H5FD__log_get_handle, /* get_handle */
|
||||
H5FD__log_read, /* read */
|
||||
H5FD__log_write, /* write */
|
||||
NULL, /* flush */
|
||||
H5FD__log_truncate, /* truncate */
|
||||
H5FD__log_lock, /* lock */
|
||||
H5FD__log_unlock, /* unlock */
|
||||
H5FD__log_delete, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_LOG_VALUE, /* value */
|
||||
"log", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
H5FD__log_term, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
sizeof(H5FD_log_fapl_t), /* fapl_size */
|
||||
H5FD__log_fapl_get, /* fapl_get */
|
||||
H5FD__log_fapl_copy, /* fapl_copy */
|
||||
H5FD__log_fapl_free, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD__log_open, /* open */
|
||||
H5FD__log_close, /* close */
|
||||
H5FD__log_cmp, /* cmp */
|
||||
H5FD__log_query, /* query */
|
||||
NULL, /* get_type_map */
|
||||
H5FD__log_alloc, /* alloc */
|
||||
H5FD__log_free, /* free */
|
||||
H5FD__log_get_eoa, /* get_eoa */
|
||||
H5FD__log_set_eoa, /* set_eoa */
|
||||
H5FD__log_get_eof, /* get_eof */
|
||||
H5FD__log_get_handle, /* get_handle */
|
||||
H5FD__log_read, /* read */
|
||||
H5FD__log_write, /* write */
|
||||
NULL, /* read vector */
|
||||
NULL, /* write vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__log_truncate, /* truncate */
|
||||
H5FD__log_lock, /* lock */
|
||||
H5FD__log_unlock, /* unlock */
|
||||
H5FD__log_delete, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
};
|
||||
|
||||
/* Default configuration, if none provided */
|
||||
|
@ -160,6 +160,7 @@ static herr_t H5FD__mirror_unlock(H5FD_t *_file);
|
||||
static herr_t H5FD__mirror_verify_reply(H5FD_mirror_t *file);
|
||||
|
||||
static const H5FD_class_t H5FD_mirror_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_MIRROR_VALUE, /* value */
|
||||
"mirror", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -188,6 +189,10 @@ static const H5FD_class_t H5FD_mirror_g = {
|
||||
NULL, /* get_handle */
|
||||
H5FD__mirror_read, /* read */
|
||||
H5FD__mirror_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__mirror_truncate, /* truncate */
|
||||
H5FD__mirror_lock, /* lock */
|
||||
|
1135
src/H5FDmpio.c
1135
src/H5FDmpio.c
File diff suppressed because it is too large
Load Diff
@ -176,6 +176,7 @@ static herr_t H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c
|
||||
|
||||
/* The class struct */
|
||||
static const H5FD_class_t H5FD_multi_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5_VFD_MULTI, /* value */
|
||||
"multi", /* name */
|
||||
HADDR_MAX, /* maxaddr */
|
||||
@ -204,6 +205,10 @@ static const H5FD_class_t H5FD_multi_g = {
|
||||
H5FD_multi_get_handle, /* get_handle */
|
||||
H5FD_multi_read, /* read */
|
||||
H5FD_multi_write, /* write */
|
||||
NULL, /*read_vector */
|
||||
NULL, /*write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
H5FD_multi_flush, /* flush */
|
||||
H5FD_multi_truncate, /* truncate */
|
||||
H5FD_multi_lock, /* lock */
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
/* Private headers needed by this file */
|
||||
#include "H5Pprivate.h" /* Property lists */
|
||||
#include "H5Sprivate.h" /* Dataspaces */
|
||||
|
||||
/*
|
||||
* The MPI drivers are needed because there are
|
||||
@ -94,6 +95,9 @@ typedef enum H5FD_get_driver_kind_t {
|
||||
H5FD_GET_DRIVER_BY_VALUE /* Value field is set */
|
||||
} H5FD_get_driver_kind_t;
|
||||
|
||||
/* Forward declarations for prototype arguments */
|
||||
struct H5S_t;
|
||||
|
||||
/*****************************/
|
||||
/* Library Private Variables */
|
||||
/*****************************/
|
||||
@ -140,6 +144,22 @@ H5_DLL herr_t H5FD_set_feature_flags(H5FD_t *file, unsigned long feature_flags)
|
||||
H5_DLL herr_t H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map);
|
||||
H5_DLL herr_t H5FD_read(H5FD_t *file, H5FD_mem_t type, haddr_t addr, size_t size, void *buf /*out*/);
|
||||
H5_DLL herr_t H5FD_write(H5FD_t *file, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf);
|
||||
H5_DLL herr_t H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
|
||||
size_t sizes[], const void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, struct H5S_t **mem_spaces,
|
||||
struct H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[],
|
||||
void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, struct H5S_t **mem_spaces,
|
||||
struct H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[],
|
||||
const void *bufs[]);
|
||||
H5_DLL herr_t H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_space_ids[],
|
||||
hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[],
|
||||
void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_space_ids[],
|
||||
hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[],
|
||||
const void *bufs[]);
|
||||
H5_DLL herr_t H5FD_flush(H5FD_t *file, hbool_t closing);
|
||||
H5_DLL herr_t H5FD_truncate(H5FD_t *file, hbool_t closing);
|
||||
H5_DLL herr_t H5FD_lock(H5FD_t *file, hbool_t rw);
|
||||
@ -152,6 +172,10 @@ H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr);
|
||||
H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file);
|
||||
H5_DLL herr_t H5FD_set_paged_aggr(H5FD_t *file, hbool_t paged);
|
||||
|
||||
H5_DLL herr_t H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t count, H5FD_mem_t types[],
|
||||
haddr_t addrs[], size_t sizes[], H5_flexible_const_ptr_t bufs[],
|
||||
H5FD_mem_t **s_types_ptr, haddr_t **s_addrs_ptr, size_t **s_sizes_ptr,
|
||||
H5_flexible_const_ptr_t **s_bufs_ptr);
|
||||
H5_DLL herr_t H5FD_init(void);
|
||||
|
||||
/* Function prototypes for MPI based VFDs*/
|
||||
|
@ -237,6 +237,7 @@ static herr_t H5FD__ros3_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing
|
||||
static herr_t H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa);
|
||||
|
||||
static const H5FD_class_t H5FD_ros3_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_ROS3_VALUE, /* value */
|
||||
"ros3", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -265,6 +266,10 @@ static const H5FD_class_t H5FD_ros3_g = {
|
||||
H5FD__ros3_get_handle, /* get_handle */
|
||||
H5FD__ros3_read, /* read */
|
||||
H5FD__ros3_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__ros3_truncate, /* truncate */
|
||||
NULL, /* lock */
|
||||
|
@ -143,6 +143,7 @@ static herr_t H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c
|
||||
void **output);
|
||||
|
||||
static const H5FD_class_t H5FD_sec2_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_SEC2_VALUE, /* value */
|
||||
"sec2", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -171,6 +172,10 @@ static const H5FD_class_t H5FD_sec2_g = {
|
||||
H5FD__sec2_get_handle, /* get_handle */
|
||||
H5FD__sec2_read, /* read */
|
||||
H5FD__sec2_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
H5FD__sec2_truncate, /* truncate */
|
||||
H5FD__sec2_lock, /* lock */
|
||||
|
@ -138,6 +138,7 @@ static herr_t H5FD__splitter_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flag
|
||||
void **output);
|
||||
|
||||
static const H5FD_class_t H5FD_splitter_g = {
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5FD_SPLITTER_VALUE, /* value */
|
||||
"splitter", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
@ -166,6 +167,10 @@ static const H5FD_class_t H5FD_splitter_g = {
|
||||
H5FD__splitter_get_handle, /* get_handle */
|
||||
H5FD__splitter_read, /* read */
|
||||
H5FD__splitter_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
H5FD__splitter_flush, /* flush */
|
||||
H5FD__splitter_truncate, /* truncate */
|
||||
H5FD__splitter_lock, /* lock */
|
||||
|
@ -183,41 +183,46 @@ static herr_t H5FD_stdio_unlock(H5FD_t *_file);
|
||||
static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id);
|
||||
|
||||
static const H5FD_class_t H5FD_stdio_g = {
|
||||
H5_VFD_STDIO, /* value */
|
||||
"stdio", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
H5FD_stdio_term, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD_stdio_open, /* open */
|
||||
H5FD_stdio_close, /* close */
|
||||
H5FD_stdio_cmp, /* cmp */
|
||||
H5FD_stdio_query, /* query */
|
||||
NULL, /* get_type_map */
|
||||
H5FD_stdio_alloc, /* alloc */
|
||||
NULL, /* free */
|
||||
H5FD_stdio_get_eoa, /* get_eoa */
|
||||
H5FD_stdio_set_eoa, /* set_eoa */
|
||||
H5FD_stdio_get_eof, /* get_eof */
|
||||
H5FD_stdio_get_handle, /* get_handle */
|
||||
H5FD_stdio_read, /* read */
|
||||
H5FD_stdio_write, /* write */
|
||||
H5FD_stdio_flush, /* flush */
|
||||
H5FD_stdio_truncate, /* truncate */
|
||||
H5FD_stdio_lock, /* lock */
|
||||
H5FD_stdio_unlock, /* unlock */
|
||||
H5FD_stdio_delete, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
H5_VFD_STDIO, /* value */
|
||||
"stdio", /* name */
|
||||
MAXADDR, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
H5FD_stdio_term, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD_stdio_open, /* open */
|
||||
H5FD_stdio_close, /* close */
|
||||
H5FD_stdio_cmp, /* cmp */
|
||||
H5FD_stdio_query, /* query */
|
||||
NULL, /* get_type_map */
|
||||
H5FD_stdio_alloc, /* alloc */
|
||||
NULL, /* free */
|
||||
H5FD_stdio_get_eoa, /* get_eoa */
|
||||
H5FD_stdio_set_eoa, /* set_eoa */
|
||||
H5FD_stdio_get_eof, /* get_eof */
|
||||
H5FD_stdio_get_handle, /* get_handle */
|
||||
H5FD_stdio_read, /* read */
|
||||
H5FD_stdio_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
H5FD_stdio_flush, /* flush */
|
||||
H5FD_stdio_truncate, /* truncate */
|
||||
H5FD_stdio_lock, /* lock */
|
||||
H5FD_stdio_unlock, /* unlock */
|
||||
H5FD_stdio_delete, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
91
src/H5Fio.c
91
src/H5Fio.c
@ -233,11 +233,100 @@ H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, const void
|
||||
/* Pass through page buffer layer */
|
||||
if (H5PB_write(f->shared, map_type, addr, size, buf) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write through page buffer failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_block_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_shared_select_read
|
||||
*
|
||||
* Purpose: Reads some data from a file/server/etc into a buffer.
|
||||
* The location of the data is defined by the mem_spaces and
|
||||
* file_spaces dataspace arrays, along with the offsets
|
||||
* array. The addresses is relative to the base address for
|
||||
* the file.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* May 3 2021
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_shared_select_read(H5F_shared_t *f_sh, H5FD_mem_t type, uint32_t count, H5S_t **mem_spaces,
|
||||
H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */)
|
||||
{
|
||||
H5FD_mem_t map_type; /* Mapped memory type */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(f_sh);
|
||||
HDassert((mem_spaces) || (count == 0));
|
||||
HDassert((file_spaces) || (count == 0));
|
||||
HDassert((offsets) || (count == 0));
|
||||
HDassert((element_sizes) || (count == 0));
|
||||
HDassert((bufs) || (count == 0));
|
||||
|
||||
/* Treat global heap as raw data */
|
||||
map_type = (type == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : type;
|
||||
|
||||
/* Pass down to file driver layer (bypass page buffer for now) */
|
||||
if (H5FD_read_selection(f_sh->lf, map_type, count, mem_spaces, file_spaces, offsets, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "selection read through file driver failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_shared_select_read() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_shared_select_write
|
||||
*
|
||||
* Purpose: Writes some data from a buffer to a file/server/etc.
|
||||
* The location of the data is defined by the mem_spaces and
|
||||
* file_spaces dataspace arrays, along with the offsets
|
||||
* array. The addresses is relative to the base address for
|
||||
* the file.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* May 4 2021
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_shared_select_write(H5F_shared_t *f_sh, H5FD_mem_t type, uint32_t count, H5S_t **mem_spaces,
|
||||
H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], const void *bufs[])
|
||||
{
|
||||
H5FD_mem_t map_type; /* Mapped memory type */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(f_sh);
|
||||
HDassert((mem_spaces) || (count == 0));
|
||||
HDassert((file_spaces) || (count == 0));
|
||||
HDassert((offsets) || (count == 0));
|
||||
HDassert((element_sizes) || (count == 0));
|
||||
HDassert((bufs) || (count == 0));
|
||||
|
||||
/* Treat global heap as raw data */
|
||||
map_type = (type == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : type;
|
||||
|
||||
/* Pass down to file driver layer (bypass page buffer for now) */
|
||||
if (H5FD_write_selection(f_sh->lf, map_type, count, mem_spaces, file_spaces, offsets, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "selection write through file driver failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_shared_select_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_flush_tagged_metadata
|
||||
*
|
||||
|
@ -758,6 +758,7 @@ struct H5O_loc_t;
|
||||
struct H5HG_heap_t;
|
||||
struct H5VL_class_t;
|
||||
struct H5P_genplist_t;
|
||||
struct H5S_t;
|
||||
|
||||
/* Forward declarations for anonymous H5F objects */
|
||||
|
||||
@ -923,6 +924,14 @@ H5_DLL herr_t H5F_shared_block_write(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_
|
||||
const void *buf);
|
||||
H5_DLL herr_t H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf);
|
||||
|
||||
/* Functions that operate on selections of elements in the file */
|
||||
H5_DLL herr_t H5F_shared_select_read(H5F_shared_t *f_sh, H5FD_mem_t type, uint32_t count,
|
||||
struct H5S_t **mem_spaces, struct H5S_t **file_spaces, haddr_t offsets[],
|
||||
size_t element_sizes[], void *bufs[] /* out */);
|
||||
H5_DLL herr_t H5F_shared_select_write(H5F_shared_t *f_sh, H5FD_mem_t type, uint32_t count,
|
||||
struct H5S_t **mem_spaces, struct H5S_t **file_spaces,
|
||||
haddr_t offsets[], size_t element_sizes[], const void *bufs[]);
|
||||
|
||||
/* Functions that flush or evict */
|
||||
H5_DLL herr_t H5F_flush_tagged_metadata(H5F_t *f, haddr_t tag);
|
||||
H5_DLL herr_t H5F_evict_tagged_metadata(H5F_t *f, haddr_t tag);
|
||||
|
@ -130,7 +130,7 @@ typedef enum {
|
||||
typedef int H5G_own_loc_t;
|
||||
|
||||
/* Structure to store information about the name an object was opened with */
|
||||
typedef struct {
|
||||
typedef struct H5G_name_t {
|
||||
H5RS_str_t *full_path_r; /* Path to object, as seen from root of current file mounting hierarchy */
|
||||
H5RS_str_t *user_path_r; /* Path to object, as opened by user */
|
||||
unsigned obj_hidden; /* Whether the object is visible in group hier. */
|
||||
|
69
src/H5PB.c
69
src/H5PB.c
@ -1302,6 +1302,75 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5PB_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5PB_enabled
|
||||
*
|
||||
* Purpose: Check if the page buffer may be enabled for the specified
|
||||
* file and data access type.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5PB_enabled(H5F_shared_t *f_sh, H5FD_mem_t type, hbool_t *enabled)
|
||||
{
|
||||
H5PB_t *page_buf; /* Page buffering info for this file */
|
||||
hbool_t bypass_pb = FALSE; /* Whether to bypass page buffering */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOERR
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(f_sh);
|
||||
|
||||
/* Get pointer to page buffer info for this file */
|
||||
page_buf = f_sh->page_buf;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if (H5F_SHARED_HAS_FEATURE(f_sh, H5FD_FEAT_HAS_MPI)) {
|
||||
#if 1
|
||||
bypass_pb = TRUE;
|
||||
#else
|
||||
/* MSC - why this stopped working ? */
|
||||
int mpi_size;
|
||||
|
||||
if ((mpi_size = H5F_shared_mpi_get_size(f_sh)) < 0)
|
||||
HGOTO_ERROR(H5E_PAGEBUF, H5E_CANTGET, FAIL, "can't retrieve MPI communicator size")
|
||||
if (1 != mpi_size)
|
||||
bypass_pb = TRUE;
|
||||
#endif
|
||||
} /* end if */
|
||||
#endif
|
||||
|
||||
/* If page buffering is disabled, or if this is a parallel raw data access,
|
||||
* bypass page buffering. Note that page buffering may still be disabled for
|
||||
* large metadata access or large non-parallel raw data access, but this
|
||||
* function doesn't take I/O size into account so if it returns TRUE the
|
||||
* page buffer may still be disabled for some I/O. If it returns FALSE it is
|
||||
* always disabled for this access type.
|
||||
*/
|
||||
if (NULL == page_buf || (bypass_pb && H5FD_MEM_DRAW == type)) {
|
||||
/* Update statistics, since wherever this function is called, if it
|
||||
* returns FALSE, the calling function performs I/O avoiding the page
|
||||
* buffer layer */
|
||||
if (page_buf) {
|
||||
HDassert(type == H5FD_MEM_DRAW);
|
||||
page_buf->bypasses[1]++;
|
||||
} /* end if */
|
||||
|
||||
/* Page buffer is disabled, at least for this data access type */
|
||||
*enabled = FALSE;
|
||||
} /* end if */
|
||||
else
|
||||
/* Page buffer may be enabled */
|
||||
*enabled = TRUE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5PB_enabled() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5PB__insert_entry()
|
||||
*
|
||||
|
@ -91,6 +91,7 @@ H5_DLL herr_t H5PB_update_entry(H5PB_t *page_buf, haddr_t addr, size_t size, con
|
||||
H5_DLL herr_t H5PB_remove_entry(const H5F_shared_t *f_sh, haddr_t addr);
|
||||
H5_DLL herr_t H5PB_read(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, void *buf /*out*/);
|
||||
H5_DLL herr_t H5PB_write(H5F_shared_t *f_sh, H5FD_mem_t type, haddr_t addr, size_t size, const void *buf);
|
||||
H5_DLL herr_t H5PB_enabled(H5F_shared_t *f_sh, H5FD_mem_t type, hbool_t *enabled);
|
||||
|
||||
/* Statistics routines */
|
||||
H5_DLL herr_t H5PB_reset_stats(H5PB_t *page_buf);
|
||||
|
@ -101,6 +101,8 @@ typedef struct H5T_subset_info_t {
|
||||
} H5T_subset_info_t;
|
||||
|
||||
/* Forward declarations for prototype arguments */
|
||||
struct H5G_loc_t;
|
||||
struct H5G_name_t;
|
||||
struct H5O_shared_t;
|
||||
|
||||
/* The native endianness of the platform */
|
||||
@ -120,14 +122,14 @@ H5_DLL size_t H5T_get_size(const H5T_t *dt);
|
||||
H5_DLL hbool_t H5T_get_force_conv(const H5T_t *dt);
|
||||
H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset);
|
||||
H5_DLL herr_t H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc);
|
||||
H5_DLL H5T_t * H5T_decode(size_t buf_size, const unsigned char *buf);
|
||||
H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE *stream);
|
||||
H5_DLL struct H5O_loc_t *H5T_oloc(H5T_t *dt);
|
||||
H5_DLL H5G_name_t *H5T_nameof(const H5T_t *dt);
|
||||
H5_DLL htri_t H5T_is_immutable(const H5T_t *dt);
|
||||
H5_DLL htri_t H5T_is_named(const H5T_t *dt);
|
||||
H5_DLL herr_t H5T_convert_committed_datatype(H5T_t *dt, H5F_t *f);
|
||||
H5_DLL htri_t H5T_is_relocatable(const H5T_t *dt);
|
||||
H5_DLL H5T_t * H5T_decode(size_t buf_size, const unsigned char *buf);
|
||||
H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE *stream);
|
||||
H5_DLL struct H5O_loc_t * H5T_oloc(H5T_t *dt);
|
||||
H5_DLL struct H5G_name_t *H5T_nameof(const H5T_t *dt);
|
||||
H5_DLL htri_t H5T_is_immutable(const H5T_t *dt);
|
||||
H5_DLL htri_t H5T_is_named(const H5T_t *dt);
|
||||
H5_DLL herr_t H5T_convert_committed_datatype(H5T_t *dt, H5F_t *f);
|
||||
H5_DLL htri_t H5T_is_relocatable(const H5T_t *dt);
|
||||
H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst);
|
||||
H5_DLL hbool_t H5T_path_noop(const H5T_path_t *p);
|
||||
H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p);
|
||||
@ -159,7 +161,7 @@ H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hi
|
||||
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
|
||||
|
||||
/* Operations on named datatypes */
|
||||
H5_DLL H5T_t *H5T_open(const H5G_loc_t *loc);
|
||||
H5_DLL H5T_t *H5T_open(const struct H5G_loc_t *loc);
|
||||
H5_DLL int H5T_link(const H5T_t *type, int adjust);
|
||||
H5_DLL herr_t H5T_update_shared(H5T_t *type);
|
||||
|
||||
|
@ -1979,6 +1979,11 @@ extern hbool_t H5_libterm_g; /* Is the library being shutdown? */
|
||||
|
||||
#endif /* H5_HAVE_THREADSAFE */
|
||||
|
||||
/* Extern global to determine if we should use selection I/O if available (this
|
||||
* variable should be removed once selection I/O performs as well as the
|
||||
* previous scalar I/O implementation */
|
||||
extern hbool_t H5_use_selection_io_g;
|
||||
|
||||
#ifdef H5_HAVE_CODESTACK
|
||||
|
||||
/* Include required function stack header */
|
||||
@ -2473,6 +2478,16 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
|
||||
#define HDcompile_assert(e) do { typedef struct { unsigned int b: (e); } x; } while(0)
|
||||
*/
|
||||
|
||||
/* Private typedefs */
|
||||
|
||||
/* Union for const/non-const pointer for use by functions that manipulate
|
||||
* pointers but do not write to their targets or return pointers to const
|
||||
* specified locations. This helps us avoid compiler warnings. */
|
||||
typedef union {
|
||||
void * vp;
|
||||
const void *cvp;
|
||||
} H5_flexible_const_ptr_t;
|
||||
|
||||
/* Private functions, not part of the publicly documented API */
|
||||
H5_DLL herr_t H5_init_library(void);
|
||||
H5_DLL void H5_term_library(void);
|
||||
|
@ -1773,41 +1773,46 @@ dummy_vfd_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hi
|
||||
/* Dummy VFD with the minimum parameters to make a VFD that can be registered */
|
||||
#define DUMMY_VFD_VALUE (H5FD_class_value_t)155
|
||||
static const H5FD_class_t H5FD_dummy_g = {
|
||||
DUMMY_VFD_VALUE, /* value */
|
||||
"dummy", /* name */
|
||||
1, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
NULL, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
dummy_vfd_open, /* open */
|
||||
dummy_vfd_close, /* close */
|
||||
NULL, /* cmp */
|
||||
NULL, /* query */
|
||||
NULL, /* get_type_map */
|
||||
NULL, /* alloc */
|
||||
NULL, /* free */
|
||||
dummy_vfd_get_eoa, /* get_eoa */
|
||||
dummy_vfd_set_eoa, /* set_eoa */
|
||||
dummy_vfd_get_eof, /* get_eof */
|
||||
NULL, /* get_handle */
|
||||
dummy_vfd_read, /* read */
|
||||
dummy_vfd_write, /* write */
|
||||
NULL, /* flush */
|
||||
NULL, /* truncate */
|
||||
NULL, /* lock */
|
||||
NULL, /* unlock */
|
||||
NULL, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
DUMMY_VFD_VALUE, /* value */
|
||||
"dummy", /* name */
|
||||
1, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
NULL, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
dummy_vfd_open, /* open */
|
||||
dummy_vfd_close, /* close */
|
||||
NULL, /* cmp */
|
||||
NULL, /* query */
|
||||
NULL, /* get_type_map */
|
||||
NULL, /* alloc */
|
||||
NULL, /* free */
|
||||
dummy_vfd_get_eoa, /* get_eoa */
|
||||
dummy_vfd_set_eoa, /* set_eoa */
|
||||
dummy_vfd_get_eof, /* get_eof */
|
||||
NULL, /* get_handle */
|
||||
dummy_vfd_read, /* read */
|
||||
dummy_vfd_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
NULL, /* truncate */
|
||||
NULL, /* lock */
|
||||
NULL, /* unlock */
|
||||
NULL, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -35,41 +35,46 @@ static herr_t H5FD_null_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
|
||||
static haddr_t H5FD_null_get_eof(const H5FD_t *_file, H5FD_mem_t type);
|
||||
|
||||
static const H5FD_class_t H5FD_null_g = {
|
||||
NULL_VFD_VALUE, /* value */
|
||||
NULL_VFD_NAME, /* name */
|
||||
1, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
NULL, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD_null_open, /* open */
|
||||
H5FD_null_close, /* close */
|
||||
NULL, /* cmp */
|
||||
NULL, /* query */
|
||||
NULL, /* get_type_map */
|
||||
NULL, /* alloc */
|
||||
NULL, /* free */
|
||||
H5FD_null_get_eoa, /* get_eoa */
|
||||
H5FD_null_set_eoa, /* set_eoa */
|
||||
H5FD_null_get_eof, /* get_eof */
|
||||
NULL, /* get_handle */
|
||||
H5FD_null_read, /* read */
|
||||
H5FD_null_write, /* write */
|
||||
NULL, /* flush */
|
||||
NULL, /* truncate */
|
||||
NULL, /* lock */
|
||||
NULL, /* unlock */
|
||||
NULL, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
H5FD_CLASS_VERSION, /* struct version */
|
||||
NULL_VFD_VALUE, /* value */
|
||||
NULL_VFD_NAME, /* name */
|
||||
1, /* maxaddr */
|
||||
H5F_CLOSE_WEAK, /* fc_degree */
|
||||
NULL, /* terminate */
|
||||
NULL, /* sb_size */
|
||||
NULL, /* sb_encode */
|
||||
NULL, /* sb_decode */
|
||||
0, /* fapl_size */
|
||||
NULL, /* fapl_get */
|
||||
NULL, /* fapl_copy */
|
||||
NULL, /* fapl_free */
|
||||
0, /* dxpl_size */
|
||||
NULL, /* dxpl_copy */
|
||||
NULL, /* dxpl_free */
|
||||
H5FD_null_open, /* open */
|
||||
H5FD_null_close, /* close */
|
||||
NULL, /* cmp */
|
||||
NULL, /* query */
|
||||
NULL, /* get_type_map */
|
||||
NULL, /* alloc */
|
||||
NULL, /* free */
|
||||
H5FD_null_get_eoa, /* get_eoa */
|
||||
H5FD_null_set_eoa, /* set_eoa */
|
||||
H5FD_null_get_eof, /* get_eof */
|
||||
NULL, /* get_handle */
|
||||
H5FD_null_read, /* read */
|
||||
H5FD_null_write, /* write */
|
||||
NULL, /* read_vector */
|
||||
NULL, /* write_vector */
|
||||
NULL, /* read_selection */
|
||||
NULL, /* write_selection */
|
||||
NULL, /* flush */
|
||||
NULL, /* truncate */
|
||||
NULL, /* lock */
|
||||
NULL, /* unlock */
|
||||
NULL, /* del */
|
||||
NULL, /* ctl */
|
||||
H5FD_FLMAP_DICHOTOMY /* fl_map */
|
||||
};
|
||||
|
||||
static H5FD_t *
|
||||
|
2030
test/vfd.c
2030
test/vfd.c
File diff suppressed because it is too large
Load Diff
@ -89,6 +89,7 @@ set (H5P_TESTS
|
||||
t_shapesame
|
||||
t_filters_parallel
|
||||
t_2Gio
|
||||
t_vfd
|
||||
)
|
||||
|
||||
foreach (h5_testp ${H5P_TESTS})
|
||||
|
@ -30,7 +30,7 @@ check_SCRIPTS = $(TEST_SCRIPT_PARA)
|
||||
|
||||
# Test programs. These are our main targets.
|
||||
#
|
||||
TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel t_2Gio
|
||||
TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel t_2Gio t_vfd
|
||||
|
||||
# t_pflush1 and t_pflush2 are used by testpflush.sh
|
||||
check_PROGRAMS = $(TEST_PROG_PARA) t_pflush1 t_pflush2
|
||||
|
@ -832,7 +832,10 @@ coll_chunktest(const char *filename, int chunk_factor, int select_factor, int ap
|
||||
VRFY((status >= 0), "dataset write succeeded");
|
||||
|
||||
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
|
||||
if (facc_type == FACC_MPIO) {
|
||||
/* Only check chunk optimization mode if selection I/O is not being used -
|
||||
* selection I/O bypasses this IO mode decision - it's effectively always
|
||||
* multi chunk currently */
|
||||
if (facc_type == FACC_MPIO && !H5_use_selection_io_g) {
|
||||
switch (api_option) {
|
||||
case API_LINK_HARD:
|
||||
status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &prop_value);
|
||||
|
@ -3351,32 +3351,38 @@ actual_io_mode_tests(void)
|
||||
int mpi_size = -1;
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
|
||||
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE);
|
||||
/* Only run these tests if selection I/O is not being used - selection I/O
|
||||
* bypasses this IO mode decision - it's effectively always multi chunk
|
||||
* currently */
|
||||
if (!H5_use_selection_io_g) {
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE);
|
||||
|
||||
/*
|
||||
* Test multi-chunk-io via proc_num threshold
|
||||
*/
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_IND);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_COL);
|
||||
/*
|
||||
* Test multi-chunk-io via proc_num threshold
|
||||
*/
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_IND);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_COL);
|
||||
|
||||
/* The Multi Chunk Mixed test requires at least three processes. */
|
||||
if (mpi_size > 2)
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX);
|
||||
else
|
||||
HDfprintf(stdout, "Multi Chunk Mixed test requires 3 processes minimum\n");
|
||||
/* The Multi Chunk Mixed test requires at least three processes. */
|
||||
if (mpi_size > 2)
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX);
|
||||
else
|
||||
HDfprintf(stdout, "Multi Chunk Mixed test requires 3 processes minimum\n");
|
||||
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_MULTI_CHUNK_MIX_DISAGREE);
|
||||
|
||||
/*
|
||||
* Test multi-chunk-io via setting direct property
|
||||
*/
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL);
|
||||
/*
|
||||
* Test multi-chunk-io via setting direct property
|
||||
*/
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_IND);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_DIRECT_MULTI_CHUNK_COL);
|
||||
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_LINK_CHUNK);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_CONTIGUOUS);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_LINK_CHUNK);
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_CONTIGUOUS);
|
||||
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_RESET);
|
||||
}
|
||||
|
||||
test_actual_io_mode(TEST_ACTUAL_IO_RESET);
|
||||
return;
|
||||
}
|
||||
|
||||
|
4055
testpar/t_vfd.c
Normal file
4055
testpar/t_vfd.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user