diff options
author | jrmainzer <72230804+jrmainzer@users.noreply.github.com> | 2021-03-16 14:51:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-16 14:51:07 (GMT) |
commit | 0c4922865fb9715b75f658fc308e2d7d6c847b77 (patch) | |
tree | 43516a73b4838af0a0cf69da4cfc893cc548d79d /src/H5FDint.c | |
parent | 216bff577826e52268d1c7db632753444a846528 (diff) | |
parent | 65b75d9fc93992d94f9197b69acf3c6345c4c834 (diff) | |
download | hdf5-0c4922865fb9715b75f658fc308e2d7d6c847b77.zip hdf5-0c4922865fb9715b75f658fc308e2d7d6c847b77.tar.gz hdf5-0c4922865fb9715b75f658fc308e2d7d6c847b77.tar.bz2 |
Merge pull request #471 from jrmainzer/selection_io
Selection io
Diffstat (limited to 'src/H5FDint.c')
-rw-r--r-- | src/H5FDint.c | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/src/H5FDint.c b/src/H5FDint.c index 25d77d1..141e7ab 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -244,6 +244,364 @@ done: } /* end H5FD_write() */ /*------------------------------------------------------------------------- + * Function: H5FD_read_vector + * + * Purpose: Private version of H5FDread_vector() + * + * Perform count reads from the specified file at the offsets + * provided in the addrs array, with the lengths and memory + * types provided in the sizes and types arrays. Data read + * is returned in the buffers provided in the bufs array. + * + * If i > 0 and sizes[i] == 0, presume sizes[n] = sizes[i-1] + * for all n >= i and < count. + * + * Similarly, if i > 0 and types[i] == H5FD_MEM_NOLIST, + * presume types[n] = types[i-1] for all n >= i and < count. + * + * If the underlying VFD supports vector reads, pass the + * call through directly. + * + * If it doesn't, convert the vector read into a sequence + * of individual reads. + * + * Note that it is not in general possible to convert a + * vector read into a selection read, because each element + * in the vector read may have a different memory type. + * In contrast, selection reads are of a single type. + * + * Return: Success: SUCCEED + * All reads have completed successfully, and + * the results havce been into the supplied + * buffers. + * + * Failure: FAIL + * The contents of supplied buffers are undefined. + * + * Programmer: JRM -- 6/10/20 + * + * Changes: None + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_read_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], + void *bufs[] /* out */) +{ + hbool_t addrs_cooked = FALSE; + hbool_t extend_sizes = FALSE; + hbool_t extend_types = FALSE; + uint32_t i; + size_t size; + H5FD_mem_t type; + hid_t dxpl_id = H5I_INVALID_HID; /* DXPL for operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(file); + HDassert(file->cls); + HDassert((types) || (count == 0)); + HDassert((addrs) || (count == 0)); + HDassert((sizes) || (count == 0)); + HDassert((bufs) || (count == 0)); + + /* verify that the first elements of the sizes and types arrays are + * valid. + */ + HDassert((count == 0) || (sizes[0] != 0)); + HDassert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + + /* Get proper DXPL for I/O */ + dxpl_id = H5CX_get_dxpl(); + +#ifndef H5_HAVE_PARALLEL + /* The no-op case + * + * Do not return early for Parallel mode since the I/O could be a + * collective transfer. + */ + if (0 == count) { + HGOTO_DONE(SUCCEED) + } +#endif /* H5_HAVE_PARALLEL */ + + if (file->base_addr > 0) { + + /* apply the base_addr offset to the addrs array. Must undo before + * we return. + */ + for (i = 0; i < count; i++) { + + addrs[i] += file->base_addr; + } + addrs_cooked = TRUE; + } + + /* If the file is open for SWMR read access, allow access to data past + * the end of the allocated space (the 'eoa'). This is done because the + * eoa stored in the file's superblock might be out of sync with the + * objects being written within the file by the application performing + * SWMR write operations. + */ + if (!(file->access_flags & H5F_ACC_SWMR_READ)) { + haddr_t eoa; + + for (i = 0; i < count; i++) { + + if (HADDR_UNDEF == (eoa = (file->cls->get_eoa)(file, types[i]))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed") + + if ((addrs[i] + sizes[i]) > eoa) + + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, + "addr overflow, addrs[%d] = %llu, sizes[%d] = %llu, eoa = %llu", (int)i, + (unsigned long long)(addrs[i]), (int)i, (unsigned long long)sizes[i], + (unsigned long long)eoa) + } + } + + /* if the underlying VFD supports vector read, make the call */ + if (file->cls->read_vector) { + + if ((file->cls->read_vector)(file, dxpl_id, count, types, addrs, sizes, bufs) < 0) + + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read vector request failed") + } + else { + + /* otherwise, implement the vector read as a sequence of regular + * read calls. + */ + extend_sizes = FALSE; + extend_types = FALSE; + + for (i = 0; i < count; i++) { + + /* we have already verified that sizes[0] != 0 and + * types[0] != H5FD_MEM_NOLIST + */ + + if (!extend_sizes) { + + if (sizes[i] == 0) { + + extend_sizes = TRUE; + size = sizes[i - 1]; + } + else { + + size = sizes[i]; + } + } + + if (!extend_types) { + + if (types[i] == H5FD_MEM_NOLIST) { + + extend_types = TRUE; + type = types[i - 1]; + } + else { + + type = types[i]; + } + } + + if ((file->cls->read)(file, type, dxpl_id, addrs[i], size, bufs[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver read request failed") + } + } + +done: + /* undo the base addr offset to the addrs array if necessary */ + if (addrs_cooked) { + + HDassert(file->base_addr > 0); + + for (i = 0; i < count; i++) { + + addrs[i] -= file->base_addr; + } + } + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_read_vector() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_write_vector + * + * Purpose: Private version of H5FDwrite_vector() + * + * Perform count writes to the specified file at the offsets + * provided in the addrs array, with the lengths and memory + * types provided in the sizes and types arrays. Data written + * is taken from the buffers provided in the bufs array. + * + * If i > 0 and sizes[i] == 0, presume sizes[n] = sizes[i-1] + * for all n >= i and < count. + * + * Similarly, if i > 0 and types[i] == H5FD_MEM_NOLIST, + * presume types[n] = types[i-1] for all n >= i and < count. + * + * If the underlying VFD supports vector writes, pass the + * call through directly. + * + * If it doesn't, convert the vector write into a sequence + * of individual writes. + * + * Note that it is not in general possible to convert a + * vector write into a selection write, because each element + * in the vector read may have a different memory type. + * In contrast, selection writes are of a single type. + * + * Return: Success: SUCCEED + * All writes have completed successfully. + * + * Failure: FAIL + * One or more writes failed. + * + * Programmer: JRM -- 6/10/20 + * + * Changes: None + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_write_vector(H5FD_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], + void *bufs[] /* out */) +{ + hbool_t addrs_cooked = FALSE; + hbool_t extend_sizes = FALSE; + hbool_t extend_types = FALSE; + uint32_t i; + size_t size; + H5FD_mem_t type; + hid_t dxpl_id; /* DXPL for operation */ + haddr_t eoa = HADDR_UNDEF; /* EOA for file */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(file); + HDassert(file->cls); + HDassert((types) || (count == 0)); + HDassert((addrs) || (count == 0)); + HDassert((sizes) || (count == 0)); + HDassert((bufs) || (count == 0)); + + /* verify that the first elements of the sizes and types arrays are + * valid. + */ + HDassert((count == 0) || (sizes[0] != 0)); + HDassert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + + /* Get proper DXPL for I/O */ + dxpl_id = H5CX_get_dxpl(); + +#ifndef H5_HAVE_PARALLEL + /* The no-op case + * + * Do not return early for Parallel mode since the I/O could be a + * collective transfer. + */ + if (0 == count) + HGOTO_DONE(SUCCEED) +#endif /* H5_HAVE_PARALLEL */ + + if (file->base_addr > 0) { + + /* apply the base_addr offset to the addrs array. Must undo before + * we return. + */ + for (i = 0; i < count; i++) { + + addrs[i] += file->base_addr; + } + addrs_cooked = TRUE; + } + + for (i = 0; i < count; i++) { + + if (HADDR_UNDEF == (eoa = (file->cls->get_eoa)(file, types[i]))) + + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed") + + if ((addrs[i] + sizes[i]) > eoa) + + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addrs[%d] = %llu, sizes[%d] = %llu, \ + eoa = %llu", + (int)i, (unsigned long long)(addrs[i]), (int)i, (unsigned long long)sizes[i], + (unsigned long long)eoa) + } + + /* if the underlying VFD supports vector write, make the call */ + if (file->cls->write_vector) { + + if ((file->cls->write_vector)(file, dxpl_id, count, types, addrs, sizes, bufs) < 0) + + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver write vector request failed") + } + else { + /* otherwise, implement the vector write as a sequence of regular + * write calls. + */ + extend_sizes = FALSE; + extend_types = FALSE; + + for (i = 0; i < count; i++) { + + /* we have already verified that sizes[0] != 0 and + * types[0] != H5FD_MEM_NOLIST + */ + + if (!extend_sizes) { + + if (sizes[i] == 0) { + + extend_sizes = TRUE; + size = sizes[i - 1]; + } + else { + + size = sizes[i]; + } + } + + if (!extend_types) { + + if (types[i] == H5FD_MEM_NOLIST) { + + extend_types = TRUE; + type = types[i - 1]; + } + else { + + type = types[i]; + } + } + + if ((file->cls->write)(file, type, dxpl_id, addrs[i], size, bufs[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "driver write request failed") + } + } + +done: + /* undo the base addr offset to the addrs array if necessary */ + if (addrs_cooked) { + + HDassert(file->base_addr > 0); + + for (i = 0; i < count; i++) { + + addrs[i] -= file->base_addr; + } + } + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_write() */ + +/*------------------------------------------------------------------------- * Function: H5FD_set_eoa * * Purpose: Private version of H5FDset_eoa() |