Merge initial version of selection I/O feature into develop (#1367)

This commit is contained in:
Neil Fortner 2022-03-26 14:30:53 -05:00 committed by GitHub
parent 25ef608e2f
commit 42b767fc67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 10731 additions and 442 deletions

View File

@ -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;

View File

@ -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"));

View File

@ -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() */

View File

@ -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)
{

View File

@ -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:

View File

@ -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)
{

View File

@ -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

View File

@ -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 */

View File

@ -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:

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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*/

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */
};
/*-------------------------------------------------------------------------

View File

@ -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
*

View File

@ -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);

View File

@ -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. */

View File

@ -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()
*

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */
};
/*-------------------------------------------------------------------------

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -89,6 +89,7 @@ set (H5P_TESTS
t_shapesame
t_filters_parallel
t_2Gio
t_vfd
)
foreach (h5_testp ${H5P_TESTS})

View File

@ -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

View File

@ -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);

View File

@ -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

File diff suppressed because it is too large Load Diff