From 25c434e7c60039b5e41728d8e66b04a24e9758f9 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Mon, 3 Jul 2023 15:45:11 -0500 Subject: [PATCH 01/19] Implementation of the mpio driver with selection I/O. This also addresses the review comments of the previous PR #3058 which will be closed. --- src/H5FD.c | 258 ++++++++++++- src/H5FDdevelop.h | 16 +- src/H5FDint.c | 576 +++++++++++++++++++++++----- src/H5FDmpio.c | 945 +++++++++++++++++++++++++++++++++++++++++++++- src/H5FDprivate.h | 37 +- 5 files changed, 1734 insertions(+), 98 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 23c1fb44195..6b5236875b7 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1723,7 +1723,7 @@ H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, /* 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, + if (H5FD_read_selection_id(SKIP_NO_CB, 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") @@ -1820,7 +1820,7 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count /* 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, + if (H5FD_write_selection_id(SKIP_NO_CB, 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") @@ -1828,6 +1828,260 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count FUNC_LEAVE_API(ret_value) } /* end H5FDwrite_selection() */ +/* + * Translate selections to vector CB if possible, if not, scalar CB + * --skip selection CB + */ +herr_t +H5FDread_vector_from_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") + } + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_read_vector_from_selection(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_vector_from_selection() */ + +/* + * Translate selections to vector CB if possible, if not, scalar CB + * --skip selection CB + */ +herr_t +H5FDwrite_vector_from_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") + } + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_write_vector_from_selection(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_vector_from_selection() */ + +/* + * Translate selections to scalar CB + * --skip selection CB + * --skip vector CB + */ +herr_t +H5FDread_from_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[]) +{ + 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") + } + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_read_from_selection(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_from_selection() */ + +/* + * Translate selections to scalar CB + * --skip selection CB + * --skip vector CB + */ +herr_t +H5FDwrite_from_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") + } + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_write_from_selection(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_from_selection() */ + + /*------------------------------------------------------------------------- * Function: H5FDflush * diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index ab1579caba8..d923edc7be5 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -196,10 +196,10 @@ typedef struct H5FD_class_t { 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[], + herr_t (*read_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*/); - herr_t (*write_selection)(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, size_t count, hid_t mem_spaces[], + herr_t (*write_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[] /*in*/); herr_t (*flush)(H5FD_t *file, hid_t dxpl_id, hbool_t closing); @@ -281,6 +281,18 @@ H5_DLL herr_t H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, 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 H5FDread_vector_from_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_vector_from_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[] /* in */); +H5_DLL herr_t H5FDread_from_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 */); +H5_DLL herr_t H5FDwrite_from_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[] /* in */); 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); diff --git a/src/H5FDint.c b/src/H5FDint.c index 892feacb9c9..fca60bad673 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -109,11 +109,13 @@ typedef struct H5FD_get_driver_ud_t { /* Local Prototypes */ /********************/ static int H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data); -static herr_t H5FD__read_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, - H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], +static herr_t H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, + hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, + H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */); -static herr_t H5FD__write_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, - H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], +static herr_t H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, + hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, + H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], const void *bufs[]); /*********************/ @@ -748,8 +750,8 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr *------------------------------------------------------------------------- */ static herr_t -H5FD__read_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, - H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], +H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, + uint32_t count, H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */) { hbool_t extend_sizes = FALSE; @@ -797,7 +799,7 @@ H5FD__read_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uin assert((bufs) || (count == 0)); /* Check if we're using vector I/O */ - use_vector = file->cls->read_vector != NULL; + use_vector = (file->cls->read_vector != NULL) && (!skip_vector_cb); if (count > 0) { /* Verify that the first elements of the element_sizes and bufs arrays are @@ -1188,8 +1190,8 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s /* Otherwise, implement the selection read as a sequence of regular * or vector read calls. */ - if (H5FD__read_selection_translate(file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, - element_sizes, bufs) < 0) + if (H5FD__read_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, + offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed") done: @@ -1238,7 +1240,7 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s *------------------------------------------------------------------------- */ herr_t -H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_space_ids[], +H5FD_read_selection_id(uint32_t skip_cb, 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 */) { @@ -1249,6 +1251,8 @@ H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_ H5S_t **file_spaces = file_spaces_local; hid_t dxpl_id = H5I_INVALID_HID; /* DXPL for operation */ uint32_t i; + uint32_t skip_selection_cb; + uint32_t skip_vector_cb; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1281,6 +1285,9 @@ H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_ } #endif /* H5_HAVE_PARALLEL */ + skip_selection_cb = skip_cb & SKIP_SELECTION_CB; + skip_vector_cb = skip_cb & SKIP_VECTOR_CB; + if (file->base_addr > 0) { /* apply the base_addr offset to the offsets array. Must undo before @@ -1319,7 +1326,7 @@ 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) { + if (!skip_selection_cb && file->cls->read_selection) { 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") @@ -1347,8 +1354,8 @@ H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_ } /* Translate to vector or scalar I/O */ - if (H5FD__read_selection_translate(file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, - element_sizes, bufs) < 0) + if (H5FD__read_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, + file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed") } @@ -1389,8 +1396,8 @@ H5FD_read_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_ *------------------------------------------------------------------------- */ static herr_t -H5FD__write_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, - H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], +H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, + uint32_t count, H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], const void *bufs[]) { hbool_t extend_sizes = FALSE; @@ -1438,7 +1445,7 @@ H5FD__write_selection_translate(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui assert((bufs) || (count == 0)); /* Check if we're using vector I/O */ - use_vector = file->cls->write_vector != NULL; + use_vector = (file->cls->write_vector != NULL) && (!skip_vector_cb); if (count > 0) { /* Verify that the first elements of the element_sizes and bufs arrays are @@ -1821,8 +1828,8 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ /* Otherwise, implement the selection write as a sequence of regular * or vector write calls. */ - if (H5FD__write_selection_translate(file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, - element_sizes, bufs) < 0) + if (H5FD__write_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, + offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed") done: @@ -1869,8 +1876,9 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ *------------------------------------------------------------------------- */ 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[]) +H5FD_write_selection_id(uint32_t skip_cb, 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[]) { hbool_t offsets_cooked = FALSE; H5S_t *mem_spaces_local[H5FD_LOCAL_SEL_ARR_LEN]; @@ -1879,6 +1887,8 @@ H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem H5S_t **file_spaces = file_spaces_local; hid_t dxpl_id = H5I_INVALID_HID; /* DXPL for operation */ uint32_t i; + uint32_t skip_selection_cb; + uint32_t skip_vector_cb; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1911,6 +1921,9 @@ H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem } #endif /* H5_HAVE_PARALLEL */ + skip_selection_cb = skip_cb & SKIP_SELECTION_CB; + skip_vector_cb = skip_cb & SKIP_VECTOR_CB; + if (file->base_addr > 0) { /* apply the base_addr offset to the offsets array. Must undo before @@ -1943,7 +1956,7 @@ 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) { + if (!skip_selection_cb && file->cls->write_selection) { 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") @@ -1971,8 +1984,8 @@ H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem } /* Translate to vector or scalar I/O */ - if (H5FD__write_selection_translate(file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, - element_sizes, bufs) < 0) + if (H5FD__write_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, + file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed") } @@ -1997,6 +2010,206 @@ H5FD_write_selection_id(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_write_selection_id() */ +/*------------------------------------------------------------------------- + * Function: H5FD_read_vector_from_selection + * + * Purpose: Internal routine for H5FDread_vector_from_selection() + * + * Return: Success: SUCCEED + * All writes have completed successfully. + * + * Failure: FAIL + * One or more writes failed. + * + * Programmer: NAF -- 5/19/21 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_read_vector_from_selection(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[]) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + assert(file); + assert(file->cls); + assert((mem_space_ids) || (count == 0)); + assert((file_space_ids) || (count == 0)); + assert((offsets) || (count == 0)); + assert((element_sizes) || (count == 0)); + assert((bufs) || (count == 0)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_read_selection_id(SKIP_SELECTION_CB, 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_NOAPI(ret_value) + +} /* end H5FD_read_vector_from_selection() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_write_vector_from_selection + * + * Purpose: Internal routine for H5FDwrite_vector_from_selection() + * + * + * Return: Success: SUCCEED + * All writes have completed successfully. + * + * Failure: FAIL + * One or more writes failed. + * + * Programmer: NAF -- 5/19/21 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_write_vector_from_selection(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[]) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + assert(file); + assert(file->cls); + assert((mem_space_ids) || (count == 0)); + assert((file_space_ids) || (count == 0)); + assert((offsets) || (count == 0)); + assert((element_sizes) || (count == 0)); + assert((bufs) || (count == 0)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_write_selection_id(SKIP_SELECTION_CB, 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_NOAPI(ret_value) + +} /* end H5FD_write_vector_from_selection() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_read_from_selection + * + * Purpose: Internal routine for H5FDread_from_selection() + * + * + * Return: Success: SUCCEED + * All writes have completed successfully. + * + * Failure: FAIL + * One or more writes failed. + * + * Programmer: NAF -- 5/19/21 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_read_from_selection(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[]) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + assert(file); + assert(file->cls); + assert((mem_space_ids) || (count == 0)); + assert((file_space_ids) || (count == 0)); + assert((offsets) || (count == 0)); + assert((element_sizes) || (count == 0)); + assert((bufs) || (count == 0)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_read_selection_id(SKIP_SELECTION_CB | SKIP_VECTOR_CB, 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_NOAPI(ret_value) + +} /* end H5FD_read_from_selection() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_write_from_selection + * + * Purpose: Internal routine for H5FDwrite_from_selection() + * + * + * Return: Success: SUCCEED + * All writes have completed successfully. + * + * Failure: FAIL + * One or more writes failed. + * + * Programmer: NAF -- 5/19/21 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_write_from_selection(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[]) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + assert(file); + assert(file->cls); + assert((mem_space_ids) || (count == 0)); + assert((file_space_ids) || (count == 0)); + assert((offsets) || (count == 0)); + assert((element_sizes) || (count == 0)); + assert((bufs) || (count == 0)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Call private function */ + /* (Note compensating for base address addition in internal routine) */ + if (H5FD_write_selection_id(SKIP_SELECTION_CB | SKIP_VECTOR_CB, 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_NOAPI(ret_value) + +} /* end H5FD_write_from_selection() */ + /*------------------------------------------------------------------------- * Function: H5FD_set_eoa * @@ -2136,6 +2349,97 @@ H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/) FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_driver_query() */ +/* + * Comparison routine used by qsort in H5FD__sort_io_req_real() + */ +static int +H5FD__vsrt_tmp_cmp(const void *element_1, const void *element_2) +{ + haddr_t addr_1 = ((const H5FD_vsrt_tmp_t *)element_1)->addr; + haddr_t addr_2 = ((const H5FD_vsrt_tmp_t *)element_2)->addr; + int ret_value = 0; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + assert(H5_addr_defined(addr_1)); + assert(H5_addr_defined(addr_2)); + + /* Compare the addresses */ + if (H5_addr_gt(addr_1, addr_2)) + ret_value = 1; + else if (H5_addr_lt(addr_1, addr_2)) + ret_value = -1; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5FD__vsrt_tmp_cmp() */ + +/* + * Common code used by: + * --H5FD_sort_vector_io_req () + * --H5FD_sort_selection_io_req() + * + */ +static herr_t +H5FD__sort_io_req_real(size_t count, haddr_t *addrs, hbool_t *was_sorted, struct H5FD_vsrt_tmp_t **srt_tmp) +{ + size_t i; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + + /* scan the offsets array to see if it is sorted */ + for (i = 1; i < count; i++) { + assert(H5_addr_defined(addrs[i - 1])); + + if (H5_addr_gt(addrs[i - 1], addrs[i])) + break; + else if (H5_addr_eq(addrs[i - 1], addrs[i])) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "duplicate addr in selections") + } + + /* if we traversed the entire array without breaking out, then + * the array was already sorted */ + if (i >= count) + *was_sorted = TRUE; + else + *was_sorted = FALSE; + + if (!(*was_sorted)) { + size_t srt_tmp_size; + + srt_tmp_size = (count * sizeof(struct H5FD_vsrt_tmp_t)); + + if (NULL == (*srt_tmp = (H5FD_vsrt_tmp_t *)malloc(srt_tmp_size))) + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't alloc srt_tmp") + + for (i = 0; i < count; i++) { + (*srt_tmp)[i].addr = addrs[i]; + (*srt_tmp)[i].index = i; + } + + /* sort the srt_tmp array */ + qsort(*srt_tmp, count, sizeof(struct H5FD_vsrt_tmp_t), H5FD__vsrt_tmp_cmp); + + /* verify no duplicate entries */ + i = 1; + + for (i = 1; i < count; i++) { + assert(H5_addr_lt((*srt_tmp)[i - 1].addr, (*srt_tmp)[i].addr)); + + if (H5_addr_eq(addrs[i - 1], addrs[i])) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "duplicate addrs in array") + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5FD__sort_io_req_real() */ + /*------------------------------------------------------------------------- * Function: H5FD_sort_vector_io_req * @@ -2167,29 +2471,6 @@ H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/) * *------------------------------------------------------------------------- */ - -static int -H5FD__vsrt_tmp_cmp(const void *element_1, const void *element_2) -{ - haddr_t addr_1 = ((const H5FD_vsrt_tmp_t *)element_1)->addr; - haddr_t addr_2 = ((const H5FD_vsrt_tmp_t *)element_2)->addr; - int ret_value = 0; /* Return value */ - - FUNC_ENTER_PACKAGE_NOERR - - /* Sanity checks */ - assert(H5_addr_defined(addr_1)); - assert(H5_addr_defined(addr_2)); - - /* Compare the addresses */ - if (H5_addr_gt(addr_1, addr_2)) - ret_value = 1; - else if (H5_addr_lt(addr_1, addr_2)) - ret_value = -1; - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD__vsrt_tmp_cmp() */ - 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, @@ -2222,22 +2503,8 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t assert((count == 0) || ((s_sizes_ptr) && (NULL == *s_sizes_ptr))); assert((count == 0) || ((s_bufs_ptr) && (NULL == *s_bufs_ptr))); - /* scan the addrs array to see if it is sorted */ - for (i = 1; i < count; i++) { - assert(H5_addr_defined(addrs[i - 1])); - - if (H5_addr_gt(addrs[i - 1], addrs[i])) - break; - else if (H5_addr_eq(addrs[i - 1], addrs[i])) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "duplicate addr in vector") - } - - /* if we traversed the entire array without breaking out, then - * the array was already sorted */ - if (i >= count) - *vector_was_sorted = TRUE; - else - *vector_was_sorted = FALSE; + if (H5FD__sort_io_req_real(count, addrs, vector_was_sorted, &srt_tmp) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sorting error in selection offsets") if (*vector_was_sorted) { @@ -2263,31 +2530,6 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t size_t j; size_t fixed_size_index = count; size_t fixed_type_index = count; - size_t srt_tmp_size; - - srt_tmp_size = (count * sizeof(struct H5FD_vsrt_tmp_t)); - - if (NULL == (srt_tmp = (H5FD_vsrt_tmp_t *)malloc(srt_tmp_size))) - - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't alloc srt_tmp") - - for (i = 0; i < count; i++) { - srt_tmp[i].addr = addrs[i]; - srt_tmp[i].index = i; - } - - /* sort the srt_tmp array */ - qsort(srt_tmp, count, sizeof(struct H5FD_vsrt_tmp_t), H5FD__vsrt_tmp_cmp); - - /* verify no duplicate entries */ - i = 1; - - for (i = 1; i < count; i++) { - assert(H5_addr_lt(srt_tmp[i - 1].addr, srt_tmp[i].addr)); - - if (H5_addr_eq(addrs[i - 1], addrs[i])) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "duplicate addr in vector") - } if ((NULL == (*s_types_ptr = (H5FD_mem_t *)malloc(count * sizeof(H5FD_mem_t)))) || (NULL == (*s_addrs_ptr = (haddr_t *)malloc(count * sizeof(haddr_t)))) || @@ -2376,6 +2618,166 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t } /* end H5FD_sort_vector_io_req() */ +/* + * This is derived from H5FD_sort_vector_io_req() + */ +herr_t +H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t mem_space_ids[], + hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], + H5_flexible_const_ptr_t bufs[], hid_t **s_mem_space_ids_ptr, + hid_t **s_file_space_ids_ptr, haddr_t **s_offsets_ptr, + size_t **s_element_sizes_ptr, H5_flexible_const_ptr_t **s_bufs_ptr) +{ + size_t count = (size_t)_count; + size_t i; + struct H5FD_vsrt_tmp_t *srt_tmp = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + + assert(selection_was_sorted); + + assert((mem_space_ids) || (count == 0)); + assert((file_space_ids) || (count == 0)); + assert((offsets) || (count == 0)); + assert((element_sizes) || (count == 0)); + assert((bufs) || (count == 0)); + + /* verify that the first elements of the element_sizes and bufs arrays are + * valid. + */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0].cvp != NULL)); + + assert((count == 0) || ((s_mem_space_ids_ptr) && (NULL == *s_mem_space_ids_ptr))); + assert((count == 0) || ((s_file_space_ids_ptr) && (NULL == *s_file_space_ids_ptr))); + assert((count == 0) || ((s_offsets_ptr) && (NULL == *s_offsets_ptr))); + assert((count == 0) || ((s_element_sizes_ptr) && (NULL == *s_element_sizes_ptr))); + assert((count == 0) || ((s_bufs_ptr) && (NULL == *s_bufs_ptr))); + + if (H5FD__sort_io_req_real(count, offsets, selection_was_sorted, &srt_tmp) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sorting error in selection offsets") + + if (*selection_was_sorted) { + + *s_mem_space_ids_ptr = mem_space_ids; + *s_file_space_ids_ptr = file_space_ids; + *s_offsets_ptr = offsets; + *s_element_sizes_ptr = element_sizes; + *s_bufs_ptr = bufs; + } + else { + + /* must sort the offsets array in increasing offset order, while + * maintaining the association between each offset, and the + * mem_space_ids[], file_space_ids[], element_sizes[], + * and bufs[] values at the same index. + * + * Do this by allocating an array of struct H5FD_ssrt_tmp_t, where + * each instance of H5FD_vsrt_tmp_t has two fields, offset and index. + * Load the array with the contents of the offsets array and + * the index of the associated entry. Sort the array, allocate + * the s_mem_space_ids_ptr, s_file_space_ids_ptr, s_offsets_ptr, + * s_element_sizes_ptr, and s_bufs_ptr + * arrays and populate them using the mapping provided by + * the sorted array of H5FD_ssrt_tmp_t. + */ + size_t j; + size_t fixed_element_sizes_index = count; + size_t fixed_bufs_index = count; + + if ((NULL == (*s_mem_space_ids_ptr = (hid_t *)malloc(count * sizeof(hid_t)))) || + (NULL == (*s_file_space_ids_ptr = (hid_t *)malloc(count * sizeof(hid_t)))) || + (NULL == (*s_offsets_ptr = (haddr_t *)malloc(count * sizeof(haddr_t)))) || + (NULL == (*s_element_sizes_ptr = (size_t *)malloc(count * sizeof(size_t)))) || + (NULL == + (*s_bufs_ptr = (H5_flexible_const_ptr_t *)malloc(count * sizeof(H5_flexible_const_ptr_t))))) { + + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't alloc sorted selection(s)") + } + + assert(element_sizes[0] != 0); + assert(bufs[0].cvp != NULL); + + /* Scan the element_sizes and bufs array to determine if the fixed + * element_sizes / bufs optimization is in use, and if so, to determine + * the index of the last valid value on each vector. + * We have already verified that the first + * elements of these arrays are valid so we can start at the second + * element (if it exists). + */ + for (i = 1; i < count && ((fixed_element_sizes_index == count) || (fixed_bufs_index == count)); i++) { + if ((fixed_element_sizes_index == count) && (element_sizes[i] == 0)) + fixed_element_sizes_index = i - 1; + if ((fixed_bufs_index == count) && (bufs[i].cvp == NULL)) + fixed_bufs_index = i - 1; + } + + assert(fixed_element_sizes_index <= count); + assert(fixed_bufs_index <= count); + + /* Populate the sorted arrays. Note that the index stored in srt_tmp + * refers to the index in the unsorted array, while the position of + * srt_tmp within the sorted array is the index in the sorted arrays */ + for (i = 0; i < count; i++) { + + j = srt_tmp[i].index; + + (*s_mem_space_ids_ptr)[i] = mem_space_ids[j]; + (*s_file_space_ids_ptr)[i] = file_space_ids[j]; + (*s_offsets_ptr)[i] = offsets[j]; + (*s_element_sizes_ptr)[i] = element_sizes[MIN(j, fixed_element_sizes_index)]; + (*s_bufs_ptr)[i] = bufs[MIN(j, fixed_bufs_index)]; + } + } + +done: + if (srt_tmp) { + free(srt_tmp); + srt_tmp = NULL; + } + + /* On failure, free the sorted arrays if they were allocated. + * Note that we only allocate these arrays if the original array + * was not sorted -- thus we check both for failure, and for + * the flag indicating that the original array was not sorted + * in increasing address order. + */ + if ((ret_value != SUCCEED) && (!(*selection_was_sorted))) { + + /* free space allocated for sorted arrays */ + if (*s_mem_space_ids_ptr) { + free(*s_mem_space_ids_ptr); + *s_mem_space_ids_ptr = NULL; + } + + if (*s_file_space_ids_ptr) { + free(*s_file_space_ids_ptr); + *s_file_space_ids_ptr = NULL; + } + + if (*s_offsets_ptr) { + free(*s_offsets_ptr); + *s_offsets_ptr = NULL; + } + + if (*s_element_sizes_ptr) { + free(*s_element_sizes_ptr); + *s_element_sizes_ptr = NULL; + } + + if (*s_bufs_ptr) { + free(*s_bufs_ptr); + *s_bufs_ptr = NULL; + } + } + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD_sort_selection_io_req() */ + /*------------------------------------------------------------------------- * Function: H5FD_delete * diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index b72b8927721..9d42b301163 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -88,6 +88,15 @@ static herr_t H5FD__mpio_read_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_i static herr_t H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[]); + +static herr_t H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, + uint32_t count, hid_t mem_space_ids[], hid_t file_space_ids[], + haddr_t offsets[], size_t element_sizes[], void *bufs[]); + +static herr_t H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED 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[]); + static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id); @@ -101,6 +110,13 @@ static herr_t H5FD__mpio_vector_build_types( MPI_Offset *mpi_off, H5_flexible_const_ptr_t *mpi_bufs_base, int *size_i, MPI_Datatype *buf_type, hbool_t *buf_type_created, MPI_Datatype *file_type, hbool_t *file_type_created, char *unused); +static herr_t H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexible_const_ptr_t mbb, + H5S_t **file_spaces, H5S_t **mem_spaces, + haddr_t offsets[], H5_flexible_const_ptr_t bufs[], + size_t src_element_sizes[], size_t dst_element_sizes[], + MPI_Datatype *final_ftype, hbool_t *final_ftype_is_derived, + MPI_Datatype *final_mtype, hbool_t *final_mtype_is_derived); + /* The MPIO file driver information */ static const H5FD_class_t H5FD_mpio_g = { H5FD_CLASS_VERSION, /* struct version */ @@ -134,8 +150,8 @@ static const H5FD_class_t H5FD_mpio_g = { H5FD__mpio_write, /* write */ H5FD__mpio_read_vector, /* read_vector */ H5FD__mpio_write_vector, /* write_vector */ - NULL, /* read_selection */ - NULL, /* write_selection */ + H5FD__mpio_read_selection, /* read_selection */ + H5FD__mpio_write_selection, /* write_selection */ H5FD__mpio_flush, /* flush */ H5FD__mpio_truncate, /* truncate */ NULL, /* lock */ @@ -2714,6 +2730,931 @@ H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t co FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__mpio_write_vector() */ +/*------------------------------------------------------------------------- + * Function: H5FD__selection_build_types + * + * Purpose: ?? + * (derived from H5D__link_piece_collective_io() in src/H5Dmpio.c) + * (also reference H5FD__mpio_vector_build_types() in src/H5FDmpio.c) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexible_const_ptr_t mbb, + H5S_t **file_spaces, H5S_t **mem_spaces, + haddr_t offsets[], H5_flexible_const_ptr_t bufs[], + size_t src_element_sizes[], size_t dst_element_sizes[], + MPI_Datatype *final_ftype, hbool_t *final_ftype_is_derived, + MPI_Datatype *final_mtype, hbool_t *final_mtype_is_derived) +{ + + MPI_Datatype *piece_mtype = NULL; + MPI_Datatype *piece_ftype = NULL; + MPI_Aint *piece_file_disp_array = NULL; + MPI_Aint *piece_mem_disp_array = NULL; + hbool_t *piece_mft_is_derived_array = + NULL; /* Flags to indicate each piece's MPI file datatype is derived */ + ; + hbool_t *piece_mmt_is_derived_array = + NULL; /* Flags to indicate each piece's MPI memory datatype is derived */ + int *piece_mpi_file_counts = NULL; /* Count of MPI file datatype for each piece */ + int *piece_mpi_mem_counts = NULL; /* Count of MPI memory datatype for each piece */ + + haddr_t base_file_addr; + size_t i; /* Local index variable */ + int mpi_code; /* MPI return code */ + + hbool_t extend_src_sizes = FALSE; + hbool_t extend_dst_sizes = FALSE; + hbool_t extend_bufs = FALSE; + H5_flexible_const_ptr_t buf; + size_t src_element_size, dst_element_size; + + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Allocate information for num_pieces */ + if (NULL == (piece_mtype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory datatype buffer") + if (NULL == (piece_ftype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file datatype buffer") + if (NULL == (piece_file_disp_array = (MPI_Aint *)H5MM_malloc(num_pieces * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file displacement buffer") + if (NULL == (piece_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_pieces * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, + "couldn't allocate piece memory displacement buffer") + if (NULL == (piece_mpi_mem_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory counts buffer") + if (NULL == (piece_mpi_file_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file counts buffer") + if (NULL == (piece_mmt_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, + "couldn't allocate piece memory is derived datatype flags buffer") + if (NULL == (piece_mft_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, + "couldn't allocate piece file is derived datatype flags buffer") + + /* save lowest file address */ + base_file_addr = offsets[0]; + + /* Obtain MPI derived datatype from all individual pieces */ + /* Iterate over selected pieces for this process */ + for (i = 0; i < num_pieces; i++) { + hsize_t *permute_map = NULL; /* array that holds the mapping from the old, + out-of-order displacements to the in-order + displacements of the MPI datatypes of the + point selection of the file space */ + hbool_t is_permuted = FALSE; + + if (!extend_src_sizes) { + if (src_element_sizes[i] == 0) { + extend_src_sizes = TRUE; + src_element_size = src_element_sizes[i - 1]; + } + else + src_element_size = src_element_sizes[i]; + } + + if (!extend_dst_sizes) { + if (dst_element_sizes[i] == 0) { + extend_dst_sizes = TRUE; + dst_element_size = dst_element_sizes[i - 1]; + } + else + dst_element_size = src_element_sizes[i]; + } + + if (!extend_bufs) { + if (bufs[i].cvp == NULL) { + extend_bufs = TRUE; + buf = bufs[i - 1]; + } + else + buf = bufs[i]; + } + + /* Obtain disk and memory MPI derived datatype */ + /* NOTE: The permute_map array can be allocated within H5S_mpio_space_type + * and will be fed into the next call to H5S_mpio_space_type + * where it will be freed. + */ + if (H5S_mpio_space_type(file_spaces[i], src_element_size, + &piece_ftype[i], /* OUT: datatype created */ + &piece_mpi_file_counts[i], /* OUT */ + &(piece_mft_is_derived_array[i]), /* OUT */ + TRUE, /* this is a file space, + so permute the + datatype if the point + selections are out of + order */ + &permute_map, /* OUT: a map to indicate the + permutation of points + selected in case they + are out of order */ + &is_permuted /* OUT */) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type") + + /* Sanity check */ + if (is_permuted) + assert(permute_map); + + if (H5S_mpio_space_type(mem_spaces[i], dst_element_size, &piece_mtype[i], + &piece_mpi_mem_counts[i], &(piece_mmt_is_derived_array[i]), + FALSE, /* this is a memory + space, so if the file + space is not + permuted, there is no + need to permute the + datatype if the point + selections are out of + order*/ + &permute_map, /* IN: the permutation map + generated by the + file_space selection + and applied to the + memory selection */ + &is_permuted /* IN */) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type") + + /* Sanity check */ + if (is_permuted) + assert(!permute_map); + + /* Piece address relative to the first piece addr + * Assign piece address to MPI displacement + * (assume MPI_Aint big enough to hold it) */ + piece_file_disp_array[i] = (MPI_Aint)offsets[i] - (MPI_Aint)base_file_addr; + + if (io_op_write) { + piece_mem_disp_array[i] = (MPI_Aint)buf.cvp - (MPI_Aint)mbb.cvp; + } + else { + piece_mem_disp_array[i] = (MPI_Aint)buf.vp - (MPI_Aint)mbb.vp; + } + } /* end for */ + + /* Create final MPI derived datatype for the file */ + if (MPI_SUCCESS != + (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_file_counts, piece_file_disp_array, + piece_ftype, final_ftype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_ftype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + *final_ftype_is_derived = TRUE; + + /* Create final MPI derived datatype for memory */ + if (MPI_SUCCESS != + (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_mem_counts, piece_mem_disp_array, + piece_mtype, final_mtype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_mtype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + *final_mtype_is_derived = TRUE; + + /* Free the file & memory MPI datatypes for each piece */ + for (i = 0; i < num_pieces; i++) { + if (piece_mmt_is_derived_array[i]) + if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_mtype + i))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + + if (piece_mft_is_derived_array[i]) + if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_ftype + i))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + } /* end for */ + +done: + + /* Release resources */ + if (piece_mtype) + H5MM_xfree(piece_mtype); + if (piece_ftype) + H5MM_xfree(piece_ftype); + if (piece_file_disp_array) + H5MM_xfree(piece_file_disp_array); + if (piece_mem_disp_array) + H5MM_xfree(piece_mem_disp_array); + if (piece_mpi_mem_counts) + H5MM_xfree(piece_mpi_mem_counts); + if (piece_mpi_file_counts) + H5MM_xfree(piece_mpi_file_counts); + if (piece_mmt_is_derived_array) + H5MM_xfree(piece_mmt_is_derived_array); + if (piece_mft_is_derived_array) + H5MM_xfree(piece_mft_is_derived_array); + + FUNC_LEAVE_NOAPI(ret_value); + +} /* H5FD__selection_build_types() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__mpio_read_selection + * + * Purpose: ???Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID using potentially complex file and buffer types to + * effect the transfer. + * + * Reading past the end of the MPI file returns zeros instead of + * failing. MPI is able to coalesce requests from different + * processes (collective or independent). + * + * Return: Success: SUCCEED. Result is stored in caller-supplied + * buffer BUF. + * + * Failure: FAIL. Contents of buffer BUF are undefined. + * + * Programmer: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED 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 */) +{ + H5FD_mpio_t *file = (H5FD_mpio_t *)_file; + MPI_Offset mpi_off; + MPI_Status mpi_stat; /* Status from I/O operation */ + int size_i; /* Integer copy of 'size' to read */ + + H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode */ + H5FD_mpio_collective_opt_t coll_opt_mode; + + MPI_Datatype final_mtype; /* Final memory MPI datatype for all pieces with selection */ + hbool_t final_mtype_is_derived = FALSE; + + MPI_Datatype final_ftype; /* Final file MPI datatype for all pieces with selection */ + hbool_t final_ftype_is_derived = FALSE; + + hid_t *s_mem_space_ids = NULL; + hid_t *s_file_space_ids = NULL; + haddr_t *s_offsets = NULL; + size_t *s_element_sizes = NULL; + H5_flexible_const_ptr_t *s_bufs = NULL; + hbool_t selection_was_sorted = TRUE; + + uint32_t i, j; + H5S_t **s_mem_spaces = NULL; + H5S_t **s_file_spaces = NULL; + haddr_t tmp_offset = 0; + void *mpi_bufs_base = NULL; + char unused = 0; /* Unused, except for non-NULL pointer value */ + +#if H5_CHECK_MPI_VERSION(3, 0) + MPI_Count bytes_read = 0; /* Number of bytes read in */ + MPI_Count type_size; /* MPI datatype used for I/O's size */ + MPI_Count io_size; /* Actual number of bytes requested */ + MPI_Count n; +#else + int bytes_read = 0; /* Number of bytes read in */ + int type_size; /* MPI datatype used for I/O's size */ + int io_size; /* Actual number of bytes requested */ + int n; +#endif + hbool_t rank0_bcast = FALSE; /* If read-with-rank0-and-bcast flag was used */ +#ifdef H5FDmpio_DEBUG + hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file)); + hbool_t H5FD_mpio_debug_r_flag = (H5FD_mpio_debug_flags_s[(int)'r'] && H5FD_MPIO_TRACE_THIS_RANK(file)); +#endif + int mpi_code; /* MPI return code */ + herr_t ret_value = SUCCEED; + H5_flexible_const_ptr_t mbb; + + FUNC_ENTER_PACKAGE + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_t_flag) + fprintf(stderr, "%s: (%d) Entering\n", __func__, file->mpi_rank); +#endif + + /* Sanity checks */ + assert(file); + assert(H5FD_MPIO == file->pub.driver_id); + assert((count == 0) || (mem_space_ids)); + assert((count == 0) || (file_space_ids)); + assert((count == 0) || (offsets)); + assert((count == 0) || (element_sizes)); + assert((count == 0) || (bufs)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Portably initialize MPI status variable */ + memset(&mpi_stat, 0, sizeof(MPI_Status)); + + if (count) { + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, + element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, + &s_file_space_ids, &s_offsets, &s_element_sizes, + &s_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); + + tmp_offset = s_offsets[0]; + } + + /* some numeric conversions */ + if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + + /* I remove the check and if/else for H5FD_MEM_DRAW */ + + /* Get the transfer mode from the API context */ + if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") + + /* + * Set up for a fancy xfer using complex types, or single byte block. We + * wouldn't need to rely on the use_view field if MPI semantics allowed + * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which + * could mean "use MPI_BYTE" by convention). + */ + if (xfer_mode == H5FD_MPIO_COLLECTIVE) { + + if (count) { + if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") + if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "memory allocation failed for memory space list") + + for (i = 0; i < count; i++) { + if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve memory dataspace from ID") + if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve file dataspace from ID") + } + + /* when we setup mpi_bufs[] below, all addresses are offsets from + * mpi_bufs_base. + * + * Since these offsets must all be positive, we must scan through + * s_bufs[] to find the smallest value, and choose that for + * mpi_bufs_base. + */ + j = 0; /* guess at the index of the smallest value of s_bufs[] */ + + if (s_bufs[j + 1].vp != NULL) { + for (i = 1; i < count; i++) + if (s_bufs[i].vp < s_bufs[j].vp) + j = i; + } + + mpi_bufs_base = s_bufs[j].vp; + mbb.vp = mpi_bufs_base; + + if (H5FD__selection_build_types( + FALSE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, + s_element_sizes, s_element_sizes, &final_ftype, &final_ftype_is_derived, &final_mtype, + &final_mtype_is_derived) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't build type for MPI-IO"); + + /* We have a single, complicated MPI datatype for both memory & file */ + size_i = 1; + + } else { + + /* No chunks selected for this process */ + size_i = 0; + + mpi_bufs_base = &unused; + + /* Set the MPI datatype */ + final_ftype = MPI_BYTE; + final_mtype = MPI_BYTE; + } + + /* + * Set the file view when we are using MPI derived types + */ + if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, mpi_off, MPI_BYTE, final_ftype, + H5FD_mpi_native_g, file->info))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + + /* When using types, use the address as the displacement for + * MPI_File_set_view and reset the address for the read to zero + */ + /* Reset mpi_off to 0 since the view now starts at the data offset */ + if (H5FD_mpi_haddr_to_MPIOff((haddr_t)0, &mpi_off) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0") + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) using MPIO collective mode\n", __func__, file->mpi_rank); +#endif + /* Get the collective_opt property to check whether the application wants to do IO individually. */ + if (H5CX_get_mpio_coll_opt(&coll_opt_mode) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property") + + if (coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO) { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) doing MPI collective IO\n", __func__, file->mpi_rank); +#endif + /* Check whether we should read from rank 0 and broadcast to other ranks */ + if (H5CX_get_mpio_rank0_bcast()) { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) doing read-rank0-and-MPI_Bcast\n", __func__, file->mpi_rank); +#endif + /* Indicate path we've taken */ + rank0_bcast = TRUE; + + /* Read on rank 0 Bcast to other ranks */ + if (file->mpi_rank == 0) { + /* If MPI_File_read_at fails, push an error, but continue + * to participate in following MPI_Bcast */ + if (MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, mpi_bufs_base, size_i, + final_mtype, &mpi_stat))) + HMPI_DONE_ERROR(FAIL, "MPI_File_read_at failed", mpi_code) + } + + if (MPI_SUCCESS != (mpi_code = MPI_Bcast(mpi_bufs_base, size_i, final_mtype, 0, file->comm))) + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code) + } /* end if */ + else + /* Perform collective read operation */ + if (MPI_SUCCESS != (mpi_code = MPI_File_read_at_all(file->f, mpi_off, mpi_bufs_base, size_i, + final_mtype, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at_all failed", mpi_code) + } /* end if */ + else { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank); +#endif + + /* Perform independent read operation */ + if (MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, mpi_bufs_base, size_i, + final_mtype, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code) + } /* end else */ + + /* + * Reset the file view when we used MPI derived types + */ + if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, + H5FD_mpi_native_g, file->info))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + + /* Only retrieve bytes read if this rank _actually_ participated in I/O */ + if (!rank0_bcast || (rank0_bcast && file->mpi_rank == 0)) { + /* How many bytes were actually read? */ +#if H5_CHECK_MPI_VERSION(3, 0) + if (MPI_SUCCESS != (mpi_code = MPI_Get_elements_x(&mpi_stat, final_mtype, &bytes_read))) { +#else + if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&mpi_stat, MPI_BYTE, &bytes_read))) { +#endif + if (rank0_bcast && file->mpi_rank == 0) { + /* If MPI_Get_elements(_x) fails for a rank 0 bcast strategy, + * push an error, but continue to participate in the following + * MPI_Bcast. + */ + bytes_read = -1; + HMPI_DONE_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + } + else + HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + } + } /* end if */ + + /* If the rank0-bcast feature was used, broadcast the # of bytes read to + * other ranks, which didn't perform any I/O. + */ + /* NOTE: This could be optimized further to be combined with the broadcast + * of the data. (QAK - 2019/1/2) + */ + if (rank0_bcast) +#if H5_CHECK_MPI_VERSION(3, 0) + if (MPI_SUCCESS != MPI_Bcast(&bytes_read, 1, MPI_COUNT, 0, file->comm)) +#else + if (MPI_SUCCESS != MPI_Bcast(&bytes_read, 1, MPI_INT, 0, file->comm)) +#endif + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", 0) + + /* Get the type's size */ +#if H5_CHECK_MPI_VERSION(3, 0) + if (MPI_SUCCESS != (mpi_code = MPI_Type_size_x(final_mtype, &type_size))) +#else + if (MPI_SUCCESS != (mpi_code = MPI_Type_size(final_mtype, &type_size))) +#endif + HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code) + + /* Compute the actual number of bytes requested */ + io_size = type_size * size_i; + + /* Check for read failure */ + if (bytes_read < 0 || bytes_read > io_size) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) mpi_off = %ld bytes_read = %lld type = %s\n", __func__, + file->mpi_rank, (long)mpi_off, (long long)bytes_read, H5FD__mem_t_to_str(type)); +#endif + + /* + * This gives us zeroes beyond end of physical MPI file. + */ + if ((n = (io_size - bytes_read)) > 0) + memset((char *)bufs[0] + bytes_read, 0, (size_t)n); + + } /* end if */ + else { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_r_flag) + fprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank); +#endif + if (_file->base_addr > 0) { + /* Undo base address addition in internal routines before passing down to the mpio driver */ + for (i = 0; i < count; i++) { + assert(offsets[i] >= _file->base_addr); + offsets[i] -= _file->base_addr; + } + } + + if (H5FD_read_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, + element_sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read vector from selection failed") + } + +done: + /* Free the MPI buf and file types, if they were derived */ + if (final_mtype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_mtype))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + if (final_ftype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_ftype))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + + /* Cleanup dataspace arrays */ + if (s_mem_spaces) + s_mem_spaces = H5MM_xfree(s_mem_spaces); + if (s_file_spaces) + s_file_spaces = H5MM_xfree(s_file_spaces); + + if (!selection_was_sorted) { + free(s_mem_space_ids); + s_mem_space_ids = NULL; + free(s_file_space_ids); + s_file_space_ids = NULL; + free(s_offsets); + s_offsets = NULL; + free(s_element_sizes); + s_element_sizes = NULL; + free(s_bufs); + s_bufs = NULL; + } + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_t_flag) + fprintf(stderr, "%s: (%d) Leaving\n", __func__, file->mpi_rank); +#endif + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__mpio_read_selection() */ + + +/*------------------------------------------------------------------------- + * Function: H5FD__mpio_write_selection + * + * Purpose: ???Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID using potentially complex file and buffer types to + * effect the transfer. + * + * MPI is able to coalesce requests from different processes + * (collective and independent). + * + * Return: Success: SUCCEED. USE_TYPES and OLD_USE_TYPES in the + * access params are altered. + * Failure: FAIL. USE_TYPES and OLD_USE_TYPES in the + * access params may be altered. + * + * Programmer: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED 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[]) +{ + H5FD_mpio_t *file = (H5FD_mpio_t *)_file; + MPI_Offset mpi_off; + MPI_Offset save_mpi_off; /* Use at the end of the routine for setting local_eof */ + MPI_Status mpi_stat; /* Status from I/O operation */ + + int size_i; + H5FD_mpio_xfer_t xfer_mode; /* I/O transfer mode */ + H5FD_mpio_collective_opt_t coll_opt_mode; + + MPI_Datatype final_mtype; /* Final memory MPI datatype for all pieces with selection */ + hbool_t final_mtype_is_derived = FALSE; + + MPI_Datatype final_ftype; /* Final file MPI datatype for all pieces with selection */ + hbool_t final_ftype_is_derived = FALSE; + + hid_t *s_mem_space_ids = NULL; + hid_t *s_file_space_ids = NULL; + haddr_t *s_offsets = NULL; + size_t *s_element_sizes = NULL; + H5_flexible_const_ptr_t *s_bufs = NULL; + hbool_t selection_was_sorted = TRUE; + const void *mpi_bufs_base = NULL; + + uint32_t i, j; + H5S_t **s_mem_spaces = NULL; + H5S_t **s_file_spaces = NULL; + haddr_t tmp_offset = 0; + char unused = 0; /* Unused, except for non-NULL pointer value */ +H5_flexible_const_ptr_t mbb; + + +#if H5_CHECK_MPI_VERSION(3, 0) + MPI_Count bytes_written; + MPI_Count type_size; /* MPI datatype used for I/O's size */ + MPI_Count io_size; /* Actual number of bytes requested */ +#else + int bytes_written; + int type_size; /* MPI datatype used for I/O's size */ + int io_size; /* Actual number of bytes requested */ +#endif + +#ifdef H5FDmpio_DEBUG + hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file)); + hbool_t H5FD_mpio_debug_w_flag = (H5FD_mpio_debug_flags_s[(int)'w'] && H5FD_MPIO_TRACE_THIS_RANK(file)); +#endif + int mpi_code; /* MPI return code */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_t_flag) + fprintf(stderr, "%s: (%d) Entering: count=%u\n", __func__, file->mpi_rank, count); +#endif + + /* Sanity checks */ + assert(file); + assert(H5FD_MPIO == file->pub.driver_id); + assert((count == 0) || (mem_space_ids)); + assert((count == 0) || (file_space_ids)); + assert((count == 0) || (offsets)); + assert((count == 0) || (element_sizes)); + assert((count == 0) || (bufs)); + + /* Verify that the first elements of the element_sizes and bufs arrays are + * valid. */ + assert((count == 0) || (element_sizes[0] != 0)); + assert((count == 0) || (bufs[0] != NULL)); + + /* Verify that no data is written when between MPI_Barrier()s during file flush */ + assert(!H5CX_get_mpi_file_flushing()); + + /* Portably initialize MPI status variable */ + memset(&mpi_stat, 0, sizeof(MPI_Status)); + + if (count) { + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, + element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, + &s_file_space_ids, &s_offsets, &s_element_sizes, + &s_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); + + tmp_offset = s_offsets[0]; + } + + /* some numeric conversions */ + if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + + /* To be used at the end of the routine for setting local_eof */ + save_mpi_off = mpi_off; + + /* Get the transfer mode from the API context */ + if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") + + /* + * Set up for a fancy xfer using complex types, or single byte block. We + * wouldn't need to rely on the use_view field if MPI semantics allowed + * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which + * could mean "use MPI_BYTE" by convention). + */ + if (xfer_mode == H5FD_MPIO_COLLECTIVE) { + + if (count) { + if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") + if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "memory allocation failed for memory space list") + + for (i = 0; i < count; i++) { + if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve file dataspace from ID") + if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve memory dataspace from ID") + } + + /* when we setup mpi_bufs[] below, all addresses are offsets from + * mpi_bufs_base. + * + * Since these offsets must all be positive, we must scan through + * s_bufs[] to find the smallest value, and choose that for + * mpi_bufs_base. + */ + j = 0; /* guess at the index of the smallest value of s_bufs[] */ + + if (s_bufs[j + 1].cvp != NULL) { + for (i = 1; i < count; i++) + if (s_bufs[i].cvp < s_bufs[j].cvp) + j = i; + } + + mpi_bufs_base = s_bufs[j].cvp; + mbb.cvp = mpi_bufs_base; + + if (H5FD__selection_build_types( + TRUE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, + s_element_sizes, s_element_sizes, &final_ftype, &final_ftype_is_derived, &final_mtype, + &final_mtype_is_derived) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't build type for MPI-IO"); + + /* We have a single, complicated MPI datatype for both memory & file */ + size_i = 1; + + } else { + + /* No chunks selected for this process */ + size_i = 0; + + mpi_bufs_base = &unused; + + /* Set the MPI datatype */ + final_ftype = MPI_BYTE; + final_mtype = MPI_BYTE; + + } + + /* + * Set the file view when we are using MPI derived types + */ + if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, mpi_off, MPI_BYTE, final_ftype, + H5FD_mpi_native_g, file->info))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + + /* Reset mpi_off to 0 since the view now starts at the data offset */ + if (H5FD_mpi_haddr_to_MPIOff((haddr_t)0, &mpi_off) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0") + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_w_flag) + fprintf(stderr, "%s: (%d) using MPIO collective mode\n", __func__, file->mpi_rank); +#endif + + /* Get the collective_opt property to check whether the application wants to do IO individually. */ + if (H5CX_get_mpio_coll_opt(&coll_opt_mode) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property") + + if (coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO) { + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_w_flag) + fprintf(stderr, "%s: (%d) doing MPI collective IO\n", __func__, file->mpi_rank); +#endif + + /* Perform collective write operation */ + if (MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(file->f, mpi_off, mpi_bufs_base, size_i, + final_mtype, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) + + /* Do MPI_File_sync when needed by underlying ROMIO driver */ + if (file->mpi_file_sync_required) { + if (MPI_SUCCESS != (mpi_code = MPI_File_sync(file->f))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code) + } + } + else { + /* I remove the check for H5FD_MEM_DRAW: Do I need that? */ + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_w_flag) + fprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank); +#endif + /* Perform independent write operation */ + if (MPI_SUCCESS != (mpi_code = MPI_File_write_at(file->f, mpi_off, mpi_bufs_base, size_i, + final_mtype, &mpi_stat))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at failed", mpi_code) + } /* end else */ + + /* Reset the file view when we used MPI derived types */ + if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, + H5FD_mpi_native_g, file->info))) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + + /* How many bytes were actually written */ +#if H5_CHECK_MPI_VERSION(3, 0) + if (MPI_SUCCESS != (mpi_code = MPI_Get_elements_x(&mpi_stat, final_mtype, &bytes_written))) +#else + if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&mpi_stat, MPI_BYTE, &bytes_written))) +#endif + HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + + /* Get the type's size */ +#if H5_CHECK_MPI_VERSION(3, 0) + if (MPI_SUCCESS != (mpi_code = MPI_Type_size_x(final_mtype, &type_size))) +#else + if (MPI_SUCCESS != (mpi_code = MPI_Type_size(final_mtype, &type_size))) +#endif + HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code) + + /* Compute the actual number of bytes requested */ + io_size = type_size * size_i; + + /* Check for write failure */ + if (bytes_written != io_size || bytes_written < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_w_flag) + fprintf(stderr, "%s: (%d) mpi_off = %ld bytes_written = %lld type = %s\n", __func__, + file->mpi_rank, (long)mpi_off, (long long)bytes_written, H5FD__mem_t_to_str(type)); +#endif + + /* Each process will keep track of its perceived EOF value locally, and + * ultimately we will reduce this value to the maximum amongst all + * processes, but until then keep the actual eof at HADDR_UNDEF just in + * case something bad happens before that point. (rather have a value + * we know is wrong sitting around rather than one that could only + * potentially be wrong.) */ + file->eof = HADDR_UNDEF; + + if (bytes_written && (((haddr_t)bytes_written + (haddr_t)save_mpi_off) > file->local_eof)) + file->local_eof = (haddr_t)save_mpi_off + (haddr_t)bytes_written; + } + else { /* Not H5FD_MPIO_COLLECTIVE */ + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_w_flag) + fprintf(stderr, "%s: (%d) doing MPI independent IO\n", __func__, file->mpi_rank); +#endif + if (_file->base_addr > 0) { + /* Undo base address addition in internal routines before passing down to the mpio driver */ + for (i = 0; i < count; i++) { + assert(offsets[i] >= _file->base_addr); + offsets[i] -= _file->base_addr; + } + } + + if (H5FD_write_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, + element_sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write vector from selection failed") + } + +done: + /* Free the MPI buf and file types, if they were derived */ + if (final_mtype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_mtype))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + if (final_ftype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_ftype))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + + /* Cleanup dataspace arrays */ + if (s_mem_spaces) + s_mem_spaces = H5MM_xfree(s_mem_spaces); + if (s_file_spaces) + s_file_spaces = H5MM_xfree(s_file_spaces); + + if (!selection_was_sorted) { + free(s_mem_space_ids); + s_mem_space_ids = NULL; + free(s_file_space_ids); + s_file_space_ids = NULL; + free(s_offsets); + s_offsets = NULL; + free(s_element_sizes); + s_element_sizes = NULL; + free(s_bufs); + s_bufs = NULL; + } + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_debug_t_flag) + fprintf(stderr, "%s: (%d) Leaving: ret_value = %d\n", __func__, file->mpi_rank, ret_value); +#endif + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__mpio_write_selection() */ + /*------------------------------------------------------------------------- * Function: H5FD__mpio_flush * diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index c4ccfdd6f9d..6015d66ca81 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -77,6 +77,11 @@ typedef struct { } \ } +#define SKIP_NO_CB 0x00u +#define SKIP_SELECTION_CB 0x01u +#define SKIP_VECTOR_CB 0x02u + + /* Define structure to hold driver ID, info & configuration string for FAPLs */ typedef struct { hid_t driver_id; /* Driver's ID */ @@ -149,12 +154,27 @@ H5_DLL herr_t H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count 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[], +H5_DLL herr_t H5FD_read_selection_id(uint32_t skip_cb, 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(uint32_t skip_cb, 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_read_vector_from_selection(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[]); + +H5_DLL herr_t H5FD_write_vector_from_selection(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_read_from_selection(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[]); + void *bufs[]); + +H5_DLL herr_t H5FD_write_from_selection(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); @@ -171,6 +191,13 @@ H5_DLL herr_t H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t count 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_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, + hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], + size_t element_sizes[], H5_flexible_const_ptr_t bufs[], + hid_t **s_mem_space_ids, hid_t **s_file_space_ids, + haddr_t **s_offsets_ptr, size_t **s_element_sizes_ptr, + H5_flexible_const_ptr_t **s_bufs_ptr); H5_DLL herr_t H5FD_init(void); /* Function prototypes for MPI based VFDs*/ From 45e0709ddca70f329654886e119a27930ac8717c Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Jul 2023 20:51:17 +0000 Subject: [PATCH 02/19] Committing clang-format changes --- src/H5FD.c | 9 +- src/H5FDdevelop.h | 6 +- src/H5FDint.c | 32 +-- src/H5FDmpio.c | 499 +++++++++++++++++++++++----------------------- src/H5FDprivate.h | 21 +- 5 files changed, 281 insertions(+), 286 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 6b5236875b7..cb1709eae39 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1723,8 +1723,8 @@ H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, /* Call private function */ /* (Note compensating for base address addition in internal routine) */ - if (H5FD_read_selection_id(SKIP_NO_CB, file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes, - bufs) < 0) + if (H5FD_read_selection_id(SKIP_NO_CB, 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: @@ -1820,8 +1820,8 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count /* Call private function */ /* (Note compensating for base address addition in internal routine) */ - if (H5FD_write_selection_id(SKIP_NO_CB, file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes, - bufs) < 0) + if (H5FD_write_selection_id(SKIP_NO_CB, 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: @@ -2081,7 +2081,6 @@ H5FDwrite_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t FUNC_LEAVE_API(ret_value) } /* end H5FDwrite_from_selection() */ - /*------------------------------------------------------------------------- * Function: H5FDflush * diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index d923edc7be5..be99a3261d9 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -199,9 +199,9 @@ typedef struct H5FD_class_t { herr_t (*read_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*/); - herr_t (*write_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[] /*in*/); + herr_t (*write_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[] /*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); diff --git a/src/H5FDint.c b/src/H5FDint.c index fca60bad673..e5dfb1329d6 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -109,14 +109,14 @@ typedef struct H5FD_get_driver_ud_t { /* Local Prototypes */ /********************/ static int H5FD__get_driver_cb(void *obj, hid_t id, void *_op_data); -static herr_t H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, - hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, - H5S_t **file_spaces, haddr_t offsets[], - size_t element_sizes[], void *bufs[] /* out */); -static herr_t H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, - hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, - H5S_t **file_spaces, haddr_t offsets[], - size_t element_sizes[], const void *bufs[]); +static herr_t H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, + hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, + H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], + void *bufs[] /* out */); +static herr_t H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, + hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, + H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], + const void *bufs[]); /*********************/ /* Package Variables */ @@ -750,7 +750,7 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr *------------------------------------------------------------------------- */ static herr_t -H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, +H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */) { @@ -1190,7 +1190,7 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s /* Otherwise, implement the selection read as a sequence of regular * or vector read calls. */ - if (H5FD__read_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, + if (H5FD__read_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed") @@ -1354,7 +1354,7 @@ H5FD_read_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t } /* Translate to vector or scalar I/O */ - if (H5FD__read_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, + if (H5FD__read_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed") } @@ -1396,7 +1396,7 @@ H5FD_read_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t *------------------------------------------------------------------------- */ static herr_t -H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, +H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, H5S_t **mem_spaces, H5S_t **file_spaces, haddr_t offsets[], size_t element_sizes[], const void *bufs[]) { @@ -1828,7 +1828,7 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ /* Otherwise, implement the selection write as a sequence of regular * or vector write calls. */ - if (H5FD__write_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, + if (H5FD__write_selection_translate(SKIP_NO_CB, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed") @@ -1876,8 +1876,8 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ *------------------------------------------------------------------------- */ herr_t -H5FD_write_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t count, - hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], +H5FD_write_selection_id(uint32_t skip_cb, 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[]) { hbool_t offsets_cooked = FALSE; @@ -1984,7 +1984,7 @@ H5FD_write_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_ } /* Translate to vector or scalar I/O */ - if (H5FD__write_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, + if (H5FD__write_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed") } diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 9d42b301163..0506c6ab945 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -97,11 +97,11 @@ static herr_t H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H uint32_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], const void *bufs[]); -static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); -static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); -static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id); -static herr_t H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, - void **output); +static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); +static herr_t H5FD__mpio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); +static herr_t H5FD__mpio_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); /* Other functions */ static herr_t H5FD__mpio_vector_build_types( @@ -110,55 +110,56 @@ static herr_t H5FD__mpio_vector_build_types( MPI_Offset *mpi_off, H5_flexible_const_ptr_t *mpi_bufs_base, int *size_i, MPI_Datatype *buf_type, hbool_t *buf_type_created, MPI_Datatype *file_type, hbool_t *file_type_created, char *unused); -static herr_t H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexible_const_ptr_t mbb, - H5S_t **file_spaces, H5S_t **mem_spaces, - haddr_t offsets[], H5_flexible_const_ptr_t bufs[], - size_t src_element_sizes[], size_t dst_element_sizes[], - MPI_Datatype *final_ftype, hbool_t *final_ftype_is_derived, - MPI_Datatype *final_mtype, hbool_t *final_mtype_is_derived); +static herr_t H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, + H5_flexible_const_ptr_t mbb, H5S_t **file_spaces, + H5S_t **mem_spaces, haddr_t offsets[], + H5_flexible_const_ptr_t bufs[], size_t src_element_sizes[], + size_t dst_element_sizes[], MPI_Datatype *final_ftype, + hbool_t *final_ftype_is_derived, MPI_Datatype *final_mtype, + hbool_t *final_mtype_is_derived); /* The MPIO file driver information */ static const H5FD_class_t H5FD_mpio_g = { - H5FD_CLASS_VERSION, /* struct version */ - H5_VFD_MPIO, /* value */ - "mpio", /* name */ - HADDR_MAX, /* maxaddr */ - H5F_CLOSE_SEMI, /* fc_degree */ - H5FD__mpio_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__mpio_open, /* open */ - H5FD__mpio_close, /* close */ - NULL, /* cmp */ - H5FD__mpio_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__mpio_get_eoa, /* get_eoa */ - H5FD__mpio_set_eoa, /* set_eoa */ - H5FD__mpio_get_eof, /* get_eof */ - H5FD__mpio_get_handle, /* get_handle */ - H5FD__mpio_read, /* read */ - H5FD__mpio_write, /* write */ - H5FD__mpio_read_vector, /* read_vector */ - H5FD__mpio_write_vector, /* write_vector */ + H5FD_CLASS_VERSION, /* struct version */ + H5_VFD_MPIO, /* value */ + "mpio", /* name */ + HADDR_MAX, /* maxaddr */ + H5F_CLOSE_SEMI, /* fc_degree */ + H5FD__mpio_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__mpio_open, /* open */ + H5FD__mpio_close, /* close */ + NULL, /* cmp */ + H5FD__mpio_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__mpio_get_eoa, /* get_eoa */ + H5FD__mpio_set_eoa, /* set_eoa */ + H5FD__mpio_get_eof, /* get_eof */ + H5FD__mpio_get_handle, /* get_handle */ + H5FD__mpio_read, /* read */ + H5FD__mpio_write, /* write */ + H5FD__mpio_read_vector, /* read_vector */ + H5FD__mpio_write_vector, /* write_vector */ H5FD__mpio_read_selection, /* read_selection */ H5FD__mpio_write_selection, /* write_selection */ - H5FD__mpio_flush, /* flush */ - H5FD__mpio_truncate, /* truncate */ - NULL, /* lock */ - NULL, /* unlock */ - H5FD__mpio_delete, /* del */ - H5FD__mpio_ctl, /* ctl */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ + H5FD__mpio_flush, /* flush */ + H5FD__mpio_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD__mpio_delete, /* del */ + H5FD__mpio_ctl, /* ctl */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; #ifdef H5FDmpio_DEBUG @@ -2745,11 +2746,11 @@ H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t co */ static herr_t H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexible_const_ptr_t mbb, - H5S_t **file_spaces, H5S_t **mem_spaces, - haddr_t offsets[], H5_flexible_const_ptr_t bufs[], - size_t src_element_sizes[], size_t dst_element_sizes[], - MPI_Datatype *final_ftype, hbool_t *final_ftype_is_derived, - MPI_Datatype *final_mtype, hbool_t *final_mtype_is_derived) + H5S_t **file_spaces, H5S_t **mem_spaces, haddr_t offsets[], + H5_flexible_const_ptr_t bufs[], size_t src_element_sizes[], + size_t dst_element_sizes[], MPI_Datatype *final_ftype, + hbool_t *final_ftype_is_derived, MPI_Datatype *final_mtype, + hbool_t *final_mtype_is_derived) { MPI_Datatype *piece_mtype = NULL; @@ -2765,7 +2766,7 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl int *piece_mpi_mem_counts = NULL; /* Count of MPI memory datatype for each piece */ haddr_t base_file_addr; - size_t i; /* Local index variable */ + size_t i; /* Local index variable */ int mpi_code; /* MPI return code */ hbool_t extend_src_sizes = FALSE; @@ -2778,156 +2779,151 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl FUNC_ENTER_PACKAGE - /* Allocate information for num_pieces */ - if (NULL == (piece_mtype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory datatype buffer") - if (NULL == (piece_ftype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file datatype buffer") - if (NULL == (piece_file_disp_array = (MPI_Aint *)H5MM_malloc(num_pieces * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file displacement buffer") - if (NULL == (piece_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_pieces * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, - "couldn't allocate piece memory displacement buffer") - if (NULL == (piece_mpi_mem_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory counts buffer") - if (NULL == (piece_mpi_file_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file counts buffer") - if (NULL == (piece_mmt_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, - "couldn't allocate piece memory is derived datatype flags buffer") - if (NULL == (piece_mft_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, - "couldn't allocate piece file is derived datatype flags buffer") - - /* save lowest file address */ - base_file_addr = offsets[0]; - - /* Obtain MPI derived datatype from all individual pieces */ - /* Iterate over selected pieces for this process */ - for (i = 0; i < num_pieces; i++) { - hsize_t *permute_map = NULL; /* array that holds the mapping from the old, - out-of-order displacements to the in-order - displacements of the MPI datatypes of the - point selection of the file space */ - hbool_t is_permuted = FALSE; - - if (!extend_src_sizes) { - if (src_element_sizes[i] == 0) { - extend_src_sizes = TRUE; - src_element_size = src_element_sizes[i - 1]; - } - else - src_element_size = src_element_sizes[i]; + /* Allocate information for num_pieces */ + if (NULL == (piece_mtype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory datatype buffer") + if (NULL == (piece_ftype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file datatype buffer") + if (NULL == (piece_file_disp_array = (MPI_Aint *)H5MM_malloc(num_pieces * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file displacement buffer") + if (NULL == (piece_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_pieces * sizeof(MPI_Aint)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory displacement buffer") + if (NULL == (piece_mpi_mem_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory counts buffer") + if (NULL == (piece_mpi_file_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file counts buffer") + if (NULL == (piece_mmt_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, + "couldn't allocate piece memory is derived datatype flags buffer") + if (NULL == (piece_mft_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, + "couldn't allocate piece file is derived datatype flags buffer") + + /* save lowest file address */ + base_file_addr = offsets[0]; + + /* Obtain MPI derived datatype from all individual pieces */ + /* Iterate over selected pieces for this process */ + for (i = 0; i < num_pieces; i++) { + hsize_t *permute_map = NULL; /* array that holds the mapping from the old, + out-of-order displacements to the in-order + displacements of the MPI datatypes of the + point selection of the file space */ + hbool_t is_permuted = FALSE; + + if (!extend_src_sizes) { + if (src_element_sizes[i] == 0) { + extend_src_sizes = TRUE; + src_element_size = src_element_sizes[i - 1]; } + else + src_element_size = src_element_sizes[i]; + } - if (!extend_dst_sizes) { - if (dst_element_sizes[i] == 0) { - extend_dst_sizes = TRUE; - dst_element_size = dst_element_sizes[i - 1]; - } - else - dst_element_size = src_element_sizes[i]; + if (!extend_dst_sizes) { + if (dst_element_sizes[i] == 0) { + extend_dst_sizes = TRUE; + dst_element_size = dst_element_sizes[i - 1]; } + else + dst_element_size = src_element_sizes[i]; + } - if (!extend_bufs) { - if (bufs[i].cvp == NULL) { - extend_bufs = TRUE; - buf = bufs[i - 1]; - } - else - buf = bufs[i]; + if (!extend_bufs) { + if (bufs[i].cvp == NULL) { + extend_bufs = TRUE; + buf = bufs[i - 1]; } + else + buf = bufs[i]; + } - /* Obtain disk and memory MPI derived datatype */ - /* NOTE: The permute_map array can be allocated within H5S_mpio_space_type - * and will be fed into the next call to H5S_mpio_space_type - * where it will be freed. - */ - if (H5S_mpio_space_type(file_spaces[i], src_element_size, - &piece_ftype[i], /* OUT: datatype created */ - &piece_mpi_file_counts[i], /* OUT */ - &(piece_mft_is_derived_array[i]), /* OUT */ - TRUE, /* this is a file space, - so permute the - datatype if the point - selections are out of - order */ - &permute_map, /* OUT: a map to indicate the - permutation of points - selected in case they - are out of order */ - &is_permuted /* OUT */) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type") - - /* Sanity check */ - if (is_permuted) - assert(permute_map); - - if (H5S_mpio_space_type(mem_spaces[i], dst_element_size, &piece_mtype[i], - &piece_mpi_mem_counts[i], &(piece_mmt_is_derived_array[i]), - FALSE, /* this is a memory - space, so if the file - space is not - permuted, there is no - need to permute the - datatype if the point - selections are out of - order*/ - &permute_map, /* IN: the permutation map - generated by the - file_space selection - and applied to the - memory selection */ - &is_permuted /* IN */) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type") - - /* Sanity check */ - if (is_permuted) - assert(!permute_map); - - /* Piece address relative to the first piece addr - * Assign piece address to MPI displacement - * (assume MPI_Aint big enough to hold it) */ - piece_file_disp_array[i] = (MPI_Aint)offsets[i] - (MPI_Aint)base_file_addr; - - if (io_op_write) { - piece_mem_disp_array[i] = (MPI_Aint)buf.cvp - (MPI_Aint)mbb.cvp; - } - else { - piece_mem_disp_array[i] = (MPI_Aint)buf.vp - (MPI_Aint)mbb.vp; - } - } /* end for */ - - /* Create final MPI derived datatype for the file */ - if (MPI_SUCCESS != - (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_file_counts, piece_file_disp_array, - piece_ftype, final_ftype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - - if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_ftype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - *final_ftype_is_derived = TRUE; - - /* Create final MPI derived datatype for memory */ - if (MPI_SUCCESS != - (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_mem_counts, piece_mem_disp_array, - piece_mtype, final_mtype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) - - if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_mtype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) - *final_mtype_is_derived = TRUE; - - /* Free the file & memory MPI datatypes for each piece */ - for (i = 0; i < num_pieces; i++) { - if (piece_mmt_is_derived_array[i]) - if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_mtype + i))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) - - if (piece_mft_is_derived_array[i]) - if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_ftype + i))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) - } /* end for */ + /* Obtain disk and memory MPI derived datatype */ + /* NOTE: The permute_map array can be allocated within H5S_mpio_space_type + * and will be fed into the next call to H5S_mpio_space_type + * where it will be freed. + */ + if (H5S_mpio_space_type(file_spaces[i], src_element_size, &piece_ftype[i], /* OUT: datatype created */ + &piece_mpi_file_counts[i], /* OUT */ + &(piece_mft_is_derived_array[i]), /* OUT */ + TRUE, /* this is a file space, + so permute the + datatype if the point + selections are out of + order */ + &permute_map, /* OUT: a map to indicate the + permutation of points + selected in case they + are out of order */ + &is_permuted /* OUT */) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type") + + /* Sanity check */ + if (is_permuted) + assert(permute_map); + + if (H5S_mpio_space_type(mem_spaces[i], dst_element_size, &piece_mtype[i], &piece_mpi_mem_counts[i], + &(piece_mmt_is_derived_array[i]), FALSE, /* this is a memory + space, so if the file + space is not + permuted, there is no + need to permute the + datatype if the point + selections are out of + order*/ + &permute_map, /* IN: the permutation map + generated by the + file_space selection + and applied to the + memory selection */ + &is_permuted /* IN */) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type") + + /* Sanity check */ + if (is_permuted) + assert(!permute_map); + + /* Piece address relative to the first piece addr + * Assign piece address to MPI displacement + * (assume MPI_Aint big enough to hold it) */ + piece_file_disp_array[i] = (MPI_Aint)offsets[i] - (MPI_Aint)base_file_addr; + + if (io_op_write) { + piece_mem_disp_array[i] = (MPI_Aint)buf.cvp - (MPI_Aint)mbb.cvp; + } + else { + piece_mem_disp_array[i] = (MPI_Aint)buf.vp - (MPI_Aint)mbb.vp; + } + } /* end for */ + + /* Create final MPI derived datatype for the file */ + if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_file_counts, + piece_file_disp_array, piece_ftype, final_ftype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_ftype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + *final_ftype_is_derived = TRUE; + + /* Create final MPI derived datatype for memory */ + if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_mem_counts, + piece_mem_disp_array, piece_mtype, final_mtype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + + if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_mtype))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + *final_mtype_is_derived = TRUE; + + /* Free the file & memory MPI datatypes for each piece */ + for (i = 0; i < num_pieces; i++) { + if (piece_mmt_is_derived_array[i]) + if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_mtype + i))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + + if (piece_mft_is_derived_array[i]) + if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_ftype + i))) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + } /* end for */ done: @@ -2993,19 +2989,19 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d MPI_Datatype final_ftype; /* Final file MPI datatype for all pieces with selection */ hbool_t final_ftype_is_derived = FALSE; - hid_t *s_mem_space_ids = NULL; - hid_t *s_file_space_ids = NULL; - haddr_t *s_offsets = NULL; - size_t *s_element_sizes = NULL; - H5_flexible_const_ptr_t *s_bufs = NULL; - hbool_t selection_was_sorted = TRUE; + hid_t *s_mem_space_ids = NULL; + hid_t *s_file_space_ids = NULL; + haddr_t *s_offsets = NULL; + size_t *s_element_sizes = NULL; + H5_flexible_const_ptr_t *s_bufs = NULL; + hbool_t selection_was_sorted = TRUE; uint32_t i, j; H5S_t **s_mem_spaces = NULL; H5S_t **s_file_spaces = NULL; - haddr_t tmp_offset = 0; + haddr_t tmp_offset = 0; void *mpi_bufs_base = NULL; - char unused = 0; /* Unused, except for non-NULL pointer value */ + char unused = 0; /* Unused, except for non-NULL pointer value */ #if H5_CHECK_MPI_VERSION(3, 0) MPI_Count bytes_read = 0; /* Number of bytes read in */ @@ -3023,8 +3019,8 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file)); hbool_t H5FD_mpio_debug_r_flag = (H5FD_mpio_debug_flags_s[(int)'r'] && H5FD_MPIO_TRACE_THIS_RANK(file)); #endif - int mpi_code; /* MPI return code */ - herr_t ret_value = SUCCEED; + int mpi_code; /* MPI return code */ + herr_t ret_value = SUCCEED; H5_flexible_const_ptr_t mbb; FUNC_ENTER_PACKAGE @@ -3054,8 +3050,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d if (count) { if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, - &s_bufs) < 0) + &s_file_space_ids, &s_offsets, &s_element_sizes, &s_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); tmp_offset = s_offsets[0]; @@ -3088,9 +3083,12 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d for (i = 0; i < count; i++) { if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) - HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve memory dataspace from ID") - if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) - HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve file dataspace from ID") + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, + "can't retrieve memory dataspace from ID") + if (NULL == + (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, + "can't retrieve file dataspace from ID") } /* when we setup mpi_bufs[] below, all addresses are offsets from @@ -3109,23 +3107,23 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d } mpi_bufs_base = s_bufs[j].vp; - mbb.vp = mpi_bufs_base; + mbb.vp = mpi_bufs_base; - if (H5FD__selection_build_types( - FALSE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, - s_element_sizes, s_element_sizes, &final_ftype, &final_ftype_is_derived, &final_mtype, - &final_mtype_is_derived) < 0) + if (H5FD__selection_build_types(FALSE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, + s_element_sizes, s_element_sizes, &final_ftype, + &final_ftype_is_derived, &final_mtype, + &final_mtype_is_derived) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't build type for MPI-IO"); /* We have a single, complicated MPI datatype for both memory & file */ size_i = 1; - - } else { + } + else { /* No chunks selected for this process */ size_i = 0; - mpi_bufs_base = &unused; + mpi_bufs_base = &unused; /* Set the MPI datatype */ final_ftype = MPI_BYTE; @@ -3321,7 +3319,6 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d } /* end H5FD__mpio_read_selection() */ - /*------------------------------------------------------------------------- * Function: H5FD__mpio_write_selection * @@ -3362,21 +3359,20 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED MPI_Datatype final_ftype; /* Final file MPI datatype for all pieces with selection */ hbool_t final_ftype_is_derived = FALSE; - hid_t *s_mem_space_ids = NULL; - hid_t *s_file_space_ids = NULL; - haddr_t *s_offsets = NULL; - size_t *s_element_sizes = NULL; - H5_flexible_const_ptr_t *s_bufs = NULL; - hbool_t selection_was_sorted = TRUE; - const void *mpi_bufs_base = NULL; - - uint32_t i, j; - H5S_t **s_mem_spaces = NULL; - H5S_t **s_file_spaces = NULL; - haddr_t tmp_offset = 0; - char unused = 0; /* Unused, except for non-NULL pointer value */ -H5_flexible_const_ptr_t mbb; - + hid_t *s_mem_space_ids = NULL; + hid_t *s_file_space_ids = NULL; + haddr_t *s_offsets = NULL; + size_t *s_element_sizes = NULL; + H5_flexible_const_ptr_t *s_bufs = NULL; + hbool_t selection_was_sorted = TRUE; + const void *mpi_bufs_base = NULL; + + uint32_t i, j; + H5S_t **s_mem_spaces = NULL; + H5S_t **s_file_spaces = NULL; + haddr_t tmp_offset = 0; + char unused = 0; /* Unused, except for non-NULL pointer value */ + H5_flexible_const_ptr_t mbb; #if H5_CHECK_MPI_VERSION(3, 0) MPI_Count bytes_written; @@ -3425,8 +3421,7 @@ H5_flexible_const_ptr_t mbb; if (count) { if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, - &s_bufs) < 0) + &s_file_space_ids, &s_offsets, &s_element_sizes, &s_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); tmp_offset = s_offsets[0]; @@ -3459,10 +3454,13 @@ H5_flexible_const_ptr_t mbb; "memory allocation failed for memory space list") for (i = 0; i < count; i++) { - if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) - HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve file dataspace from ID") + if (NULL == + (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, + "can't retrieve file dataspace from ID") if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) - HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, "can't retrieve memory dataspace from ID") + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, + "can't retrieve memory dataspace from ID") } /* when we setup mpi_bufs[] below, all addresses are offsets from @@ -3481,18 +3479,18 @@ H5_flexible_const_ptr_t mbb; } mpi_bufs_base = s_bufs[j].cvp; - mbb.cvp = mpi_bufs_base; + mbb.cvp = mpi_bufs_base; - if (H5FD__selection_build_types( - TRUE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, - s_element_sizes, s_element_sizes, &final_ftype, &final_ftype_is_derived, &final_mtype, - &final_mtype_is_derived) < 0) + if (H5FD__selection_build_types(TRUE, count, mbb, s_file_spaces, s_mem_spaces, s_offsets, s_bufs, + s_element_sizes, s_element_sizes, &final_ftype, + &final_ftype_is_derived, &final_mtype, + &final_mtype_is_derived) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't build type for MPI-IO"); /* We have a single, complicated MPI datatype for both memory & file */ size_i = 1; - - } else { + } + else { /* No chunks selected for this process */ size_i = 0; @@ -3502,7 +3500,6 @@ H5_flexible_const_ptr_t mbb; /* Set the MPI datatype */ final_ftype = MPI_BYTE; final_mtype = MPI_BYTE; - } /* diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 6015d66ca81..debc5d69897 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -81,7 +81,6 @@ typedef struct { #define SKIP_SELECTION_CB 0x01u #define SKIP_VECTOR_CB 0x02u - /* Define structure to hold driver ID, info & configuration string for FAPLs */ typedef struct { hid_t driver_id; /* Driver's ID */ @@ -154,15 +153,15 @@ H5_DLL herr_t H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count 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(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t count, - hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], +H5_DLL herr_t H5FD_read_selection_id(uint32_t skip_cb, 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(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t count, - hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], +H5_DLL herr_t H5FD_write_selection_id(uint32_t skip_cb, 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_read_vector_from_selection(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[]); +H5_DLL herr_t H5FD_read_vector_from_selection(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[]); H5_DLL herr_t H5FD_write_vector_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t mem_space_ids[], hid_t file_space_ids[], @@ -172,9 +171,9 @@ H5_DLL herr_t H5FD_read_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t c hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], void *bufs[]); -H5_DLL herr_t H5FD_write_from_selection(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_write_from_selection(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); From a8c0351bfd9500e93e03687f34179a707da01670 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Thu, 6 Jul 2023 12:19:49 -0500 Subject: [PATCH 03/19] Add comments for the changes. Minor modifications to the mpio driver for selection I/O. --- src/H5FD.c | 168 +++++++++++++++++++++++++++++++++++++++++---- src/H5FDint.c | 182 ++++++++++++++++++++++++++++++++++--------------- src/H5FDmpio.c | 137 ++++++++++++++++++------------------- 3 files changed, 347 insertions(+), 140 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index cb1709eae39..5d2c2fe9f8d 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1828,9 +1828,46 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count FUNC_LEAVE_API(ret_value) } /* end H5FDwrite_selection() */ -/* - * Translate selections to vector CB if possible, if not, scalar CB - * --skip selection CB +/*------------------------------------------------------------------------- + * Purpose: This is similar to H5FDread_selection() with the + * exception noted below. + * + * 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. + * + * Note: + * It will skip selection read call whether the underlying VFD + * supports selection reads or not. + * + * It will translate the selection read to a vector read call + * if vector reads are supported, or a series of scalar read + * calls otherwise. + * + * 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. + * + *------------------------------------------------------------------------- */ herr_t H5FDread_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, @@ -1891,9 +1928,44 @@ H5FDread_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uin FUNC_LEAVE_API(ret_value) } /* end H5FDread_vector_from_selection() */ -/* - * Translate selections to vector CB if possible, if not, scalar CB - * --skip selection CB +/*------------------------------------------------------------------------- + * Purpose: This is similar to H5FDwrite_selection() with the + * exception noted below. + * + * 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. + * + * Note: + * It will skip selection write call whether the underlying VFD + * supports selection writes or not. + * + * It will translate the selection write to a vector write call + * if vector writes are supported, or a series of scalar write + * calls otherwise. + * + * 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. + * + *------------------------------------------------------------------------- */ herr_t H5FDwrite_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, @@ -1954,10 +2026,45 @@ H5FDwrite_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui FUNC_LEAVE_API(ret_value) } /* end H5FDwrite_vector_from_selection() */ -/* - * Translate selections to scalar CB - * --skip selection CB - * --skip vector CB +/*------------------------------------------------------------------------- + * Purpose: This is similar to H5FDread_selection() with the + * exception noted below. + * + * 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. + * + * Note: + * It will skip selection and vector read calls whether the underlying + * VFD supports selection and vector reads or not. + * + * It will translate the selection read to a series of + * scalar read calls. + * + * 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. + * + *------------------------------------------------------------------------- */ herr_t H5FDread_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[], @@ -2017,10 +2124,43 @@ H5FDread_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t c FUNC_LEAVE_API(ret_value) } /* end H5FDread_from_selection() */ -/* - * Translate selections to scalar CB - * --skip selection CB - * --skip vector CB +/*------------------------------------------------------------------------- + * Purpose: This is similar to H5FDwrite_selection() with the + * exception noted below. + * + * 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. + * + * Note: + * It will skip selection and vector write calls whether the underlying + * VFD supports selection and vector writes or not. + * + * It will translate the selection write to a series of + * scalar write calls. + * + * 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. + * + *------------------------------------------------------------------------- */ herr_t H5FDwrite_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[], diff --git a/src/H5FDint.c b/src/H5FDint.c index e5dfb1329d6..6ef40d5612d 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -62,17 +62,17 @@ /************************************************************************* * - * H5FD_vsrt_tmp_t + * H5FD_srt_tmp_t * - * Structure used to store vector I/O request addresses and the associated + * Structure used to store I/O request addresses and the associated * indexes in the addrs[] array for the purpose of determine the sorted * order. * - * This is done by allocating an array of H5FD_vsrt_tmp_t of length + * This is done by allocating an array of H5FD_srt_tmp_t of length * count, loading it with the contents of the addrs[] array and the * associated indices, and then sorting it. * - * This sorted array of H5FD_vsrt_tmp_t is then used to populate sorted + * This sorted array of H5FD_srt_tmp_t is then used to populate sorted * versions of the types[], addrs[], sizes[] and bufs[] vectors. * * addr: haddr_t containing the value of addrs[i], @@ -82,10 +82,10 @@ * *************************************************************************/ -typedef struct H5FD_vsrt_tmp_t { +typedef struct H5FD_srt_tmp_t { haddr_t addr; size_t index; -} H5FD_vsrt_tmp_t; +} H5FD_srt_tmp_t; /* Information needed for iterating over the registered VFD hid_t IDs. * The name or value of the new VFD that is being registered is stored @@ -736,8 +736,8 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr * Function: H5FD__read_selection_translate * * Purpose: Translates a selection read call to a vector read call if - * vector reads are supported, or a series of scalar read - * calls otherwise. + * vector reads are supported and !skip_vector_cb, + * or a series of scalar read calls otherwise. * * Return: Success: SUCCEED * All reads have completed successfully, and @@ -1064,8 +1064,8 @@ H5FD__read_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_t * If the underlying VFD supports selection reads, pass the * call through directly. * - * If it doesn't, convert the vector read into a sequence - * of individual reads. + * If it doesn't, convert the selection read into a sequence + * of vector or scalar reads. * * Return: Success: SUCCEED * All reads have completed successfully, and @@ -1229,6 +1229,15 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s * Purpose: Like H5FD_read_selection(), but takes hid_t arrays instead * of H5S_t * arrays for the dataspaces. * + * Depending on the parameter skip_cb which is translated into + * skip_selection_cb and skip_vector_cb: + * + * --If the underlying VFD supports selection reads and !skip_selection_cb, + * pass the call through directly. + * + * --If it doesn't, convert the selection reads into a sequence of vector or + * scalar reads depending on skip_vector_cb. + * * Return: Success: SUCCEED * All reads have completed successfully, and * the results havce been into the supplied @@ -1384,8 +1393,8 @@ H5FD_read_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t * Function: H5FD__write_selection_translate * * Purpose: Translates a selection write call to a vector write call - * if vector writes are supported, or a series of scalar - * write calls otherwise. + * if vector writes are supported and !skip_vector_cb, + * or a series of scalar write calls otherwise. * * Return: Success: SUCCEED * All writes have completed successfully. @@ -1710,8 +1719,8 @@ H5FD__write_selection_translate(uint32_t skip_vector_cb, H5FD_t *file, H5FD_mem_ * If the underlying VFD supports selection writes, pass the * call through directly. * - * If it doesn't, convert the vector write into a sequence - * of individual writes. + * If it doesn't, convert the selection write into a sequence + * of vector or scalar writes. * * Return: Success: SUCCEED * All writes have completed successfully. @@ -1867,6 +1876,15 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ * Purpose: Like H5FD_write_selection(), but takes hid_t arrays * instead of H5S_t * arrays for the dataspaces. * + * Depending on the parameter skip_cb which is translated into + * skip_selection_cb and skip_vector_cb: + * + * --If the underlying VFD supports selection writes and !skip_selection_cb, + * pass the call through directly. + * + * --If it doesn't, convert the selection writes into a sequence of vector or + * scalar reads depending on skip_vector_cb. + * * Return: Success: SUCCEED * All writes have completed successfully. * @@ -2015,6 +2033,10 @@ H5FD_write_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_ * * Purpose: Internal routine for H5FDread_vector_from_selection() * + * It will translate the selection read to a vector read call + * if vector reads are supported, or a series of scalar read + * calls otherwise. + * * Return: Success: SUCCEED * All writes have completed successfully. * @@ -2064,6 +2086,9 @@ H5FD_read_vector_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, h * * Purpose: Internal routine for H5FDwrite_vector_from_selection() * + * It will translate the selection write to a vector write call + * if vector writes are supported, or a series of scalar write + * calls otherwise. * * Return: Success: SUCCEED * All writes have completed successfully. @@ -2114,6 +2139,8 @@ H5FD_write_vector_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, * * Purpose: Internal routine for H5FDread_from_selection() * + * It will translate the selection read to a series of + * scalar read calls. * * Return: Success: SUCCEED * All writes have completed successfully. @@ -2164,6 +2191,8 @@ H5FD_read_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t me * * Purpose: Internal routine for H5FDwrite_from_selection() * + * It will translate the selection write to a series of + * scalar write calls. * * Return: Success: SUCCEED * All writes have completed successfully. @@ -2349,14 +2378,19 @@ H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags /*out*/) FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_driver_query() */ -/* - * Comparison routine used by qsort in H5FD__sort_io_req_real() +/*------------------------------------------------------------------------ + * Function: H5FD__vstr_tmp_cmp() + * + * Purpose: This is the comparison callback function used by qsort() + * in H5FD__sort_io_req_real( ) + * + *------------------------------------------------------------------------- */ static int -H5FD__vsrt_tmp_cmp(const void *element_1, const void *element_2) +H5FD__srt_tmp_cmp(const void *element_1, const void *element_2) { - haddr_t addr_1 = ((const H5FD_vsrt_tmp_t *)element_1)->addr; - haddr_t addr_2 = ((const H5FD_vsrt_tmp_t *)element_2)->addr; + haddr_t addr_1 = ((const H5FD_srt_tmp_t *)element_1)->addr; + haddr_t addr_2 = ((const H5FD_srt_tmp_t *)element_2)->addr; int ret_value = 0; /* Return value */ FUNC_ENTER_PACKAGE_NOERR @@ -2372,16 +2406,33 @@ H5FD__vsrt_tmp_cmp(const void *element_1, const void *element_2) ret_value = -1; FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD__vsrt_tmp_cmp() */ +} /* H5FD__srt_tmp_cmp() */ -/* - * Common code used by: - * --H5FD_sort_vector_io_req () - * --H5FD_sort_selection_io_req() +/*------------------------------------------------------------------------- + * Function: H5FD__sort_io_req_real() + * + * Purpose: Scan the addrs array to see if it is sorted. + * + * If sorted, return TRUE in *was_sorted. + * + * If not sorted, use qsort() to sort the array. + * Do this by allocating an array of struct H5FD_srt_tmp_t, + * where each instance of H5FD_srt_tmp_t has two fields, + * addr and index. Load the array with the contents of the + * addrs array and the index of the associated entry. + * Then sort the array using qsort(). + * Return *FALSE in was_sorted. * + * This is a common routine used by: + * --H5FD_sort_vector_io_req () + * --H5FD_sort_selection_io_req() + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- */ static herr_t -H5FD__sort_io_req_real(size_t count, haddr_t *addrs, hbool_t *was_sorted, struct H5FD_vsrt_tmp_t **srt_tmp) +H5FD__sort_io_req_real(size_t count, haddr_t *addrs, hbool_t *was_sorted, struct H5FD_srt_tmp_t **srt_tmp) { size_t i; herr_t ret_value = SUCCEED; /* Return value */ @@ -2410,9 +2461,9 @@ H5FD__sort_io_req_real(size_t count, haddr_t *addrs, hbool_t *was_sorted, struct if (!(*was_sorted)) { size_t srt_tmp_size; - srt_tmp_size = (count * sizeof(struct H5FD_vsrt_tmp_t)); + srt_tmp_size = (count * sizeof(struct H5FD_srt_tmp_t)); - if (NULL == (*srt_tmp = (H5FD_vsrt_tmp_t *)malloc(srt_tmp_size))) + if (NULL == (*srt_tmp = (H5FD_srt_tmp_t *)malloc(srt_tmp_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't alloc srt_tmp") @@ -2422,7 +2473,7 @@ H5FD__sort_io_req_real(size_t count, haddr_t *addrs, hbool_t *was_sorted, struct } /* sort the srt_tmp array */ - qsort(*srt_tmp, count, sizeof(struct H5FD_vsrt_tmp_t), H5FD__vsrt_tmp_cmp); + qsort(*srt_tmp, count, sizeof(struct H5FD_srt_tmp_t), H5FD__srt_tmp_cmp); /* verify no duplicate entries */ i = 1; @@ -2479,7 +2530,7 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t herr_t ret_value = SUCCEED; /* Return value */ size_t count = (size_t)_count; size_t i; - struct H5FD_vsrt_tmp_t *srt_tmp = NULL; + struct H5FD_srt_tmp_t *srt_tmp = NULL; FUNC_ENTER_NOAPI(FAIL) @@ -2503,6 +2554,10 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t assert((count == 0) || ((s_sizes_ptr) && (NULL == *s_sizes_ptr))); assert((count == 0) || ((s_bufs_ptr) && (NULL == *s_bufs_ptr))); + /* Sort the addrs array in increasing addr order, while + * maintaining the association between each addr, and the + * sizes[], types[], and bufs[] values at the same index. + */ if (H5FD__sort_io_req_real(count, addrs, vector_was_sorted, &srt_tmp) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sorting error in selection offsets") @@ -2515,17 +2570,10 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t } else { - /* must sort the addrs array in increasing addr order, while - * maintaining the association between each addr, and the - * sizes[], types[], and bufs[] values at the same index. - * - * Do this by allocating an array of struct H5FD_vsrt_tmp_t, where - * each instance of H5FD_vsrt_tmp_t has two fields, addr and index. - * Load the array with the contents of the addrs array and - * the index of the associated entry. Sort the array, allocate - * the s_types_ptr, s_addrs_ptr, s_sizes_ptr, and s_bufs_ptr + /* + * Allocate the s_types_ptr, s_addrs_ptr, s_sizes_ptr, and s_bufs_ptr * arrays and populate them using the mapping provided by - * the sorted array of H5FD_vsrt_tmp_t. + * the sorted array of H5FD_srt_tmp_t. */ size_t j; size_t fixed_size_index = count; @@ -2618,8 +2666,34 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t } /* end H5FD_sort_vector_io_req() */ -/* - * This is derived from H5FD_sort_vector_io_req() +/*------------------------------------------------------------------------- + * Purpose: Determine whether the supplied selection I/O request is + * sorted. + * + * if is is, set *selection_was_sorted to TRUE, set: + * + * *s_mem_space_ids_ptr = mem_space_ids; + * *s_file_space_ids_ptr = file_space_ids; + * *s_offsets_ptr = offsets; + * *s_element_sizes_ptr = element_sizes; + * *s_bufs_ptr = bufs; + * + * and return. + * + * If it is not sorted, duplicate the mem_space_ids, file_space_ids, + * offsets, element_sizes and bufs arrays, storing the base + * addresses of the new arrays in *s_mem_space_ids_ptr, + * s_file_space_ids_ptr, s_offsets_ptr, *s_element_sizes_ptr, + * and s_bufs_ptr respectively. Determine the sorted order + * of the selection I/O request, and load it into the new + * selections in sorted order. + * + * Note that in this case, it is the callers responsibility + * to free the sorted vectors. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- */ herr_t H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t mem_space_ids[], @@ -2630,7 +2704,7 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t { size_t count = (size_t)_count; size_t i; - struct H5FD_vsrt_tmp_t *srt_tmp = NULL; + struct H5FD_srt_tmp_t *srt_tmp = NULL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2657,6 +2731,11 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t assert((count == 0) || ((s_element_sizes_ptr) && (NULL == *s_element_sizes_ptr))); assert((count == 0) || ((s_bufs_ptr) && (NULL == *s_bufs_ptr))); + /* Sort the offsets array in increasing offet order, while + * maintaining the association between each offset, and the + * mem_space_ids[], file_space_ids[], element_sizes and bufs[] + * values at the same index. + */ if (H5FD__sort_io_req_real(count, offsets, selection_was_sorted, &srt_tmp) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sorting error in selection offsets") @@ -2670,19 +2749,10 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t } else { - /* must sort the offsets array in increasing offset order, while - * maintaining the association between each offset, and the - * mem_space_ids[], file_space_ids[], element_sizes[], - * and bufs[] values at the same index. - * - * Do this by allocating an array of struct H5FD_ssrt_tmp_t, where - * each instance of H5FD_vsrt_tmp_t has two fields, offset and index. - * Load the array with the contents of the offsets array and - * the index of the associated entry. Sort the array, allocate - * the s_mem_space_ids_ptr, s_file_space_ids_ptr, s_offsets_ptr, - * s_element_sizes_ptr, and s_bufs_ptr - * arrays and populate them using the mapping provided by - * the sorted array of H5FD_ssrt_tmp_t. + /* + * Allocate the s_mem_space_ids_ptr, s_file_space_ids_ptr, s_offsets_ptr, + * s_element_sizes_ptr and s_bufs_ptr arrays and populate them using the + * mapping provided by the sorted array of H5FD_srt_tmp_t. */ size_t j; size_t fixed_element_sizes_index = count; @@ -2703,7 +2773,7 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t /* Scan the element_sizes and bufs array to determine if the fixed * element_sizes / bufs optimization is in use, and if so, to determine - * the index of the last valid value on each vector. + * the index of the last valid value on each array. * We have already verified that the first * elements of these arrays are valid so we can start at the second * element (if it exists). diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 0506c6ab945..0bb392338f9 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -2734,13 +2734,13 @@ H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t co /*------------------------------------------------------------------------- * Function: H5FD__selection_build_types * - * Purpose: ?? - * (derived from H5D__link_piece_collective_io() in src/H5Dmpio.c) - * (also reference H5FD__mpio_vector_build_types() in src/H5FDmpio.c) + * Purpose: Build MPI derived datatype for each piece and then + * build MPI final derived datatype for file and memory. * - * Return: Non-negative on success/Negative on failure + * Note: This is derived from H5D__link_piece_collective_io() in + * src/H5Dmpio.c. * - * Programmer: + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -2952,21 +2952,24 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl /*------------------------------------------------------------------------- * Function: H5FD__mpio_read_selection * - * Purpose: ???Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID using potentially complex file and buffer types to - * effect the transfer. - * - * Reading past the end of the MPI file returns zeros instead of - * failing. MPI is able to coalesce requests from different - * processes (collective or independent). + * Purpose: The behaviour of this function dependes on the value of + * the transfer mode obtained from the context. * - * Return: Success: SUCCEED. Result is stored in caller-supplied - * buffer BUF. + * If the transfer mode is H5FD_MPIO_COLLECTIVE: + * --sort the selections + * --set mpi_bufs_base + * --build the MPI derived types + * --perform MPI_File_set_view() + * --perform MPI_File_read_at_all() or MPI_File_read_at() + * depending on whether this is a H5FD_MPIO_COLLECTIVE_IO * - * Failure: FAIL. Contents of buffer BUF are undefined. + * If this is not H5FD_MPIO_COLLECTIVE: + * --undo possible base address addition in internal routines + * --call H5FD_read_vector_from_selection() to perform vector + * or scalar writes for the selections * - * Programmer: + * Return: Success: SUCCEED. + * Failure: FAIL. * *------------------------------------------------------------------------- */ @@ -3019,9 +3022,9 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file)); hbool_t H5FD_mpio_debug_r_flag = (H5FD_mpio_debug_flags_s[(int)'r'] && H5FD_MPIO_TRACE_THIS_RANK(file)); #endif - int mpi_code; /* MPI return code */ - herr_t ret_value = SUCCEED; + int mpi_code; /* MPI return code */ H5_flexible_const_ptr_t mbb; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -3047,21 +3050,6 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d /* Portably initialize MPI status variable */ memset(&mpi_stat, 0, sizeof(MPI_Status)); - if (count) { - if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, - element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, &s_bufs) < 0) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); - - tmp_offset = s_offsets[0]; - } - - /* some numeric conversions */ - if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") - - /* I remove the check and if/else for H5FD_MEM_DRAW */ - /* Get the transfer mode from the API context */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") @@ -3075,6 +3063,14 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d if (xfer_mode == H5FD_MPIO_COLLECTIVE) { if (count) { + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, + element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, + &s_file_space_ids, &s_offsets, &s_element_sizes, + &s_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); + + tmp_offset = s_offsets[0]; + if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) @@ -3130,6 +3126,10 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d final_mtype = MPI_BYTE; } + /* some numeric conversions */ + if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + /* * Set the file view when we are using MPI derived types */ @@ -3322,20 +3322,25 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d /*------------------------------------------------------------------------- * Function: H5FD__mpio_write_selection * - * Purpose: ???Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID using potentially complex file and buffer types to - * effect the transfer. - * - * MPI is able to coalesce requests from different processes - * (collective and independent). - * - * Return: Success: SUCCEED. USE_TYPES and OLD_USE_TYPES in the - * access params are altered. - * Failure: FAIL. USE_TYPES and OLD_USE_TYPES in the - * access params may be altered. + * Purpose: The behaviour of this function dependes on the value of + * the transfer mode obtained from the context. + * + * If the transfer mode is H5FD_MPIO_COLLECTIVE: + * --sort the selections + * --set mpi_bufs_base + * --build the MPI derived types + * --perform MPI_File_set_view() + * --perform MPI_File_write_at_all() or MPI_File_write_at() + * depending on whether this is a H5FD_MPIO_COLLECTIVE_IO + * --calculate and set the file's eof for the bytes written + * + * If this is not H5FD_MPIO_COLLECTIVE: + * --undo possible base address addition in internal routines + * --call H5FD_write_vector_from_selection() to perform vector + * or scalar writes for the selections * - * Programmer: + * Return: Success: SUCCEED. + * Failure: FAIL. * *------------------------------------------------------------------------- */ @@ -3418,35 +3423,21 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* Portably initialize MPI status variable */ memset(&mpi_stat, 0, sizeof(MPI_Status)); - if (count) { - if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, - element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, &s_bufs) < 0) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); - - tmp_offset = s_offsets[0]; - } - - /* some numeric conversions */ - if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") - - /* To be used at the end of the routine for setting local_eof */ - save_mpi_off = mpi_off; - /* Get the transfer mode from the API context */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") - /* - * Set up for a fancy xfer using complex types, or single byte block. We - * wouldn't need to rely on the use_view field if MPI semantics allowed - * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which - * could mean "use MPI_BYTE" by convention). - */ if (xfer_mode == H5FD_MPIO_COLLECTIVE) { if (count) { + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, + element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, + &s_file_space_ids, &s_offsets, &s_element_sizes, + &s_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); + + tmp_offset = s_offsets[0]; + if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) @@ -3502,6 +3493,13 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED final_mtype = MPI_BYTE; } + /* some numeric conversions */ + if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + + /* To be used at the end of the routine for setting local_eof */ + save_mpi_off = mpi_off; + /* * Set the file view when we are using MPI derived types */ @@ -3541,7 +3539,6 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED } } else { - /* I remove the check for H5FD_MEM_DRAW: Do I need that? */ #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_w_flag) From c3fee2979e2a37a760e40849468d74cf2806ef9d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:23:17 +0000 Subject: [PATCH 04/19] Committing clang-format changes --- src/H5FD.c | 10 +++++----- src/H5FDint.c | 40 ++++++++++++++++++++-------------------- src/H5FDmpio.c | 28 ++++++++++++++-------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 5d2c2fe9f8d..1b55ceec1e7 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1829,7 +1829,7 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count } /* end H5FDwrite_selection() */ /*------------------------------------------------------------------------- - * Purpose: This is similar to H5FDread_selection() with the + * Purpose: This is similar to H5FDread_selection() with the * exception noted below. * * Perform count reads from the specified file at the @@ -1929,7 +1929,7 @@ H5FDread_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uin } /* end H5FDread_vector_from_selection() */ /*------------------------------------------------------------------------- - * Purpose: This is similar to H5FDwrite_selection() with the + * Purpose: This is similar to H5FDwrite_selection() with the * exception noted below. * * Perform count writes to the specified file at the @@ -2027,7 +2027,7 @@ H5FDwrite_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui } /* end H5FDwrite_vector_from_selection() */ /*------------------------------------------------------------------------- - * Purpose: This is similar to H5FDread_selection() with the + * Purpose: This is similar to H5FDread_selection() with the * exception noted below. * * Perform count reads from the specified file at the @@ -2050,7 +2050,7 @@ H5FDwrite_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui * It will skip selection and vector read calls whether the underlying * VFD supports selection and vector reads or not. * - * It will translate the selection read to a series of + * It will translate the selection read to a series of * scalar read calls. * * All reads are done according to the data transfer property @@ -2125,7 +2125,7 @@ H5FDread_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t c } /* end H5FDread_from_selection() */ /*------------------------------------------------------------------------- - * Purpose: This is similar to H5FDwrite_selection() with the + * Purpose: This is similar to H5FDwrite_selection() with the * exception noted below. * * Perform count writes to the specified file at the diff --git a/src/H5FDint.c b/src/H5FDint.c index 6ef40d5612d..e269e9a6f0c 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -736,7 +736,7 @@ H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addr * Function: H5FD__read_selection_translate * * Purpose: Translates a selection read call to a vector read call if - * vector reads are supported and !skip_vector_cb, + * vector reads are supported and !skip_vector_cb, * or a series of scalar read calls otherwise. * * Return: Success: SUCCEED @@ -1232,7 +1232,7 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s * Depending on the parameter skip_cb which is translated into * skip_selection_cb and skip_vector_cb: * - * --If the underlying VFD supports selection reads and !skip_selection_cb, + * --If the underlying VFD supports selection reads and !skip_selection_cb, * pass the call through directly. * * --If it doesn't, convert the selection reads into a sequence of vector or @@ -1393,7 +1393,7 @@ H5FD_read_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t * Function: H5FD__write_selection_translate * * Purpose: Translates a selection write call to a vector write call - * if vector writes are supported and !skip_vector_cb, + * if vector writes are supported and !skip_vector_cb, * or a series of scalar write calls otherwise. * * Return: Success: SUCCEED @@ -1879,7 +1879,7 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ * Depending on the parameter skip_cb which is translated into * skip_selection_cb and skip_vector_cb: * - * --If the underlying VFD supports selection writes and !skip_selection_cb, + * --If the underlying VFD supports selection writes and !skip_selection_cb, * pass the call through directly. * * --If it doesn't, convert the selection writes into a sequence of vector or @@ -2417,9 +2417,9 @@ H5FD__srt_tmp_cmp(const void *element_1, const void *element_2) * * If not sorted, use qsort() to sort the array. * Do this by allocating an array of struct H5FD_srt_tmp_t, - * where each instance of H5FD_srt_tmp_t has two fields, - * addr and index. Load the array with the contents of the - * addrs array and the index of the associated entry. + * where each instance of H5FD_srt_tmp_t has two fields, + * addr and index. Load the array with the contents of the + * addrs array and the index of the associated entry. * Then sort the array using qsort(). * Return *FALSE in was_sorted. * @@ -2527,9 +2527,9 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t 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) { - herr_t ret_value = SUCCEED; /* Return value */ - size_t count = (size_t)_count; - size_t i; + herr_t ret_value = SUCCEED; /* Return value */ + size_t count = (size_t)_count; + size_t i; struct H5FD_srt_tmp_t *srt_tmp = NULL; FUNC_ENTER_NOAPI(FAIL) @@ -2570,7 +2570,7 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t } else { - /* + /* * Allocate the s_types_ptr, s_addrs_ptr, s_sizes_ptr, and s_bufs_ptr * arrays and populate them using the mapping provided by * the sorted array of H5FD_srt_tmp_t. @@ -2681,8 +2681,8 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t * and return. * * If it is not sorted, duplicate the mem_space_ids, file_space_ids, - * offsets, element_sizes and bufs arrays, storing the base - * addresses of the new arrays in *s_mem_space_ids_ptr, + * offsets, element_sizes and bufs arrays, storing the base + * addresses of the new arrays in *s_mem_space_ids_ptr, * s_file_space_ids_ptr, s_offsets_ptr, *s_element_sizes_ptr, * and s_bufs_ptr respectively. Determine the sorted order * of the selection I/O request, and load it into the new @@ -2702,10 +2702,10 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t hid_t **s_file_space_ids_ptr, haddr_t **s_offsets_ptr, size_t **s_element_sizes_ptr, H5_flexible_const_ptr_t **s_bufs_ptr) { - size_t count = (size_t)_count; - size_t i; + size_t count = (size_t)_count; + size_t i; struct H5FD_srt_tmp_t *srt_tmp = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2733,7 +2733,7 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t /* Sort the offsets array in increasing offet order, while * maintaining the association between each offset, and the - * mem_space_ids[], file_space_ids[], element_sizes and bufs[] + * mem_space_ids[], file_space_ids[], element_sizes and bufs[] * values at the same index. */ if (H5FD__sort_io_req_real(count, offsets, selection_was_sorted, &srt_tmp) < 0) @@ -2749,9 +2749,9 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t } else { - /* - * Allocate the s_mem_space_ids_ptr, s_file_space_ids_ptr, s_offsets_ptr, - * s_element_sizes_ptr and s_bufs_ptr arrays and populate them using the + /* + * Allocate the s_mem_space_ids_ptr, s_file_space_ids_ptr, s_offsets_ptr, + * s_element_sizes_ptr and s_bufs_ptr arrays and populate them using the * mapping provided by the sorted array of H5FD_srt_tmp_t. */ size_t j; diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 0bb392338f9..7772c3af3b1 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -2737,7 +2737,7 @@ H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t co * Purpose: Build MPI derived datatype for each piece and then * build MPI final derived datatype for file and memory. * - * Note: This is derived from H5D__link_piece_collective_io() in + * Note: This is derived from H5D__link_piece_collective_io() in * src/H5Dmpio.c. * * Return: Non-negative on success/Negative on failure @@ -2956,11 +2956,11 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl * the transfer mode obtained from the context. * * If the transfer mode is H5FD_MPIO_COLLECTIVE: - * --sort the selections + * --sort the selections * --set mpi_bufs_base * --build the MPI derived types * --perform MPI_File_set_view() - * --perform MPI_File_read_at_all() or MPI_File_read_at() + * --perform MPI_File_read_at_all() or MPI_File_read_at() * depending on whether this is a H5FD_MPIO_COLLECTIVE_IO * * If this is not H5FD_MPIO_COLLECTIVE: @@ -3022,9 +3022,9 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d hbool_t H5FD_mpio_debug_t_flag = (H5FD_mpio_debug_flags_s[(int)'t'] && H5FD_MPIO_TRACE_THIS_RANK(file)); hbool_t H5FD_mpio_debug_r_flag = (H5FD_mpio_debug_flags_s[(int)'r'] && H5FD_MPIO_TRACE_THIS_RANK(file)); #endif - int mpi_code; /* MPI return code */ + int mpi_code; /* MPI return code */ H5_flexible_const_ptr_t mbb; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -3063,9 +3063,9 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d if (xfer_mode == H5FD_MPIO_COLLECTIVE) { if (count) { - if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, - element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, + offsets, element_sizes, (H5_flexible_const_ptr_t *)bufs, + &s_mem_space_ids, &s_file_space_ids, &s_offsets, &s_element_sizes, &s_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); @@ -3326,11 +3326,11 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d * the transfer mode obtained from the context. * * If the transfer mode is H5FD_MPIO_COLLECTIVE: - * --sort the selections + * --sort the selections * --set mpi_bufs_base * --build the MPI derived types * --perform MPI_File_set_view() - * --perform MPI_File_write_at_all() or MPI_File_write_at() + * --perform MPI_File_write_at_all() or MPI_File_write_at() * depending on whether this is a H5FD_MPIO_COLLECTIVE_IO * --calculate and set the file's eof for the bytes written * @@ -3430,10 +3430,10 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED if (xfer_mode == H5FD_MPIO_COLLECTIVE) { if (count) { - if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, offsets, - element_sizes, (H5_flexible_const_ptr_t *)bufs, &s_mem_space_ids, - &s_file_space_ids, &s_offsets, &s_element_sizes, - &s_bufs) < 0) + if (H5FD_sort_selection_io_req(&selection_was_sorted, count, mem_space_ids, file_space_ids, + offsets, element_sizes, (H5_flexible_const_ptr_t *)bufs, + &s_mem_space_ids, &s_file_space_ids, &s_offsets, &s_element_sizes, + &s_bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't sort selection I/O request"); tmp_offset = s_offsets[0]; From f75cbd327c5ce5ffb64a573d0f387d9a3c41e9ce Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Thu, 6 Jul 2023 12:26:14 -0500 Subject: [PATCH 05/19] Correct spelling error. --- src/H5FDint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5FDint.c b/src/H5FDint.c index e269e9a6f0c..767d1a27a5f 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -2731,7 +2731,7 @@ H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t assert((count == 0) || ((s_element_sizes_ptr) && (NULL == *s_element_sizes_ptr))); assert((count == 0) || ((s_bufs_ptr) && (NULL == *s_bufs_ptr))); - /* Sort the offsets array in increasing offet order, while + /* Sort the offsets array in increasing offset order, while * maintaining the association between each offset, and the * mem_space_ids[], file_space_ids[], element_sizes and bufs[] * values at the same index. From 56e0ca3fd4f9c429e1defd8eace83b2a7fcea7a5 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Wed, 19 Jul 2023 11:03:43 -0500 Subject: [PATCH 06/19] Add tests for the three bugs found when setting H5D_SELECTION_IO_MODE_ON as the default in the library. Minor cleanups. --- test/select_io_dset.c | 22 ++- testpar/t_select_io_dset.c | 393 ++++++++++++++++++++++++++++++++++++- 2 files changed, 408 insertions(+), 7 deletions(-) diff --git a/test/select_io_dset.c b/test/select_io_dset.c index 2746bcceb6e..b0abc8c1ddc 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -2751,9 +2751,6 @@ test_set_get_select_io_mode(hid_t fid) if (H5Pget_selection_io(dxpl, &selection_io_mode) < 0) TEST_ERROR; - if (selection_io_mode != H5D_SELECTION_IO_MODE_DEFAULT) - TEST_ERROR; - /* Disable case */ if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_OFF) < 0) TEST_ERROR; @@ -3063,11 +3060,29 @@ static herr_t test_get_no_selection_io_cause(const char *filename, hid_t fapl) { + hid_t dxpl = H5I_INVALID_HID; + H5D_selection_io_mode_t selection_io_mode; int errs = 0; printf("\n"); TESTING("H5Pget_no_selection_io_cause()"); + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + FAIL_STACK_ERROR; + + if (H5Pget_selection_io(dxpl, &selection_io_mode) < 0) + TEST_ERROR; + + if (H5Pclose(dxpl) < 0) + FAIL_STACK_ERROR; + + /* The following tests are based on H5D_SELECTION_IO_MODE_DEFAULT as the + default setting in the library; skip the tests if that is not true */ + if (selection_io_mode != H5D_SELECTION_IO_MODE_DEFAULT) { + SKIPPED(); + return SUCCEED; + } + errs += test_no_selection_io_cause_mode(filename, fapl, TEST_DISABLE_BY_API); errs += test_no_selection_io_cause_mode(filename, fapl, TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET); errs += test_no_selection_io_cause_mode(filename, fapl, TEST_CONTIGUOUS_SIEVE_BUFFER); @@ -3083,6 +3098,7 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) errs += test_no_selection_io_cause_mode(filename, fapl, TEST_PAGE_BUFFER); #endif +error: if (errs) { printf(" FAILED\n"); return FAIL; diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index eb64bfe8cfe..02082f02fbe 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -128,6 +128,11 @@ typedef enum { #define TEST_TCONV_BUF_TOO_SMALL 0x008 #define TEST_IN_PLACE_TCONV 0x010 +/* Definitions used by test_bug_optimized_bufs() and test_bug_api_library() */ +#define DIMS 10000 +#define BIG_X_FACTOR 1048576 +#define BIG_Y_FACTOR 32 + /* * Helper routine to set dxpl * --selection I/O mode @@ -3515,12 +3520,36 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ } /* test_no_selection_io_cause_mode() */ + /* * Test for causes of not performing selection I/O */ static void test_get_no_selection_io_cause(const char *filename, hid_t fapl) { + hid_t dxpl = H5I_INVALID_HID; + H5D_selection_io_mode_t selection_io_mode; + + if (MAINPROCESS) { + printf("\n"); + TESTING("for H5Pget_no_selection_io_cause()"); + } + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + if (H5Pget_selection_io(dxpl, &selection_io_mode) < 0) + P_TEST_ERROR; + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + /* The following tests are based on H5D_SELECTION_IO_MODE_DEFAULT as the + * default setting in the library; skip the tests if that is not true */ + if (selection_io_mode != H5D_SELECTION_IO_MODE_DEFAULT) { + if (MAINPROCESS) + SKIPPED(); + return; + } + test_no_selection_io_cause_mode(filename, fapl, TEST_DISABLE_BY_API); test_no_selection_io_cause_mode(filename, fapl, TEST_NOT_CONTIGUOUS_OR_CHUNKED_DATASET); test_no_selection_io_cause_mode(filename, fapl, TEST_DATATYPE_CONVERSION); @@ -3533,6 +3562,364 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) return; } /* test_get_no_selection_io_cause() */ + +/* + * This bug is exposed when running testpar/t_coll_md.c via testphdf5. + * + * Optimized bufs (bufs[1] is NULL) is used when passing as a parameter to the mpio driver + * for selection I/O. When computing mpi_bufs_base in that routine, it is not accounted + * for and therefore causing segmentation fault when running the test. + * + * Fix: + * Check for optimized bufs when computing mpi_bufs_base. + */ +static void +test_bug_optimized_bufs(const char *filename, hid_t fapl) +{ + hid_t dxpl = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; + hsize_t dims[1]; + hsize_t cdims[1]; + hsize_t start[1]; + hsize_t stride[1]; + hsize_t count[1]; + hsize_t block[1]; + int *wbuf; + + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + P_TEST_ERROR; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + P_TEST_ERROR; + + dims[0] = (hsize_t)mpi_size * (hsize_t)DIMS; + + fspace_id = H5Screate_simple(1, dims, NULL); + + cdims[0] = (hsize_t)mpi_size; + + if (H5Pset_chunk(dcpl, 1, cdims) < 0) + P_TEST_ERROR; + + if ((did = H5Dcreate2(fid, "bug_optimized_bufs", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + start[0] = (hsize_t)mpi_rank; + stride[0] = (hsize_t)mpi_size; + count[0] = DIMS; + block[0] = 1; + + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if ((mspace_id = H5Screate_simple(1, count, NULL)) < 0) + P_TEST_ERROR; + + if ((wbuf = calloc(1, count[0] * sizeof(int))) == NULL) + P_TEST_ERROR; + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Enable collection transfer mode */ + if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0) + P_TEST_ERROR; + + /* Enable selection I/O */ + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) + P_TEST_ERROR; + + if (H5Dwrite(did, H5T_NATIVE_INT, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + if (H5Dclose(did) < 0) + P_TEST_ERROR; + + if (H5Pclose(dcpl) < 0) + P_TEST_ERROR; + + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + + if (H5Fclose(fid) < 0) + P_TEST_ERROR; + + return; + +} /* test_bug_optimized_bufs() */ + +/* + * The bug is exposed when running testpar/t_pread.c. + * + * The file is created with userblock. Before pasing down to the mpio driver for + * selection I/O, the parameter offsets[] is added by base_addr (size of the uesrblock). + * For the independent case in the mpio driver for selection I/O, + * the intermediate routine for the API H5FDread/write_vector_from_selection() is called. + * The parameter offsets[] is passed as is to the intermediate routine which will + * be added again by base_addr causing incorrect data retrieval. + * + * Fix: + * The parameter offsets[] needs to be adjusted by the base_addr addition before calling + * the intermediate routine. + */ +static void +test_bug_base_addr(const char *filename, hid_t fapl) +{ + hid_t dxpl = H5I_INVALID_HID; + hid_t dxpl_read = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t fcpl = H5I_INVALID_HID; + hsize_t dims[1]; + hid_t tid = H5T_NATIVE_INT; + int wbuf[DSET_SELECT_DIM]; + int rbuf[DSET_SELECT_DIM]; + int i; + + /* Create user block */ + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) + P_TEST_ERROR; + + if (H5Pset_userblock(fcpl, 512) < 0) + P_TEST_ERROR; + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Create the file with userblock */ + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) + P_TEST_ERROR; + + /* Create 1d data space */ + dims[0] = DSET_SELECT_DIM; + + if ((sid = H5Screate_simple(1, dims, NULL)) < 0) + P_TEST_ERROR; + + if ((did = H5Dcreate2(fid, "bug_base_addr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + /* Initialize data */ + for (i = 0; i < DSET_SELECT_DIM; i++) + wbuf[i] = i; + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Enable selection I/O */ + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) + P_TEST_ERROR; + + /* Independent by default and with selection I/O ON for reading */ + if ((dxpl_read = H5Pcopy(dxpl)) < 0) + P_TEST_ERROR; + + /* Enable collective and with selection I/O ON for writing */ + if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0) + P_TEST_ERROR; + + if (H5Dwrite(did, tid, H5S_ALL, H5S_ALL, dxpl, wbuf) < 0) + P_TEST_ERROR; + + if (H5Dread(did, tid, H5S_ALL, H5S_ALL, dxpl_read, rbuf) < 0) + P_TEST_ERROR; + + if (H5Dclose(did) < 0) + P_TEST_ERROR; + + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + if (H5Pclose(dxpl_read) < 0) + P_TEST_ERROR; + + if (H5Sclose(sid) < 0) + P_TEST_ERROR; + + if (H5Pclose(fcpl) < 0) + P_TEST_ERROR; + + if (H5Fclose(fid) < 0) + P_TEST_ERROR; + return; + +} /* test_bug_base_addr() */ + +/* + * This bug is exposed when running testpar/t_2Gio.c with at least 2 processes. + * + * The root problem is from calling an API function from within the library i.e. + * calling H5FDread/write_vector_from_selection() for independent access in the + * mpio driver for selection I/O. + * + * The test scenario is described below with the test writing to a dataset + * via H5Dwrite(): + * --running with 2 processes + * --with selection I/O on + * --with COLLECTIVE xfer mode + * + * For process 1: + * The library internal calls H5D__write(): + * --io_info.use_select_io is ON + * --io_info.use_select_io is OFF after calling H5D__typeinfo_init_phase2() + * due to H5D_SEL_IO_TCONV_BUF_TOO_SMALL + * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to + * H5FD_MPIO_INDEPENDENT + * The library eventually calls H5FD__mpio_write() performing scalar calls for the writes + * + * For process 0: + * The library internal calls H5D__write(): + * --io_info.use_select_io is ON + * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to + * H5FD_MPIO_INDEPENDENT + * The library eventually calls H5FD__mpio_write_selection(): + * --since the xfer mode is INDEPENDENT it calls the API + * H5FDwrite_vector_from_selection(), which eventually calls + * H5FD__mpio_write_vector(). This routine obtains the + * xfer mode via API context which returns COLLECTIVE. + * Then the test hangs when trying to do MPI_File_set_view(). + * + * Fix: + * Create wrapper functions for the API H5FDread/write_vector_from_selection() and + * they will be called by H5FD__mpio_read/write_selection() for independent access. + * + */ +static void +test_bug_api_library(const char *filename, hid_t fapl) +{ + hid_t dxpl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; + hsize_t dims[2]; + hsize_t start[2]; + hsize_t stride[2]; + hsize_t count[2]; + hsize_t block[2]; + int *wbuf; + hsize_t i, j; + + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + P_TEST_ERROR; + + dims[0] = (hsize_t)BIG_X_FACTOR; + dims[1] = (hsize_t)BIG_Y_FACTOR; + + if ((sid = H5Screate_simple(2, dims, NULL)) < 0) + P_TEST_ERROR; + + if ((did = H5Dcreate2(fid, "bug_coll_to_ind", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + P_TEST_ERROR; + + if ((wbuf = malloc((size_t)dims[0] * (size_t)dims[1] * sizeof(int))) == NULL) + P_TEST_ERROR; + + /* Each process takes a slabs of rows. */ + block[0] = (hsize_t)dims[0] / (hsize_t)mpi_size; + block[1] = (hsize_t)dims[1]; + stride[0] = block[0]; + stride[1] = block[1]; + count[0] = 1; + count[1] = 1; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + + if ((fspace_id = H5Dget_space(did)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(fspace_id) < 0) + P_TEST_ERROR; + } /* end if */ + else { + if (H5Sselect_hyperslab(fspace_id, H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + } /* end else */ + + if ((mspace_id = H5Screate_simple(2, block, NULL)) < 0) + P_TEST_ERROR; + if (MAINPROCESS) { + if (H5Sselect_none(mspace_id) < 0) + P_TEST_ERROR; + } /* end if */ + + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) + P_TEST_ERROR; + + /* Enable collective transfer */ + if (H5Pset_dxpl_mpio(dxpl, H5FD_MPIO_COLLECTIVE) < 0) + P_TEST_ERROR; + + /* Enable selection I/O */ + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) + P_TEST_ERROR; + + /* Put some trivial data in wbuf */ + for (i = 0; i < block[0]; i++) { + for (j = 0; j < block[1]; j++) { + *wbuf = (int)((i + start[0]) * 100 + (j + start[1] + 1)); + wbuf++; + } + } + + /* With datatype conversion */ + if (H5Dwrite(did, H5T_NATIVE_UCHAR, mspace_id, fspace_id, dxpl, wbuf) < 0) + P_TEST_ERROR; + + if (H5Dclose(did) < 0) + P_TEST_ERROR; + + if (H5Pclose(dxpl) < 0) + P_TEST_ERROR; + + if (H5Sclose(fspace_id) < 0) + P_TEST_ERROR; + + if (H5Sclose(mspace_id) < 0) + P_TEST_ERROR; + + if (H5Fclose(fid) < 0) + P_TEST_ERROR; + + return; + +} /* test_bug_api_library() */ + +/* + * Verify bugs exposed when H5D_SELECTION_IO_MODE_ON is set as the + * default in the library. + */ +static void +test_bugs_select_on(const char *filename, hid_t fapl) +{ + if (MAINPROCESS) { + printf("\n"); + TESTING("to verify bugs exposed when H5D_SELECTION_IO_MODE_ON is set as library default"); + } + + test_bug_optimized_bufs(filename, fapl); + test_bug_base_addr(filename, fapl); + test_bug_api_library(filename, fapl); + + CHECK_PASSED(); + return; + +} /* test_bugs_select_on() */ + /*------------------------------------------------------------------------- * Function: main * @@ -3740,12 +4127,10 @@ main(int argc, char *argv[]) if (H5Fclose(fid) < 0) P_TEST_ERROR; - if (MAINPROCESS) { - printf("\n"); - TESTING("Testing for H5Pget_no_selection_io_cause()"); - } test_get_no_selection_io_cause(FILENAME, fapl); + test_bugs_select_on(FILENAME, fapl); + /* Barrier to make sure all ranks are done before deleting the file, and * also to clean up output (make sure PASSED is printed before any of the * following messages) */ From 41f68d46d041ebc3fec0f618ba0de207f651ca8e Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 16:09:38 +0000 Subject: [PATCH 07/19] Committing clang-format changes --- test/select_io_dset.c | 6 +-- testpar/t_select_io_dset.c | 101 ++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/test/select_io_dset.c b/test/select_io_dset.c index b0abc8c1ddc..e3eae5a1f54 100644 --- a/test/select_io_dset.c +++ b/test/select_io_dset.c @@ -3060,9 +3060,9 @@ static herr_t test_get_no_selection_io_cause(const char *filename, hid_t fapl) { - hid_t dxpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; H5D_selection_io_mode_t selection_io_mode; - int errs = 0; + int errs = 0; printf("\n"); TESTING("H5Pget_no_selection_io_cause()"); @@ -3076,7 +3076,7 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) if (H5Pclose(dxpl) < 0) FAIL_STACK_ERROR; - /* The following tests are based on H5D_SELECTION_IO_MODE_DEFAULT as the + /* The following tests are based on H5D_SELECTION_IO_MODE_DEFAULT as the default setting in the library; skip the tests if that is not true */ if (selection_io_mode != H5D_SELECTION_IO_MODE_DEFAULT) { SKIPPED(); diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index 02082f02fbe..fce0956f363 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -129,9 +129,9 @@ typedef enum { #define TEST_IN_PLACE_TCONV 0x010 /* Definitions used by test_bug_optimized_bufs() and test_bug_api_library() */ -#define DIMS 10000 -#define BIG_X_FACTOR 1048576 -#define BIG_Y_FACTOR 32 +#define DIMS 10000 +#define BIG_X_FACTOR 1048576 +#define BIG_Y_FACTOR 32 /* * Helper routine to set dxpl @@ -3520,14 +3520,13 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ } /* test_no_selection_io_cause_mode() */ - /* * Test for causes of not performing selection I/O */ static void test_get_no_selection_io_cause(const char *filename, hid_t fapl) { - hid_t dxpl = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; H5D_selection_io_mode_t selection_io_mode; if (MAINPROCESS) { @@ -3562,12 +3561,11 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) return; } /* test_get_no_selection_io_cause() */ - -/* +/* * This bug is exposed when running testpar/t_coll_md.c via testphdf5. * - * Optimized bufs (bufs[1] is NULL) is used when passing as a parameter to the mpio driver - * for selection I/O. When computing mpi_bufs_base in that routine, it is not accounted + * Optimized bufs (bufs[1] is NULL) is used when passing as a parameter to the mpio driver + * for selection I/O. When computing mpi_bufs_base in that routine, it is not accounted * for and therefore causing segmentation fault when running the test. * * Fix: @@ -3576,19 +3574,19 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) static void test_bug_optimized_bufs(const char *filename, hid_t fapl) { - hid_t dxpl = H5I_INVALID_HID; - hid_t dcpl = H5I_INVALID_HID; - hid_t fid = H5I_INVALID_HID; - hid_t did = H5I_INVALID_HID; - hid_t fspace_id = H5I_INVALID_HID; - hid_t mspace_id = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t dcpl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; hsize_t dims[1]; hsize_t cdims[1]; hsize_t start[1]; hsize_t stride[1]; hsize_t count[1]; hsize_t block[1]; - int *wbuf; + int *wbuf; if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) P_TEST_ERROR; @@ -3605,7 +3603,8 @@ test_bug_optimized_bufs(const char *filename, hid_t fapl) if (H5Pset_chunk(dcpl, 1, cdims) < 0) P_TEST_ERROR; - if ((did = H5Dcreate2(fid, "bug_optimized_bufs", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid, "bug_optimized_bufs", H5T_NATIVE_INT, fspace_id, H5P_DEFAULT, dcpl, + H5P_DEFAULT)) < 0) P_TEST_ERROR; start[0] = (hsize_t)mpi_rank; @@ -3658,7 +3657,7 @@ test_bug_optimized_bufs(const char *filename, hid_t fapl) } /* test_bug_optimized_bufs() */ -/* +/* * The bug is exposed when running testpar/t_pread.c. * * The file is created with userblock. Before pasing down to the mpio driver for @@ -3675,17 +3674,17 @@ test_bug_optimized_bufs(const char *filename, hid_t fapl) static void test_bug_base_addr(const char *filename, hid_t fapl) { - hid_t dxpl = H5I_INVALID_HID; - hid_t dxpl_read = H5I_INVALID_HID; - hid_t fid = H5I_INVALID_HID; - hid_t did = H5I_INVALID_HID; - hid_t sid = H5I_INVALID_HID; - hid_t fcpl = H5I_INVALID_HID; - hsize_t dims[1]; - hid_t tid = H5T_NATIVE_INT; - int wbuf[DSET_SELECT_DIM]; - int rbuf[DSET_SELECT_DIM]; - int i; + hid_t dxpl = H5I_INVALID_HID; + hid_t dxpl_read = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t fcpl = H5I_INVALID_HID; + hsize_t dims[1]; + hid_t tid = H5T_NATIVE_INT; + int wbuf[DSET_SELECT_DIM]; + int rbuf[DSET_SELECT_DIM]; + int i; /* Create user block */ if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) @@ -3707,8 +3706,8 @@ test_bug_base_addr(const char *filename, hid_t fapl) if ((sid = H5Screate_simple(1, dims, NULL)) < 0) P_TEST_ERROR; - if ((did = H5Dcreate2(fid, "bug_base_addr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid, "bug_base_addr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < + 0) P_TEST_ERROR; /* Initialize data */ @@ -3752,66 +3751,66 @@ test_bug_base_addr(const char *filename, hid_t fapl) P_TEST_ERROR; if (H5Fclose(fid) < 0) - P_TEST_ERROR; + P_TEST_ERROR; return; } /* test_bug_base_addr() */ -/* +/* * This bug is exposed when running testpar/t_2Gio.c with at least 2 processes. * * The root problem is from calling an API function from within the library i.e. * calling H5FDread/write_vector_from_selection() for independent access in the * mpio driver for selection I/O. * - * The test scenario is described below with the test writing to a dataset + * The test scenario is described below with the test writing to a dataset * via H5Dwrite(): - * --running with 2 processes + * --running with 2 processes * --with selection I/O on * --with COLLECTIVE xfer mode * * For process 1: * The library internal calls H5D__write(): * --io_info.use_select_io is ON - * --io_info.use_select_io is OFF after calling H5D__typeinfo_init_phase2() + * --io_info.use_select_io is OFF after calling H5D__typeinfo_init_phase2() * due to H5D_SEL_IO_TCONV_BUF_TOO_SMALL - * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to + * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to * H5FD_MPIO_INDEPENDENT * The library eventually calls H5FD__mpio_write() performing scalar calls for the writes * * For process 0: * The library internal calls H5D__write(): * --io_info.use_select_io is ON - * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to + * --H5D__mpio_opt_possible() returns 0 so xfer mode is set to * H5FD_MPIO_INDEPENDENT - * The library eventually calls H5FD__mpio_write_selection(): + * The library eventually calls H5FD__mpio_write_selection(): * --since the xfer mode is INDEPENDENT it calls the API * H5FDwrite_vector_from_selection(), which eventually calls - * H5FD__mpio_write_vector(). This routine obtains the + * H5FD__mpio_write_vector(). This routine obtains the * xfer mode via API context which returns COLLECTIVE. * Then the test hangs when trying to do MPI_File_set_view(). * * Fix: - * Create wrapper functions for the API H5FDread/write_vector_from_selection() and + * Create wrapper functions for the API H5FDread/write_vector_from_selection() and * they will be called by H5FD__mpio_read/write_selection() for independent access. * */ static void test_bug_api_library(const char *filename, hid_t fapl) { - hid_t dxpl = H5I_INVALID_HID; - hid_t fid = H5I_INVALID_HID; - hid_t did = H5I_INVALID_HID; - hid_t sid = H5I_INVALID_HID; - hid_t fspace_id = H5I_INVALID_HID; - hid_t mspace_id = H5I_INVALID_HID; + hid_t dxpl = H5I_INVALID_HID; + hid_t fid = H5I_INVALID_HID; + hid_t did = H5I_INVALID_HID; + hid_t sid = H5I_INVALID_HID; + hid_t fspace_id = H5I_INVALID_HID; + hid_t mspace_id = H5I_INVALID_HID; hsize_t dims[2]; hsize_t start[2]; hsize_t stride[2]; hsize_t count[2]; hsize_t block[2]; - int *wbuf; - hsize_t i, j; + int *wbuf; + hsize_t i, j; if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) P_TEST_ERROR; @@ -3822,7 +3821,8 @@ test_bug_api_library(const char *filename, hid_t fapl) if ((sid = H5Screate_simple(2, dims, NULL)) < 0) P_TEST_ERROR; - if ((did = H5Dcreate2(fid, "bug_coll_to_ind", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + if ((did = H5Dcreate2(fid, "bug_coll_to_ind", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) P_TEST_ERROR; if ((wbuf = malloc((size_t)dims[0] * (size_t)dims[1] * sizeof(int))) == NULL) @@ -3838,7 +3838,6 @@ test_bug_api_library(const char *filename, hid_t fapl) start[0] = (hsize_t)mpi_rank * block[0]; start[1] = 0; - if ((fspace_id = H5Dget_space(did)) < 0) P_TEST_ERROR; if (MAINPROCESS) { From eddb31503c3637249a5d096b5e7d48f8af1e8181 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Wed, 19 Jul 2023 11:15:31 -0500 Subject: [PATCH 08/19] Correct spelling error. --- testpar/t_select_io_dset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index fce0956f363..d891839c255 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -3660,7 +3660,7 @@ test_bug_optimized_bufs(const char *filename, hid_t fapl) /* * The bug is exposed when running testpar/t_pread.c. * - * The file is created with userblock. Before pasing down to the mpio driver for + * The file is created with userblock. Before passing down to the mpio driver for * selection I/O, the parameter offsets[] is added by base_addr (size of the uesrblock). * For the independent case in the mpio driver for selection I/O, * the intermediate routine for the API H5FDread/write_vector_from_selection() is called. From 5f20722f4b7bf42625b8d68faacdc5bd70416870 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Thu, 27 Jul 2023 11:43:12 -0500 Subject: [PATCH 09/19] Add tests for selection I/O which are derived from test/vfd.c and modified for parallel testing. --- testpar/t_select_io_dset.c | 6 + testpar/t_vfd.c | 1838 ++++++++++++++++++++++++++++++++++-- 2 files changed, 1768 insertions(+), 76 deletions(-) diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index d891839c255..efc2f451931 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -2965,6 +2965,8 @@ test_multi_dsets_all(int niter, hid_t fid, unsigned chunked, unsigned mwbuf) const void *wbufs[MULTI_NUM_DSETS]; void *rbufs[MULTI_NUM_DSETS]; + curr_nerrors = nerrors; + /* for n niter to ensure that all randomized dset_types with multi_dset_type_t will be covered */ for (n = 0; n < niter; n++) { @@ -3534,6 +3536,8 @@ test_get_no_selection_io_cause(const char *filename, hid_t fapl) TESTING("for H5Pget_no_selection_io_cause()"); } + curr_nerrors = nerrors; + if ((dxpl = H5Pcreate(H5P_DATASET_XFER)) < 0) P_TEST_ERROR; if (H5Pget_selection_io(dxpl, &selection_io_mode) < 0) @@ -3910,6 +3914,8 @@ test_bugs_select_on(const char *filename, hid_t fapl) TESTING("to verify bugs exposed when H5D_SELECTION_IO_MODE_ON is set as library default"); } + curr_nerrors = nerrors; + test_bug_optimized_bufs(filename, fapl); test_bug_base_addr(filename, fapl); test_bug_api_library(filename, fapl); diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index 827faf4cd31..40b8725fed6 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -100,6 +100,100 @@ static unsigned vector_write_test_6(int file_name_id, int mpi_rank, int mpi_size H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); static unsigned vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer_t xfer_mode, H5FD_mpio_collective_opt_t coll_opt_mode, const char *vfd_name); +/* + * Tests for selection I/O: + * They are derived from test_selection_io() in test/vfd.c and modified for parallel testing. + */ + +/* + * Global declarations for selection I/O tests` + */ + +/* Number of errors */ +int nerrors = 0; +int curr_nerrors = 0; + +/* Test file name */ +#define SELECT_FNAME "mpio_select_test_file" + +/* Dimemsion sizes */ +#define SEL_IO_DIM0 4 +#define SEL_IO_DIM1 8 +int sel_dim0 = SEL_IO_DIM0; +int sel_dim1 = SEL_IO_DIM1; + +/* Write buffers */ +int *wbuf1 = NULL; +int *wbuf2 = NULL; +int *wbufs[2] = {NULL, NULL}; + +/* File buffers */ +int *fbuf1 = NULL; +int *fbuf2 = NULL; +int *fbufs[2] = {NULL, NULL}; /* Array of file buffers */ + +/* Expected read buffers */ +int *erbuf1 = NULL; +int *erbuf2 = NULL; +int *erbufs[2] = {NULL, NULL}; /* Array of expected read buffers */ + +/* iotypes for testing: + H5FD_MPIO_INDEPENDENT + H5FD_MPIO_COLLECTIVE + --H5FD_MPIO_COLLECTIVE_IO + --H5FD_MPIO_INDIVIDUAL_IO +*/ +#define iotypes 3 + +#define P_TEST_ERROR \ + do { \ + nerrors++; \ + H5_FAILED(); \ + AT(); \ + } while (0) + +#define CHECK_PASSED() \ + do { \ + int err_result = (nerrors > curr_nerrors); \ + \ + MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); \ + \ + if (MAINPROCESS) { \ + if (err_result == 0) \ + PASSED(); \ + else \ + HDputs(" ***TEST FAILED***"); \ + } \ + } while (0) + + +/* Utility functions for selection I/O */ +static herr_t test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], + H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], + size_t element_sizes[], uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs); + +static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, + hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], int *wb[]); + +/* Test functions for selection I/O */ +static void test_selection_io(int mpi_rank, int mpi_size); +static void test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl); +static void test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[]); +static void test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims2[]); +static void test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[], hsize_t dims2[]); +static void test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[], hsize_t dims2[]); + + +/****************************************************************************/ + /****************************************************************************/ /***************************** Utility Functions ****************************/ @@ -4065,86 +4159,22 @@ vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size, H5FD_mpio_xfer } /* vector_write_test_7() */ -/*------------------------------------------------------------------------- - * Function: main - * - * Purpose: Run parallel VFD tests. - * - * Return: Success: 0 - * - * Failure: 1 - * - *------------------------------------------------------------------------- - */ - -int -main(int argc, char **argv) +static void +test_vector_io(int mpi_rank, int mpi_size) { unsigned nerrs = 0; -#ifdef H5_HAVE_SUBFILING_VFD - int required = MPI_THREAD_MULTIPLE; - int provided = 0; -#endif - int mpi_size; - int mpi_rank = 0; -#ifdef H5_HAVE_SUBFILING_VFD - if (MPI_SUCCESS != MPI_Init_thread(&argc, &argv, required, &provided)) { - printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); - goto finish; - } - - if (provided != required) { - printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); - goto finish; - } -#else - if (MPI_SUCCESS != MPI_Init(&argc, &argv)) { - printf(" MPI_Init failed. Exiting\n"); - goto finish; - } -#endif - - MPI_Comm_size(comm, &mpi_size); - MPI_Comm_rank(comm, &mpi_rank); - - /* Attempt to turn off atexit post processing so that in case errors - * occur during the test and the process is aborted, it will not hang - * in the atexit post processing. If it does, it may try to make MPI - * calls which may not work. - */ - if (H5dont_atexit() < 0) - printf("%d:Failed to turn off atexit processing. Continue.\n", mpi_rank); - - H5open(); - - if (mpi_rank == 0) { - printf("=========================================\n"); - printf("Parallel virtual file driver (VFD) tests\n"); - printf(" mpi_size = %d\n", mpi_size); - printf("=========================================\n"); - } - - if (mpi_size < 2) { - if (mpi_rank == 0) - printf(" Need at least 2 processes. Exiting.\n"); - goto finish; - } - - alloc_and_init_file_images(mpi_size); + nerrs += alloc_and_init_file_images(mpi_size); if (!pass) { printf("\nAllocation and initialize of file image buffers failed. Test aborted.\n"); + nerrors += (int)nerrs; + return; } MPI_Barrier(comm); - if (mpi_rank == 0) { - - printf("\n\n --- TESTING MPIO VFD --- \n\n"); - } - nerrs += vector_read_test_1(0, mpi_rank, mpi_size, H5FD_MPIO_INDEPENDENT, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); nerrs += vector_read_test_1(0, mpi_rank, mpi_size, H5FD_MPIO_COLLECTIVE, H5FD_MPIO_INDIVIDUAL_IO, "mpio"); @@ -4312,18 +4342,1674 @@ main(int argc, char **argv) H5FD_SUBFILING_NAME); #endif + nerrors += (int)nerrs; + + /* return(nerrs);*/ + +} /* test_vector_io() */ + + +/* + * Utilty routine to perform the actual selection I/O read + */ +static herr_t +test_selection_io_read_verify(hid_t dxpl, int mpi_rank, + hsize_t start[], hsize_t block[], H5FD_t *lf, H5FD_mem_t type, uint32_t count, + hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], + uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs) +{ + int *rbuf1 = NULL; + int *rbuf2 = NULL; + int *rbufs[2] = {NULL, NULL}; + size_t bufsize; + int i; + int j; + + bufsize = (hsize_t)(sel_dim0 * sel_dim1) * sizeof(int); + if ((rbuf1 = malloc(bufsize)) == NULL) + goto error; + if ((rbuf2 = malloc(bufsize)) == NULL) + goto error; + rbufs[0] = rbuf1; + rbufs[1] = rbuf2; + + /* Initialize read buffer */ + for (i = 0; i < (int)rbufcount; i++) + for (j = 0; j < sel_dim0 * sel_dim1; j++) + rbufs[i][j] = -1; + + /* Handle elements in count that are not part of rbufcount */ + for (i = (int)rbufcount; i < (int)count; i++) + if (shorten_rbufs) + rbufs[i] = NULL; + else + rbufs[i] = rbufs[rbufcount - 1]; + + /* Issue read call */ + if (H5FDread_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, + (void **)rbufs) < 0) + goto error; + + /* Verify result */ + for (i = 0; i < (int)rbufcount; i++) { + hsize_t endblock = MIN((start[i] + block[i]), (hsize_t)(sel_dim0 * sel_dim1)); + //printf("mpi_rank = %d: start[i]=%lu, block[i]=%lu, MIN is %lu\n", + // mpi_rank, start[i], block[i], endblock); + for (j = (int)start[i]; j < (int)endblock; j++) + if (rbufs[i][j] != erb[i][j]) { + H5_FAILED(); + AT(); + printf("data read from file does not match expected values at mapping array location %d: %d\n", + i, mpi_rank); + printf("expected data: \n"); + for (j = 0; j < sel_dim0 * sel_dim1; j++) { + printf("%6d", erb[i][j]); + if (!((j + 1) % sel_dim1)) + printf("\n"); + } + printf("read data: \n"); + for (j = 0; j < (sel_dim0 * sel_dim1); j++) { + printf("%6d", rbufs[i][j]); + if (!((j + 1) % sel_dim1)) + printf("\n"); + } + goto error; + } + } + + if(rbuf1) free(rbuf1); + if(rbuf2) free(rbuf2); + return 0; + +error: + if(rbuf1) free(rbuf1); + if(rbuf2) free(rbuf2); + return -1; + +} /* end test_selection_io_read_verify() */ + +/* + * Utilty routine to perform the actual selection I/O write + */ +static herr_t +test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, + hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], + size_t element_sizes[], int *wb[]) +{ + const void **bufs = NULL; /* Avoids cast/const warnings */ + int i; + int j; + + if (NULL == (bufs = calloc(count, sizeof(void *)))) + goto error; + + /* Update write buffer */ + for (i = 0; i < (int)count; i++) { + if (wb[i] && (i == 0 || wb[i] != wb[i - 1])) + for (j = 0; j < (sel_dim0 * sel_dim1); j++) + wb[i][j] += 2 * (sel_dim0 * sel_dim1); + bufs[i] = wb[i]; + } + + /* Issue write call */ + if (H5FDwrite_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, + bufs) < 0) + goto error; + + if (bufs) free(bufs); + + return 0; + +error: + if (bufs) free(bufs); + return -1; + +} /* end test_selection_io_write() */ + + +/* + * Perform the following tests that use shortened arrays for wbuf and element sizes + * --Test 1: Strided <> Strided 1D and 2D I/O for both file and memory spaces + * --Reset selections + * --Test 2: Strided <> Strided 2D I/O, 2 different selections in the same memory buffer + * --Reset selections + */ +static void +test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[], hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + int shorten_element_sizes; /* Whether to shorten the element sizes array */ + + + for (shorten_element_sizes = 0; shorten_element_sizes <= 1; shorten_element_sizes++) { + /* + * Test 1: Strided <> Strided 1D and 2D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in memory (1D) */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1 ) / 2) / mpi_size); + stride[0] = 2; + start[0] = (hsize_t)mpi_rank * stride[0] * count[0]; + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + + /* Strided selection in file (1D) */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in file (2D) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 0) in memory (2D) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[1] = start[0] * count[1]; + verify_block[1] = (count[0] * count[1] * stride[0]); + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 2, + mem_spaces, file_spaces, addrs, element_sizes, + (int **)wbufs) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file bufs */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[(2 * i) + 1] = wbuf1[2 * i]; + for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read bufs */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[2 * i] = wbuf1[2 * i]; + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = -1; + for (i = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + + /* Read and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, + (int **)erbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + verify_start[0] = start[0]; + verify_block[0] = block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + verify_start[1] = start[0] * block[1]; + verify_block[1] = (block[0] * block[1]); + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, + (int **)fbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided <> Strided 2D I/O, 2 different selections in the same memory buffer + */ + /* Switch mem and file spaces to both be 2D */ + if (H5Sset_extent_simple(mem_spaces[0], 2, dims2, NULL) < 0) + P_TEST_ERROR; + if (H5Sset_extent_simple(file_spaces[0], 2, dims2, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory (1st) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = (hsize_t)mpi_rank * count[0] * stride[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + + /* Strided selection (across dim 0) in memory (2nd) */ + start[0] = 1 + ((hsize_t)mpi_rank * count[0] * stride[0]); + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + verify_start[1] = start[0] * count[1]; + verify_block[1] = (count[0] * count[1] * stride[0]); + + /* Strided selection in file (1st) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in file (2nd) */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Use the same memory buffer for both selections */ + wbufs[0] = wbuf2; + + /* Shorten wbuf array */ + if (shorten_element_sizes) + wbufs[1] = NULL; + else + wbufs[1] = wbufs[0]; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 2, + mem_spaces, file_spaces, addrs, element_sizes, + (int **)wbufs) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file bufs - need to reuse 1D array so data stays consistent, so use math to + * find 1D index into 2D array */ + for (i = 0, i2 = 0, j2 = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf1[(i2 * sel_dim1) + j2] = wbuf2[i*sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 0; + } + } + for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < sel_dim0); + fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1 + j]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = -1; + for (i = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + for (i = 1; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + + /* Read and verify */ + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 1, + (int **)&erbufs[1], shorten_element_sizes ? TRUE : FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + verify_start[1] = start[0] * block[1]; + verify_block[1] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, + (int **)fbufs, FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Reset first spaces to 1D */ + if (H5Sset_extent_simple(mem_spaces[0], 1, dims1, NULL) < 0) + P_TEST_ERROR; + if (H5Sset_extent_simple(file_spaces[0], 1, dims1, NULL) < 0) + P_TEST_ERROR; + + /* Reset write buffer array */ + wbufs[0] = wbuf1; + wbufs[1] = wbuf2; + + /* Change to shortened element sizes array */ + element_sizes[1] = 0; + + MPI_Barrier(comm); + } + + /* Reset element sizes array */ + element_sizes[1] = element_sizes[0]; + + return; + +} /* test_selection_io_types_shorten() */ + +/* + * Perform the following tests for 1 & 2 dimensional spaces: + * --Test 1: Strided 1D (memory) <> Strided 2D (file) I/O + * --Reset selections + * --Test 2: Strided 2D (memory) <> Strided 1D (file) I/O + * --Reset selections + */ +static void +test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + + /* + * Test 1: Strided 1D (memory) <> Strided 2D (file) I/O + */ + /* Strided selection (across dim 1) in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[0], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 1, i2 = 0, j2 = 1; i < (sel_dim0 * sel_dim1); i += 2) { + assert(i2 < sel_dim0); + fbuf2[(i2*sel_dim1) + j2] = wbuf1[i]; + j2 += 2; + if (j2 >= sel_dim1) { + i2++; + j2 = 1; + } + } + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 1; i < (sel_dim0 * sel_dim1); i += 2) + erbuf1[i] = wbuf1[i]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 2: Strided 2D (memory) <> Strided 1D (file) I/O + */ + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = (hsize_t)mpi_rank * stride[0] * count[0]; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 0) in memory */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = (hsize_t)mpi_rank * count[0] * stride[0]; + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[1], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0, i2 = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) { + assert(i2 < (sel_dim0 * sel_dim1)); + fbuf1[i2] = wbuf2[i*sel_dim1 + j]; + i2 += 2; + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i * sel_dim1) + j] = -1; + for (i = 0; i < sel_dim0; i += 2) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i*sel_dim1) + j] = wbuf2[i*sel_dim1 + j]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Each process takes x number of elements */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + P_TEST_ERROR; + + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_1d_2d() */ + +/* + * Perform the following tests for 2 dimensional spaces: + * --Test 1: Simple 2D contiguous I/O for both file and memory spaces + * --Test 2: Strided (memory) <> Contiguous(file) 2D I/O + * --Reset selections + * --Test 3: Contiguous (memory) <> Strided (file) 2D I/O + * --Reset selections + * --Test 4: Strided (memory) <> Strided (file) 2D I/O + * --Reset selections + */ +static void +test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims2[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + int j; + int i2; + int j2; + + + /* + * Test 1: Simple 2D contiguous I/O + */ + + /* Contiguous selection in file and memory */ + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + fbuf2[(i*sel_dim1) + j] = wbuf2[(i * sel_dim1) + j]; + + /* Read and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + + /* + * Test 2: Strided (memory) <> Contiguous(file) 2D I/O + */ + /* Contiguous selection in file */ + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + block[1] = 1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[1] = 0; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0/ 2; i++) + for (j = 0; j < sel_dim1; j++) { + fbuf2[((i + 1) * sel_dim1) + j] = wbuf2[(((2*i)+1) * sel_dim1) + j]; + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(i*sel_dim1) + j] = -1; + for (i = 0; i < sel_dim0/ 2; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[(((2*i) + 1) * sel_dim1) + j] = wbuf2[(((2*i)+1) * sel_dim1) + j]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1]; + verify_block[0] = (count[0] * count[1] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 3: Contiguous (memory) <> Strided (file) 2D I/O + */ + + /* Strided selection in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Contiguous selection in memory */ + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1 / 2; j++) + fbuf2[i*sel_dim1 + (2 * j) + 1] = wbuf2[i * sel_dim1 + (j+1)]; + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1 + j] = -1; + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1/2; j++) + erbuf2[i*sel_dim1 + (j + 1)] = wbuf2[i*sel_dim1 + (j+1)]; + + /* Read and verify */ + verify_start[0] = start[0] * count[1] * stride[1]; + verify_block[0] = (count[0] * count[1] * stride[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 4: Strided (memory) <> Strided (file) 2D I/O + */ + /* sel_dim0 and sel_dim1 must be even */ + assert(sel_dim0 / 2 == (sel_dim0 + 1) / 2); + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection (across dim 0) in file */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + stride[0] = 2; + stride[1] = 1; + start[0] = 1 + ((hsize_t)mpi_rank * count[0] * stride[0]); + start[1] = 0; + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection (across dim 1) in memory */ + block[0] = 1; + block[1] = 1; + count[0] = (hsize_t)(sel_dim0/ mpi_size); + count[1] = (hsize_t)sel_dim1/ 2; + stride[0] = 1; + stride[1] = 2; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + (int **)&wbufs[1]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0, i2 = 1, j2 = 0; i < sel_dim0; i++) + for (j = 1; j < sel_dim1; j += 2) { + assert(i2 < sel_dim0); + fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1+ j]; + if (++j2 == sel_dim1) { + i2 += 2; + j2 = 0; + } + } + + /* Update expected read buf */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) + erbuf2[i*sel_dim1+j] = -1; + for (i = 0; i < sel_dim0; i++) + for (j = 1; j < sel_dim1; j += 2) + erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1+ j]; + /* Read and verify */ + verify_start[0] = start[0] * count[1] * stride[1]; + verify_block[0] = (count[0] * count[1] * stride[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(file_spaces[1]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(mem_spaces[1]) < 0) + P_TEST_ERROR; + + block[0] = dims2[0] / (hsize_t)mpi_size; + block[1] = dims2[1]; + count[0] = 1; + count[1] = 1; + stride[0] = block[0]; + stride[1] = block[1]; + start[0] = (hsize_t)mpi_rank * block[0]; + start[1] = 0; + + if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0] * block[1]; + verify_block[0] = (block[0] * block[1]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], + element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_2d() */ + +/* + * Perform the following tests for 1 dimensional spaces: + * --Test 1: Simple 1D contiguous I/O in both file and memory spaces + * --Test 2: Strided (memory) <> Contiguous (file) 1D I/O + * --Reset selections + * --Test 3: Contiguous (memory) <> Strided (file) 1D I/O + * --Reset selections + * --Test 4: Strided (memory) <> Strided 1D (file) I/O + * --Reset selections + */ +static void +test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[]) +{ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ + hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ + hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ + int i; + + + /* + * Test 1: Simple 1D contiguous I/O + */ + + /* Contiguous selection in file and memory */ + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + + /* Update file buf */ + for (i = 0; i < sel_dim0 * sel_dim1; i++) + fbuf1[i] = wbuf1[i]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + + /* + * Test 2: Strided (memory) <> Contiguous (file) 1D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Contiguous selection in file */ + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + block[0] = 1; + stride[0] = 2; + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[i + 1] = wbuf1[(2 * i) + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[(2 * i) + 1] = wbuf1[(2 * i) + 1]; + + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 3: Contiguous (memory) <> Strided (file) 1D I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); /* count is this value from twice above */ + stride[0] = 2; /* stride is this value from twice above */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Contiguous selection in memory */ + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[(2 * i) + 1] = wbuf1[i + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[i + 1] = wbuf1[i + 1]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = count[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Test 4: Strided (memory) <> Strided 1D (file) I/O + */ + /* sel_dim1 must be even */ + assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); + + /* Strided selection in file */ + block[0] = 1; + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + stride[0] = 2; + start[0] = 0 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Strided selection in memory */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Issue write call */ + if (test_selection_io_write(dxpl, lf, type, 1, + &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* Update file buf */ + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + fbuf1[2 * i] = wbuf1[(2 * i) + 1]; + + /* Update expected read buf */ + for (i = 0; i < (sel_dim0 * sel_dim1); i++) + erbuf1[i] = -1; + for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) + erbuf1[(2 * i) + 1] = wbuf1[(2 * i) + 1]; + + /* Read and verify */ + verify_start[0] = start[0]; + verify_block[0] = (count[0] * stride[0]); + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + /* + * Reset selections + */ + if (H5Sselect_all(mem_spaces[0]) < 0) + P_TEST_ERROR; + if (H5Sselect_all(file_spaces[0]) < 0) + P_TEST_ERROR; + + block[0] = dims1[0] / (hsize_t)mpi_size; + count[0] = 1; + stride[0] = block[0]; + start[0] = (hsize_t)mpi_rank * block[0]; + + if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) + P_TEST_ERROR; + + /* Read entire file buffer and verify */ + verify_start[0] = start[0]; + verify_block[0] = block[0]; + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, + lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], + element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + P_TEST_ERROR; + + MPI_Barrier(comm); + + return; + +} /* test_selection_io_types_1d() */ + +/* + * Perform the following tests for selection I/O: + * + * test_selection_io_types_1d(): + * ---Selection I/O tests for 1 dimensional spaces + * test_selection_io_types_2d() + * ---Selection I/O tests for 2 dimensional spaces + * test_selection_io_types_1d_2d() + * ---Selection I/O tests for 1 & 2 dimensional spaces + * test_selection_io_types_shorten() + * --Selection I/O tests that use shortened arrays for wbuf and element sizes + */ +static void +test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) +{ + hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ + hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ + hsize_t dims1[1]; /* 1d dimension sizes */ + hsize_t dims2[2]; /* 2d dimension sizes */ + + H5FD_mem_t type; /* File type */ + haddr_t addrs[2]; /* File allocation address */ + size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ + size_t bufsize; /* Buffer size */ + int i; + int j; + + curr_nerrors = nerrors; + + /* + * Default dimension sizes for mpi_size 1 or 2: + * int sel_dim0 = SELECT_IO_DIM0; + * int sel_dim1 = SELECT_IO_DIM1; + */ + if (mpi_size >= 3) { + sel_dim0 = mpi_size * 2; + sel_dim1 = mpi_size * 4; + } + + dims1[0] = (hsize_t)(sel_dim0 * sel_dim1); + dims2[0] = (hsize_t)sel_dim0, + dims2[1] = (hsize_t)sel_dim1; + + /* Create dataspaces - location 0 will be 1D and location 1 will be 2D */ + if ((mem_spaces[0] = H5Screate_simple(1, dims1, NULL)) < 0) + P_TEST_ERROR; + if ((mem_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) + P_TEST_ERROR; + if ((file_spaces[0] = H5Screate_simple(1, dims1, NULL)) < 0) + P_TEST_ERROR; + if ((file_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) + P_TEST_ERROR; + +//printf("mpi_size is %d, mpi_rank is %d, sel_dim0 is %d, sel_dim1 is %d\n", mpi_size, mpi_rank, sel_dim0, sel_dim1); + + /* Initialize global buffers: + * --wbuf1, wbuf2: write buffers + * --fbuf1, fbuf1: expected file buffers + * --erbuf1, erbuf2: expected read buffers + */ + bufsize = (size_t)(sel_dim0 * sel_dim1) * sizeof(int); + + if ((wbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((wbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + wbufs[0] = wbuf1; + wbufs[1] = wbuf2; + + if ((fbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((fbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + fbufs[0] = fbuf1; + fbufs[1] = fbuf2; + + if ((erbuf1 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + if ((erbuf2 = malloc(bufsize)) == NULL) + P_TEST_ERROR; + + erbufs[0] = erbuf1; + erbufs[1] = erbuf2; + + /* Initialize data */ + for (i = 0; i < sel_dim0; i++) + for (j = 0; j < sel_dim1; j++) { + wbuf1[(i * sel_dim1) + j] = (i * sel_dim1) + j; + wbuf2[(i * sel_dim1) + j] = (i * sel_dim1) + j + (sel_dim0 * sel_dim1); + } + + /* Loop over memory types */ + for (type = 1; type < H5FD_MEM_NTYPES; type++) { + //for (type = 1; type < 2; type++) { + + addrs[0] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); + addrs[1] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); + +#ifdef OUT +if(MAINPROCESS) +printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); +#endif + + test_selection_io_types_1d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, + mem_spaces, file_spaces, dims1); + test_selection_io_types_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, + mem_spaces, file_spaces, dims2); + test_selection_io_types_1d_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, + mem_spaces, file_spaces, dims1, dims2); + test_selection_io_types_shorten(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, + mem_spaces, file_spaces, dims1, dims2); + + } /* end for */ + + /* Close dataspaces */ + for (i = 0; i < 2; i++) { + if (H5Sclose(mem_spaces[i]) < 0) + P_TEST_ERROR; + if (H5Sclose(file_spaces[i]) < 0) + P_TEST_ERROR; + } + + /* Free the buffers */ + if (wbuf1) free(wbuf1); + if (wbuf2) free(wbuf2); + if (fbuf1) free(fbuf1); + if (fbuf2) free(fbuf2); + if (erbuf1) free(erbuf1); + if (erbuf2) free(erbuf2); + + CHECK_PASSED(); + + return; + +} /* test_selection_io_real() */ + +/* + * These tests for selection I/O are derived from test_selection_io() in + * test/vfd.c and modified for parallel testing. + */ +static void +test_selection_io(int mpi_rank, int mpi_size) +{ + H5FD_t *lf = NULL; /* VFD struct ptr */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + char filename[1024]; /* Test file name */ + unsigned flags = 0; /* File access flags */ + + unsigned collective; /* Types of I/O for testing */ + hid_t dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + hid_t def_dxpl = H5I_INVALID_HID; /* dxpl: independent access */ + hid_t col_xfer_dxpl = H5I_INVALID_HID; /* dxpl: collective access with collective I/O */ + hid_t ind_io_dxpl = H5I_INVALID_HID; /* dxpl: collective access with individual I/O */ + + /* If I use fapl in this call, I got an environment printout */ + h5_fixname(SELECT_FNAME, H5P_DEFAULT, filename, sizeof(filename)); + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + P_TEST_ERROR; + + if (H5Pset_fapl_mpio(fapl, comm, info) < 0) + P_TEST_ERROR; + + /* Create file */ + flags = H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC; + + if (NULL == (lf = H5FDopen(filename, flags, fapl, HADDR_UNDEF))) + P_TEST_ERROR; + + /* Default dxpl which will be H5FD_MPIO_INDEPENDENT by defalt */ + def_dxpl = H5Pcreate(H5P_DATASET_XFER); + + /* Set dxpl for collective access which will have H5FD_MPIO_COLLECTIVE_IO as default */ + if ((col_xfer_dxpl = H5Pcopy(def_dxpl)) < 0) + P_TEST_ERROR; + if (H5Pset_dxpl_mpio(col_xfer_dxpl, H5FD_MPIO_COLLECTIVE) < 0) + P_TEST_ERROR; + + /* Set dxpl for H5FD_MPIO_INDIVIDUAL_IO */ + if ((ind_io_dxpl = H5Pcopy(col_xfer_dxpl)) < 0) + P_TEST_ERROR; + if (H5Pset_dxpl_mpio_collective_opt(ind_io_dxpl, H5FD_MPIO_INDIVIDUAL_IO) < 0) + P_TEST_ERROR; + + for (collective = 0; collective < iotypes; collective++) { + //for (collective = 0; collective < 1; collective++) { + if (collective) + dxpl = collective == 1 ? col_xfer_dxpl : ind_io_dxpl; + else + dxpl = def_dxpl; + + if(MAINPROCESS) { + if (collective) { + if (collective == 1) + printf(" Testing with Collective access: collective I/O "); + else + printf(" Testing with Collective_access: Individual I/O "); + } else + printf(" Testing with Independent access "); + } + + /* Perform the actual tests */ + test_selection_io_real(mpi_rank, mpi_size, lf, dxpl); + + } + + /* Close file */ + if (H5FDclose(lf) < 0) + P_TEST_ERROR; + + /* Close the fapl */ + if (H5Pclose(fapl) < 0) + P_TEST_ERROR; + + if (H5Pclose(def_dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(col_xfer_dxpl) < 0) + P_TEST_ERROR; + if (H5Pclose(ind_io_dxpl) < 0) + P_TEST_ERROR; + + //if (MAINPROCESS && HDremove(filename) < 0) + // P_TEST_ERROR; + + +} /* test_selection_io() */ + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Run parallel VFD tests. + * + * Return: Success: 0 + * + * Failure: 1 + * + *------------------------------------------------------------------------- + */ + +int +main(int argc, char **argv) +{ + +#ifdef H5_HAVE_SUBFILING_VFD + int required = MPI_THREAD_MULTIPLE; + int provided = 0; +#endif + int mpi_size; + int mpi_rank; + int ret; + +#ifdef H5_HAVE_SUBFILING_VFD + if (MPI_SUCCESS != MPI_Init_thread(&argc, &argv, required, &provided)) { + printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); + goto finish; + } + + if (provided != required) { + printf(" MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE. Exiting\n"); + goto finish; + } +#else + if (MPI_SUCCESS != MPI_Init(&argc, &argv)) { + printf(" MPI_Init failed. Exiting\n"); + goto finish; + } +#endif + + MPI_Comm_size(comm, &mpi_size); + MPI_Comm_rank(comm, &mpi_rank); + + /* Attempt to turn off atexit post processing so that in case errors + * occur during the test and the process is aborted, it will not hang + * in the atexit post processing. If it does, it may try to make MPI + * calls which may not work. + */ + if (H5dont_atexit() < 0) + printf("%d:Failed to turn off atexit processing. Continue.\n", mpi_rank); + + H5open(); + + if (mpi_rank == 0) { + printf("=========================================\n"); + printf("Parallel virtual file driver (VFD) tests\n"); + printf(" mpi_size = %d\n", mpi_size); + printf("=========================================\n"); + } + + MPI_Barrier(comm); + + if (mpi_rank == 0) + printf("\n --- TESTING MPIO VFD: selection I/O --- \n"); + + test_selection_io(mpi_rank, mpi_size); + + if (mpi_rank == 0) + printf("\n --- TESTING MPIO VFD: vector I/O --- \n"); + + if (mpi_size < 2) { + if (mpi_rank == 0) { + printf(" Need at least 2 processes to run tests for vector I/O."); + SKIPPED(); + } + printf("\n"); + goto finish; + } + + test_vector_io(mpi_rank, mpi_size); + finish: /* make sure all processes are finished before final report, cleanup * and exit. */ MPI_Barrier(comm); - if (mpi_rank == 0) { /* only process 0 reports */ - printf("===================================\n"); - if (nerrs > 0) - printf("***vfd tests detected %d failures***\n", nerrs); + /* Gather errors from all processes */ + MPI_Allreduce(&nerrors, &ret, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); + nerrors = ret; + + if (MAINPROCESS) { + printf("\n===================================\n"); + if (nerrors) + printf("***Parallel vfd tests detected %d errors***\n", nerrors); else - printf("vfd tests finished with no failures\n"); + printf("Parallel vfd tests finished with no errors\n"); printf("===================================\n"); } @@ -4337,6 +6023,6 @@ main(int argc, char **argv) MPI_Finalize(); /* cannot just return (nerrs) because exit code is limited to 1byte */ - return (nerrs > 0); + return (nerrors != 0); -} /* main() */ +} /* main() */ From efbe96cb9290915f7d1be6a8c95396c8640e6ea4 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 16:48:13 +0000 Subject: [PATCH 10/19] Committing clang-format changes --- testpar/t_vfd.c | 658 +++++++++++++++++++++++------------------------- 1 file changed, 319 insertions(+), 339 deletions(-) diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index 40b8725fed6..ac8adb30eaf 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -105,7 +105,7 @@ static unsigned vector_write_test_7(int file_name_id, int mpi_rank, int mpi_size * They are derived from test_selection_io() in test/vfd.c and modified for parallel testing. */ -/* +/* * Global declarations for selection I/O tests` */ @@ -123,27 +123,27 @@ int sel_dim0 = SEL_IO_DIM0; int sel_dim1 = SEL_IO_DIM1; /* Write buffers */ -int *wbuf1 = NULL; -int *wbuf2 = NULL; +int *wbuf1 = NULL; +int *wbuf2 = NULL; int *wbufs[2] = {NULL, NULL}; /* File buffers */ -int *fbuf1 = NULL; -int *fbuf2 = NULL; -int *fbufs[2] = {NULL, NULL}; /* Array of file buffers */ +int *fbuf1 = NULL; +int *fbuf2 = NULL; +int *fbufs[2] = {NULL, NULL}; /* Array of file buffers */ /* Expected read buffers */ -int *erbuf1 = NULL; -int *erbuf2 = NULL; -int *erbufs[2] = {NULL, NULL}; /* Array of expected read buffers */ +int *erbuf1 = NULL; +int *erbuf2 = NULL; +int *erbufs[2] = {NULL, NULL}; /* Array of expected read buffers */ -/* iotypes for testing: +/* iotypes for testing: H5FD_MPIO_INDEPENDENT H5FD_MPIO_COLLECTIVE - --H5FD_MPIO_COLLECTIVE_IO - --H5FD_MPIO_INDIVIDUAL_IO + --H5FD_MPIO_COLLECTIVE_IO + --H5FD_MPIO_INDIVIDUAL_IO */ -#define iotypes 3 +#define iotypes 3 #define P_TEST_ERROR \ do { \ @@ -166,35 +166,35 @@ int *erbufs[2] = {NULL, NULL}; /* Array of expected read buf } \ } while (0) - /* Utility functions for selection I/O */ -static herr_t test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], - H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], - size_t element_sizes[], uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs); +static herr_t test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], + H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], + hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], + uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs); -static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, - hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], int *wb[]); +static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, + hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], + size_t element_sizes[], int *wb[]); /* Test functions for selection I/O */ static void test_selection_io(int mpi_rank, int mpi_size); static void test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl); -static void test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], - hsize_t dims1[]); -static void test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], - hsize_t dims2[]); -static void test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], - hsize_t dims1[], hsize_t dims2[]); +static void test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[]); +static void test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims2[]); +static void test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]); static void test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], - hsize_t dims1[], hsize_t dims2[]); - + H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], + hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[], + hsize_t dims2[]); /****************************************************************************/ - /****************************************************************************/ /***************************** Utility Functions ****************************/ /****************************************************************************/ @@ -4348,22 +4348,21 @@ test_vector_io(int mpi_rank, int mpi_size) } /* test_vector_io() */ - /* * Utilty routine to perform the actual selection I/O read */ static herr_t -test_selection_io_read_verify(hid_t dxpl, int mpi_rank, - hsize_t start[], hsize_t block[], H5FD_t *lf, H5FD_mem_t type, uint32_t count, - hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], - uint32_t rbufcount, int *erb[], hbool_t shorten_rbufs) +test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], H5FD_t *lf, + H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], hid_t file_spaces[], + haddr_t offsets[], size_t element_sizes[], uint32_t rbufcount, int *erb[], + hbool_t shorten_rbufs) { - int *rbuf1 = NULL; - int *rbuf2 = NULL; - int *rbufs[2] = {NULL, NULL}; + int *rbuf1 = NULL; + int *rbuf2 = NULL; + int *rbufs[2] = {NULL, NULL}; size_t bufsize; - int i; - int j; + int i; + int j; bufsize = (hsize_t)(sel_dim0 * sel_dim1) * sizeof(int); if ((rbuf1 = malloc(bufsize)) == NULL) @@ -4393,14 +4392,15 @@ test_selection_io_read_verify(hid_t dxpl, int mpi_rank, /* Verify result */ for (i = 0; i < (int)rbufcount; i++) { hsize_t endblock = MIN((start[i] + block[i]), (hsize_t)(sel_dim0 * sel_dim1)); - //printf("mpi_rank = %d: start[i]=%lu, block[i]=%lu, MIN is %lu\n", - // mpi_rank, start[i], block[i], endblock); + // printf("mpi_rank = %d: start[i]=%lu, block[i]=%lu, MIN is %lu\n", + // mpi_rank, start[i], block[i], endblock); for (j = (int)start[i]; j < (int)endblock; j++) if (rbufs[i][j] != erb[i][j]) { H5_FAILED(); AT(); - printf("data read from file does not match expected values at mapping array location %d: %d\n", - i, mpi_rank); + printf( + "data read from file does not match expected values at mapping array location %d: %d\n", + i, mpi_rank); printf("expected data: \n"); for (j = 0; j < sel_dim0 * sel_dim1; j++) { printf("%6d", erb[i][j]); @@ -4417,24 +4417,27 @@ test_selection_io_read_verify(hid_t dxpl, int mpi_rank, } } - if(rbuf1) free(rbuf1); - if(rbuf2) free(rbuf2); + if (rbuf1) + free(rbuf1); + if (rbuf2) + free(rbuf2); return 0; error: - if(rbuf1) free(rbuf1); - if(rbuf2) free(rbuf2); + if (rbuf1) + free(rbuf1); + if (rbuf2) + free(rbuf2); return -1; } /* end test_selection_io_read_verify() */ /* - * Utilty routine to perform the actual selection I/O write + * Utilty routine to perform the actual selection I/O write */ static herr_t -test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, - hid_t mem_spaces[], hid_t file_spaces[], haddr_t offsets[], - size_t element_sizes[], int *wb[]) +test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], + hid_t file_spaces[], haddr_t offsets[], size_t element_sizes[], int *wb[]) { const void **bufs = NULL; /* Avoids cast/const warnings */ int i; @@ -4444,7 +4447,7 @@ test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, goto error; /* Update write buffer */ - for (i = 0; i < (int)count; i++) { + for (i = 0; i < (int)count; i++) { if (wb[i] && (i == 0 || wb[i] != wb[i - 1])) for (j = 0; j < (sel_dim0 * sel_dim1); j++) wb[i][j] += 2 * (sel_dim0 * sel_dim1); @@ -4452,21 +4455,21 @@ test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, } /* Issue write call */ - if (H5FDwrite_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, - bufs) < 0) + if (H5FDwrite_selection(lf, type, dxpl, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) goto error; - if (bufs) free(bufs); + if (bufs) + free(bufs); return 0; error: - if (bufs) free(bufs); + if (bufs) + free(bufs); return -1; } /* end test_selection_io_write() */ - /* * Perform the following tests that use shortened arrays for wbuf and element sizes * --Test 1: Strided <> Strided 1D and 2D I/O for both file and memory spaces @@ -4475,25 +4478,23 @@ test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, * --Reset selections */ static void -test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], - hid_t mem_spaces[], hid_t file_spaces[], - hsize_t dims1[], hsize_t dims2[]) +test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) { - hsize_t start[2]; /* start for hyperslab */ - hsize_t stride[2]; /* stride for hyperslab */ - hsize_t count[2]; /* count for hyperslab */ - hsize_t block[2]; /* block for hyperslab */ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ - int i; - int j; - int i2; - int j2; + int i; + int j; + int i2; + int j2; int shorten_element_sizes; /* Whether to shorten the element sizes array */ - for (shorten_element_sizes = 0; shorten_element_sizes <= 1; shorten_element_sizes++) { /* * Test 1: Strided <> Strided 1D and 2D I/O @@ -4503,7 +4504,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx /* Strided selection in memory (1D) */ block[0] = 1; - count[0] = (hsize_t)(((sel_dim0 * sel_dim1 ) / 2) / mpi_size); + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); stride[0] = 2; start[0] = (hsize_t)mpi_rank * stride[0] * count[0]; if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) @@ -4536,7 +4537,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx count[1] = (hsize_t)sel_dim1; stride[0] = 2; stride[1] = 1; - start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); start[1] = 0; if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; @@ -4545,8 +4546,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx verify_block[1] = (count[0] * count[1] * stride[0]); /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 2, - mem_spaces, file_spaces, addrs, element_sizes, + if (test_selection_io_write(dxpl, lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, (int **)wbufs) < 0) P_TEST_ERROR; @@ -4558,13 +4558,13 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) { assert(i2 < sel_dim0); - fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1 + j]; + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; j2 += 2; if (j2 >= sel_dim1) { - i2++; - j2 = 1; + i2++; + j2 = 1; } - } + } /* Update expected read bufs */ for (i = 0; i < (sel_dim0 * sel_dim1); i++) @@ -4573,21 +4573,20 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx erbuf1[2 * i] = wbuf1[2 * i]; for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = -1; + erbuf2[i * sel_dim1 + j] = -1; for (i = 1; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; /* Read and verify */ - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, - (int **)erbufs, FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)erbufs, FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[0]) < 0) P_TEST_ERROR; @@ -4632,9 +4631,8 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx P_TEST_ERROR; /* Read entire file buffer and verify */ - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, - (int **)fbufs, FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)fbufs, FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -4706,8 +4704,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx wbufs[1] = wbufs[0]; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 2, - mem_spaces, file_spaces, addrs, element_sizes, + if (test_selection_io_write(dxpl, lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, (int **)wbufs) < 0) P_TEST_ERROR; @@ -4718,7 +4715,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx for (i = 0, i2 = 0, j2 = 0; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) { assert(i2 < sel_dim0); - fbuf1[(i2 * sel_dim1) + j2] = wbuf2[i*sel_dim1 + j]; + fbuf1[(i2 * sel_dim1) + j2] = wbuf2[i * sel_dim1 + j]; j2 += 2; if (j2 >= sel_dim1) { i2++; @@ -4728,7 +4725,7 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx for (i = 1, i2 = 0, j2 = 1; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) { assert(i2 < sel_dim0); - fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1 + j]; + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; j2 += 2; if (j2 >= sel_dim1) { i2++; @@ -4739,24 +4736,24 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx /* Update expected read buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = -1; + erbuf2[i * sel_dim1 + j] = -1; for (i = 0; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; for (i = 1; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1 + j]; + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; /* Read and verify */ - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 1, - (int **)&erbufs[1], shorten_element_sizes ? TRUE : FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 1, (int **)&erbufs[1], + shorten_element_sizes ? TRUE : FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[0]) < 0) P_TEST_ERROR; @@ -4793,9 +4790,8 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx verify_block[0] = (block[0] * block[1]); verify_start[1] = start[0] * block[1]; verify_block[1] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 2, mem_spaces, file_spaces, addrs, element_sizes, 2, - (int **)fbufs, FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 2, mem_spaces, + file_spaces, addrs, element_sizes, 2, (int **)fbufs, FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -4831,21 +4827,20 @@ test_selection_io_types_shorten(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dx * --Reset selections */ static void -test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], - hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) +test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], + hid_t file_spaces[], hsize_t dims1[], hsize_t dims2[]) { - hsize_t start[2]; /* start for hyperslab */ - hsize_t stride[2]; /* stride for hyperslab */ - hsize_t count[2]; /* count for hyperslab */ - hsize_t block[2]; /* block for hyperslab */ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ - int i; - int j; - int i2; - int j2; - + int i; + int j; + int i2; + int j2; /* * Test 1: Strided 1D (memory) <> Strided 2D (file) I/O @@ -4871,8 +4866,7 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[0], &file_spaces[1], &addrs[1], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], element_sizes, (int **)&wbufs[0]) < 0) P_TEST_ERROR; @@ -4881,7 +4875,7 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl /* Update file buf */ for (i = 1, i2 = 0, j2 = 1; i < (sel_dim0 * sel_dim1); i += 2) { assert(i2 < sel_dim0); - fbuf2[(i2*sel_dim1) + j2] = wbuf1[i]; + fbuf2[(i2 * sel_dim1) + j2] = wbuf1[i]; j2 += 2; if (j2 >= sel_dim1) { i2++; @@ -4898,15 +4892,15 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl /* Read and verify */ verify_start[0] = start[0]; verify_block[0] = (count[0] * stride[0]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(file_spaces[1]) < 0) P_TEST_ERROR; @@ -4935,9 +4929,9 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl /* Read entire file buffer and verify */ verify_start[0] = start[0]; verify_block[0] = block[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -4966,8 +4960,7 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[1], &file_spaces[0], &addrs[0], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], element_sizes, (int **)&wbufs[1]) < 0) P_TEST_ERROR; @@ -4977,7 +4970,7 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl for (i = 0, i2 = 0; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) { assert(i2 < (sel_dim0 * sel_dim1)); - fbuf1[i2] = wbuf2[i*sel_dim1 + j]; + fbuf1[i2] = wbuf2[i * sel_dim1 + j]; i2 += 2; } @@ -4987,20 +4980,20 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl erbuf2[(i * sel_dim1) + j] = -1; for (i = 0; i < sel_dim0; i += 2) for (j = 0; j < sel_dim1; j++) - erbuf2[(i*sel_dim1) + j] = wbuf2[i*sel_dim1 + j]; + erbuf2[(i * sel_dim1) + j] = wbuf2[i * sel_dim1 + j]; /* Read and verify */ verify_start[0] = start[0] * count[1]; verify_block[0] = (count[0] * count[1] * stride[0]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(file_spaces[0]) < 0) P_TEST_ERROR; @@ -5031,12 +5024,11 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl /* Read entire file buffer and verify */ verify_start[0] = start[0] * block[1]; verify_block[0] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) P_TEST_ERROR; - MPI_Barrier(comm); return; @@ -5054,24 +5046,23 @@ test_selection_io_types_1d_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl * --Reset selections */ static void -test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], - hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims2[]) +test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims2[]) { - hsize_t start[2]; /* start for hyperslab */ - hsize_t stride[2]; /* stride for hyperslab */ - hsize_t count[2]; /* count for hyperslab */ - hsize_t block[2]; /* block for hyperslab */ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ - int i; - int j; - int i2; - int j2; + int i; + int j; + int i2; + int j2; - - /* - * Test 1: Simple 2D contiguous I/O + /* + * Test 1: Simple 2D contiguous I/O */ /* Contiguous selection in file and memory */ @@ -5089,8 +5080,7 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, (int **)&wbufs[1]) < 0) P_TEST_ERROR; @@ -5099,27 +5089,26 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Update file buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - fbuf2[(i*sel_dim1) + j] = wbuf2[(i * sel_dim1) + j]; + fbuf2[(i * sel_dim1) + j] = wbuf2[(i * sel_dim1) + j]; /* Read and verify */ verify_start[0] = start[0] * block[1]; verify_block[0] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* * Test 2: Strided (memory) <> Contiguous(file) 2D I/O */ /* Contiguous selection in file */ - count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); - count[1] = (hsize_t)sel_dim1; - start[0] = 1 + ((hsize_t)mpi_rank * count[0]); - start[1] = 0; + count[0] = (hsize_t)((sel_dim0 / 2) / mpi_size); + count[1] = (hsize_t)sel_dim1; + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + start[1] = 0; if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, NULL, count, NULL) < 0) P_TEST_ERROR; @@ -5134,39 +5123,38 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, (int **)&wbufs[1]) < 0) P_TEST_ERROR; MPI_Barrier(comm); /* Update file buf */ - for (i = 0; i < sel_dim0/ 2; i++) + for (i = 0; i < sel_dim0 / 2; i++) for (j = 0; j < sel_dim1; j++) { - fbuf2[((i + 1) * sel_dim1) + j] = wbuf2[(((2*i)+1) * sel_dim1) + j]; + fbuf2[((i + 1) * sel_dim1) + j] = wbuf2[(((2 * i) + 1) * sel_dim1) + j]; } /* Update expected read buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[(i*sel_dim1) + j] = -1; - for (i = 0; i < sel_dim0/ 2; i++) + erbuf2[(i * sel_dim1) + j] = -1; + for (i = 0; i < sel_dim0 / 2; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[(((2*i) + 1) * sel_dim1) + j] = wbuf2[(((2*i)+1) * sel_dim1) + j]; + erbuf2[(((2 * i) + 1) * sel_dim1) + j] = wbuf2[(((2 * i) + 1) * sel_dim1) + j]; /* Read and verify */ verify_start[0] = start[0] * count[1]; verify_block[0] = (count[0] * count[1] * stride[0]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[1]) < 0) P_TEST_ERROR; @@ -5190,9 +5178,9 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0] * block[1]; verify_block[0] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5204,12 +5192,12 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Strided selection in file */ block[0] = 1; block[1] = 1; - count[0] = (hsize_t)(sel_dim0 / mpi_size); - count[1] = (hsize_t)sel_dim1 / 2; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; stride[0] = 1; stride[1] = 2; - start[0] = (hsize_t)mpi_rank * count[0]; - start[1] = 1; + start[0] = (hsize_t)mpi_rank * count[0]; + start[1] = 1; if (H5Sselect_hyperslab(file_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; @@ -5218,8 +5206,7 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, (int **)&wbufs[1]) < 0) P_TEST_ERROR; @@ -5228,29 +5215,29 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Update file buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1 / 2; j++) - fbuf2[i*sel_dim1 + (2 * j) + 1] = wbuf2[i * sel_dim1 + (j+1)]; + fbuf2[i * sel_dim1 + (2 * j) + 1] = wbuf2[i * sel_dim1 + (j + 1)]; /* Update expected read buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1 + j] = -1; + erbuf2[i * sel_dim1 + j] = -1; for (i = 0; i < sel_dim0; i++) - for (j = 0; j < sel_dim1/2; j++) - erbuf2[i*sel_dim1 + (j + 1)] = wbuf2[i*sel_dim1 + (j+1)]; + for (j = 0; j < sel_dim1 / 2; j++) + erbuf2[i * sel_dim1 + (j + 1)] = wbuf2[i * sel_dim1 + (j + 1)]; /* Read and verify */ verify_start[0] = start[0] * count[1] * stride[1]; verify_block[0] = (count[0] * count[1] * stride[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections - */ + /* + * Reset selections + */ if (H5Sselect_all(mem_spaces[1]) < 0) P_TEST_ERROR; if (H5Sselect_all(file_spaces[1]) < 0) @@ -5273,9 +5260,9 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0] * block[1]; verify_block[0] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5302,8 +5289,8 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Strided selection (across dim 1) in memory */ block[0] = 1; block[1] = 1; - count[0] = (hsize_t)(sel_dim0/ mpi_size); - count[1] = (hsize_t)sel_dim1/ 2; + count[0] = (hsize_t)(sel_dim0 / mpi_size); + count[1] = (hsize_t)sel_dim1 / 2; stride[0] = 1; stride[1] = 2; start[0] = (hsize_t)mpi_rank * count[0]; @@ -5311,10 +5298,8 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, if (H5Sselect_hyperslab(mem_spaces[1], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; - /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], element_sizes, (int **)&wbufs[1]) < 0) P_TEST_ERROR; @@ -5324,7 +5309,7 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, for (i = 0, i2 = 1, j2 = 0; i < sel_dim0; i++) for (j = 1; j < sel_dim1; j += 2) { assert(i2 < sel_dim0); - fbuf2[i2*sel_dim1 + j2] = wbuf2[i*sel_dim1+ j]; + fbuf2[i2 * sel_dim1 + j2] = wbuf2[i * sel_dim1 + j]; if (++j2 == sel_dim1) { i2 += 2; j2 = 0; @@ -5334,22 +5319,22 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Update expected read buf */ for (i = 0; i < sel_dim0; i++) for (j = 0; j < sel_dim1; j++) - erbuf2[i*sel_dim1+j] = -1; + erbuf2[i * sel_dim1 + j] = -1; for (i = 0; i < sel_dim0; i++) for (j = 1; j < sel_dim1; j += 2) - erbuf2[i*sel_dim1 + j] = wbuf2[i*sel_dim1+ j]; + erbuf2[i * sel_dim1 + j] = wbuf2[i * sel_dim1 + j]; /* Read and verify */ verify_start[0] = start[0] * count[1] * stride[1]; verify_block[0] = (count[0] * count[1] * stride[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&erbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&erbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(file_spaces[1]) < 0) P_TEST_ERROR; @@ -5373,9 +5358,9 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0] * block[1]; verify_block[0] = (block[0] * block[1]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[1], &file_spaces[1], &addrs[1], - element_sizes, 1, (int **)&fbufs[1], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[1], + &file_spaces[1], &addrs[1], element_sizes, 1, (int **)&fbufs[1], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5384,7 +5369,7 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, } /* test_selection_io_types_2d() */ -/* +/* * Perform the following tests for 1 dimensional spaces: * --Test 1: Simple 1D contiguous I/O in both file and memory spaces * --Test 2: Strided (memory) <> Contiguous (file) 1D I/O @@ -5395,18 +5380,17 @@ test_selection_io_types_2d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, * --Reset selections */ static void -test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, - H5FD_mem_t type, haddr_t addrs[], size_t element_sizes[], - hid_t mem_spaces[], hid_t file_spaces[], hsize_t dims1[]) +test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, H5FD_mem_t type, + haddr_t addrs[], size_t element_sizes[], hid_t mem_spaces[], hid_t file_spaces[], + hsize_t dims1[]) { - hsize_t start[2]; /* start for hyperslab */ - hsize_t stride[2]; /* stride for hyperslab */ - hsize_t count[2]; /* count for hyperslab */ - hsize_t block[2]; /* block for hyperslab */ + hsize_t start[2]; /* start for hyperslab */ + hsize_t stride[2]; /* stride for hyperslab */ + hsize_t count[2]; /* count for hyperslab */ + hsize_t block[2]; /* block for hyperslab */ hsize_t verify_start[2] = {0, 0}; /* Starting block for verified data */ hsize_t verify_block[2] = {0, 0}; /* Block size for verified data */ - int i; - + int i; /* * Test 1: Simple 1D contiguous I/O @@ -5423,17 +5407,14 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; - /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, - (int **)&wbufs[0]) < 0) + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + (int **)&wbufs[0]) < 0) P_TEST_ERROR; MPI_Barrier(comm); - - /* Update file buf */ + /* Update file buf */ for (i = 0; i < sel_dim0 * sel_dim1; i++) fbuf1[i] = wbuf1[i]; @@ -5441,14 +5422,13 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, verify_start[0] = start[0]; verify_block[0] = block[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* * Test 2: Strided (memory) <> Contiguous (file) 1D I/O */ @@ -5456,7 +5436,7 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); /* Contiguous selection in file */ - count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); + count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); start[0] = 1 + ((hsize_t)mpi_rank * count[0]); if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) P_TEST_ERROR; @@ -5468,10 +5448,8 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; - /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, (int **)&wbufs[0]) < 0) P_TEST_ERROR; @@ -5487,19 +5465,18 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, for (i = 0; i < (sel_dim0 * sel_dim1) / 2; i++) erbuf1[(2 * i) + 1] = wbuf1[(2 * i) + 1]; - /* Read and verify */ verify_start[0] = start[0]; verify_block[0] = (count[0] * stride[0]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[0]) < 0) P_TEST_ERROR; @@ -5519,9 +5496,9 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0]; verify_block[0] = block[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5533,21 +5510,20 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, assert(sel_dim1 / 2 == (sel_dim1 + 1) / 2); /* Strided selection in file */ - block[0] = 1; + block[0] = 1; count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); /* count is this value from twice above */ - stride[0] = 2; /* stride is this value from twice above */ - start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + stride[0] = 2; /* stride is this value from twice above */ + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; /* Contiguous selection in memory */ - start[0] = 1 + ((hsize_t)mpi_rank * count[0]); + start[0] = 1 + ((hsize_t)mpi_rank * count[0]); if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, NULL, count, NULL) < 0) P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, (int **)&wbufs[0]) < 0) P_TEST_ERROR; @@ -5566,15 +5542,15 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read and verify */ verify_start[0] = start[0]; verify_block[0] = count[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[0]) < 0) P_TEST_ERROR; @@ -5594,9 +5570,9 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0]; verify_block[0] = block[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5611,18 +5587,17 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, block[0] = 1; count[0] = (hsize_t)(((sel_dim0 * sel_dim1) / 2) / mpi_size); stride[0] = 2; - start[0] = 0 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[0] = 0 + ((hsize_t)mpi_rank * stride[0] * count[0]); if (H5Sselect_hyperslab(file_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; /* Strided selection in memory */ - start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); + start[0] = 1 + ((hsize_t)mpi_rank * stride[0] * count[0]); if (H5Sselect_hyperslab(mem_spaces[0], H5S_SELECT_SET, start, stride, count, block) < 0) P_TEST_ERROR; /* Issue write call */ - if (test_selection_io_write(dxpl, lf, type, 1, - &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, + if (test_selection_io_write(dxpl, lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], element_sizes, (int **)&wbufs[0]) < 0) P_TEST_ERROR; @@ -5641,15 +5616,15 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read and verify */ verify_start[0] = start[0]; verify_block[0] = (count[0] * stride[0]); - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&erbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&erbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); - /* - * Reset selections + /* + * Reset selections */ if (H5Sselect_all(mem_spaces[0]) < 0) P_TEST_ERROR; @@ -5669,9 +5644,9 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, /* Read entire file buffer and verify */ verify_start[0] = start[0]; verify_block[0] = block[0]; - if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, - lf, type, 1, &mem_spaces[0], &file_spaces[0], &addrs[0], - element_sizes, 1, (int **)&fbufs[0], FALSE) < 0) + if (test_selection_io_read_verify(dxpl, mpi_rank, verify_start, verify_block, lf, type, 1, &mem_spaces[0], + &file_spaces[0], &addrs[0], element_sizes, 1, (int **)&fbufs[0], + FALSE) < 0) P_TEST_ERROR; MPI_Barrier(comm); @@ -5695,33 +5670,32 @@ test_selection_io_types_1d(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl, static void test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) { - hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ - hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ - hsize_t dims1[1]; /* 1d dimension sizes */ - hsize_t dims2[2]; /* 2d dimension sizes */ - - H5FD_mem_t type; /* File type */ - haddr_t addrs[2]; /* File allocation address */ - size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ - size_t bufsize; /* Buffer size */ - int i; - int j; + hid_t mem_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* memory dataspaces vector */ + hid_t file_spaces[2] = {H5I_INVALID_HID, H5I_INVALID_HID}; /* file dataspaces vector */ + hsize_t dims1[1]; /* 1d dimension sizes */ + hsize_t dims2[2]; /* 2d dimension sizes */ + + H5FD_mem_t type; /* File type */ + haddr_t addrs[2]; /* File allocation address */ + size_t element_sizes[2] = {sizeof(int), sizeof(int)}; /* Element size */ + size_t bufsize; /* Buffer size */ + int i; + int j; curr_nerrors = nerrors; - /* + /* * Default dimension sizes for mpi_size 1 or 2: * int sel_dim0 = SELECT_IO_DIM0; * int sel_dim1 = SELECT_IO_DIM1; */ if (mpi_size >= 3) { sel_dim0 = mpi_size * 2; - sel_dim1 = mpi_size * 4; + sel_dim1 = mpi_size * 4; } - dims1[0] = (hsize_t)(sel_dim0 * sel_dim1); - dims2[0] = (hsize_t)sel_dim0, - dims2[1] = (hsize_t)sel_dim1; + dims1[0] = (hsize_t)(sel_dim0 * sel_dim1); + dims2[0] = (hsize_t)sel_dim0, dims2[1] = (hsize_t)sel_dim1; /* Create dataspaces - location 0 will be 1D and location 1 will be 2D */ if ((mem_spaces[0] = H5Screate_simple(1, dims1, NULL)) < 0) @@ -5733,7 +5707,8 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) if ((file_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) P_TEST_ERROR; -//printf("mpi_size is %d, mpi_rank is %d, sel_dim0 is %d, sel_dim1 is %d\n", mpi_size, mpi_rank, sel_dim0, sel_dim1); + // printf("mpi_size is %d, mpi_rank is %d, sel_dim0 is %d, sel_dim1 is %d\n", mpi_size, mpi_rank, + // sel_dim0, sel_dim1); /* Initialize global buffers: * --wbuf1, wbuf2: write buffers @@ -5763,7 +5738,7 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) if ((erbuf1 = malloc(bufsize)) == NULL) P_TEST_ERROR; - if ((erbuf2 = malloc(bufsize)) == NULL) + if ((erbuf2 = malloc(bufsize)) == NULL) P_TEST_ERROR; erbufs[0] = erbuf1; @@ -5778,24 +5753,24 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) /* Loop over memory types */ for (type = 1; type < H5FD_MEM_NTYPES; type++) { - //for (type = 1; type < 2; type++) { + // for (type = 1; type < 2; type++) { addrs[0] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); addrs[1] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); #ifdef OUT -if(MAINPROCESS) -printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); + if (MAINPROCESS) + printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); #endif - test_selection_io_types_1d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, - mem_spaces, file_spaces, dims1); - test_selection_io_types_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, - mem_spaces, file_spaces, dims2); - test_selection_io_types_1d_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, - mem_spaces, file_spaces, dims1, dims2); - test_selection_io_types_shorten(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, - mem_spaces, file_spaces, dims1, dims2); + test_selection_io_types_1d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1); + test_selection_io_types_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims2); + test_selection_io_types_1d_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1, dims2); + test_selection_io_types_shorten(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, + file_spaces, dims1, dims2); } /* end for */ @@ -5808,12 +5783,18 @@ printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); } /* Free the buffers */ - if (wbuf1) free(wbuf1); - if (wbuf2) free(wbuf2); - if (fbuf1) free(fbuf1); - if (fbuf2) free(fbuf2); - if (erbuf1) free(erbuf1); - if (erbuf2) free(erbuf2); + if (wbuf1) + free(wbuf1); + if (wbuf2) + free(wbuf2); + if (fbuf1) + free(fbuf1); + if (fbuf2) + free(fbuf2); + if (erbuf1) + free(erbuf1); + if (erbuf2) + free(erbuf2); CHECK_PASSED(); @@ -5822,22 +5803,22 @@ printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); } /* test_selection_io_real() */ /* - * These tests for selection I/O are derived from test_selection_io() in + * These tests for selection I/O are derived from test_selection_io() in * test/vfd.c and modified for parallel testing. */ static void test_selection_io(int mpi_rank, int mpi_size) { - H5FD_t *lf = NULL; /* VFD struct ptr */ - hid_t fapl = H5I_INVALID_HID; /* File access property list */ - char filename[1024]; /* Test file name */ - unsigned flags = 0; /* File access flags */ + H5FD_t *lf = NULL; /* VFD struct ptr */ + hid_t fapl = H5I_INVALID_HID; /* File access property list */ + char filename[1024]; /* Test file name */ + unsigned flags = 0; /* File access flags */ - unsigned collective; /* Types of I/O for testing */ - hid_t dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - hid_t def_dxpl = H5I_INVALID_HID; /* dxpl: independent access */ - hid_t col_xfer_dxpl = H5I_INVALID_HID; /* dxpl: collective access with collective I/O */ - hid_t ind_io_dxpl = H5I_INVALID_HID; /* dxpl: collective access with individual I/O */ + unsigned collective; /* Types of I/O for testing */ + hid_t dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + hid_t def_dxpl = H5I_INVALID_HID; /* dxpl: independent access */ + hid_t col_xfer_dxpl = H5I_INVALID_HID; /* dxpl: collective access with collective I/O */ + hid_t ind_io_dxpl = H5I_INVALID_HID; /* dxpl: collective access with individual I/O */ /* If I use fapl in this call, I got an environment printout */ h5_fixname(SELECT_FNAME, H5P_DEFAULT, filename, sizeof(filename)); @@ -5850,7 +5831,7 @@ test_selection_io(int mpi_rank, int mpi_size) /* Create file */ flags = H5F_ACC_RDWR | H5F_ACC_CREAT | H5F_ACC_TRUNC; - + if (NULL == (lf = H5FDopen(filename, flags, fapl, HADDR_UNDEF))) P_TEST_ERROR; @@ -5868,33 +5849,33 @@ test_selection_io(int mpi_rank, int mpi_size) P_TEST_ERROR; if (H5Pset_dxpl_mpio_collective_opt(ind_io_dxpl, H5FD_MPIO_INDIVIDUAL_IO) < 0) P_TEST_ERROR; - + for (collective = 0; collective < iotypes; collective++) { - //for (collective = 0; collective < 1; collective++) { + // for (collective = 0; collective < 1; collective++) { if (collective) dxpl = collective == 1 ? col_xfer_dxpl : ind_io_dxpl; else dxpl = def_dxpl; - if(MAINPROCESS) { - if (collective) { - if (collective == 1) - printf(" Testing with Collective access: collective I/O "); + if (MAINPROCESS) { + if (collective) { + if (collective == 1) + printf(" Testing with Collective access: collective I/O "); + else + printf(" Testing with Collective_access: Individual I/O "); + } else - printf(" Testing with Collective_access: Individual I/O "); - } else - printf(" Testing with Independent access "); - } + printf(" Testing with Independent access "); + } /* Perform the actual tests */ test_selection_io_real(mpi_rank, mpi_size, lf, dxpl); - } /* Close file */ if (H5FDclose(lf) < 0) P_TEST_ERROR; - + /* Close the fapl */ if (H5Pclose(fapl) < 0) P_TEST_ERROR; @@ -5906,9 +5887,8 @@ test_selection_io(int mpi_rank, int mpi_size) if (H5Pclose(ind_io_dxpl) < 0) P_TEST_ERROR; - //if (MAINPROCESS && HDremove(filename) < 0) - // P_TEST_ERROR; - + // if (MAINPROCESS && HDremove(filename) < 0) + // P_TEST_ERROR; } /* test_selection_io() */ @@ -5934,7 +5914,7 @@ main(int argc, char **argv) #endif int mpi_size; int mpi_rank; - int ret; + int ret; #ifdef H5_HAVE_SUBFILING_VFD if (MPI_SUCCESS != MPI_Init_thread(&argc, &argv, required, &provided)) { @@ -6025,4 +6005,4 @@ main(int argc, char **argv) /* cannot just return (nerrs) because exit code is limited to 1byte */ return (nerrors != 0); -} /* main() */ +} /* main() */ From 40c3d648aff1ba699ea91794d4815bc3eaf6f430 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Thu, 27 Jul 2023 11:55:11 -0500 Subject: [PATCH 11/19] Correct spelling errors. Remove debugging printfs. --- testpar/t_vfd.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index ac8adb30eaf..c2c07e2c207 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -4349,7 +4349,7 @@ test_vector_io(int mpi_rank, int mpi_size) } /* test_vector_io() */ /* - * Utilty routine to perform the actual selection I/O read + * Utility routine to perform the actual selection I/O read */ static herr_t test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t block[], H5FD_t *lf, @@ -4392,8 +4392,6 @@ test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t /* Verify result */ for (i = 0; i < (int)rbufcount; i++) { hsize_t endblock = MIN((start[i] + block[i]), (hsize_t)(sel_dim0 * sel_dim1)); - // printf("mpi_rank = %d: start[i]=%lu, block[i]=%lu, MIN is %lu\n", - // mpi_rank, start[i], block[i], endblock); for (j = (int)start[i]; j < (int)endblock; j++) if (rbufs[i][j] != erb[i][j]) { H5_FAILED(); @@ -4433,7 +4431,7 @@ test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t } /* end test_selection_io_read_verify() */ /* - * Utilty routine to perform the actual selection I/O write + * Utility routine to perform the actual selection I/O write */ static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], @@ -5707,9 +5705,6 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) if ((file_spaces[1] = H5Screate_simple(2, dims2, NULL)) < 0) P_TEST_ERROR; - // printf("mpi_size is %d, mpi_rank is %d, sel_dim0 is %d, sel_dim1 is %d\n", mpi_size, mpi_rank, - // sel_dim0, sel_dim1); - /* Initialize global buffers: * --wbuf1, wbuf2: write buffers * --fbuf1, fbuf1: expected file buffers @@ -5753,16 +5748,10 @@ test_selection_io_real(int mpi_rank, int mpi_size, H5FD_t *lf, hid_t dxpl) /* Loop over memory types */ for (type = 1; type < H5FD_MEM_NTYPES; type++) { - // for (type = 1; type < 2; type++) { addrs[0] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); addrs[1] = H5FDalloc(lf, type, H5P_DEFAULT, (sizeof(int) * (hsize_t)sel_dim0 * (hsize_t)sel_dim1)); -#ifdef OUT - if (MAINPROCESS) - printf("type is %u, addrs[0]=%d, addrs[1]=%d\n", type, addrs[0], addrs[1]); -#endif - test_selection_io_types_1d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, file_spaces, dims1); test_selection_io_types_2d(mpi_rank, mpi_size, lf, dxpl, type, addrs, element_sizes, mem_spaces, @@ -5835,7 +5824,7 @@ test_selection_io(int mpi_rank, int mpi_size) if (NULL == (lf = H5FDopen(filename, flags, fapl, HADDR_UNDEF))) P_TEST_ERROR; - /* Default dxpl which will be H5FD_MPIO_INDEPENDENT by defalt */ + /* Default dxpl which will be H5FD_MPIO_INDEPENDENT by default */ def_dxpl = H5Pcreate(H5P_DATASET_XFER); /* Set dxpl for collective access which will have H5FD_MPIO_COLLECTIVE_IO as default */ From 83ab87d53bf91646e5b91e618ad80e19b6f312a7 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Jul 2023 16:58:15 +0000 Subject: [PATCH 12/19] Committing clang-format changes --- testpar/t_vfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testpar/t_vfd.c b/testpar/t_vfd.c index c2c07e2c207..5e9070d651e 100644 --- a/testpar/t_vfd.c +++ b/testpar/t_vfd.c @@ -4431,7 +4431,7 @@ test_selection_io_read_verify(hid_t dxpl, int mpi_rank, hsize_t start[], hsize_t } /* end test_selection_io_read_verify() */ /* - * Utility routine to perform the actual selection I/O write + * Utility routine to perform the actual selection I/O write */ static herr_t test_selection_io_write(hid_t dxpl, H5FD_t *lf, H5FD_mem_t type, uint32_t count, hid_t mem_spaces[], From 1fadf80a28d58faa917f3347eac0d685b0fc1673 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:25:30 +0000 Subject: [PATCH 13/19] Committing clang-format changes --- src/H5FD.c | 2 -- src/H5FDint.c | 4 ---- 2 files changed, 6 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 7498a62a091..3e65a7d9c44 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1727,7 +1727,6 @@ H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, 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() */ @@ -1826,7 +1825,6 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count 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() */ diff --git a/src/H5FDint.c b/src/H5FDint.c index e7bb47a54bd..cdbd62617fa 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -1195,7 +1195,6 @@ H5FD_read_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_s offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed"); - done: /* undo the base addr offset to the offsets array if necessary */ if (offsets_cooked) { @@ -1369,7 +1368,6 @@ H5FD_read_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_t if (H5FD__read_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "translation to vector or scalar read failed"); - } done: @@ -1847,7 +1845,6 @@ H5FD_write_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, H5S_t **mem_ offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed"); - done: /* undo the base addr offset to the offsets array if necessary */ if (offsets_cooked) { @@ -2013,7 +2010,6 @@ H5FD_write_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_ if (H5FD__write_selection_translate(skip_vector_cb, file, type, dxpl_id, count, mem_spaces, file_spaces, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "translation to vector or scalar write failed"); - } done: From a1fd1f4a24537f1df5e9210f5109e7224e9bc705 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Thu, 3 Aug 2023 16:56:32 -0500 Subject: [PATCH 14/19] Fix CI failures due ot ";" after macros. --- src/H5FDmpio.c | 114 ++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index b5da27239ec..9b3341b0c2b 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -2783,23 +2783,23 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl /* Allocate information for num_pieces */ if (NULL == (piece_mtype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory datatype buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory datatype buffer"); if (NULL == (piece_ftype = (MPI_Datatype *)H5MM_malloc(num_pieces * sizeof(MPI_Datatype)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file datatype buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file datatype buffer"); if (NULL == (piece_file_disp_array = (MPI_Aint *)H5MM_malloc(num_pieces * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file displacement buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file displacement buffer"); if (NULL == (piece_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_pieces * sizeof(MPI_Aint)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory displacement buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory displacement buffer"); if (NULL == (piece_mpi_mem_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory counts buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece memory counts buffer"); if (NULL == (piece_mpi_file_counts = (int *)H5MM_calloc(num_pieces * sizeof(int)))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file counts buffer") + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate piece file counts buffer"); if (NULL == (piece_mmt_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, - "couldn't allocate piece memory is derived datatype flags buffer") + "couldn't allocate piece memory is derived datatype flags buffer"); if (NULL == (piece_mft_is_derived_array = (hbool_t *)H5MM_calloc(num_pieces * sizeof(hbool_t)))) HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, - "couldn't allocate piece file is derived datatype flags buffer") + "couldn't allocate piece file is derived datatype flags buffer"); /* save lowest file address */ base_file_addr = offsets[0]; @@ -2858,7 +2858,7 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl selected in case they are out of order */ &is_permuted /* OUT */) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI file type"); /* Sanity check */ if (is_permuted) @@ -2879,7 +2879,7 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl and applied to the memory selection */ &is_permuted /* IN */) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type") + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "couldn't create MPI buf type"); /* Sanity check */ if (is_permuted) @@ -2901,30 +2901,30 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl /* Create final MPI derived datatype for the file */ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_file_counts, piece_file_disp_array, piece_ftype, final_ftype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_ftype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code); *final_ftype_is_derived = TRUE; /* Create final MPI derived datatype for memory */ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct((int)num_pieces, piece_mpi_mem_counts, piece_mem_disp_array, piece_mtype, final_mtype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(final_mtype))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code); *final_mtype_is_derived = TRUE; /* Free the file & memory MPI datatypes for each piece */ for (i = 0; i < num_pieces; i++) { if (piece_mmt_is_derived_array[i]) if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_mtype + i))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); if (piece_mft_is_derived_array[i]) if (MPI_SUCCESS != (mpi_code = MPI_Type_free(piece_ftype + i))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); } /* end for */ done: @@ -3054,7 +3054,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d /* Get the transfer mode from the API context */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode"); /* * Set up for a fancy xfer using complex types, or single byte block. We @@ -3074,19 +3074,19 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d tmp_offset = s_offsets[0]; if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list"); if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "memory allocation failed for memory space list") + "memory allocation failed for memory space list"); for (i = 0; i < count; i++) { if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, - "can't retrieve memory dataspace from ID") + "can't retrieve memory dataspace from ID"); if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, - "can't retrieve file dataspace from ID") + "can't retrieve file dataspace from ID"); } /* when we setup mpi_bufs[] below, all addresses are offsets from @@ -3130,21 +3130,21 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d /* some numeric conversions */ if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off"); /* * Set the file view when we are using MPI derived types */ if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, mpi_off, MPI_BYTE, final_ftype, H5FD_mpi_native_g, file->info))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code); /* When using types, use the address as the displacement for * MPI_File_set_view and reset the address for the read to zero */ /* Reset mpi_off to 0 since the view now starts at the data offset */ if (H5FD_mpi_haddr_to_MPIOff((haddr_t)0, &mpi_off) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0"); #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_r_flag) @@ -3152,7 +3152,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d #endif /* Get the collective_opt property to check whether the application wants to do IO individually. */ if (H5CX_get_mpio_coll_opt(&coll_opt_mode) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property") + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property"); if (coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO) { #ifdef H5FDmpio_DEBUG @@ -3174,17 +3174,17 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d * to participate in following MPI_Bcast */ if (MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, mpi_bufs_base, size_i, final_mtype, &mpi_stat))) - HMPI_DONE_ERROR(FAIL, "MPI_File_read_at failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_File_read_at failed", mpi_code); } if (MPI_SUCCESS != (mpi_code = MPI_Bcast(mpi_bufs_base, size_i, final_mtype, 0, file->comm))) - HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); } /* end if */ else /* Perform collective read operation */ if (MPI_SUCCESS != (mpi_code = MPI_File_read_at_all(file->f, mpi_off, mpi_bufs_base, size_i, final_mtype, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at_all failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at_all failed", mpi_code); } /* end if */ else { #ifdef H5FDmpio_DEBUG @@ -3195,7 +3195,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d /* Perform independent read operation */ if (MPI_SUCCESS != (mpi_code = MPI_File_read_at(file->f, mpi_off, mpi_bufs_base, size_i, final_mtype, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_read_at failed", mpi_code); } /* end else */ /* @@ -3203,7 +3203,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d */ if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code); /* Only retrieve bytes read if this rank _actually_ participated in I/O */ if (!rank0_bcast || (rank0_bcast && file->mpi_rank == 0)) { @@ -3219,10 +3219,10 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d * MPI_Bcast. */ bytes_read = -1; - HMPI_DONE_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Get_elements failed", mpi_code); } else - HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code); } } /* end if */ @@ -3238,7 +3238,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d #else if (MPI_SUCCESS != MPI_Bcast(&bytes_read, 1, MPI_INT, 0, file->comm)) #endif - HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", 0) + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", 0); /* Get the type's size */ #if H5_CHECK_MPI_VERSION(3, 0) @@ -3246,14 +3246,14 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d #else if (MPI_SUCCESS != (mpi_code = MPI_Type_size(final_mtype, &type_size))) #endif - HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code); /* Compute the actual number of bytes requested */ io_size = type_size * size_i; /* Check for read failure */ if (bytes_read < 0 || bytes_read > io_size) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed"); #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_r_flag) @@ -3283,15 +3283,15 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d if (H5FD_read_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read vector from selection failed") + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read vector from selection failed"); } done: /* Free the MPI buf and file types, if they were derived */ if (final_mtype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_mtype))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); if (final_ftype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_ftype))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); /* Cleanup dataspace arrays */ if (s_mem_spaces) @@ -3427,7 +3427,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* Get the transfer mode from the API context */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode") + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode"); if (xfer_mode == H5FD_MPIO_COLLECTIVE) { @@ -3441,19 +3441,19 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED tmp_offset = s_offsets[0]; if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list"); if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "memory allocation failed for memory space list") + "memory allocation failed for memory space list"); for (i = 0; i < count; i++) { if (NULL == (s_file_spaces[i] = (H5S_t *)H5I_object_verify(s_file_space_ids[i], H5I_DATASPACE))) HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, - "can't retrieve file dataspace from ID") + "can't retrieve file dataspace from ID"); if (NULL == (s_mem_spaces[i] = (H5S_t *)H5I_object_verify(s_mem_space_ids[i], H5I_DATASPACE))) HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, H5I_INVALID_HID, - "can't retrieve memory dataspace from ID") + "can't retrieve memory dataspace from ID"); } /* when we setup mpi_bufs[] below, all addresses are offsets from @@ -3497,7 +3497,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* some numeric conversions */ if (H5FD_mpi_haddr_to_MPIOff(tmp_offset, &mpi_off /*out*/) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't convert from haddr to MPI off"); /* To be used at the end of the routine for setting local_eof */ save_mpi_off = mpi_off; @@ -3507,11 +3507,11 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED */ if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, mpi_off, MPI_BYTE, final_ftype, H5FD_mpi_native_g, file->info))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code); /* Reset mpi_off to 0 since the view now starts at the data offset */ if (H5FD_mpi_haddr_to_MPIOff((haddr_t)0, &mpi_off) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0") + HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL, "can't set MPI off to 0"); #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_w_flag) @@ -3520,7 +3520,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* Get the collective_opt property to check whether the application wants to do IO individually. */ if (H5CX_get_mpio_coll_opt(&coll_opt_mode) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property") + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property"); if (coll_opt_mode == H5FD_MPIO_COLLECTIVE_IO) { @@ -3532,12 +3532,12 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* Perform collective write operation */ if (MPI_SUCCESS != (mpi_code = MPI_File_write_at_all(file->f, mpi_off, mpi_bufs_base, size_i, final_mtype, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at_all failed", mpi_code); /* Do MPI_File_sync when needed by underlying ROMIO driver */ if (file->mpi_file_sync_required) { if (MPI_SUCCESS != (mpi_code = MPI_File_sync(file->f))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_sync failed", mpi_code); } } else { @@ -3549,13 +3549,13 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED /* Perform independent write operation */ if (MPI_SUCCESS != (mpi_code = MPI_File_write_at(file->f, mpi_off, mpi_bufs_base, size_i, final_mtype, &mpi_stat))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_write_at failed", mpi_code); } /* end else */ /* Reset the file view when we used MPI derived types */ if (MPI_SUCCESS != (mpi_code = MPI_File_set_view(file->f, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, H5FD_mpi_native_g, file->info))) - HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_File_set_view failed", mpi_code); /* How many bytes were actually written */ #if H5_CHECK_MPI_VERSION(3, 0) @@ -3563,7 +3563,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED #else if (MPI_SUCCESS != (mpi_code = MPI_Get_elements(&mpi_stat, MPI_BYTE, &bytes_written))) #endif - HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Get_elements failed", mpi_code); /* Get the type's size */ #if H5_CHECK_MPI_VERSION(3, 0) @@ -3571,14 +3571,14 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED #else if (MPI_SUCCESS != (mpi_code = MPI_Type_size(final_mtype, &type_size))) #endif - HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_size failed", mpi_code); /* Compute the actual number of bytes requested */ io_size = type_size * size_i; /* Check for write failure */ if (bytes_written != io_size || bytes_written < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed"); #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_w_flag) @@ -3613,15 +3613,15 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED if (H5FD_write_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) - HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write vector from selection failed") + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write vector from selection failed"); } done: /* Free the MPI buf and file types, if they were derived */ if (final_mtype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_mtype))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); if (final_ftype_is_derived && MPI_SUCCESS != (mpi_code = MPI_Type_free(&final_ftype))) - HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code) + HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code); /* Cleanup dataspace arrays */ if (s_mem_spaces) From de6a7fdcfb0aee783bd96f234e4bd38e64257762 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Aug 2023 22:19:13 +0000 Subject: [PATCH 15/19] Committing clang-format changes --- src/H5FDmpio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 9b3341b0c2b..01e16c3c4cc 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -3074,7 +3074,8 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d tmp_offset = s_offsets[0]; if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "memory allocation failed for file space list"); if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for memory space list"); @@ -3441,7 +3442,8 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED tmp_offset = s_offsets[0]; if (NULL == (s_file_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, + "memory allocation failed for file space list"); if (NULL == (s_mem_spaces = H5MM_malloc(count * sizeof(H5S_t *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for memory space list"); From 8e4249080dd84019c8d1322c6be93a3d99e2498d Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Fri, 4 Aug 2023 10:34:12 -0500 Subject: [PATCH 16/19] This changes the default selection I/O to on for MPIO. This is a fix from Neil. --- src/H5Dio.c | 30 ++++++++++++++++-------------- src/H5Dmpio.c | 22 +++------------------- testpar/t_coll_chunk.c | 2 +- testpar/t_dset.c | 2 +- 4 files changed, 21 insertions(+), 35 deletions(-) diff --git a/src/H5Dio.c b/src/H5Dio.c index 89afde53f83..b978139a8a7 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -415,8 +415,14 @@ H5D__read(size_t count, H5D_dset_io_info_t *dset_info) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode"); /* Only report the collective I/O mode if we're actually performing collective I/O */ - if (xfer_mode == H5FD_MPIO_COLLECTIVE) + if (xfer_mode == H5FD_MPIO_COLLECTIVE) { H5CX_set_mpio_actual_io_mode(io_info.actual_io_mode); + + /* If we did selection I/O, report that we used "link chunk" mode, since that's the most + * analogous to what selection I/O does */ + if (io_info.use_select_io == H5D_SELECTION_IO_MODE_ON) + H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_LINK_CHUNK); + } } #endif /* H5_HAVE_PARALLEL */ } @@ -1131,20 +1137,16 @@ H5D__typeinfo_init_phase2(H5D_io_info_t *io_info) assert(io_info); /* If selection I/O mode is default (auto), enable it here if the VFD supports it (it will be turned off - * later if something else conflicts), otherwise disable it. If we're using the MPIO VFD, the automatic - * selection will happen in H5D__mpio_opt_possible() inside H5D__ioinfo_adjust(). */ -#ifdef H5_HAVE_PARALLEL - if (!io_info->using_mpi_vfd) -#endif /* H5_HAVE_PARALLEL */ - if (io_info->use_select_io == H5D_SELECTION_IO_MODE_DEFAULT) { - if (H5F_has_vector_select_io(io_info->dsets_info[0].dset->oloc.file, - io_info->op_type == H5D_IO_OP_WRITE)) - io_info->use_select_io = H5D_SELECTION_IO_MODE_ON; - else { - io_info->use_select_io = H5D_SELECTION_IO_MODE_OFF; - io_info->no_selection_io_cause |= H5D_SEL_IO_DEFAULT_OFF; - } + * later if something else conflicts), otherwise disable it */ + if (io_info->use_select_io == H5D_SELECTION_IO_MODE_DEFAULT) { + if (H5F_has_vector_select_io(io_info->dsets_info[0].dset->oloc.file, + io_info->op_type == H5D_IO_OP_WRITE)) + io_info->use_select_io = H5D_SELECTION_IO_MODE_ON; + else { + io_info->use_select_io = H5D_SELECTION_IO_MODE_OFF; + io_info->no_selection_io_cause |= H5D_SEL_IO_DEFAULT_OFF; } + } /* If we're doing type conversion and we might be doing selection I/O, check if the buffers are large * enough to handle the whole I/O */ diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index 901907ceaba..82bcf024374 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -622,6 +622,9 @@ H5D__mpio_opt_possible(H5D_io_info_t *io_info) if (!H5FD_mpi_opt_types_g) local_cause[0] |= H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED; + /* Decision on whether to use selection I/O should have been made by now */ + assert(io_info->use_select_io != H5D_SELECTION_IO_MODE_DEFAULT); + /* Datatype conversions and transformations are allowed with selection I/O. If the selection I/O mode * is auto (default), disable collective for now and re-enable later if we can */ if (io_info->use_select_io != H5D_SELECTION_IO_MODE_ON) { @@ -731,25 +734,6 @@ H5D__mpio_opt_possible(H5D_io_info_t *io_info) HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code) } /* end else */ - /* If the selection I/O mode is default (auto), decide here whether it should be on or off */ - if (io_info->use_select_io == H5D_SELECTION_IO_MODE_DEFAULT) { - /* If the only reason(s) we've disabled collective are type conversions and/or transforms, enable - * selection I/O and re-enable collective I/O since it's supported by selection I/O */ - if (global_cause[0] && !(global_cause[0] & ~((unsigned)H5D_MPIO_DATATYPE_CONVERSION | - (unsigned)H5D_MPIO_DATA_TRANSFORMS))) { - assert(!(local_cause[0] & - ~((unsigned)H5D_MPIO_DATATYPE_CONVERSION | (unsigned)H5D_MPIO_DATA_TRANSFORMS))); - local_cause[0] = 0; - global_cause[0] = 0; - io_info->use_select_io = H5D_SELECTION_IO_MODE_ON; - } - else { - /* Otherwise, there's currently no benefit to selection I/O, so leave it off */ - io_info->use_select_io = H5D_SELECTION_IO_MODE_OFF; - io_info->no_selection_io_cause |= H5D_SEL_IO_DEFAULT_OFF; - } - } - /* Set the local & global values of no-collective-cause in the API context */ H5CX_set_mpio_local_no_coll_cause(local_cause[0]); H5CX_set_mpio_global_no_coll_cause(global_cause[0]); diff --git a/testpar/t_coll_chunk.c b/testpar/t_coll_chunk.c index fd7798823ab..1ff7a8e2c15 100644 --- a/testpar/t_coll_chunk.c +++ b/testpar/t_coll_chunk.c @@ -782,7 +782,7 @@ coll_chunktest(const char *filename, int chunk_factor, int select_factor, int ap status = H5Pget_selection_io(xfer_plist, &selection_io_mode); VRFY((status >= 0), "testing property list get succeeded"); - if (facc_type == FACC_MPIO && (selection_io_mode != H5D_SELECTION_IO_MODE_ON)) { + if (facc_type == FACC_MPIO && (selection_io_mode == H5D_SELECTION_IO_MODE_OFF)) { switch (api_option) { case API_LINK_HARD: status = H5Pget(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, &prop_value); diff --git a/testpar/t_dset.c b/testpar/t_dset.c index e401cd56cb8..b75b6aefa97 100644 --- a/testpar/t_dset.c +++ b/testpar/t_dset.c @@ -3356,7 +3356,7 @@ actual_io_mode_tests(void) ret = H5Pclose(dxpl_id); VRFY((ret >= 0), "H5Pclose succeeded"); - if (selection_io_mode != H5D_SELECTION_IO_MODE_ON) { + if (selection_io_mode == H5D_SELECTION_IO_MODE_OFF) { test_actual_io_mode(TEST_ACTUAL_IO_NO_COLLECTIVE); /* From d61facc7f17f16005a0ab50fcdf6f98b1d073842 Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Sat, 5 Aug 2023 14:15:58 -0500 Subject: [PATCH 17/19] Fixes for the two issues in PR review: 1) Revert the type for as size_t in the H5FD_class_t struct 2) The independent xfer mode case in H5FD__mpio_read/write_selection() should be calling H5FD_read/write_from_selection(). 3) Fix the test in testpar/t_select_io_dset.c due to the change. --- src/H5FDdevelop.h | 4 ++-- src/H5FDint.c | 3 +-- src/H5FDmpio.c | 18 +++++++++--------- src/H5FDprivate.h | 2 +- testpar/t_select_io_dset.c | 20 ++++++++++++++------ 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index 2d37b1fb15b..8a50090baf5 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -196,10 +196,10 @@ typedef struct H5FD_class_t { 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, uint32_t count, hid_t mem_spaces[], + 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, uint32_t count, + 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); diff --git a/src/H5FDint.c b/src/H5FDint.c index cdbd62617fa..48b8f78d775 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -2701,13 +2701,12 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t *------------------------------------------------------------------------- */ herr_t -H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, hid_t mem_space_ids[], +H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], H5_flexible_const_ptr_t bufs[], hid_t **s_mem_space_ids_ptr, hid_t **s_file_space_ids_ptr, haddr_t **s_offsets_ptr, size_t **s_element_sizes_ptr, H5_flexible_const_ptr_t **s_bufs_ptr) { - size_t count = (size_t)_count; size_t i; struct H5FD_srt_tmp_t *srt_tmp = NULL; herr_t ret_value = SUCCEED; /* Return value */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 01e16c3c4cc..addb8e003fd 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -90,11 +90,11 @@ static herr_t H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_ const void *bufs[]); static herr_t H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, - uint32_t count, hid_t mem_space_ids[], hid_t file_space_ids[], + size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], void *bufs[]); static herr_t H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, - uint32_t count, hid_t mem_space_ids[], hid_t file_space_ids[], + size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], const void *bufs[]); static herr_t H5FD__mpio_flush(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); @@ -110,7 +110,7 @@ static herr_t H5FD__mpio_vector_build_types( MPI_Offset *mpi_off, H5_flexible_const_ptr_t *mpi_bufs_base, int *size_i, MPI_Datatype *buf_type, hbool_t *buf_type_created, MPI_Datatype *file_type, hbool_t *file_type_created, char *unused); -static herr_t H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, +static herr_t H5FD__selection_build_types(hbool_t io_op_write, size_t num_pieces, H5_flexible_const_ptr_t mbb, H5S_t **file_spaces, H5S_t **mem_spaces, haddr_t offsets[], H5_flexible_const_ptr_t bufs[], size_t src_element_sizes[], @@ -2747,7 +2747,7 @@ H5FD__mpio_write_vector(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t co *------------------------------------------------------------------------- */ static herr_t -H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexible_const_ptr_t mbb, +H5FD__selection_build_types(hbool_t io_op_write, size_t num_pieces, H5_flexible_const_ptr_t mbb, H5S_t **file_spaces, H5S_t **mem_spaces, haddr_t offsets[], H5_flexible_const_ptr_t bufs[], size_t src_element_sizes[], size_t dst_element_sizes[], MPI_Datatype *final_ftype, @@ -2976,7 +2976,7 @@ H5FD__selection_build_types(hbool_t io_op_write, uint32_t num_pieces, H5_flexibl *------------------------------------------------------------------------- */ static herr_t -H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t count, +H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */) { @@ -3282,7 +3282,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d } } - if (H5FD_read_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, + if (H5FD_read_from_selection(_file, type, (uint32_t)count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read vector from selection failed"); } @@ -3348,7 +3348,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d *------------------------------------------------------------------------- */ static herr_t -H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, uint32_t count, +H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], const void *bufs[]) { @@ -3403,7 +3403,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED #ifdef H5FDmpio_DEBUG if (H5FD_mpio_debug_t_flag) - fprintf(stderr, "%s: (%d) Entering: count=%u\n", __func__, file->mpi_rank, count); + fprintf(stderr, "%s: (%d) Entering\n", __func__, file->mpi_rank); #endif /* Sanity checks */ @@ -3613,7 +3613,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED } } - if (H5FD_write_vector_from_selection(_file, type, count, mem_space_ids, file_space_ids, offsets, + if (H5FD_write_from_selection(_file, type, (uint32_t)count, mem_space_ids, file_space_ids, offsets, element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write vector from selection failed"); } diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index debc5d69897..aa9bd0d6616 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -191,7 +191,7 @@ H5_DLL herr_t H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t count 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_sort_selection_io_req(hbool_t *selection_was_sorted, uint32_t _count, +H5_DLL herr_t H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, size_t count, hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], H5_flexible_const_ptr_t bufs[], hid_t **s_mem_space_ids, hid_t **s_file_space_ids, diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index efc2f451931..6076271c728 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -3441,6 +3441,19 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ /* Datatype conversion */ if (test_mode & TEST_DATATYPE_CONVERSION) { + + /* With one exception, all will land at H5FD__mpio_read/write_selection(). + * As the xfer mode is H5FD_MPIO_INDEPENDENT, this will call + * H5FD__read/write_from_selection() triggering H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB. + */ + no_selection_io_cause_read_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; + + /* Exception case: This will turn off selection I/O landing at H5FD__mpio_write() */ + if ((test_mode & TEST_TCONV_BUF_TOO_SMALL) && !(test_mode & TEST_IN_PLACE_TCONV)) + no_selection_io_cause_write_expected |= H5D_SEL_IO_TCONV_BUF_TOO_SMALL; + else + no_selection_io_cause_write_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) P_TEST_ERROR; tid = H5T_NATIVE_UINT; @@ -3450,18 +3463,13 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ if (H5Pset_buffer(dxpl, sizeof(int), NULL, NULL) < 0) P_TEST_ERROR; - /* If we're using in-place type conversion sel io will succeed */ if (test_mode & TEST_IN_PLACE_TCONV) { if (H5Pset_modify_write_buf(dxpl, TRUE) < 0) P_TEST_ERROR; } - else - no_selection_io_cause_write_expected |= H5D_SEL_IO_TCONV_BUF_TOO_SMALL; - /* In-place type conversion for read doesn't require modify_write_buf */ - } - /* If the tconv buf is largge enough sel io will succeed */ + } } /* Create 1d data space */ From 2621bbb823654babb1ed970492d2a5d70d8e1fb2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Aug 2023 19:28:49 +0000 Subject: [PATCH 18/19] Committing clang-format changes --- src/H5FDdevelop.h | 6 +++--- src/H5FDmpio.c | 9 ++++----- src/H5FDprivate.h | 11 +++++------ testpar/t_select_io_dset.c | 7 +++---- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index 8a50090baf5..75e63b14c07 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -199,9 +199,9 @@ typedef struct H5FD_class_t { 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 (*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); diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index addb8e003fd..aa83be4a5bb 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -110,9 +110,8 @@ static herr_t H5FD__mpio_vector_build_types( MPI_Offset *mpi_off, H5_flexible_const_ptr_t *mpi_bufs_base, int *size_i, MPI_Datatype *buf_type, hbool_t *buf_type_created, MPI_Datatype *file_type, hbool_t *file_type_created, char *unused); -static herr_t H5FD__selection_build_types(hbool_t io_op_write, size_t num_pieces, - H5_flexible_const_ptr_t mbb, H5S_t **file_spaces, - H5S_t **mem_spaces, haddr_t offsets[], +static herr_t H5FD__selection_build_types(hbool_t io_op_write, size_t num_pieces, H5_flexible_const_ptr_t mbb, + H5S_t **file_spaces, H5S_t **mem_spaces, haddr_t offsets[], H5_flexible_const_ptr_t bufs[], size_t src_element_sizes[], size_t dst_element_sizes[], MPI_Datatype *final_ftype, hbool_t *final_ftype_is_derived, MPI_Datatype *final_mtype, @@ -3283,7 +3282,7 @@ H5FD__mpio_read_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED d } if (H5FD_read_from_selection(_file, type, (uint32_t)count, mem_space_ids, file_space_ids, offsets, - element_sizes, bufs) < 0) + element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read vector from selection failed"); } @@ -3614,7 +3613,7 @@ H5FD__mpio_write_selection(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED } if (H5FD_write_from_selection(_file, type, (uint32_t)count, mem_space_ids, file_space_ids, offsets, - element_sizes, bufs) < 0) + element_sizes, bufs) < 0) HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write vector from selection failed"); } diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index aa9bd0d6616..6b8e2dac7fa 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -191,12 +191,11 @@ H5_DLL herr_t H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t count 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_sort_selection_io_req(hbool_t *selection_was_sorted, size_t count, - hid_t mem_space_ids[], hid_t file_space_ids[], haddr_t offsets[], - size_t element_sizes[], H5_flexible_const_ptr_t bufs[], - hid_t **s_mem_space_ids, hid_t **s_file_space_ids, - haddr_t **s_offsets_ptr, size_t **s_element_sizes_ptr, - H5_flexible_const_ptr_t **s_bufs_ptr); +H5_DLL herr_t H5FD_sort_selection_io_req(hbool_t *selection_was_sorted, size_t count, hid_t mem_space_ids[], + hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], + H5_flexible_const_ptr_t bufs[], hid_t **s_mem_space_ids, + hid_t **s_file_space_ids, haddr_t **s_offsets_ptr, + size_t **s_element_sizes_ptr, H5_flexible_const_ptr_t **s_bufs_ptr); H5_DLL herr_t H5FD_init(void); /* Function prototypes for MPI based VFDs*/ diff --git a/testpar/t_select_io_dset.c b/testpar/t_select_io_dset.c index 6076271c728..daeacf01270 100644 --- a/testpar/t_select_io_dset.c +++ b/testpar/t_select_io_dset.c @@ -3449,11 +3449,11 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ no_selection_io_cause_read_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; /* Exception case: This will turn off selection I/O landing at H5FD__mpio_write() */ - if ((test_mode & TEST_TCONV_BUF_TOO_SMALL) && !(test_mode & TEST_IN_PLACE_TCONV)) + if ((test_mode & TEST_TCONV_BUF_TOO_SMALL) && !(test_mode & TEST_IN_PLACE_TCONV)) no_selection_io_cause_write_expected |= H5D_SEL_IO_TCONV_BUF_TOO_SMALL; else no_selection_io_cause_write_expected |= H5D_SEL_IO_NO_VECTOR_OR_SELECTION_IO_CB; - + if (H5Pset_selection_io(dxpl, H5D_SELECTION_IO_MODE_ON) < 0) P_TEST_ERROR; tid = H5T_NATIVE_UINT; @@ -3468,8 +3468,7 @@ test_no_selection_io_cause_mode(const char *filename, hid_t fapl, uint32_t test_ P_TEST_ERROR; } /* In-place type conversion for read doesn't require modify_write_buf */ - - } + } } /* Create 1d data space */ From 3bf430f10264512a993c25c9c56efb42227c1e7f Mon Sep 17 00:00:00 2001 From: "vchoi-hdfgroup.org" Date: Sun, 6 Aug 2023 17:55:07 -0500 Subject: [PATCH 19/19] Address spelling/grammar errors from PR review. --- src/H5FD.c | 4 ++-- src/H5FDint.c | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/H5FD.c b/src/H5FD.c index 3e65a7d9c44..e2c32c6df1a 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1862,7 +1862,7 @@ H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count * * Return: Success: SUCCEED * All reads have completed successfully, and - * the results havce been into the supplied + * the results have been written into the supplied * buffers. * * Failure: FAIL @@ -2059,7 +2059,7 @@ H5FDwrite_vector_from_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, ui * * Return: Success: SUCCEED * All reads have completed successfully, and - * the results havce been into the supplied + * the results have been written into the supplied * buffers. * * Failure: FAIL diff --git a/src/H5FDint.c b/src/H5FDint.c index 48b8f78d775..fcc1b6c6fcd 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -2048,8 +2048,6 @@ H5FD_write_selection_id(uint32_t skip_cb, H5FD_t *file, H5FD_mem_t type, uint32_ * Failure: FAIL * One or more writes failed. * - * Programmer: NAF -- 5/19/21 - * *------------------------------------------------------------------------- */ herr_t @@ -2101,8 +2099,6 @@ H5FD_read_vector_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, h * Failure: FAIL * One or more writes failed. * - * Programmer: NAF -- 5/19/21 - * *------------------------------------------------------------------------- */ herr_t @@ -2153,8 +2149,6 @@ H5FD_write_vector_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, * Failure: FAIL * One or more writes failed. * - * Programmer: NAF -- 5/19/21 - * *------------------------------------------------------------------------- */ herr_t @@ -2205,8 +2199,6 @@ H5FD_read_from_selection(H5FD_t *file, H5FD_mem_t type, uint32_t count, hid_t me * Failure: FAIL * One or more writes failed. * - * Programmer: NAF -- 5/19/21 - * *------------------------------------------------------------------------- */ herr_t @@ -2693,7 +2685,7 @@ H5FD_sort_vector_io_req(hbool_t *vector_was_sorted, uint32_t _count, H5FD_mem_t * of the selection I/O request, and load it into the new * selections in sorted order. * - * Note that in this case, it is the callers responsibility + * Note that in this case, it is the caller's responsibility * to free the sorted vectors. * * Return: SUCCEED/FAIL