diff options
author | Neil Fortner <fortnern@gmail.com> | 2023-05-17 17:00:50 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-17 17:00:50 (GMT) |
commit | 49dc0e7bbf8bc790070cd71d259286897bf686bf (patch) | |
tree | 5d4714b07ec3f87f5c961c8f077dec54a007e53c | |
parent | de5f8c5aece3fa2e1f0e08a5f382475aa82aeec0 (diff) | |
parent | 00e904a3952133e8558e7f604f54eadc48a2e1ce (diff) | |
download | hdf5-feature/select_io_tconv.zip hdf5-feature/select_io_tconv.tar.gz hdf5-feature/select_io_tconv.tar.bz2 |
Merge pull request #2876 from vchoi-hdfgroup/2my_feature_select_io_tconvfeature/select_io_tconv
2my feature select io tconv
-rw-r--r-- | src/H5CX.c | 89 | ||||
-rw-r--r-- | src/H5CXprivate.h | 2 | ||||
-rw-r--r-- | src/H5Dprivate.h | 19 | ||||
-rw-r--r-- | src/H5FDint.c | 79 | ||||
-rw-r--r-- | src/H5Pdxpl.c | 48 | ||||
-rw-r--r-- | src/H5Ppublic.h | 55 | ||||
-rw-r--r-- | test/select_io_dset.c | 51 | ||||
-rw-r--r-- | testpar/CMakeLists.txt | 1 | ||||
-rw-r--r-- | testpar/t_select_io_dset.c | 33 |
9 files changed, 345 insertions, 32 deletions
@@ -305,6 +305,11 @@ typedef struct H5CX_t { hbool_t no_selection_io_cause_set; /* Whether reason for not performing selection I/O is set */ hbool_t no_selection_io_cause_valid; /* Whether reason for not performing selection I/O is valid */ + uint32_t + actual_selection_io_mode; /* Actual selection I/O mode used (H5D_ACTUAL_SELECTION_IO_MODE_NAME) */ + hbool_t actual_selection_io_mode_set; /* Whether actual selection I/O mode is set */ + hbool_t actual_selection_io_mode_valid; /* Whether actual selection I/O mode is valid */ + /* Cached LCPL properties */ H5T_cset_t encoding; /* Link name character encoding */ hbool_t encoding_valid; /* Whether link name character encoding is valid */ @@ -386,6 +391,8 @@ typedef struct H5CX_dxpl_cache_t { H5D_selection_io_mode_t selection_io_mode; /* Selection I/O mode (H5D_XFER_SELECTION_IO_MODE_NAME) */ uint32_t no_selection_io_cause; /* Reasons for not performing selection I/O (H5D_XFER_NO_SELECTION_IO_CAUSE_NAME) */ + uint32_t actual_selection_io_mode; /* Actual selection I/O mode + (H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME) */ hbool_t modify_write_buf; /* Whether the library can modify write buffers */ } H5CX_dxpl_cache_t; @@ -576,13 +583,18 @@ H5CX_init(void) /* Get the selection I/O mode */ if (H5P_get(dx_plist, H5D_XFER_SELECTION_IO_MODE_NAME, &H5CX_def_dxpl_cache.selection_io_mode) < 0) - HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve parallel transfer method") + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve selection I/O mode") /* Get the local & global reasons for breaking selection I/O values */ if (H5P_get(dx_plist, H5D_XFER_NO_SELECTION_IO_CAUSE_NAME, &H5CX_def_dxpl_cache.no_selection_io_cause) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve cause for no selection I/O") + /* Get the actual selection I/O mode */ + if (H5P_get(dx_plist, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, + &H5CX_def_dxpl_cache.actual_selection_io_mode) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve actual selection I/O mode") + /* Get the modify write buffer property */ if (H5P_get(dx_plist, H5D_XFER_MODIFY_WRITE_BUF_NAME, &H5CX_def_dxpl_cache.modify_write_buf) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve modify write buffer property") @@ -2658,6 +2670,43 @@ done: } /* end H5CX_get_no_selection_io_cause() */ /*------------------------------------------------------------------------- + * Function: H5CX_get_no_selection_io_cause + * + * Purpose: Retrieves the cause for not performing selection I/O + * for the current API call context. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Vailin Choi + * April 15, 2023 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_actual_selection_io_mode(uint32_t *actual_selection_io_mode) +{ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(actual_selection_io_mode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); + + H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, + actual_selection_io_mode) + + /* Get the value */ + *actual_selection_io_mode = (*head)->ctx.actual_selection_io_mode; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_actual_selection_io_mode() */ + +/*------------------------------------------------------------------------- * Function: H5CX_get_modify_write_buf * * Purpose: Retrieves the modify write buffer property for the current API call context. @@ -3702,7 +3751,42 @@ H5CX_set_no_selection_io_cause(uint32_t no_selection_io_cause) } /* end if */ FUNC_LEAVE_NOAPI_VOID -} /* end H5CX_set_no_selectiion_io_cause() */ +} /* end H5CX_set_no_selection_io_cause() */ + +/*------------------------------------------------------------------------- + * Function: H5CX_set_actual_selecction_io_mode + * + * Purpose: Sets the actual selection I/O mode for the current API + * call context. + * + * Return: <none> + * + * Programmer: Vailin Choi + * April 15, 2023 + * + *------------------------------------------------------------------------- + */ +void +H5CX_set_actual_selection_io_mode(uint32_t actual_selection_io_mode) +{ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); + HDassert((*head)->ctx.dxpl_id != H5P_DEFAULT); + + /* If we're using the default DXPL, don't modify it */ + if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT) { + /* Cache the value for later, marking it to set in DXPL when context popped */ + (*head)->ctx.actual_selection_io_mode = actual_selection_io_mode; + (*head)->ctx.actual_selection_io_mode_set = TRUE; + } /* end if */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5CX_set_actual_selection_io_mode() */ /*------------------------------------------------------------------------- * Function: H5CX_get_ohdr_flags @@ -3766,6 +3850,7 @@ H5CX__pop_common(hbool_t update_dxpl_props) /* Check for cached DXPL properties to return to application */ if (update_dxpl_props) { H5CX_SET_PROP(H5D_XFER_NO_SELECTION_IO_CAUSE_NAME, no_selection_io_cause) + H5CX_SET_PROP(H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, actual_selection_io_mode) #ifdef H5_HAVE_PARALLEL H5CX_SET_PROP(H5D_MPIO_ACTUAL_CHUNK_OPT_MODE_NAME, mpio_actual_chunk_opt) H5CX_SET_PROP(H5D_MPIO_ACTUAL_IO_MODE_NAME, mpio_actual_io_mode) diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index f0bec20..885d6a6 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -117,6 +117,7 @@ H5_DLL herr_t H5CX_get_vlen_alloc_info(H5T_vlen_alloc_info_t *vl_alloc_info); H5_DLL herr_t H5CX_get_dt_conv_cb(H5T_conv_cb_t *cb_struct); H5_DLL herr_t H5CX_get_selection_io_mode(H5D_selection_io_mode_t *selection_io_mode); H5_DLL herr_t H5CX_get_no_selection_io_cause(uint32_t *no_selection_io_cause); +H5_DLL herr_t H5CX_get_actual_selection_io_mode(uint32_t *actual_selection_io_mode); H5_DLL herr_t H5CX_get_modify_write_buf(hbool_t *modify_write_buf); /* "Getter" routines for LCPL properties cached in API context */ @@ -163,6 +164,7 @@ H5_DLL herr_t H5CX_init(void); /* "Setter" routines for cached DXPL properties that must be returned to application */ H5_DLL void H5CX_set_no_selection_io_cause(uint32_t no_selection_io_cause); +H5_DLL void H5CX_set_actual_selection_io_mode(uint32_t actual_selection_io_mode); #ifdef H5_HAVE_PARALLEL H5_DLL void H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t chunk_opt); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 8265ac2..285529c 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -78,15 +78,16 @@ #define H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME \ "local_no_collective_cause" /* cause of broken collective I/O in each process */ #define H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME \ - "global_no_collective_cause" /* cause of broken collective I/O in all processes */ -#define H5D_XFER_EDC_NAME "err_detect" /* EDC */ -#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */ -#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */ -#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */ -#define H5D_XFER_DSET_IO_SEL_NAME "dset_io_selection" /* Dataset I/O selection */ -#define H5D_XFER_SELECTION_IO_MODE_NAME "selection_io_mode" /* Selection I/O mode */ -#define H5D_XFER_NO_SELECTION_IO_CAUSE_NAME "no_selection_io_cause" /* Cause for no selection I/O */ -#define H5D_XFER_MODIFY_WRITE_BUF_NAME "modify_write_buf" /* Modify write buffers */ + "global_no_collective_cause" /* cause of broken collective I/O in all processes */ +#define H5D_XFER_EDC_NAME "err_detect" /* EDC */ +#define H5D_XFER_FILTER_CB_NAME "filter_cb" /* Filter callback function */ +#define H5D_XFER_CONV_CB_NAME "type_conv_cb" /* Type conversion callback function */ +#define H5D_XFER_XFORM_NAME "data_transform" /* Data transform */ +#define H5D_XFER_DSET_IO_SEL_NAME "dset_io_selection" /* Dataset I/O selection */ +#define H5D_XFER_SELECTION_IO_MODE_NAME "selection_io_mode" /* Selection I/O mode */ +#define H5D_XFER_NO_SELECTION_IO_CAUSE_NAME "no_selection_io_cause" /* Cause for no selection I/O */ +#define H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME "actual_selection_io_mode" /* Actual selection I/O mode */ +#define H5D_XFER_MODIFY_WRITE_BUF_NAME "modify_write_buf" /* Modify write buffers */ #ifdef H5_HAVE_INSTRUMENTED_LIBRARY /* Collective chunk instrumentation properties */ #define H5D_XFER_COLL_CHUNK_LINK_HARD_NAME "coll_chunk_link_hard" diff --git a/src/H5FDint.c b/src/H5FDint.c index 6d90aae..bc23ba2 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -457,10 +457,16 @@ H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs /* if the underlying VFD supports vector read, make the call */ if (file->cls->read_vector) { + uint32_t actual_selection_io_mode; if ((file->cls->read_vector)(file, dxpl_id, count, types, addrs, sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read vector request failed") + + /* Set actual selection I/O mode */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_VECTOR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { @@ -470,6 +476,7 @@ H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs extend_sizes = FALSE; extend_types = FALSE; uint32_t no_selection_io_cause; + uint32_t actual_selection_io_mode; for (i = 0; i < count; i++) { @@ -511,6 +518,11 @@ H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs H5CX_get_no_selection_io_cause(&no_selection_io_cause); no_selection_io_cause |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; H5CX_set_no_selection_io_cause(no_selection_io_cause); + + /* Set actual selection I/O mode */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SCALAR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } done: @@ -665,9 +677,16 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr /* if the underlying VFD supports vector write, make the call */ if (file->cls->write_vector) { + uint32_t actual_selection_io_mode; + if ((file->cls->write_vector)(file, dxpl_id, count, types, addrs, sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write vector request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_VECTOR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { /* otherwise, implement the vector write as a sequence of regular @@ -676,6 +695,7 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr extend_sizes = FALSE; extend_types = FALSE; uint32_t no_selection_io_cause; + uint32_t actual_selection_io_mode; for (i = 0; i < count; i++) { @@ -717,6 +737,11 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr H5CX_get_no_selection_io_cause(&no_selection_io_cause); no_selection_io_cause |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; H5CX_set_no_selection_io_cause(no_selection_io_cause); + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SCALAR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } done: @@ -998,18 +1023,31 @@ H5FD__read_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uin /* Issue vector read call if appropriate */ if (use_vector) { + uint32_t actual_selection_io_mode; + H5_CHECK_OVERFLOW(vec_arr_nused, size_t, uint32_t) if ((file->cls->read_vector)(file, dxpl_id, (uint32_t)vec_arr_nused, types, addrs, sizes, vec_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read vector request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_VECTOR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { uint32_t no_selection_io_cause; + uint32_t actual_selection_io_mode; /* Add H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB to no selection I/O cause */ H5CX_get_no_selection_io_cause(&no_selection_io_cause); no_selection_io_cause |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; H5CX_set_no_selection_io_cause(no_selection_io_cause); + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SCALAR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } done: @@ -1165,6 +1203,8 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s /* if the underlying VFD supports selection read, make the call */ if (file->cls->read_selection) { + uint32_t actual_selection_io_mode; + /* Allocate array of space IDs if necessary, otherwise use local * buffers */ if (count > sizeof(mem_space_ids_local) / sizeof(mem_space_ids_local[0])) { @@ -1190,6 +1230,11 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s if ((file->cls->read_selection)(file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read selection request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SELECTION_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else /* Otherwise, implement the selection read as a sequence of regular @@ -1329,9 +1374,16 @@ H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_ /* if the underlying VFD supports selection read, make the call */ if (file->cls->read_selection) { + uint32_t actual_selection_io_mode; + if ((file->cls->read_selection)(file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read selection request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SELECTION_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { /* Otherwise, implement the selection read as a sequence of regular @@ -1645,18 +1697,31 @@ H5FD__write_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui /* Issue vector write call if appropriate */ if (use_vector) { + uint32_t actual_selection_io_mode; + H5_CHECK_OVERFLOW(vec_arr_nused, size_t, uint32_t) if ((file->cls->write_vector)(file, dxpl_id, (uint32_t)vec_arr_nused, types, addrs, sizes, vec_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write vector request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_VECTOR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { uint32_t no_selection_io_cause; + uint32_t actual_selection_io_mode; /* Add H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB to no selection I/O cause */ H5CX_get_no_selection_io_cause(&no_selection_io_cause); no_selection_io_cause |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; H5CX_set_no_selection_io_cause(no_selection_io_cause); + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SCALAR_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } done: @@ -1804,6 +1869,8 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ /* if the underlying VFD supports selection write, make the call */ if (file->cls->write_selection) { + uint32_t actual_selection_io_mode; + /* Allocate array of space IDs if necessary, otherwise use local * buffers */ if (count > sizeof(mem_space_ids_local) / sizeof(mem_space_ids_local[0])) { @@ -1829,6 +1896,11 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ if ((file->cls->write_selection)(file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write selection request failed") + + /* Set actual selection I/O */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SELECTION_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else /* Otherwise, implement the selection write as a sequence of regular @@ -1959,9 +2031,16 @@ H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem /* if the underlying VFD supports selection write, make the call */ if (file->cls->write_selection) { + uint32_t actual_selection_io_mode; + if ((file->cls->write_selection)(file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "driver write selection request failed") + + /* Set actual selection I/O mode */ + H5CX_get_actual_selection_io_mode(&actual_selection_io_mode); + actual_selection_io_mode |= H5D_SELECTION_IO; + H5CX_set_actual_selection_io_mode(actual_selection_io_mode); } else { /* Otherwise, implement the selection write as a sequence of regular diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 6eef558..fd63a66 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -176,6 +176,9 @@ /* Definitions for cause of no selection I/O property */ #define H5D_XFER_NO_SELECTION_IO_CAUSE_SIZE sizeof(uint32_t) #define H5D_XFER_NO_SELECTION_IO_CAUSE_DEF 0 +/* Definitions for actual selection I/O mode property */ +#define H5D_XFER_ACTUAL_SELECTION_IO_MODE_SIZE sizeof(uint32_t) +#define H5D_XFER_ACTUAL_SELECTION_IO_MODE_DEF 0 /* Definitions for modify write buffer property */ #define H5D_XFER_MODIFY_WRITE_BUF_SIZE sizeof(hbool_t) #define H5D_XFER_MODIFY_WRITE_BUF_DEF FALSE @@ -296,7 +299,8 @@ static const H5S_t *H5D_def_dset_io_sel_g = H5D_XFER_DSET_IO_SEL_DEF; /* Default value for dataset I/O selection */ static const H5D_selection_io_mode_t H5D_def_selection_io_mode_g = H5D_XFER_SELECTION_IO_MODE_DEF; static const uint32_t H5D_def_no_selection_io_cause_g = H5D_XFER_NO_SELECTION_IO_CAUSE_DEF; -static const hbool_t H5D_def_modify_write_buf_g = H5D_XFER_MODIFY_WRITE_BUF_DEF; +static const uint32_t H5D_def_actual_selection_io_mode_g = H5D_XFER_ACTUAL_SELECTION_IO_MODE_DEF; +static const hbool_t H5D_def_modify_write_buf_g = H5D_XFER_MODIFY_WRITE_BUF_DEF; /*------------------------------------------------------------------------- * Function: H5P__dxfr_reg_prop @@ -473,6 +477,13 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the actual selection I/O mode property */ + /* (Note: this property should not have an encode/decode callback) */ + if (H5P__register_real(pclass, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, + H5D_XFER_ACTUAL_SELECTION_IO_MODE_SIZE, &H5D_def_actual_selection_io_mode_g, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the modify write buffer property */ if (H5P__register_real(pclass, H5D_XFER_MODIFY_WRITE_BUF_NAME, H5D_XFER_MODIFY_WRITE_BUF_SIZE, &H5D_def_modify_write_buf_g, NULL, NULL, NULL, H5D_XFER_MODIFY_WRITE_BUF_ENC, @@ -2562,7 +2573,7 @@ H5Pget_selection_io(hid_t plist_id, H5D_selection_io_mode_t *selection_io_mode / herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*DC", plist_id, selection_io_mode); + H5TRACE2("e", "ix", plist_id, selection_io_mode); /* Check arguments */ if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER))) @@ -2611,6 +2622,39 @@ done: } /* end H5Pget_no_selection_io_cause() */ /*------------------------------------------------------------------------- + * Function: H5Pget_actual_selection_io_mode + * + * Purpose: Retrieves actual selection I/O mode + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * April 27, 2023 + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_actual_selection_io_mode(hid_t plist_id, uint32_t *actual_selection_io_mode /*out*/) +{ + H5P_genplist_t *plist; + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", plist_id, actual_selection_io_mode); + + /* Get the plist structure */ + if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID") + + /* Return values */ + if (actual_selection_io_mode) + if (H5P_get(plist, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, actual_selection_io_mode) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get actual_selection_io_mode value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_actual_selection_io_mode() */ + +/*------------------------------------------------------------------------- * Function: H5P__dxfr_modify_write_buf_enc * * Purpose: Callback routine which is called whenever the modify write diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index a08119d..518b147 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -423,6 +423,11 @@ typedef enum H5D_selection_io_mode_t { } H5D_selection_io_mode_t; //! <!--[H5D_selection_io_mode_t_snip] --> +/* Actual selection I/O modes for H5Pget_actual_selection_io_mode() property */ +#define H5D_SCALAR_IO 0x1 /* Scalar (or legacy MPIO) I/O was performed */ +#define H5D_VECTOR_IO 0x2 /* Vector I/O was performed */ +#define H5D_SELECTION_IO 0x4 /* Selection I/O was performed */ + /********************/ /* Public Variables */ /********************/ @@ -8398,6 +8403,56 @@ H5_DLL herr_t H5Pget_selection_io(hid_t plist_id, H5D_selection_io_mode_t *selec H5_DLL herr_t H5Pget_no_selection_io_cause(hid_t plist_id, uint32_t *no_selection_io_cause); /** + * \ingroup DXPL + * + * \brief Retrieves the type(s) of I/O that HDF5 actually performed on + * last I/O call (not necessarily the type requested) + * + * \dxpl_id{plist_id} + * \param[out] actual_selection_io_mode A bitwise set value indicating the + * type(s) of I/O performed + * \return \herr_t + * + * \par Motivation: + * A user can request selection I/O to be performed via a data transfer + * property list (DXPL). This can be used to enable collective I/O with + * type conversion, or with custom VFDs that support vector or selection + * I/O. However, there are conditions that can cause HDF5 to forgo + * selection or vector I/O and perform legacy (scalar) I/O instead. + * This function allows the user to determine which type or types of + * I/O were actually performed. + * + * \details H5Pget_actual_selection_io_mode() allows the user to determine which + * type(s) of I/O were actually performed during the last I/O operation + * which used \p plist_id. This property is set after all I/O is + * completed; if I/O fails, it will not be set. + * + * H5Pget_no_selection_io_cause() can be used to determine the reason + * why selection or vector I/O was not performed. + * + * Valid values returned in \p actual_selection_io_mode are listed + * as follows. + * + * - #H5D_SCALAR_IO + * Scalar (or legacy MPIO) I/O was performed + * - #H5D_VECTOR_IO + * Vector I/O was performed + * - #H5D_SELECTION_IO + * Selection I/O was performed + * + * Be aware that this function will include the types of all I/O that + * were performed during this operation, including any metadata + * operations that may be incidental to the requested I/O. To make sure + * this function is only capturing raw data I/O, one can temporarily + * disable metadata cache evictions by calling H5Fset_mdc_config() with + * evictions_enabled set to false. + * + * \since 1.14.2 + * + */ +H5_DLL herr_t H5Pget_actual_selection_io_mode(hid_t plist_id, uint32_t *actual_selection_io_mode); + +/** * * \ingroup DXPL * diff --git a/test/select_io_dset.c b/test/select_io_dset.c index 9a1de06..a84c40d 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -106,6 +106,21 @@ typedef enum { #define TEST_TCONV_BUF_TOO_SMALL 0x100 #define TEST_IN_PLACE_TCONV 0x200 +static herr_t +check_actual_selection_io_mode(hid_t dxpl, uint32_t sel_io_mode_expected) +{ + uint32_t actual_sel_io_mode; + + if (H5Pget_actual_selection_io_mode(dxpl, &actual_sel_io_mode) < 0) + FAIL_STACK_ERROR; + if (actual_sel_io_mode != sel_io_mode_expected) + TEST_ERROR; + + return SUCCEED; +error: + return FAIL; +} + /* * Case 1: single dataset read/write, no type conversion (null case) * --create dataset with H5T_NATIVE_INT @@ -127,7 +142,8 @@ test_no_type_conv(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) int trans_wbuf[DSET_SELECT_DIM]; int rbuf[DSET_SELECT_DIM]; char dset_name[DSET_NAME_LEN]; - const char *expr = "2*x"; + const char *expr = "2*x"; + uint32_t no_selection_io_cause = 0; /* Create 1d data space */ dims[0] = DSET_SELECT_DIM; @@ -256,17 +272,18 @@ error: static herr_t test_no_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) { - int i; - hid_t did = H5I_INVALID_HID; - hid_t sid = H5I_INVALID_HID; - hid_t dcpl = H5I_INVALID_HID; - hid_t dxpl = H5I_INVALID_HID; - hsize_t dims[1]; - hsize_t cdims[1]; - char *wbuf = NULL; - char *wbuf_bak = NULL; - char *rbuf = NULL; - char dset_name[DSET_NAME_LEN]; + int i; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + char *wbuf = NULL; + char *wbuf_bak = NULL; + char *rbuf = NULL; + char dset_name[DSET_NAME_LEN]; + uint32_t no_selection_io_cause = 0; if ((wbuf = (char *)HDmalloc((size_t)(4 * DSET_SELECT_DIM))) == NULL) FAIL_STACK_ERROR; @@ -417,7 +434,8 @@ test_larger_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsign long trans_wbuf[DSET_SELECT_DIM]; long long rbuf[DSET_SELECT_DIM]; char dset_name[DSET_NAME_LEN]; - const char *expr = "5 * (10 - x)"; + const char *expr = "5 * (10 - x)"; + uint32_t no_selection_io_cause = 0; /* Create 1d data space */ dims[0] = DSET_SELECT_DIM; @@ -559,7 +577,8 @@ test_smaller_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsig short trans_wbuf[DSET_SELECT_DIM]; short rbuf[DSET_SELECT_DIM]; char dset_name[DSET_NAME_LEN]; - const char *expr = "2 * (10 + x)"; + const char *expr = "2 * (10 + x)"; + uint32_t no_selection_io_cause = 0; /* Create 1d data space */ dims[0] = DSET_SELECT_DIM; @@ -1060,6 +1079,7 @@ test_multi_dsets_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsigned m const void *wbufs[MULTI_NUM_DSETS]; void *rbufs[MULTI_NUM_DSETS]; const char *expr = "2*x"; + uint32_t no_selection_io_cause; ndsets = MAX(MULTI_MIN_DSETS, MULTI_NUM_DSETS); @@ -2886,9 +2906,6 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) FAIL_STACK_ERROR; - /* If default mode, 1st write will trigger cb, 2nd write will trigger sieve */ - /* If on mode, will trigger nothing because the on mode path is different */ - /* Need 2 writes */ if (test_mode & TEST_CONTIGUOUS_SIEVE_BUFFER) { no_selection_io_cause_write_expected |= H5D_SEL_IO_CONTIGUOUS_SIEVE_BUFFER; no_selection_io_cause_read_expected |= H5D_SEL_IO_CONTIGUOUS_SIEVE_BUFFER; diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt index fb66e76..3a44fca 100644 --- a/testpar/CMakeLists.txt +++ b/testpar/CMakeLists.txt @@ -8,7 +8,6 @@ project (HDF5_TEST_PAR C) set (testphdf5_SOURCES ${HDF5_TEST_PAR_SOURCE_DIR}/testphdf5.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_dset.c - ${HDF5_TEST_PAR_SOURCE_DIR}/t_select_io_dset.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_file.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_file_image.c ${HDF5_TEST_PAR_SOURCE_DIR}/t_mdset.c diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index 10b29e4..cda5620 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -154,7 +154,7 @@ set_dxpl(hid_t dxpl, H5D_selection_io_mode_t select_io_mode, H5FD_mpio_xfer_t mp } /* set_dxpl() */ /* - * Helper routine to check actual I/O mode on a dxpl + * Helper routine to check actual parallel I/O mode on a dxpl */ static void check_io_mode(hid_t dxpl, unsigned chunked) @@ -182,6 +182,20 @@ check_io_mode(hid_t dxpl, unsigned chunked) } /* check_io_mode() */ /* + * Helper routine to check actual selection I/O mode on a dxpl + */ +static void +check_actual_selection_io_mode(hid_t dxpl, uint32_t sel_io_mode_expected) +{ + uint32_t actual_sel_io_mode; + + if (H5Pget_actual_selection_io_mode(dxpl, &actual_sel_io_mode) < 0) + P_TEST_ERROR; + if (actual_sel_io_mode != sel_io_mode_expected) + P_TEST_ERROR; +} + +/* * Case 1: single dataset read/write, no type conversion (null case) */ static void @@ -280,6 +294,7 @@ test_no_type_conv(hid_t fid, unsigned chunked, unsigned dtrans, unsigned mwbuf) HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ if (H5Dread(did, H5T_NATIVE_INT, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) @@ -426,6 +441,7 @@ test_no_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) HDmemcpy(wbuf, wbuf_bak, (size_t)(4 * DSET_SELECT_DIM)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read the data from the dataset with little endian */ if (H5Dread(did, H5T_STD_I32LE, mspace_id, fspace_id, dxpl, rbuf) < 0) @@ -578,6 +594,7 @@ test_larger_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsign HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ if (H5Dread(did, H5T_NATIVE_LLONG, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) @@ -727,6 +744,7 @@ test_smaller_mem_type_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsig HDmemcpy(wbuf, wbuf_bak, sizeof(wbuf)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ if (H5Dread(did, H5T_NATIVE_SHORT, mspace_id, fspace_id, ntrans_dxpl, rbuf) < 0) @@ -918,6 +936,7 @@ test_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) HDmemcpy(s1_wbuf, s1_wbuf_bak, sizeof(s1_t) * DSET_SELECT_DIM); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read all the data from the dataset */ HDmemset(s1_rbuf, 0, sizeof(s1_t) * DSET_SELECT_DIM); @@ -1224,6 +1243,7 @@ test_type_conv_sel_empty(hid_t fid, unsigned chunked, unsigned dtrans, unsigned HDmemcpy(lwbuf, lwbuf_bak, sizeof(lwbuf)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read the data from the dataset: type conversion int-->long */ /* If dtrans, without data transform set in dxpl */ @@ -1552,6 +1572,7 @@ test_multi_dsets_no_bkg(hid_t fid, unsigned chunked, unsigned dtrans, unsigned m HDmemcpy(total_wbuf, total_wbuf_bak, ndsets * DSET_SELECT_DIM * sizeof(int)); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read data from the dataset (if dtrans, without data transform set in dxpl) */ if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, ntrans_dxpl, rbufs) < 0) @@ -1856,6 +1877,7 @@ test_multi_dsets_cmpd_with_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) P_TEST_ERROR; @@ -2297,6 +2319,7 @@ test_multi_dsets_size_change_no_bkg(hid_t fid, unsigned chunked, unsigned mwbuf) HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Read data from the dataset */ if (H5Dread_multi(ndsets, dset_dids, mem_tids, mem_sids, file_sids, dxpl, rbufs) < 0) @@ -2766,6 +2789,7 @@ test_multi_dsets_conv_sel_empty(hid_t fid, unsigned chunked, unsigned dtrans, un HDmemcpy(total_wbuf, total_wbuf_bak, buf_size); check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Initialize buffer indices */ for (i = 0; i < (int)ndsets; i++) { @@ -3243,6 +3267,7 @@ test_multi_dsets_all(int niter, hid_t fid, unsigned chunked, unsigned mwbuf) P_TEST_ERROR; check_io_mode(dxpl, chunked); + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); /* Verify result read */ /* for i ndsets */ @@ -3418,6 +3443,8 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) P_TEST_ERROR; + set_dxpl(dxpl, H5D_SELECTION_IO_MODE_ON, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_COLLECTIVE_IO, false); + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) P_TEST_ERROR; @@ -3482,6 +3509,10 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, dxpl, wbuf) < 0) P_TEST_ERROR; + if (!(test_mode & TEST_DISABLE_BY_API || test_mode & TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET || + ((test_mode & TEST_TCONV_BUF_TOO_SMALL) && !(test_mode & TEST_IN_PLACE_TCONV)))) + check_actual_selection_io_mode(dxpl, H5D_VECTOR_IO); + if (H5Pget_no_selection_io_cause(dxpl, &no_selection_io_cause_write) < 0) P_TEST_ERROR; |