mirror of
https://github.com/HDFGroup/hdf5.git
synced 2026-09-25 04:09:44 +03:00
Multi Dataset (#2120)
* Fix bug with cross platform compatibility of references within vlens. No testing yet. * Merge from multi_rd_wd_coll_io to a more recent branch from develop. Untested, probably does not work yet. * Committing clang-format changes * Committing clang-format changes * Fix many bugs in multi dataset branch. Mostly works, some issues in SWMR tests. * Committing clang-format changes * Disable test in swmr.c that was failing due to bug in HDF5 unrelated to multi dataset. * Committing clang-format changes * Fixed fortran multi-dataset tests * Fixed xlf errors * Added benchmark code for multi-datasets * loops over datasets * added missing error arg. * Added gnuplot formatting * Jonathan Kim original MD benchmarking code * updated MD benchmarking code * code clean-up * Only make files in feature test mode * misc clean-up * removed TEST_MDSET_NO_LAST_DSET_2ND_PROC option * Committing clang-format changes * Change multi dataset API to use arrays of individual parameters instead of the parameter struct. * Committing clang-format changes * Update to new multi dataset Fortran API and tests. (#1724) * Update to new multi dataset Fortran API and tests. * Sync Fortran with develop. * skipping h5pget_mpio_actual_io_mode_f for now * Fixed issue with dxpl_id, changed to variable size dim. (#1770) * Remove "is_coll_broken" field from H5D_io_info_t struct * Committing clang-format changes * Minor cleanup in multi dataset code. * Committing clang-format changes * Clean up in multi dataset code. * Committing clang-format changes * Committing clang-format changes * Fix speeling * Fix bug in parallel compression. Switch base_maddr in io_info to be a union. * Committing clang-format changes * Implement selection I/O support with multi dataset. Will be broken in parallel until PR 1803 is merged to develop then the MDS branch. * Committing clang-format changes * Spelling * Fix bug in multi dataset that could cause errors when only some of the datasets in the multi dataset I/O used type conversion. * Committing clang-format changes * Integrate multi dataset APIs with VOL layer. Add async versions of multi dataset APIs. * Committing clang-format changes * Spelling fixes * Fix bug in non-parallel HDF5 compilation. * Committing clang-format changes * Fix potential memory/free list error. Minor performance fix. Other minor changes. * Committing clang-format changes * Fix memory leak with memory dataspace for I/O. * Committing clang-format changes * Fix stack variables too large. Rename H5D_dset_info_t to H5D_dset_io_info_t. * Committing clang-format changes * Remove mem_space_alloc field from H5D_dset_io_info_t. Each function is now responsible for freeing any spaces it adds to dset_info. * Committing clang-format changes * fixed _multi Fortran declaration * Refactor various things in (mostly) the serial I/O code path to make things more maintainable. * Committing clang-format changes * updated to array based, doxygen, and examples * Reinstate H5D_chunk_map_t, stored (via pointer) inside H5D_dset_io_info_t. * Change from calloc to malloc for H5D_dset_io_info_t and H5D_chunk_map_t. Switch temporary dset_infos to be local stack variables. * Committing clang-format changes * format cleanup * format cleanup * added coll and ind * Modify all parallel I/O paths to take dset_info instead of assuming dset_info[0]. * Committing clang-format changes * fixed output * Rework parallel I/O code to work properly with multi dataset in more cases. Fix bug in parallel compression. * Committing clang-format changes * Prevent H5D__multi_chunk_collective_io() from messing up collective opt property for other datasets in I/O. Other minor cleanup. Add new test case to t_pmulti_dset.c for H5FD_MPIO_INDIVIDUAL_IO, disabled for now due to failures apparently unrelated to multi dataset code. * Fix spelling * Committing clang-format changes * Replace N log N algorithm for finding chunk in H5D__multi_chunk_collective_io() with O(N) algorithm, and remove use of io_info->sel_pieces in that function. * Committing clang-format changes * Replace sel_pieces skiplist in io_info with flat array of pointers, use qsort in I/O routine only when necessary. * Committing clang-format changes * Add new test case to mdset.c * Committing clang-format changes * Fix spelling * Very minor fix in H5VL__native_dataset_read() * Fix bug that could affect filtered parallel multi-dataset I/O. * Add RM entries for H5Dread_multi(), H5Dread_multi_async(), H5Dwrite_multi(), and H5Dwrite_multi_async() * Unskip test in swmr.c * Committing clang-format changes * Eliminate H5D__pre_read and H5D__pre_write * Remove examples/ph5mdsettest.c. Will fix and re-add as a test. * Enable hyperslab combinations in mdset test * Committing clang-format changes * Clarify H5Dread/write_multi documentation. * Fix bugs in multi-dataset I/O. Expand serial multi dataset test. Update macro in parallel multi dataset test. * Committing clang-format changes * Spelling * Remove obsolete entry in bin/trace * Rework type conversion buffer allocation. Only one buffer is shared between datasets in mdset mode, and it is malloced instead of calloced. * Committing clang-format changes * Fix bug in error handling in H5D__read/write * added multi-dataset fortran check with optional dataset creation id (#2150) * removed dup. dll entry * Address comments from code review. * Remove spurious changes in H5Fmpi.c * Fix issue with reading unallocated datasets in multi-dataset mode. Address other comments from code review. * Committing clang-format changes * Delay chunk index lookup from io_init to mdio_init so it doesn't add overhead to single dataset I/O. * Committing clang-format changes * Fix inappropriate use of piece_count * updated copyright on new file, removed benchmark from testing dir. Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: M. Scot Breitenfeld <brtnfld@hdfgroup.org> Co-authored-by: Dana Robinson <43805+derobins@users.noreply.github.com>
This commit is contained in:
co-authored by
github-actions
M. Scot Breitenfeld
Dana Robinson
parent
a898cef6c2
commit
93754cae33
+103
-1
@@ -1098,7 +1098,7 @@ CONTAINS
|
||||
!>
|
||||
!! \ingroup FH5D
|
||||
!!
|
||||
!! \brief Writes raw data from a dataset into a buffer.
|
||||
!! \brief Writes raw data from a buffer to a dataset.
|
||||
!!
|
||||
!! \attention \fortran_approved
|
||||
!!
|
||||
@@ -1762,6 +1762,108 @@ CONTAINS
|
||||
CALL h5dfill_ptr(f_ptr_fill_value, fill_type_id, f_ptr_buf, mem_type_id, space_id, hdferr)
|
||||
|
||||
END SUBROUTINE h5dfill_char
|
||||
!>
|
||||
!! \ingroup FH5D
|
||||
!!
|
||||
!! \brief Reads data from a file to memory buffers for multiple datasets.
|
||||
!!
|
||||
!! \param count Number of datasets to write to.
|
||||
!! \param dset_id Identifier of the dataset to write to.
|
||||
!! \param mem_type_id Identifier of the memory datatype.
|
||||
!! \param mem_space_id Identifier of the memory dataspace.
|
||||
!! \param file_space_id Identifier of the dataset's dataspace in the file.
|
||||
!! \param buf Buffer with data to be written to the file.
|
||||
!! \param hdferr \fortran_error
|
||||
!! \param xfer_prp Identifier of a transfer property list for this I/O operation.
|
||||
!!
|
||||
SUBROUTINE H5Dread_multi_f(count, dset_id, mem_type_id, mem_space_id, file_space_id, buf, hdferr, xfer_prp)
|
||||
IMPLICIT NONE
|
||||
|
||||
INTEGER(SIZE_T), INTENT(IN) :: count
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: dset_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: mem_type_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: mem_space_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: file_space_id
|
||||
TYPE(C_PTR), DIMENSION(*) :: buf
|
||||
INTEGER, INTENT(OUT) :: hdferr
|
||||
INTEGER(HID_T), INTENT(IN), OPTIONAL :: xfer_prp
|
||||
|
||||
INTEGER(HID_T) :: xfer_prp_default
|
||||
|
||||
INTERFACE
|
||||
INTEGER FUNCTION H5Dread_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, xfer_prp, buf) &
|
||||
BIND(C, NAME='H5Dread_multi')
|
||||
IMPORT :: SIZE_T
|
||||
IMPORT :: HID_T
|
||||
IMPORT :: C_PTR
|
||||
IMPLICIT NONE
|
||||
INTEGER(SIZE_T), VALUE :: count
|
||||
INTEGER(HID_T), DIMENSION(*) :: dset_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: mem_type_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: mem_space_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: file_space_id
|
||||
INTEGER(HID_T), VALUE :: xfer_prp
|
||||
TYPE(C_PTR), DIMENSION(*) :: buf
|
||||
END FUNCTION H5Dread_multi
|
||||
END INTERFACE
|
||||
|
||||
xfer_prp_default = H5P_DEFAULT_F
|
||||
IF (PRESENT(xfer_prp)) xfer_prp_default = xfer_prp
|
||||
|
||||
hdferr = H5Dread_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, xfer_prp_default, buf)
|
||||
|
||||
END SUBROUTINE H5Dread_multi_f
|
||||
!>
|
||||
!! \ingroup FH5D
|
||||
!!
|
||||
!! \brief Writes data in memory to a file for multiple datasets.
|
||||
!!
|
||||
!! \param count Number of datasets to write to.
|
||||
!! \param dset_id Identifier of the dataset to write to.
|
||||
!! \param mem_type_id Identifier of the memory datatype.
|
||||
!! \param mem_space_id Identifier of the memory dataspace.
|
||||
!! \param file_space_id Identifier of the dataset's dataspace in the file.
|
||||
!! \param buf Buffer with data to be written to the file.
|
||||
!! \param hdferr \fortran_error
|
||||
!! \param xfer_prp Identifier of a transfer property list for this I/O operation.
|
||||
!!
|
||||
SUBROUTINE H5Dwrite_multi_f(count, dset_id, mem_type_id, mem_space_id, file_space_id, buf, hdferr, xfer_prp)
|
||||
IMPLICIT NONE
|
||||
|
||||
INTEGER(SIZE_T), INTENT(IN) :: count
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: dset_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: mem_type_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: mem_space_id
|
||||
INTEGER(HID_T), INTENT(IN), DIMENSION(*) :: file_space_id
|
||||
TYPE(C_PTR), DIMENSION(*) :: buf
|
||||
INTEGER, INTENT(OUT) :: hdferr
|
||||
INTEGER(HID_T), INTENT(IN), OPTIONAL :: xfer_prp
|
||||
|
||||
INTEGER(HID_T) :: xfer_prp_default
|
||||
|
||||
INTERFACE
|
||||
INTEGER FUNCTION H5Dwrite_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, xfer_prp, buf) &
|
||||
BIND(C, NAME='H5Dwrite_multi')
|
||||
IMPORT :: SIZE_T
|
||||
IMPORT :: HID_T
|
||||
IMPORT :: C_PTR
|
||||
IMPLICIT NONE
|
||||
INTEGER(SIZE_T), VALUE :: count
|
||||
INTEGER(HID_T), DIMENSION(*) :: dset_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: mem_type_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: mem_space_id
|
||||
INTEGER(HID_T), DIMENSION(*) :: file_space_id
|
||||
INTEGER(HID_T), VALUE :: xfer_prp
|
||||
TYPE(C_PTR), DIMENSION(*) :: buf
|
||||
END FUNCTION H5Dwrite_multi
|
||||
END INTERFACE
|
||||
|
||||
xfer_prp_default = H5P_DEFAULT_F
|
||||
IF (PRESENT(xfer_prp)) xfer_prp_default = xfer_prp
|
||||
|
||||
hdferr = H5Dwrite_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, xfer_prp_default, buf)
|
||||
|
||||
END SUBROUTINE H5Dwrite_multi_f
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -80,6 +80,8 @@ H5D_mp_H5DGET_ACCESS_PLIST_F
|
||||
H5D_mp_H5DWRITE_PTR
|
||||
H5D_mp_H5DREAD_PTR
|
||||
H5D_mp_H5DVLEN_RECLAIM_F
|
||||
H5D_mp_H5DREAD_MULTI_F
|
||||
H5D_mp_H5DWRITE_MULTI_F
|
||||
; H5E
|
||||
H5E_mp_H5ECLEAR_F
|
||||
H5E_mp_H5EPRINT_F
|
||||
|
||||
@@ -151,6 +151,10 @@ PROGRAM fortranlibtest_F03
|
||||
CALL test_h5p_file_image(ret_total_error)
|
||||
CALL write_test_status(ret_total_error, ' Testing h5pset/get file image', total_error)
|
||||
|
||||
ret_total_error = 0
|
||||
CALL multiple_dset_rw(ret_total_error)
|
||||
CALL write_test_status(ret_total_error, ' Testing multi-dataset reads and writes', total_error)
|
||||
|
||||
! write(*,*)
|
||||
! write(*,*) '========================================='
|
||||
! write(*,*) 'Testing OBJECT interface '
|
||||
|
||||
@@ -3407,4 +3407,258 @@ SUBROUTINE t_enum_conv(total_error)
|
||||
|
||||
END SUBROUTINE t_enum_conv
|
||||
|
||||
! Tests the reading and writing of multiple datasets using H5Dread_multi and
|
||||
! H5Dwrite_multi
|
||||
|
||||
SUBROUTINE multiple_dset_rw(total_error)
|
||||
|
||||
!-------------------------------------------------------------------------
|
||||
! Subroutine: multiple_dset_rw
|
||||
!
|
||||
! Purpose: Tests the reading and writing of multiple datasets
|
||||
! using H5Dread_multi and H5Dwrite_multi
|
||||
!
|
||||
! Return: Success: 0
|
||||
! Failure: number of errors
|
||||
!
|
||||
! Programmer: M. Scot Breitenfeld
|
||||
! April 2, 2014
|
||||
!
|
||||
!-------------------------------------------------------------------------
|
||||
!
|
||||
USE iso_c_binding
|
||||
USE hdf5
|
||||
IMPLICIT NONE
|
||||
|
||||
INTEGER, INTENT(INOUT) :: total_error ! number of errors
|
||||
INTEGER :: error ! HDF hdferror flag
|
||||
|
||||
INTEGER(SIZE_T), PARAMETER :: ndset = 5 ! Number of data sets
|
||||
INTEGER(HID_T), DIMENSION(:), ALLOCATABLE :: dset_id
|
||||
INTEGER(HID_T), DIMENSION(:), ALLOCATABLE :: mem_type_id
|
||||
INTEGER(HID_T), DIMENSION(:), ALLOCATABLE :: mem_space_id
|
||||
INTEGER(HID_T), DIMENSION(:), ALLOCATABLE :: file_space_id
|
||||
|
||||
INTEGER, PARAMETER :: idim=10, idim2=5, idim3=3 ! size of integer array
|
||||
INTEGER, PARAMETER :: rdim=5 ! size of real array
|
||||
INTEGER, PARAMETER :: cdim=3 ! size of character array
|
||||
INTEGER, PARAMETER :: sdim=2 ! length of character string
|
||||
INTEGER, PARAMETER :: ddim=2 ! size of derived type array
|
||||
INTEGER :: i,j,k
|
||||
|
||||
TYPE(C_PTR), ALLOCATABLE, DIMENSION(:) :: buf_md ! array to hold the multi-datasets
|
||||
|
||||
INTEGER, DIMENSION(1:idim), TARGET :: wbuf_int ! integer write buffer
|
||||
INTEGER, DIMENSION(1:idim,idim2,idim3), TARGET :: wbuf_intmd
|
||||
REAL, DIMENSION(1:rdim), TARGET :: wbuf_real ! real write buffer
|
||||
CHARACTER(LEN=sdim), DIMENSION(1:cdim), TARGET :: wbuf_chr ! character write buffer
|
||||
INTEGER, DIMENSION(1:idim), TARGET :: rbuf_int ! integer read buffer
|
||||
INTEGER, DIMENSION(1:idim,idim2,idim3), TARGET :: rbuf_intmd ! integer read buffer
|
||||
REAL, DIMENSION(1:rdim), TARGET :: rbuf_real ! real read buffer
|
||||
CHARACTER(LEN=sdim), DIMENSION(1:cdim), TARGET :: rbuf_chr ! character read buffer
|
||||
|
||||
TYPE derived
|
||||
REAL :: r
|
||||
INTEGER :: i
|
||||
CHARACTER(LEN=sdim) :: c
|
||||
END TYPE derived
|
||||
|
||||
TYPE(derived), DIMENSION(1:ddim), TARGET :: wbuf_derived ! derived type write buffer
|
||||
TYPE(derived), DIMENSION(1:ddim), TARGET :: rbuf_derived ! derived type read buffer
|
||||
INTEGER(HSIZE_T), DIMENSION(1:1) :: dims ! dimension of the spaces
|
||||
INTEGER(HSIZE_T), DIMENSION(1:3) :: dimsmd ! dimension of the spaces
|
||||
INTEGER(HID_T) :: file_id, strtype ! handles
|
||||
INTEGER(SIZE_T) :: obj_count
|
||||
|
||||
ALLOCATE(buf_md(1:ndset),stat=error)
|
||||
IF (error .NE. 0) THEN
|
||||
WRITE(*,*) 'allocate error'
|
||||
total_error = total_error + 1
|
||||
RETURN
|
||||
ENDIF
|
||||
ALLOCATE(dset_id(1:ndset),stat=error)
|
||||
IF (error .NE. 0) THEN
|
||||
WRITE(*,*) 'allocate error'
|
||||
total_error = total_error + 1
|
||||
RETURN
|
||||
ENDIF
|
||||
ALLOCATE(mem_type_id(1:ndset),stat=error)
|
||||
IF (error .NE. 0) THEN
|
||||
WRITE(*,*) 'allocate error'
|
||||
total_error = total_error + 1
|
||||
RETURN
|
||||
ENDIF
|
||||
ALLOCATE(mem_space_id(1:ndset),stat=error)
|
||||
IF (error .NE. 0) THEN
|
||||
WRITE(*,*) 'allocate error'
|
||||
total_error = total_error + 1
|
||||
RETURN
|
||||
ENDIF
|
||||
ALLOCATE(file_space_id(1:ndset),stat=error)
|
||||
IF (error .NE. 0) THEN
|
||||
WRITE(*,*) 'allocate error'
|
||||
total_error = total_error + 1
|
||||
RETURN
|
||||
ENDIF
|
||||
|
||||
CALL h5fcreate_f("multidset_rw.h5", H5F_ACC_TRUNC_F, file_id, error)
|
||||
CALL check("h5fcreate_f", error, total_error)
|
||||
!
|
||||
! Create real dataset
|
||||
!
|
||||
wbuf_real(1:rdim) = (/(i,i=1,rdim)/)
|
||||
dims(1) = rdim
|
||||
buf_md(1) = C_LOC(wbuf_real(1))
|
||||
mem_type_id(1) = H5T_NATIVE_REAL
|
||||
CALL h5screate_simple_f(1, dims, file_space_id(1), error)
|
||||
CALL check("h5screate_simple_f", error, total_error)
|
||||
CALL h5dcreate_f(file_id, "ds real", mem_type_id(1), file_space_id(1), dset_id(1), error)
|
||||
CALL check("h5dcreate_f", error, total_error)
|
||||
mem_space_id(1) = file_space_id(1)
|
||||
|
||||
! Create integer dataset (1D)
|
||||
wbuf_int(1:idim) = (/(i,i=1,idim)/)
|
||||
dims(1) = idim
|
||||
buf_md(2) = C_LOC(wbuf_int(1))
|
||||
mem_type_id(2) = H5T_NATIVE_INTEGER
|
||||
CALL h5screate_simple_f(1, dims, file_space_id(2), error)
|
||||
CALL check("h5screate_simple_f", error, total_error)
|
||||
CALL h5dcreate_f(file_id, "ds int", mem_type_id(2), file_space_id(2), dset_id(2), error)
|
||||
CALL check("h5dcreate_f", error, total_error)
|
||||
mem_space_id(2) = file_space_id(2)
|
||||
|
||||
! Create character dataset
|
||||
wbuf_chr(1:cdim) = (/'ab','cd','ef'/)
|
||||
dims(1) = cdim
|
||||
buf_md(3) = C_LOC(wbuf_chr(1)(1:1))
|
||||
CALL H5Tcopy_f(H5T_FORTRAN_S1, mem_type_id(3), error)
|
||||
CALL check("H5Tcopy_f", error, total_error)
|
||||
CALL H5Tset_size_f(mem_type_id(3), INT(sdim,SIZE_T), error)
|
||||
CALL check("H5Tset_size_f", error, total_error)
|
||||
CALL h5screate_simple_f(1, dims, file_space_id(3), error)
|
||||
CALL check("h5screate_simple_f", error, total_error)
|
||||
CALL h5dcreate_f(file_id, "ds chr", mem_type_id(3), file_space_id(3), dset_id(3), error)
|
||||
CALL check("h5dcreate_f", error, total_error)
|
||||
mem_space_id(3) = file_space_id(3)
|
||||
|
||||
! Create derived type dataset
|
||||
wbuf_derived(1:ddim)%r = (/10.,20./)
|
||||
wbuf_derived(1:ddim)%i = (/30,40/)
|
||||
wbuf_derived(1:ddim)%c = (/'wx','yz'/)
|
||||
buf_md(4) = C_LOC(wbuf_derived(1)%r)
|
||||
CALL h5tcreate_f(H5T_COMPOUND_F, H5OFFSETOF(C_LOC(wbuf_derived(1)), C_LOC(wbuf_derived(2))), mem_type_id(4), error)
|
||||
CALL check("h5tcreate_f", error, total_error)
|
||||
CALL h5tinsert_f(mem_type_id(4), "real", &
|
||||
H5OFFSETOF(C_LOC(wbuf_derived(1)),C_LOC(wbuf_derived(1)%r)), H5T_NATIVE_REAL, error)
|
||||
CALL check("h5tinsert_f", error, total_error)
|
||||
CALL h5tinsert_f(mem_type_id(4), "int", &
|
||||
H5OFFSETOF(C_LOC(wbuf_derived(1)),C_LOC(wbuf_derived(1)%i)), H5T_NATIVE_INTEGER, error)
|
||||
CALL check("h5tinsert_f", error, total_error)
|
||||
CALL h5tcopy_f(H5T_NATIVE_CHARACTER, strtype, error)
|
||||
CALL check("h5tcopy_f", error, total_error)
|
||||
CALL h5tset_size_f(strtype, INT(sdim,size_t), error)
|
||||
CALL check("h5tset_size_f", error, total_error)
|
||||
CALL h5tinsert_f(mem_type_id(4), "chr", &
|
||||
H5OFFSETOF(C_LOC(wbuf_derived(1)),C_LOC(wbuf_derived(1)%c(1:1))), strtype, error)
|
||||
CALL check("h5tinsert_f", error, total_error)
|
||||
|
||||
dims(1) = ddim
|
||||
CALL h5screate_simple_f(1, dims, file_space_id(4), error)
|
||||
CALL check("h5screate_simple_f", error, total_error)
|
||||
CALL h5dcreate_f(file_id, "ds derived", mem_type_id(4), file_space_id(4), dset_id(4), error)
|
||||
CALL check("h5dcreate_f", error, total_error)
|
||||
mem_space_id(4) = file_space_id(4)
|
||||
|
||||
|
||||
! Create integer dataset (3D)
|
||||
|
||||
DO i = 1, idim
|
||||
DO j = 1, idim2
|
||||
DO k = 1, idim3
|
||||
wbuf_intmd(i,j,k) = i*j
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
|
||||
dimsmd(1:3) = (/idim,idim2,idim3/)
|
||||
buf_md(5) = C_LOC(wbuf_intmd(1,1,1))
|
||||
mem_type_id(5) = H5T_NATIVE_INTEGER
|
||||
CALL h5screate_simple_f(3, dimsmd, file_space_id(5), error)
|
||||
CALL check("h5screate_simple_f", error, total_error)
|
||||
CALL h5dcreate_f(file_id, "ds int 3d", mem_type_id(5), file_space_id(5), dset_id(5), error)
|
||||
CALL check("h5dcreate_f", error, total_error)
|
||||
mem_space_id(5) = file_space_id(5)
|
||||
|
||||
! write all the datasets
|
||||
CALL h5dwrite_multi_f(ndset, dset_id, mem_type_id, mem_space_id, file_space_id, buf_md, error)
|
||||
CALL check("h5dwrite_multi_f", error, total_error)
|
||||
|
||||
! point to read buffers
|
||||
|
||||
buf_md(1) = C_LOC(rbuf_real(1))
|
||||
buf_md(2) = C_LOC(rbuf_int(1))
|
||||
buf_md(3) = C_LOC(rbuf_chr(1)(1:1))
|
||||
buf_md(4) = C_LOC(rbuf_derived(1)%r)
|
||||
buf_md(5) = C_LOC(rbuf_intmd(1,1,1))
|
||||
|
||||
! read all the datasets
|
||||
CALL h5dread_multi_f(ndset, dset_id, mem_type_id, mem_space_id, file_space_id, buf_md, error)
|
||||
CALL check("h5dread_multi_f", error, total_error)
|
||||
|
||||
! check the written and read in values
|
||||
DO i = 1, rdim
|
||||
IF(rbuf_real(i).NE.wbuf_real(i))THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
END DO
|
||||
DO i = 1, idim
|
||||
IF(rbuf_int(i).NE.wbuf_int(i))THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
END DO
|
||||
DO i = 1, cdim
|
||||
IF(rbuf_chr(i).NE.wbuf_chr(i))THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
END DO
|
||||
DO i = 1, ddim
|
||||
IF(rbuf_derived(i)%r.NE.wbuf_derived(i)%r)THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
IF(rbuf_derived(i)%i.NE.wbuf_derived(i)%i)THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
IF(rbuf_derived(i)%c.NE.wbuf_derived(i)%c)THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
END DO
|
||||
DO i = 1, idim
|
||||
DO j = 1, idim2
|
||||
DO k = 1, idim3
|
||||
IF(rbuf_intmd(i,j,k).NE.wbuf_intmd(i,j,k))THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
END DO
|
||||
ENDDO
|
||||
ENDDO
|
||||
|
||||
DO i = 1, ndset
|
||||
CALL H5Dclose_f(dset_id(i), error)
|
||||
CALL check("H5Dclose_f", error, total_error)
|
||||
CALL H5Sclose_f(file_space_id(i), error)
|
||||
CALL check("H5Sclose_f", error, total_error)
|
||||
ENDDO
|
||||
CALL H5Tclose_f(mem_type_id(4), error)
|
||||
CALL check("H5Tclose_f", error, total_error)
|
||||
|
||||
CALL h5fget_obj_count_f(file_id, H5F_OBJ_ALL_F, obj_count, error)
|
||||
IF(obj_count.NE.1)THEN
|
||||
total_error = total_error + 1
|
||||
END IF
|
||||
|
||||
CALL H5Fclose_f(file_id, error)
|
||||
|
||||
END SUBROUTINE multiple_dset_rw
|
||||
|
||||
|
||||
END MODULE TH5T_F03
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ CONTAINS
|
||||
error_string = skip
|
||||
ENDIF
|
||||
|
||||
WRITE(*, fmt = '(A, T80, A)') test_title, error_string
|
||||
WRITE(*, fmt = '(A, T88, A)') test_title, error_string
|
||||
|
||||
IF(test_result.GT.0) total_error = total_error + test_result
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ add_executable (parallel_test
|
||||
ptest.F90
|
||||
hyper.F90
|
||||
mdset.F90
|
||||
multidsetrw.F90
|
||||
)
|
||||
target_include_directories (parallel_test
|
||||
PRIVATE ${TESTPAR_INCLUDES}
|
||||
|
||||
@@ -40,7 +40,7 @@ check_PROGRAMS=$(TEST_PROG_PARA)
|
||||
CHECK_CLEANFILES+=parf[12].h5 subf.h5*
|
||||
|
||||
# Test source files
|
||||
parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90
|
||||
parallel_test_SOURCES=ptest.F90 hyper.F90 mdset.F90 multidsetrw.F90
|
||||
subfiling_test_SOURCES=subfiling.F90
|
||||
|
||||
# The tests depend on several libraries.
|
||||
|
||||
+17
-14
@@ -237,19 +237,23 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors)
|
||||
CALL h5pget_mpio_actual_io_mode_f(dxpl_id, actual_io_mode, hdferror)
|
||||
CALL check("h5pget_mpio_actual_io_mode_f", hdferror, nerrors)
|
||||
|
||||
IF(do_collective.AND.do_chunk)THEN
|
||||
IF(actual_io_mode.NE.H5D_MPIO_CHUNK_COLLECTIVE_F)THEN
|
||||
CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
ENDIF
|
||||
ELSEIF(.NOT.do_collective)THEN
|
||||
IF(actual_io_mode.NE.H5D_MPIO_NO_COLLECTIVE_F)THEN
|
||||
CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
ENDIF
|
||||
ELSEIF( do_collective.AND.(.NOT.do_chunk))THEN
|
||||
IF(actual_io_mode.NE.H5D_MPIO_CONTIG_COLLECTIVE_F)THEN
|
||||
CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
ENDIF
|
||||
ENDIF
|
||||
! MSB -- TODO FIX: skipping for now since multi-dataset
|
||||
! has no specific path for contiguous collective
|
||||
!
|
||||
! IF(do_collective.AND.do_chunk)THEN
|
||||
! IF(actual_io_mode.NE.H5D_MPIO_CHUNK_COLLECTIVE_F)THEN
|
||||
! CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
! ENDIF
|
||||
! ELSEIF(.NOT.do_collective)THEN
|
||||
! IF(actual_io_mode.NE.H5D_MPIO_NO_COLLECTIVE_F)THEN
|
||||
! CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
! ENDIF
|
||||
! ELSEIF( do_collective.AND.(.NOT.do_chunk))THEN
|
||||
! IF(actual_io_mode.NE.H5D_MPIO_CONTIG_COLLECTIVE_F)THEN
|
||||
! CALL check("h5pget_mpio_actual_io_mode_f", -1, nerrors)
|
||||
! ENDIF
|
||||
! ENDIF
|
||||
! MSB
|
||||
|
||||
!
|
||||
! close HDF5 I/O
|
||||
@@ -318,7 +322,6 @@ SUBROUTINE hyper(length,do_collective,do_chunk, mpi_size, mpi_rank, nerrors)
|
||||
|
||||
CALL h5pcreate_f(H5P_DATASET_XFER_F, dxpl_id, hdferror)
|
||||
CALL check("h5pcreate_f", hdferror, nerrors)
|
||||
|
||||
IF (do_collective) THEN
|
||||
CALL h5pset_dxpl_mpio_f(dxpl_id, H5FD_MPIO_COLLECTIVE_F, hdferror)
|
||||
CALL check("h5pset_dxpl_mpio_f", hdferror, nerrors)
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
! Copyright by The HDF Group. *
|
||||
! All rights reserved. *
|
||||
! *
|
||||
! This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
! terms governing use, modification, and redistribution, is contained in *
|
||||
! the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
! of the source code distribution tree; Copyright.html can be found at the *
|
||||
! root level of an installed copy of the electronic HDF5 document set and *
|
||||
! is linked from the top-level documents page. It can also be found at *
|
||||
! http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
! access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
!
|
||||
! writes/reads dataset by hyperslabs using multi-dataset routines, h5dread_multi and
|
||||
! h5dwrite_multi
|
||||
!
|
||||
|
||||
SUBROUTINE pmultiple_dset_hyper_rw(do_collective, do_chunk, mpi_size, mpi_rank, nerrors)
|
||||
|
||||
USE iso_c_binding
|
||||
USE TH5_MISC
|
||||
USE hdf5
|
||||
USE mpi
|
||||
IMPLICIT NONE
|
||||
|
||||
LOGICAL, INTENT(in) :: do_collective ! use collective IO
|
||||
LOGICAL, INTENT(in) :: do_chunk ! use chunking
|
||||
INTEGER, INTENT(in) :: mpi_size ! number of processes in the group of communicator
|
||||
INTEGER, INTENT(in) :: mpi_rank ! rank of the calling process in the communicator
|
||||
INTEGER, INTENT(inout) :: nerrors ! number of errors
|
||||
CHARACTER(LEN=80):: dsetname ! Dataset name
|
||||
INTEGER(hsize_t), DIMENSION(1:2) :: cdims ! chunk dimensions
|
||||
|
||||
INTEGER(HID_T) :: file_id ! File identifier
|
||||
INTEGER(HID_T) :: filespace ! Dataspace identifier in file
|
||||
INTEGER(HID_T) :: memspace ! Dataspace identifier in memory
|
||||
INTEGER(HID_T) :: plist_id ! Property list identifier
|
||||
INTEGER(HID_T) :: dcpl_id ! Dataset creation property list
|
||||
INTEGER(HSIZE_T), DIMENSION(1:2) :: dimsf ! Dataset dimensions.
|
||||
|
||||
INTEGER(HSIZE_T), DIMENSION(1:2) :: count
|
||||
INTEGER(HSSIZE_T), DIMENSION(1:2) :: offset
|
||||
INTEGER, ALLOCATABLE, DIMENSION(:,:,:), TARGET :: DATA ! Data to write
|
||||
INTEGER, ALLOCATABLE, DIMENSION(:,:,:), TARGET :: rDATA ! Data to write
|
||||
INTEGER, PARAMETER :: rank = 2 ! Dataset rank
|
||||
INTEGER :: i
|
||||
INTEGER(HSIZE_T) :: ii, jj, kk, istart
|
||||
INTEGER :: error ! Error flags
|
||||
|
||||
INTEGER(SIZE_T), PARAMETER :: ndsets = 5
|
||||
INTEGER(HID_T), DIMENSION(1:ndsets) :: dset_id
|
||||
INTEGER(HID_T), DIMENSION(1:ndsets) :: mem_type_id
|
||||
INTEGER(HID_T), DIMENSION(1:ndsets) :: mem_space_id
|
||||
INTEGER(HID_T), DIMENSION(1:ndsets) :: file_space_id
|
||||
TYPE(C_PTR), DIMENSION(1:ndsets) :: buf_md
|
||||
INTEGER(SIZE_T) :: obj_count
|
||||
INTEGER :: data_xfer_mode
|
||||
|
||||
dimsf(1) = 5_hsize_t
|
||||
dimsf(2) = INT(mpi_size, hsize_t)*8_hsize_t
|
||||
|
||||
!
|
||||
! Setup file access property list with parallel I/O access.
|
||||
!
|
||||
CALL h5pcreate_f(H5P_FILE_ACCESS_F, plist_id, error)
|
||||
CALL check("h5pcreate_f", error, nerrors)
|
||||
CALL h5pset_fapl_mpio_f(plist_id, MPI_COMM_WORLD, MPI_INFO_NULL, error)
|
||||
CALL check("h5pset_fapl_mpio_f", error, nerrors)
|
||||
!
|
||||
! Create the file collectively.
|
||||
!
|
||||
CALL h5fcreate_f("parf2.h5", H5F_ACC_TRUNC_F, file_id, error, access_prp = plist_id)
|
||||
CALL check("h5fcreate_f", error, nerrors)
|
||||
CALL h5pclose_f(plist_id, error)
|
||||
CALL check("h5pclose_f", error, nerrors)
|
||||
!
|
||||
! Create the data space for the dataset.
|
||||
!
|
||||
CALL h5screate_simple_f(rank, dimsf, filespace, error)
|
||||
CALL check("h5screate_simple_f", error, nerrors)
|
||||
!
|
||||
! Each process defines dataset in memory and writes it to the hyperslab
|
||||
! in the file.
|
||||
!
|
||||
count(1) = dimsf(1)
|
||||
count(2) = dimsf(2)/mpi_size
|
||||
offset(1) = 0
|
||||
offset(2) = mpi_rank * count(2)
|
||||
CALL h5screate_simple_f(rank, count, memspace, error)
|
||||
CALL check("h5screate_simple_f", error, nerrors)
|
||||
|
||||
!
|
||||
! Modify dataset creation properties to enable chunking
|
||||
!
|
||||
|
||||
CALL h5pcreate_f(H5P_DATASET_CREATE_F, dcpl_id, error)
|
||||
CALL check("h5pcreate_f", error, nerrors)
|
||||
|
||||
IF (do_chunk) THEN
|
||||
cdims(1) = dimsf(1)
|
||||
cdims(2) = dimsf(2)/mpi_size/2
|
||||
CALL h5pset_chunk_f(dcpl_id, 2, cdims, error)
|
||||
CALL check("h5pset_chunk_f", error, nerrors)
|
||||
ENDIF
|
||||
!
|
||||
! Select hyperslab in the file.
|
||||
!
|
||||
CALL h5sselect_hyperslab_f(filespace, H5S_SELECT_SET_F, offset, count, error)
|
||||
CALL check("h5sselect_hyperslab_f", error, nerrors)
|
||||
!
|
||||
! Initialize data buffer
|
||||
!
|
||||
ALLOCATE ( DATA(COUNT(1),COUNT(2), ndsets))
|
||||
ALLOCATE ( rdata(COUNT(1),COUNT(2), ndsets))
|
||||
|
||||
! Create property list for collective dataset write
|
||||
!
|
||||
CALL h5pcreate_f(H5P_DATASET_XFER_F, plist_id, error)
|
||||
CALL check("h5pcreate_f", error, nerrors)
|
||||
IF(do_collective)THEN
|
||||
CALL h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, error)
|
||||
CALL check("h5pset_dxpl_mpio_f", error, nerrors)
|
||||
ELSE
|
||||
CALL h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_INDEPENDENT_F, error)
|
||||
CALL check("h5pset_dxpl_mpio_f", error, nerrors)
|
||||
ENDIF
|
||||
|
||||
!
|
||||
! Create the dataset with default properties.
|
||||
!
|
||||
mem_type_id(1:ndsets) = H5T_NATIVE_INTEGER
|
||||
mem_space_id(1:ndsets) = memspace
|
||||
file_space_id(1:ndsets)= filespace
|
||||
|
||||
DO ii = 1, ndsets
|
||||
! Create the data
|
||||
DO kk = 1, COUNT(1)
|
||||
DO jj = 1, COUNT(2)
|
||||
istart = (kk-1)*dimsf(2) + mpi_rank*COUNT(2)
|
||||
DATA(kk,jj,ii) = INT((istart + jj)*10**(ii-1))
|
||||
ENDDO
|
||||
ENDDO
|
||||
! Point to te data
|
||||
buf_md(ii) = C_LOC(DATA(1,1,ii))
|
||||
|
||||
! direct the output of the write statement to unit "dsetname"
|
||||
WRITE(dsetname,'("dataset ",I0)') ii
|
||||
! create the dataset
|
||||
CALL h5dcreate_f(file_id, dsetname, H5T_NATIVE_INTEGER, filespace, dset_id(ii), error, dcpl_id)
|
||||
CALL check("h5dcreate_f", error, nerrors)
|
||||
ENDDO
|
||||
|
||||
!
|
||||
! Write the dataset collectively.
|
||||
!
|
||||
CALL h5dwrite_multi_f(ndsets, dset_id, mem_type_id, mem_space_id, file_space_id, buf_md, error, plist_id)
|
||||
CALL check("h5dwrite_multi_f", error, nerrors)
|
||||
|
||||
CALL h5pget_dxpl_mpio_f(plist_id, data_xfer_mode, error)
|
||||
CALL check("h5pget_dxpl_mpio_f", error, nerrors)
|
||||
|
||||
IF(do_collective)THEN
|
||||
IF(data_xfer_mode.NE.H5FD_MPIO_COLLECTIVE_F)THEN
|
||||
nerrors = nerrors + 1
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
DO i = 1, ndsets
|
||||
! Point to the read buffer
|
||||
buf_md(i) = C_LOC(rdata(1,1,i))
|
||||
ENDDO
|
||||
|
||||
CALL H5Dread_multi_f(ndsets, dset_id, mem_type_id, mem_space_id, file_space_id, buf_md, error, plist_id)
|
||||
CALL check("h5dread_multi_f", error, nerrors)
|
||||
|
||||
CALL h5pget_dxpl_mpio_f(plist_id, data_xfer_mode, error)
|
||||
CALL check("h5pget_dxpl_mpio_f", error, nerrors)
|
||||
|
||||
IF(do_collective)THEN
|
||||
IF(data_xfer_mode.NE.H5FD_MPIO_COLLECTIVE_F)THEN
|
||||
nerrors = nerrors + 1
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
DO i = 1, ndsets
|
||||
! Close all the datasets
|
||||
CALL h5dclose_f(dset_id(i), error)
|
||||
CALL check("h5dclose_f", error, nerrors)
|
||||
ENDDO
|
||||
|
||||
! check the data read and write buffers
|
||||
DO ii = 1, ndsets
|
||||
! Create the data
|
||||
DO kk = 1, COUNT(1)
|
||||
DO jj = 1, COUNT(2)
|
||||
IF(rDATA(kk,jj,ii).NE.DATA(kk,jj,ii))THEN
|
||||
nerrors = nerrors + 1
|
||||
ENDIF
|
||||
ENDDO
|
||||
ENDDO
|
||||
ENDDO
|
||||
!
|
||||
! Deallocate data buffer.
|
||||
!
|
||||
DEALLOCATE(data, rdata)
|
||||
|
||||
!
|
||||
! Close dataspaces.
|
||||
!
|
||||
CALL h5sclose_f(filespace, error)
|
||||
CALL check("h5sclose_f", error, nerrors)
|
||||
CALL h5sclose_f(memspace, error)
|
||||
CALL check("h5sclose_f", error, nerrors)
|
||||
!
|
||||
! Close the dataset and property list.
|
||||
!
|
||||
CALL h5pclose_f(dcpl_id, error)
|
||||
CALL check("h5pclose_f", error, nerrors)
|
||||
CALL h5pclose_f(plist_id, error)
|
||||
CALL check("h5pclose_f", error, nerrors)
|
||||
|
||||
CALL h5fget_obj_count_f(file_id, H5F_OBJ_ALL_F, obj_count, error)
|
||||
IF(obj_count.NE.1)THEN
|
||||
nerrors = nerrors + 1
|
||||
END IF
|
||||
|
||||
!
|
||||
! Close the file.
|
||||
!
|
||||
CALL h5fclose_f(file_id, error)
|
||||
CALL check("h5fclose_f", error, nerrors)
|
||||
|
||||
END SUBROUTINE pmultiple_dset_hyper_rw
|
||||
@@ -76,7 +76,18 @@ PROGRAM parallel_test
|
||||
CALL multiple_dset_write(length, do_collective(1), do_chunk(1), mpi_size, mpi_rank, ret_total_error)
|
||||
IF(mpi_rank==0) CALL write_test_status(ret_total_error, &
|
||||
'Writing/reading several datasets (contiguous layout, independent MPI I/O)', total_error)
|
||||
|
||||
!
|
||||
! test write/read multiple hyperslab datasets
|
||||
!
|
||||
DO i = 1, 2
|
||||
DO j = 1, 2
|
||||
ret_total_error = 0
|
||||
CALL pmultiple_dset_hyper_rw(do_collective(j), do_chunk(i), mpi_size, mpi_rank, ret_total_error)
|
||||
IF(mpi_rank==0) CALL write_test_status(ret_total_error, &
|
||||
"Writing/reading multiple datasets by hyperslab ("//TRIM(chr_chunk(i))//" layout, "&
|
||||
//TRIM(chr_collective(j))//" MPI I/O)", total_error)
|
||||
ENDDO
|
||||
ENDDO
|
||||
!
|
||||
! close HDF5 interface
|
||||
!
|
||||
|
||||
@@ -50,10 +50,11 @@ static hid_t H5D__create_api_common(hid_t loc_id, const char *name, hid_t type_
|
||||
static hid_t H5D__open_api_common(hid_t loc_id, const char *name, hid_t dapl_id, void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr);
|
||||
static hid_t H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
|
||||
static herr_t H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
|
||||
static herr_t H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf, void **token_ptr,
|
||||
static herr_t H5D__read_api_common(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr);
|
||||
static herr_t H5D__write_api_common(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr);
|
||||
static herr_t H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr);
|
||||
@@ -943,26 +944,64 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
|
||||
void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
|
||||
H5D__read_api_common(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr)
|
||||
{
|
||||
H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */
|
||||
H5VL_object_t **vol_obj_ptr =
|
||||
(_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
H5VL_t *connector; /* VOL connector pointer */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check arguments */
|
||||
if (mem_space_id < 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
|
||||
if (file_space_id < 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
|
||||
if (count == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count must be greater than 0")
|
||||
if (!dset_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dset_id array not provided")
|
||||
if (!mem_type_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided")
|
||||
if (!mem_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided")
|
||||
if (!file_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided")
|
||||
if (!buf)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided")
|
||||
|
||||
/* Get dataset pointer */
|
||||
if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)H5MM_malloc(count * sizeof(void *))))
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate space for object array")
|
||||
|
||||
/* Get vol_obj_ptr (return just the first dataset to caller if requested) */
|
||||
if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id[0], H5I_DATASET)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
|
||||
|
||||
/* Save the connector of the first dataset. Unpack the connector and call
|
||||
* the "direct" read function here to avoid allocating an array of count
|
||||
* H5VL_object_ts. */
|
||||
connector = (*vol_obj_ptr)->connector;
|
||||
|
||||
/* Build obj array */
|
||||
obj[0] = (*vol_obj_ptr)->data;
|
||||
for (i = 1; i < count; i++) {
|
||||
/* Get the object */
|
||||
if (NULL == (tmp_vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id[i], H5I_DATASET)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
|
||||
obj[i] = tmp_vol_obj->data;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (tmp_vol_obj->connector->cls->value != connector->cls->value)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
|
||||
"datasets are accessed through different VOL connectors and can't be used in the "
|
||||
"same I/O call")
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -970,11 +1009,15 @@ H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
|
||||
|
||||
/* Read the data */
|
||||
if (H5VL_dataset_read(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) <
|
||||
0)
|
||||
if (H5VL_dataset_read_direct(count, obj, connector, mem_type_id, mem_space_id, file_space_id, dxpl_id,
|
||||
buf, token_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
|
||||
done:
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
H5MM_free(obj);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__read_api_common() */
|
||||
|
||||
@@ -1022,7 +1065,8 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_i
|
||||
H5TRACE6("e", "iiiiix", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
|
||||
|
||||
/* Read the data */
|
||||
if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) < 0)
|
||||
if (H5D__read_api_common(1, &dset_id, &mem_type_id, &mem_space_id, &file_space_id, dxpl_id, &buf, NULL,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't synchronously read data")
|
||||
|
||||
done:
|
||||
@@ -1059,8 +1103,8 @@ H5Dread_async(const char *app_file, const char *app_func, unsigned app_line, hid
|
||||
token_ptr = &token; /* Point at token for VOL connector to set up */
|
||||
|
||||
/* Read the data */
|
||||
if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr,
|
||||
&vol_obj) < 0)
|
||||
if (H5D__read_api_common(1, &dset_id, &mem_type_id, &mem_space_id, &file_space_id, dxpl_id, &buf,
|
||||
token_ptr, &vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't asynchronously read data")
|
||||
|
||||
/* If a token was created, add the token to the event set */
|
||||
@@ -1075,6 +1119,84 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dread_async() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dread_multi
|
||||
*
|
||||
* Purpose: Multi-version of H5Dread(), which reads selections from
|
||||
* multiple datasets from a file into application memory BUFS.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dread_multi(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[], hid_t file_space_id[],
|
||||
hid_t dxpl_id, void *buf[] /*out*/)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE7("e", "z*i*i*i*iix", count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
|
||||
|
||||
if (count == 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Read the data */
|
||||
if (H5D__read_api_common(count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't synchronously read data")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dread_multi() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dread_multi_async
|
||||
*
|
||||
* Purpose: Asynchronously read dataset elements from multiple
|
||||
* datasets.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dread_multi_async(const char *app_file, const char *app_func, unsigned app_line, size_t count,
|
||||
hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[], hid_t file_space_id[],
|
||||
hid_t dxpl_id, void *buf[] /*out*/, hid_t es_id)
|
||||
{
|
||||
H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */
|
||||
void *token = NULL; /* Request token for async operation */
|
||||
void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE11("e", "*s*sIuz*i*i*i*iixi", app_file, app_func, app_line, count, dset_id, mem_type_id,
|
||||
mem_space_id, file_space_id, dxpl_id, buf, es_id);
|
||||
|
||||
/* Set up request token pointer for asynchronous operation */
|
||||
if (H5ES_NONE != es_id)
|
||||
token_ptr = &token; /* Point at token for VOL connector to set up */
|
||||
|
||||
/* Read the data */
|
||||
if (H5D__read_api_common(count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
|
||||
token_ptr, &vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't asynchronously read data")
|
||||
|
||||
/* If a token was created, add the token to the event set */
|
||||
if (NULL != token)
|
||||
/* clang-format off */
|
||||
if (H5ES_insert(es_id, vol_obj->connector, token,
|
||||
H5ARG_TRACE11(__func__, "*s*sIuz*i*i*i*iixi", app_file, app_func, app_line, count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0)
|
||||
/* clang-format on */
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dread_multi_async() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dread_chunk
|
||||
*
|
||||
@@ -1142,26 +1264,64 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
|
||||
H5D__write_api_common(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **token_ptr,
|
||||
H5VL_object_t **_vol_obj_ptr)
|
||||
{
|
||||
H5VL_object_t *tmp_vol_obj = NULL; /* Object for loc_id */
|
||||
H5VL_object_t **vol_obj_ptr =
|
||||
(_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
H5VL_t *connector; /* VOL connector pointer */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check arguments */
|
||||
if (mem_space_id < 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
|
||||
if (file_space_id < 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
|
||||
if (count == 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count must be greater than 0")
|
||||
if (!dset_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dset_id array not provided")
|
||||
if (!mem_type_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided")
|
||||
if (!mem_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided")
|
||||
if (!file_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided")
|
||||
if (!buf)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided")
|
||||
|
||||
/* Get dataset pointer */
|
||||
if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)H5MM_malloc(count * sizeof(void *))))
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate space for object array")
|
||||
|
||||
/* Get vol_obj_ptr (return just the first dataset to caller if requested) */
|
||||
if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id[0], H5I_DATASET)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
|
||||
|
||||
/* Save the connector of the first dataset. Unpack the connector and call
|
||||
* the "direct" write function here to avoid allocating an array of count
|
||||
* H5VL_object_ts. */
|
||||
connector = (*vol_obj_ptr)->connector;
|
||||
|
||||
/* Build obj array */
|
||||
obj[0] = (*vol_obj_ptr)->data;
|
||||
for (i = 1; i < count; i++) {
|
||||
/* Get the object */
|
||||
if (NULL == (tmp_vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id[i], H5I_DATASET)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
|
||||
obj[i] = tmp_vol_obj->data;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (tmp_vol_obj->connector->cls->value != connector->cls->value)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
|
||||
"datasets are accessed through different VOL connectors and can't be used in the "
|
||||
"same I/O call")
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@@ -1169,11 +1329,15 @@ H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
|
||||
|
||||
/* Write the data */
|
||||
if (H5VL_dataset_write(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) <
|
||||
0)
|
||||
if (H5VL_dataset_write_direct(count, obj, connector, mem_type_id, mem_space_id, file_space_id, dxpl_id,
|
||||
buf, token_ptr) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
|
||||
|
||||
done:
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
H5MM_free(obj);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__write_api_common() */
|
||||
|
||||
@@ -1222,8 +1386,8 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_
|
||||
H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
|
||||
|
||||
/* Write the data */
|
||||
if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) <
|
||||
0)
|
||||
if (H5D__write_api_common(1, &dset_id, &mem_type_id, &mem_space_id, &file_space_id, dxpl_id, &buf, NULL,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't synchronously write data")
|
||||
|
||||
done:
|
||||
@@ -1261,8 +1425,8 @@ H5Dwrite_async(const char *app_file, const char *app_func, unsigned app_line, hi
|
||||
token_ptr = &token; /* Point at token for VOL connector to set up */
|
||||
|
||||
/* Write the data */
|
||||
if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr,
|
||||
&vol_obj) < 0)
|
||||
if (H5D__write_api_common(1, &dset_id, &mem_type_id, &mem_space_id, &file_space_id, dxpl_id, &buf,
|
||||
token_ptr, &vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't asynchronously write data")
|
||||
|
||||
/* If a token was created, add the token to the event set */
|
||||
@@ -1277,6 +1441,84 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dwrite_async() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dwrite_multi
|
||||
*
|
||||
* Purpose: Multi-version of H5Dwrite(), which writes selections from
|
||||
* application memory BUFs into multiple datasets in a file.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dwrite_multi(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[])
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE7("e", "z*i*i*i*ii**x", count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
|
||||
|
||||
if (count == 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Write the data */
|
||||
if (H5D__write_api_common(count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't synchronously write data")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dwrite_multi() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dwrite_multi_async
|
||||
*
|
||||
* Purpose: Asynchronously write dataset elements to multiple
|
||||
* datasets.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5Dwrite_multi_async(const char *app_file, const char *app_func, unsigned app_line, size_t count,
|
||||
hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[], hid_t file_space_id[],
|
||||
hid_t dxpl_id, const void *buf[], hid_t es_id)
|
||||
{
|
||||
H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */
|
||||
void *token = NULL; /* Request token for async operation */
|
||||
void **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE11("e", "*s*sIuz*i*i*i*ii**xi", app_file, app_func, app_line, count, dset_id, mem_type_id,
|
||||
mem_space_id, file_space_id, dxpl_id, buf, es_id);
|
||||
|
||||
/* Set up request token pointer for asynchronous operation */
|
||||
if (H5ES_NONE != es_id)
|
||||
token_ptr = &token; /* Point at token for VOL connector to set up */
|
||||
|
||||
/* Write the data */
|
||||
if (H5D__write_api_common(count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
|
||||
token_ptr, &vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't asynchronously write data")
|
||||
|
||||
/* If a token was created, add the token to the event set */
|
||||
if (NULL != token)
|
||||
/* clang-format off */
|
||||
if (H5ES_insert(es_id, vol_obj->connector, token,
|
||||
H5ARG_TRACE11(__func__, "*s*sIuz*i*i*i*ii**xi", app_file, app_func, app_line, count, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0)
|
||||
/* clang-format on */
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Dwrite_multi_async() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5Dwrite_chunk
|
||||
*
|
||||
|
||||
+947
-746
@@ -67,11 +67,19 @@
|
||||
/****************/
|
||||
|
||||
/* Macros for iterating over chunks to operate on */
|
||||
#define H5D_CHUNK_GET_FIRST_NODE(map) (map->use_single ? (H5SL_node_t *)(1) : H5SL_first(map->sel_chunks))
|
||||
#define H5D_CHUNK_GET_NODE_INFO(map, node) \
|
||||
(map->use_single ? map->single_chunk_info : (H5D_chunk_info_t *)H5SL_item(node))
|
||||
#define H5D_CHUNK_GET_NEXT_NODE(map, node) (map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
|
||||
#define H5D_CHUNK_GET_NODE_COUNT(map) (map->use_single ? (size_t)1 : H5SL_count(map->sel_chunks))
|
||||
#define H5D_CHUNK_GET_FIRST_NODE(dinfo) \
|
||||
(dinfo->layout_io_info.chunk_map->use_single \
|
||||
? (H5SL_node_t *)(1) \
|
||||
: H5SL_first(dinfo->layout_io_info.chunk_map->dset_sel_pieces))
|
||||
#define H5D_CHUNK_GET_NODE_INFO(dinfo, node) \
|
||||
(dinfo->layout_io_info.chunk_map->use_single ? dinfo->layout_io_info.chunk_map->single_piece_info \
|
||||
: (H5D_piece_info_t *)H5SL_item(node))
|
||||
#define H5D_CHUNK_GET_NEXT_NODE(dinfo, node) \
|
||||
(dinfo->layout_io_info.chunk_map->use_single ? (H5SL_node_t *)NULL : H5SL_next(node))
|
||||
#define H5D_CHUNK_GET_NODE_COUNT(dinfo) \
|
||||
(dinfo->layout_io_info.chunk_map->use_single \
|
||||
? (size_t)1 \
|
||||
: H5SL_count(dinfo->layout_io_info.chunk_map->dset_sel_pieces))
|
||||
|
||||
/* Sanity check on chunk index types: commonly used by a lot of routines in this file */
|
||||
#define H5D_CHUNK_STORAGE_INDEX_CHK(storage) \
|
||||
@@ -143,6 +151,7 @@ typedef struct H5D_chunk_it_ud1_t {
|
||||
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
|
||||
const H5D_chk_idx_info_t *idx_info; /* Chunked index info */
|
||||
const H5D_io_info_t *io_info; /* I/O info for dataset operation */
|
||||
const H5D_dset_io_info_t *dset_info; /* Dataset specific I/O info */
|
||||
const hsize_t *space_dim; /* New dataset dimensions */
|
||||
const hbool_t *shrunk_dim; /* Dimensions which have been shrunk */
|
||||
H5S_t *chunk_space; /* Dataspace for a chunk */
|
||||
@@ -231,14 +240,6 @@ typedef struct H5D_chunk_info_iter_ud_t {
|
||||
hbool_t found; /* Whether the chunk was found */
|
||||
} H5D_chunk_info_iter_ud_t;
|
||||
|
||||
/* Callback info for file selection iteration */
|
||||
typedef struct H5D_chunk_file_iter_ud_t {
|
||||
H5D_chunk_map_t *fm; /* File->memory chunk mapping info */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
const H5D_io_info_t *io_info; /* I/O info for operation */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
} H5D_chunk_file_iter_ud_t;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* information to construct a collective I/O operation for filling chunks */
|
||||
typedef struct H5D_chunk_coll_fill_info_t {
|
||||
@@ -264,16 +265,13 @@ typedef struct H5D_chunk_iter_ud_t {
|
||||
/* Chunked layout operation callbacks */
|
||||
static herr_t H5D__chunk_construct(H5F_t *f, H5D_t *dset);
|
||||
static herr_t H5D__chunk_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__chunk_io_init_selections(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__chunk_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__chunk_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__chunk_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__chunk_flush(H5D_t *dset);
|
||||
static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_io_term(H5D_io_info_t *io_info, H5D_dset_io_info_t *di);
|
||||
static herr_t H5D__chunk_dest(H5D_t *dset);
|
||||
|
||||
/* Chunk query operation callbacks */
|
||||
@@ -283,8 +281,8 @@ static int H5D__get_chunk_info_by_coord_cb(const H5D_chunk_rec_t *chunk_rec, voi
|
||||
static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata);
|
||||
|
||||
/* "Nonexistent" layout operation callback */
|
||||
static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq,
|
||||
size_t *chunk_curr_seq, size_t chunk_len_arr[],
|
||||
static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[],
|
||||
hsize_t chunk_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
|
||||
@@ -292,29 +290,28 @@ static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chun
|
||||
static int H5D__chunk_format_convert_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata);
|
||||
|
||||
/* Helper routines */
|
||||
static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims,
|
||||
const hsize_t *max_dims);
|
||||
static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
|
||||
static herr_t H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata);
|
||||
static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udata);
|
||||
static herr_t H5D__free_chunk_info(void *item, void *key, void *opdata);
|
||||
static herr_t H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__chunk_file_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
|
||||
void *fm);
|
||||
static herr_t H5D__chunk_mem_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
|
||||
void *fm);
|
||||
static htri_t H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info);
|
||||
static herr_t H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize_t *curr_dims,
|
||||
const hsize_t *max_dims);
|
||||
static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last);
|
||||
static herr_t H5D__chunk_cinfo_cache_update(H5D_chunk_cached_t *last, const H5D_chunk_ud_t *udata);
|
||||
static hbool_t H5D__chunk_cinfo_cache_found(const H5D_chunk_cached_t *last, H5D_chunk_ud_t *udata);
|
||||
static herr_t H5D__create_piece_map_single(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_piece_file_map_all(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_piece_file_map_hyper(H5D_dset_io_info_t *di, H5D_io_info_t *io_info);
|
||||
static herr_t H5D__create_piece_mem_map_1d(const H5D_dset_io_info_t *di);
|
||||
static herr_t H5D__create_piece_mem_map_hyper(const H5D_dset_io_info_t *di);
|
||||
static herr_t H5D__piece_file_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
|
||||
void *_opdata);
|
||||
static herr_t H5D__piece_mem_cb(void *elem, const H5T_t *type, unsigned ndims, const hsize_t *coords,
|
||||
void *_opdata);
|
||||
static htri_t H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
|
||||
static unsigned H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled);
|
||||
static herr_t H5D__chunk_flush_entry(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t reset);
|
||||
static herr_t H5D__chunk_cache_evict(const H5D_t *dset, H5D_rdcc_ent_t *ent, hbool_t flush);
|
||||
static void *H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax,
|
||||
hbool_t prev_unfilt_chunk);
|
||||
static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty,
|
||||
void *chunk, uint32_t naccessed);
|
||||
static void *H5D__chunk_lock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk);
|
||||
static herr_t H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk, uint32_t naccessed);
|
||||
static herr_t H5D__chunk_cache_prune(const H5D_t *dset, size_t size);
|
||||
static herr_t H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk);
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
@@ -337,17 +334,14 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
|
||||
H5D__chunk_is_space_alloc, /* is_space_alloc */
|
||||
H5D__chunk_is_data_cached, /* is_data_cached */
|
||||
H5D__chunk_io_init, /* io_init */
|
||||
H5D__chunk_mdio_init, /* mdio_init */
|
||||
H5D__chunk_read, /* ser_read */
|
||||
H5D__chunk_write, /* ser_write */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5D__chunk_collective_read, /* par_read */
|
||||
H5D__chunk_collective_write, /* par_write */
|
||||
#endif
|
||||
NULL, /* readvv */
|
||||
NULL, /* writevv */
|
||||
H5D__chunk_flush, /* flush */
|
||||
H5D__chunk_io_term, /* io_term */
|
||||
H5D__chunk_dest /* dest */
|
||||
NULL, /* readvv */
|
||||
NULL, /* writevv */
|
||||
H5D__chunk_flush, /* flush */
|
||||
H5D__chunk_io_term, /* io_term */
|
||||
H5D__chunk_dest /* dest */
|
||||
}};
|
||||
|
||||
/*******************/
|
||||
@@ -355,11 +349,8 @@ const H5D_layout_ops_t H5D_LOPS_CHUNK[1] = {{
|
||||
/*******************/
|
||||
|
||||
/* "nonexistent" storage layout I/O ops */
|
||||
const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {{NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
NULL, NULL,
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5D__nonexistent_readvv, NULL, NULL, NULL, NULL}};
|
||||
const H5D_layout_ops_t H5D_LOPS_NONEXISTENT[1] = {
|
||||
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, H5D__nonexistent_readvv, NULL, NULL, NULL, NULL}};
|
||||
|
||||
/* Declare a free list to manage the H5F_rdcc_ent_ptr_t sequence information */
|
||||
H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t);
|
||||
@@ -368,7 +359,10 @@ H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t);
|
||||
H5FL_DEFINE_STATIC(H5D_rdcc_ent_t);
|
||||
|
||||
/* Declare a free list to manage the H5D_chunk_info_t struct */
|
||||
H5FL_DEFINE(H5D_chunk_info_t);
|
||||
H5FL_DEFINE(H5D_chunk_map_t);
|
||||
|
||||
/* Declare a free list to manage the H5D_piece_info_t struct */
|
||||
H5FL_DEFINE(H5D_piece_info_t);
|
||||
|
||||
/* Declare a free list to manage the chunk sequence information */
|
||||
H5FL_BLK_DEFINE_STATIC(chunk);
|
||||
@@ -389,8 +383,7 @@ H5FL_EXTERN(H5S_sel_iter_t);
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size,
|
||||
const void *buf)
|
||||
H5D__chunk_direct_write(H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size, const void *buf)
|
||||
{
|
||||
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
|
||||
H5D_chunk_ud_t udata; /* User data for querying chunk info */
|
||||
@@ -406,16 +399,9 @@ H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, ui
|
||||
HDassert(layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Allocate dataspace and initialize it if it hasn't been. */
|
||||
if (!H5D__chunk_is_space_alloc(&layout->storage)) {
|
||||
H5D_io_info_t io_info; /* to hold the dset info */
|
||||
|
||||
io_info.dset = dset;
|
||||
io_info.f_sh = H5F_SHARED(dset->oloc.file);
|
||||
|
||||
/* Allocate storage */
|
||||
if (H5D__alloc_storage(&io_info, H5D_ALLOC_WRITE, FALSE, NULL) < 0)
|
||||
if (!H5D__chunk_is_space_alloc(&layout->storage))
|
||||
if (H5D__alloc_storage(dset, H5D_ALLOC_WRITE, FALSE, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
|
||||
}
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
H5VM_chunk_scaled(dset->shared->ndims, offset, layout->u.chunk.dim, scaled);
|
||||
@@ -1069,26 +1055,40 @@ H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm)
|
||||
H5D__chunk_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
|
||||
hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
|
||||
htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
|
||||
unsigned f_ndims; /* The number of dimensions of the file's dataspace */
|
||||
int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
const H5D_t *dataset = dinfo->dset; /* Local pointer to dataset info */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
|
||||
htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
|
||||
unsigned f_ndims; /* The number of dimensions of the file's dataspace */
|
||||
int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Allocate chunk map */
|
||||
if (NULL == (dinfo->layout_io_info.chunk_map = H5FL_MALLOC(H5D_chunk_map_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk map")
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
|
||||
/* Get layout for dataset */
|
||||
fm->layout = &(dataset->shared->layout);
|
||||
fm->nelmts = nelmts;
|
||||
dinfo->layout = &(dataset->shared->layout);
|
||||
|
||||
/* Initialize "last chunk" information */
|
||||
fm->last_index = (hsize_t)-1;
|
||||
fm->last_piece_info = NULL;
|
||||
|
||||
/* Clear other fields */
|
||||
fm->mchunk_tmpl = NULL;
|
||||
fm->dset_sel_pieces = NULL;
|
||||
fm->single_space = NULL;
|
||||
fm->single_piece_info = NULL;
|
||||
|
||||
/* Check if the memory space is scalar & make equivalent memory space */
|
||||
if ((sm_ndims = H5S_GET_EXTENT_NDIMS(mem_space)) < 0)
|
||||
if ((sm_ndims = H5S_GET_EXTENT_NDIMS(dinfo->mem_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number")
|
||||
/* Set the number of dimensions for the memory dataspace */
|
||||
H5_CHECKED_ASSIGN(fm->m_ndims, unsigned, sm_ndims, int);
|
||||
@@ -1102,49 +1102,28 @@ H5D__chunk_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsi
|
||||
* speed up hyperslab calculations by removing the extra checks and/or
|
||||
* additions involving the offset and the hyperslab selection -QAK)
|
||||
*/
|
||||
if ((file_space_normalized = H5S_hyper_normalize_offset(file_space, old_offset)) < 0)
|
||||
if ((file_space_normalized = H5S_hyper_normalize_offset(dinfo->file_space, old_offset)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to normalize selection")
|
||||
|
||||
/* Decide the number of chunks in each dimension */
|
||||
for (u = 0; u < f_ndims; u++)
|
||||
/* Keep the size of the chunk dimensions as hsize_t for various routines */
|
||||
fm->chunk_dim[u] = fm->layout->u.chunk.dim[u];
|
||||
fm->chunk_dim[u] = dinfo->layout->u.chunk.dim[u];
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Calculate total chunk in file map*/
|
||||
fm->select_chunk = NULL;
|
||||
if (io_info->using_mpi_vfd) {
|
||||
H5_CHECK_OVERFLOW(fm->layout->u.chunk.nchunks, hsize_t, size_t);
|
||||
if (fm->layout->u.chunk.nchunks)
|
||||
if (NULL == (fm->select_chunk = (H5D_chunk_info_t **)H5MM_calloc(
|
||||
(size_t)fm->layout->u.chunk.nchunks * sizeof(H5D_chunk_info_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
|
||||
} /* end if */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Initialize "last chunk" information */
|
||||
fm->last_index = (hsize_t)-1;
|
||||
fm->last_chunk_info = NULL;
|
||||
|
||||
/* Point at the dataspaces */
|
||||
fm->file_space = file_space;
|
||||
fm->mem_space = mem_space;
|
||||
|
||||
if (H5D__chunk_io_init_selections(io_info, type_info, fm) < 0)
|
||||
if (H5D__chunk_io_init_selections(io_info, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file and memory chunk selections")
|
||||
|
||||
/* Check if we're performing selection I/O and save the result */
|
||||
if ((use_selection_io = H5D__chunk_may_use_select_io(io_info)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
/* Check if we're performing selection I/O and save the result if it hasn't
|
||||
* been disabled already */
|
||||
if (io_info->use_select_io) {
|
||||
if ((use_selection_io = H5D__chunk_may_use_select_io(io_info, dinfo)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
}
|
||||
|
||||
done:
|
||||
/* Reset the global dataspace info */
|
||||
fm->file_space = NULL;
|
||||
fm->mem_space = NULL;
|
||||
|
||||
if (file_space_normalized == TRUE)
|
||||
if (H5S_hyper_denormalize_offset(file_space, old_offset) < 0)
|
||||
if (H5S_hyper_denormalize_offset(dinfo->file_space, old_offset) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't denormalize selection")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@@ -1163,34 +1142,44 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm)
|
||||
H5D__chunk_io_init_selections(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
|
||||
const H5T_t *mem_type = type_info->mem_type; /* Local pointer to memory datatype */
|
||||
H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */
|
||||
H5T_t *file_type = NULL; /* Temporary copy of file datatype for iteration */
|
||||
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
|
||||
char bogus; /* "bogus" buffer to pass to selection iterator */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
const H5D_t *dataset; /* Local pointer to dataset info */
|
||||
const H5T_t *mem_type; /* Local pointer to memory datatype */
|
||||
H5S_t *tmp_mspace = NULL; /* Temporary memory dataspace */
|
||||
H5T_t *file_type = NULL; /* Temporary copy of file datatype for iteration */
|
||||
hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
|
||||
char bogus; /* "bogus" buffer to pass to selection iterator */
|
||||
H5D_io_info_wrap_t io_info_wrap;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(dinfo);
|
||||
|
||||
/* Set convenience pointers */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
HDassert(fm);
|
||||
dataset = dinfo->dset;
|
||||
mem_type = dinfo->type_info.mem_type;
|
||||
|
||||
/* Special case for only one element in selection */
|
||||
/* (usually appending a record) */
|
||||
if (fm->nelmts == 1
|
||||
if (dinfo->nelmts == 1
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
&& !(io_info->using_mpi_vfd)
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
&& H5S_SEL_ALL != H5S_GET_SELECT_TYPE(fm->file_space)) {
|
||||
&& H5S_SEL_ALL != H5S_GET_SELECT_TYPE(dinfo->file_space)) {
|
||||
/* Initialize skip list for chunk selections */
|
||||
fm->sel_chunks = NULL;
|
||||
fm->use_single = TRUE;
|
||||
|
||||
/* Initialize single chunk dataspace */
|
||||
if (NULL == dataset->shared->cache.chunk.single_space) {
|
||||
/* Make a copy of the dataspace for the dataset */
|
||||
if ((dataset->shared->cache.chunk.single_space = H5S_copy(fm->file_space, TRUE, FALSE)) == NULL)
|
||||
if ((dataset->shared->cache.chunk.single_space = H5S_copy(dinfo->file_space, TRUE, FALSE)) ==
|
||||
NULL)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space")
|
||||
|
||||
/* Resize chunk's dataspace dimensions to size of chunk */
|
||||
@@ -1205,17 +1194,17 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
|
||||
HDassert(fm->single_space);
|
||||
|
||||
/* Allocate the single chunk information */
|
||||
if (NULL == dataset->shared->cache.chunk.single_chunk_info)
|
||||
if (NULL == (dataset->shared->cache.chunk.single_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
|
||||
if (NULL == dataset->shared->cache.chunk.single_piece_info)
|
||||
if (NULL == (dataset->shared->cache.chunk.single_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
|
||||
fm->single_chunk_info = dataset->shared->cache.chunk.single_chunk_info;
|
||||
HDassert(fm->single_chunk_info);
|
||||
fm->single_piece_info = dataset->shared->cache.chunk.single_piece_info;
|
||||
HDassert(fm->single_piece_info);
|
||||
|
||||
/* Reset chunk template information */
|
||||
fm->mchunk_tmpl = NULL;
|
||||
|
||||
/* Set up chunk mapping for single element */
|
||||
if (H5D__create_chunk_map_single(fm, io_info) < 0)
|
||||
if (H5D__create_piece_map_single(dinfo, io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"unable to create chunk selections for single element")
|
||||
} /* end if */
|
||||
@@ -1226,16 +1215,16 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
|
||||
if (NULL == dataset->shared->cache.chunk.sel_chunks)
|
||||
if (NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections")
|
||||
fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks;
|
||||
HDassert(fm->sel_chunks);
|
||||
fm->dset_sel_pieces = dataset->shared->cache.chunk.sel_chunks;
|
||||
HDassert(fm->dset_sel_pieces);
|
||||
|
||||
/* We are not using single element mode */
|
||||
fm->use_single = FALSE;
|
||||
|
||||
/* Get type of selection on disk & in memory */
|
||||
if ((fm->fsel_type = H5S_GET_SELECT_TYPE(fm->file_space)) < H5S_SEL_NONE)
|
||||
if ((fm->fsel_type = H5S_GET_SELECT_TYPE(dinfo->file_space)) < H5S_SEL_NONE)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
|
||||
if ((fm->msel_type = H5S_GET_SELECT_TYPE(fm->mem_space)) < H5S_SEL_NONE)
|
||||
if ((fm->msel_type = H5S_GET_SELECT_TYPE(dinfo->mem_space)) < H5S_SEL_NONE)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
|
||||
|
||||
/* If the selection is NONE or POINTS, set the flag to FALSE */
|
||||
@@ -1248,57 +1237,53 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
|
||||
if (sel_hyper_flag) {
|
||||
/* Build the file selection for each chunk */
|
||||
if (H5S_SEL_ALL == fm->fsel_type) {
|
||||
if (H5D__create_chunk_file_map_all(fm, io_info) < 0)
|
||||
if (H5D__create_piece_file_map_all(dinfo, io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Sanity check */
|
||||
HDassert(fm->fsel_type == H5S_SEL_HYPERSLABS);
|
||||
|
||||
if (H5D__create_chunk_file_map_hyper(fm, io_info) < 0)
|
||||
if (H5D__create_piece_file_map_hyper(dinfo, io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else {
|
||||
H5S_sel_iter_op_t iter_op; /* Operator for iteration */
|
||||
H5D_chunk_file_iter_ud_t udata; /* User data for iteration */
|
||||
H5S_sel_iter_op_t iter_op; /* Operator for iteration */
|
||||
|
||||
/* Create temporary datatypes for selection iteration */
|
||||
if (NULL == (file_type = H5T_copy(dataset->shared->type, H5T_COPY_ALL)))
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, FAIL, "unable to copy file datatype")
|
||||
|
||||
/* Initialize the user data */
|
||||
udata.fm = fm;
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
udata.io_info = io_info;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
iter_op.op_type = H5S_SEL_ITER_OP_LIB;
|
||||
iter_op.u.lib_op = H5D__chunk_file_cb;
|
||||
/* set opdata for H5D__piece_mem_cb */
|
||||
io_info_wrap.io_info = io_info;
|
||||
io_info_wrap.dinfo = dinfo;
|
||||
iter_op.op_type = H5S_SEL_ITER_OP_LIB;
|
||||
iter_op.u.lib_op = H5D__piece_file_cb;
|
||||
|
||||
/* Spaces might not be the same shape, iterate over the file selection directly */
|
||||
if (H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, &udata) < 0)
|
||||
if (H5S_select_iterate(&bogus, file_type, dinfo->file_space, &iter_op, &io_info_wrap) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
|
||||
|
||||
/* Reset "last chunk" info */
|
||||
/* Reset "last piece" info */
|
||||
fm->last_index = (hsize_t)-1;
|
||||
fm->last_chunk_info = NULL;
|
||||
fm->last_piece_info = NULL;
|
||||
} /* end else */
|
||||
|
||||
/* Build the memory selection for each chunk */
|
||||
if (sel_hyper_flag && H5S_SELECT_SHAPE_SAME(fm->file_space, fm->mem_space) == TRUE) {
|
||||
if (sel_hyper_flag && H5S_SELECT_SHAPE_SAME(dinfo->file_space, dinfo->mem_space) == TRUE) {
|
||||
/* Reset chunk template information */
|
||||
fm->mchunk_tmpl = NULL;
|
||||
|
||||
/* If the selections are the same shape, use the file chunk information
|
||||
* to generate the memory chunk information quickly.
|
||||
/* If the selections are the same shape, use the file chunk
|
||||
* information to generate the memory chunk information quickly.
|
||||
*/
|
||||
if (H5D__create_chunk_mem_map_hyper(fm) < 0)
|
||||
if (H5D__create_piece_mem_map_hyper(dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
|
||||
} /* end if */
|
||||
else if (sel_hyper_flag && fm->f_ndims == 1 && fm->m_ndims == 1 &&
|
||||
H5S_SELECT_IS_REGULAR(fm->mem_space) && H5S_SELECT_IS_SINGLE(fm->mem_space)) {
|
||||
if (H5D__create_chunk_mem_map_1d(fm) < 0)
|
||||
H5S_SELECT_IS_REGULAR(dinfo->mem_space) && H5S_SELECT_IS_SINGLE(dinfo->mem_space)) {
|
||||
if (H5D__create_piece_mem_map_1d(dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create file chunk selections")
|
||||
} /* end else-if */
|
||||
else {
|
||||
@@ -1306,7 +1291,7 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
|
||||
size_t elmt_size; /* Memory datatype size */
|
||||
|
||||
/* Make a copy of equivalent memory space */
|
||||
if ((tmp_mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
|
||||
if ((tmp_mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
|
||||
|
||||
/* De-select the mem space copy */
|
||||
@@ -1324,15 +1309,18 @@ H5D__chunk_io_init_selections(const H5D_io_info_t *io_info, const H5D_type_info_
|
||||
/* Create selection iterator for memory selection */
|
||||
if (0 == (elmt_size = H5T_get_size(mem_type)))
|
||||
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
|
||||
if (H5S_select_iter_init(&(fm->mem_iter), fm->mem_space, elmt_size, 0) < 0)
|
||||
if (H5S_select_iter_init(&(fm->mem_iter), dinfo->mem_space, elmt_size, 0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
||||
iter_init = TRUE; /* Selection iteration info has been initialized */
|
||||
|
||||
iter_op.op_type = H5S_SEL_ITER_OP_LIB;
|
||||
iter_op.u.lib_op = H5D__chunk_mem_cb;
|
||||
/* set opdata for H5D__piece_mem_cb */
|
||||
io_info_wrap.io_info = io_info;
|
||||
io_info_wrap.dinfo = dinfo;
|
||||
iter_op.op_type = H5S_SEL_ITER_OP_LIB;
|
||||
iter_op.u.lib_op = H5D__piece_mem_cb;
|
||||
|
||||
/* Spaces aren't the same shape, iterate over the memory selection directly */
|
||||
if (H5S_select_iterate(&bogus, file_type, fm->file_space, &iter_op, fm) < 0)
|
||||
if (H5S_select_iterate(&bogus, file_type, dinfo->file_space, &iter_op, &io_info_wrap) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create memory chunk selections")
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
@@ -1344,7 +1332,7 @@ done:
|
||||
if (H5S_close(tmp_mspace) < 0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL,
|
||||
"can't release memory chunk dataspace template")
|
||||
if (H5D__chunk_io_term(fm) < 0)
|
||||
if (H5D__chunk_io_term(io_info, dinfo) < 0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release chunk mapping")
|
||||
} /* end if */
|
||||
|
||||
@@ -1466,14 +1454,17 @@ H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline)
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
H5D__free_chunk_info
|
||||
H5D__free_piece_info
|
||||
PURPOSE
|
||||
Internal routine to destroy a chunk info node
|
||||
Performs initialization before any sort of I/O on the raw data
|
||||
This was derived from H5D__free_chunk_info for multi-dset work.
|
||||
USAGE
|
||||
void H5D__free_chunk_info(chunk_info)
|
||||
herr_t H5D__free_piece_info(chunk_info, key, opdata)
|
||||
void *chunk_info; IN: Pointer to chunk info to destroy
|
||||
void *key; Unused
|
||||
void *opdata; Unused
|
||||
RETURNS
|
||||
No return value
|
||||
Non-negative on success, negative on failure
|
||||
DESCRIPTION
|
||||
Releases all the memory for a chunk info node. Called by H5SL_free
|
||||
GLOBAL VARIABLES
|
||||
@@ -1481,51 +1472,48 @@ H5D__chunk_mem_realloc(void *chk, size_t size, const H5O_pline_t *pline)
|
||||
EXAMPLES
|
||||
REVISION LOG
|
||||
--------------------------------------------------------------------------*/
|
||||
static herr_t
|
||||
H5D__free_chunk_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *opdata)
|
||||
herr_t
|
||||
H5D__free_piece_info(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *opdata)
|
||||
{
|
||||
H5D_chunk_info_t *chunk_info = (H5D_chunk_info_t *)item;
|
||||
H5D_piece_info_t *piece_info = (H5D_piece_info_t *)item;
|
||||
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
HDassert(chunk_info);
|
||||
HDassert(piece_info);
|
||||
|
||||
/* Close the chunk's file dataspace, if it's not shared */
|
||||
if (!chunk_info->fspace_shared)
|
||||
(void)H5S_close(chunk_info->fspace);
|
||||
/* Close the piece's file dataspace, if it's not shared */
|
||||
if (!piece_info->fspace_shared)
|
||||
(void)H5S_close(piece_info->fspace);
|
||||
else
|
||||
H5S_select_all(chunk_info->fspace, TRUE);
|
||||
H5S_select_all(piece_info->fspace, TRUE);
|
||||
|
||||
/* Close the chunk's memory dataspace, if it's not shared */
|
||||
if (!chunk_info->mspace_shared && chunk_info->mspace)
|
||||
(void)H5S_close(chunk_info->mspace);
|
||||
/* Close the piece's memory dataspace, if it's not shared */
|
||||
if (!piece_info->mspace_shared && piece_info->mspace)
|
||||
(void)H5S_close((H5S_t *)piece_info->mspace);
|
||||
|
||||
/* Free the actual chunk info */
|
||||
chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
|
||||
/* Free the actual piece info */
|
||||
piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
|
||||
|
||||
FUNC_LEAVE_NOAPI(0)
|
||||
} /* H5D__free_chunk_info() */
|
||||
} /* H5D__free_piece_info() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__create_chunk_map_single
|
||||
* Function: H5D__create_piece_map_single
|
||||
*
|
||||
* Purpose: Create chunk selections when appending a single record
|
||||
* Purpose: Create piece selections when appending a single record
|
||||
* This was derived from H5D__create_chunk_map_single for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, November 20, 2007
|
||||
*
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
#ifndef H5_HAVE_PARALLEL
|
||||
H5_ATTR_UNUSED
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
*io_info)
|
||||
H5D__create_piece_map_single(H5D_dset_io_info_t *di, H5D_io_info_t *io_info)
|
||||
{
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information to insert into skip list */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5D_piece_info_t *piece_info; /* Piece information to insert into skip list */
|
||||
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of chunk */
|
||||
hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
|
||||
hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
|
||||
@@ -1534,64 +1522,68 @@ H5D__create_chunk_map_single(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
/* Set convenience pointer */
|
||||
fm = di->layout_io_info.chunk_map;
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(fm);
|
||||
HDassert(fm->f_ndims > 0);
|
||||
|
||||
/* Get coordinate for selection */
|
||||
if (H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
|
||||
if (H5S_SELECT_BOUNDS(di->file_space, sel_start, sel_end) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Initialize the 'single chunk' file & memory chunk information */
|
||||
chunk_info = fm->single_chunk_info;
|
||||
chunk_info->chunk_points = 1;
|
||||
/* Initialize the 'single piece' file & memory piece information */
|
||||
piece_info = fm->single_piece_info;
|
||||
piece_info->piece_points = 1;
|
||||
|
||||
/* Set chunk location & hyperslab size */
|
||||
for (u = 0; u < fm->f_ndims; u++) {
|
||||
/* Validate this chunk dimension */
|
||||
if (fm->layout->u.chunk.dim[u] == 0)
|
||||
if (di->layout->u.chunk.dim[u] == 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
|
||||
HDassert(sel_start[u] == sel_end[u]);
|
||||
chunk_info->scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u];
|
||||
coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u];
|
||||
piece_info->scaled[u] = sel_start[u] / di->layout->u.chunk.dim[u];
|
||||
coords[u] = piece_info->scaled[u] * di->layout->u.chunk.dim[u];
|
||||
} /* end for */
|
||||
chunk_info->scaled[fm->f_ndims] = 0;
|
||||
piece_info->scaled[fm->f_ndims] = 0;
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
chunk_info->index =
|
||||
H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, chunk_info->scaled);
|
||||
piece_info->index =
|
||||
H5VM_array_offset_pre(fm->f_ndims, di->layout->u.chunk.down_chunks, piece_info->scaled);
|
||||
|
||||
/* Copy selection for file's dataspace into chunk dataspace */
|
||||
if (H5S_select_copy(fm->single_space, fm->file_space, FALSE) < 0)
|
||||
if (H5S_select_copy(fm->single_space, di->file_space, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file selection")
|
||||
|
||||
/* Move selection back to have correct offset in chunk */
|
||||
if (H5S_SELECT_ADJUST_U(fm->single_space, coords) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't adjust chunk selection")
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* store chunk selection information */
|
||||
if (io_info->using_mpi_vfd)
|
||||
fm->select_chunk[chunk_info->index] = chunk_info;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Set the file dataspace for the chunk to the shared 'single' dataspace */
|
||||
chunk_info->fspace = fm->single_space;
|
||||
piece_info->fspace = fm->single_space;
|
||||
|
||||
/* Indicate that the chunk's file dataspace is shared */
|
||||
chunk_info->fspace_shared = TRUE;
|
||||
piece_info->fspace_shared = TRUE;
|
||||
|
||||
/* Just point at the memory dataspace & selection */
|
||||
chunk_info->mspace = fm->mem_space;
|
||||
piece_info->mspace = di->mem_space;
|
||||
|
||||
/* Indicate that the chunk's memory dataspace is shared */
|
||||
chunk_info->mspace_shared = TRUE;
|
||||
piece_info->mspace_shared = TRUE;
|
||||
|
||||
/* make connection to related dset info from this piece_info */
|
||||
piece_info->dset_info = di;
|
||||
|
||||
/* Add piece to global piece_count */
|
||||
io_info->piece_count++;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__create_chunk_map_single() */
|
||||
} /* end H5D__create_piece_map_single() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__create_chunk_file_map_all
|
||||
* Function: H5D__create_piece_file_map_all
|
||||
*
|
||||
* Purpose: Create all chunk selections in file, for an "all" selection.
|
||||
*
|
||||
@@ -1603,21 +1595,18 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
#ifndef H5_HAVE_PARALLEL
|
||||
H5_ATTR_UNUSED
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
*io_info)
|
||||
H5D__create_piece_file_map_all(H5D_dset_io_info_t *di, H5D_io_info_t *io_info)
|
||||
{
|
||||
H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
|
||||
hsize_t file_dims[H5S_MAX_RANK]; /* File dataspace dims */
|
||||
hsize_t sel_points; /* Number of elements in file selection */
|
||||
hsize_t zeros[H5S_MAX_RANK]; /* All zero vector (for start parameter to setting hyperslab on partial
|
||||
chunks) */
|
||||
hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
|
||||
hsize_t end[H5S_MAX_RANK]; /* Final coordinates of chunk */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
hsize_t chunk_index; /* "Index" of chunk */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
|
||||
hsize_t file_dims[H5S_MAX_RANK]; /* File dataspace dims */
|
||||
hsize_t sel_points; /* Number of elements in file selection */
|
||||
hsize_t zeros[H5S_MAX_RANK]; /* All zero vector (for start parameter to setting hyperslab on partial
|
||||
chunks) */
|
||||
hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
|
||||
hsize_t end[H5S_MAX_RANK]; /* Final coordinates of chunk */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
hsize_t chunk_index; /* "Index" of chunk */
|
||||
hsize_t curr_partial_clip[H5S_MAX_RANK]; /* Current partial dimension sizes to clip against */
|
||||
hsize_t partial_dim_size[H5S_MAX_RANK]; /* Size of a partial dimension */
|
||||
hbool_t is_partial_dim[H5S_MAX_RANK]; /* Whether a dimension is currently a partial chunk */
|
||||
@@ -1627,14 +1616,18 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
/* Set convenience pointer */
|
||||
fm = di->layout_io_info.chunk_map;
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(fm);
|
||||
HDassert(fm->f_ndims > 0);
|
||||
|
||||
/* Get number of elements selected in file */
|
||||
sel_points = fm->nelmts;
|
||||
sel_points = di->nelmts;
|
||||
|
||||
/* Get dataspace dimensions */
|
||||
if (H5S_get_simple_extent_dims(fm->file_space, file_dims, NULL) < 0)
|
||||
if (H5S_get_simple_extent_dims(di->file_space, file_dims, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Set initial chunk location, partial dimensions, etc */
|
||||
@@ -1642,7 +1635,7 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
HDmemset(zeros, 0, sizeof(zeros));
|
||||
for (u = 0; u < fm->f_ndims; u++) {
|
||||
/* Validate this chunk dimension */
|
||||
if (fm->layout->u.chunk.dim[u] == 0)
|
||||
if (di->layout->u.chunk.dim[u] == 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
|
||||
|
||||
/* Set up start / end coordinates for first chunk */
|
||||
@@ -1672,54 +1665,54 @@ H5D__create_chunk_file_map_all(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
|
||||
/* Iterate through each chunk in the dataset */
|
||||
while (sel_points) {
|
||||
H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
|
||||
H5D_piece_info_t *new_piece_info; /* Piece information to insert into skip list */
|
||||
hsize_t chunk_points; /* Number of elements in chunk selection */
|
||||
|
||||
/* Add temporary chunk to the list of chunks */
|
||||
/* Add temporary chunk to the list of pieces */
|
||||
|
||||
/* Allocate the file & memory chunk information */
|
||||
if (NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info")
|
||||
if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate piece info")
|
||||
|
||||
/* Initialize the chunk information */
|
||||
|
||||
/* Set the chunk index */
|
||||
new_chunk_info->index = chunk_index;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Store chunk selection information, for multi-chunk I/O */
|
||||
if (io_info->using_mpi_vfd)
|
||||
fm->select_chunk[chunk_index] = new_chunk_info;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
new_piece_info->index = chunk_index;
|
||||
|
||||
/* Set the file chunk dataspace */
|
||||
if (NULL == (new_chunk_info->fspace = H5S_copy(tmp_fchunk, TRUE, FALSE)))
|
||||
if (NULL == (new_piece_info->fspace = H5S_copy(tmp_fchunk, TRUE, FALSE)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy chunk dataspace")
|
||||
new_chunk_info->fspace_shared = FALSE;
|
||||
new_piece_info->fspace_shared = FALSE;
|
||||
|
||||
/* If there are partial dimensions for this chunk, set the hyperslab for them */
|
||||
if (num_partial_dims > 0)
|
||||
if (H5S_select_hyperslab(new_chunk_info->fspace, H5S_SELECT_SET, zeros, NULL, curr_partial_clip,
|
||||
if (H5S_select_hyperslab(new_piece_info->fspace, H5S_SELECT_SET, zeros, NULL, curr_partial_clip,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk selection")
|
||||
|
||||
/* Set the memory chunk dataspace */
|
||||
new_chunk_info->mspace = NULL;
|
||||
new_chunk_info->mspace_shared = FALSE;
|
||||
new_piece_info->mspace = NULL;
|
||||
new_piece_info->mspace_shared = FALSE;
|
||||
|
||||
/* Copy the chunk's scaled coordinates */
|
||||
H5MM_memcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
new_chunk_info->scaled[fm->f_ndims] = 0;
|
||||
H5MM_memcpy(new_piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
new_piece_info->scaled[fm->f_ndims] = 0;
|
||||
|
||||
/* make connection to related dset info from this piece_info */
|
||||
new_piece_info->dset_info = di;
|
||||
|
||||
/* Insert the new chunk into the skip list */
|
||||
if (H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) {
|
||||
H5D__free_chunk_info(new_chunk_info, NULL, NULL);
|
||||
if (H5SL_insert(fm->dset_sel_pieces, new_piece_info, &new_piece_info->index) < 0) {
|
||||
H5D__free_piece_info(new_piece_info, NULL, NULL);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
|
||||
} /* end if */
|
||||
|
||||
/* Add piece to global piece_count*/
|
||||
io_info->piece_count++;
|
||||
|
||||
/* Get number of elements selected in chunk */
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace);
|
||||
H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, chunk_points, hsize_t);
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(new_piece_info->fspace);
|
||||
new_piece_info->piece_points = chunk_points;
|
||||
|
||||
/* Decrement # of points left in file selection */
|
||||
sel_points -= chunk_points;
|
||||
@@ -1796,74 +1789,75 @@ done:
|
||||
} /* end H5D__create_chunk_file_map_all() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__create_chunk_file_map_hyper
|
||||
* Function: H5D__create_piece_file_map_hyper
|
||||
*
|
||||
* Purpose: Create all chunk selections in file, for a hyperslab selection.
|
||||
* Purpose: Create all chunk selections in file.
|
||||
* This was derived from H5D__create_chunk_file_map_hyper for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, May 29, 2003
|
||||
*
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
#ifndef H5_HAVE_PARALLEL
|
||||
H5_ATTR_UNUSED
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
*io_info)
|
||||
H5D__create_piece_file_map_hyper(H5D_dset_io_info_t *dinfo, H5D_io_info_t *io_info)
|
||||
{
|
||||
H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
|
||||
hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
|
||||
hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
|
||||
hsize_t sel_points; /* Number of elements in file selection */
|
||||
hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
|
||||
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
|
||||
hsize_t end[H5O_LAYOUT_NDIMS]; /* Final coordinates of chunk */
|
||||
hsize_t chunk_index; /* Index of chunk */
|
||||
hsize_t start_scaled[H5S_MAX_RANK]; /* Starting scaled coordinates of selection */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
int curr_dim; /* Current dimension to increment */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5S_t *tmp_fchunk = NULL; /* Temporary file dataspace */
|
||||
hsize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
|
||||
hsize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
|
||||
hsize_t sel_points; /* Number of elements in file selection */
|
||||
hsize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
|
||||
hsize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
|
||||
hsize_t end[H5O_LAYOUT_NDIMS]; /* Final coordinates of chunk */
|
||||
hsize_t chunk_index; /* Index of chunk */
|
||||
hsize_t start_scaled[H5S_MAX_RANK]; /* Starting scaled coordinates of selection */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
int curr_dim; /* Current dimension to increment */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
/* Set convenience pointer */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(fm);
|
||||
HDassert(fm->f_ndims > 0);
|
||||
|
||||
/* Get number of elements selected in file */
|
||||
sel_points = fm->nelmts;
|
||||
sel_points = dinfo->nelmts;
|
||||
|
||||
/* Get bounding box for selection (to reduce the number of chunks to iterate over) */
|
||||
if (H5S_SELECT_BOUNDS(fm->file_space, sel_start, sel_end) < 0)
|
||||
if (H5S_SELECT_BOUNDS(dinfo->file_space, sel_start, sel_end) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Set initial chunk location & hyperslab size */
|
||||
for (u = 0; u < fm->f_ndims; u++) {
|
||||
/* Validate this chunk dimension */
|
||||
if (fm->layout->u.chunk.dim[u] == 0)
|
||||
if (dinfo->layout->u.chunk.dim[u] == 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "chunk size must be > 0, dim = %u ", u)
|
||||
scaled[u] = start_scaled[u] = sel_start[u] / fm->layout->u.chunk.dim[u];
|
||||
coords[u] = start_coords[u] = scaled[u] * fm->layout->u.chunk.dim[u];
|
||||
scaled[u] = start_scaled[u] = sel_start[u] / dinfo->layout->u.chunk.dim[u];
|
||||
coords[u] = start_coords[u] = scaled[u] * dinfo->layout->u.chunk.dim[u];
|
||||
end[u] = (coords[u] + fm->chunk_dim[u]) - 1;
|
||||
} /* end for */
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
chunk_index = H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, scaled);
|
||||
chunk_index = H5VM_array_offset_pre(fm->f_ndims, dinfo->layout->u.chunk.down_chunks, scaled);
|
||||
|
||||
/* Iterate through each chunk in the dataset */
|
||||
while (sel_points) {
|
||||
/* Check for intersection of current chunk and file selection */
|
||||
if (TRUE == H5S_SELECT_INTERSECT_BLOCK(fm->file_space, coords, end)) {
|
||||
H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */
|
||||
if (TRUE == H5S_SELECT_INTERSECT_BLOCK(dinfo->file_space, coords, end)) {
|
||||
H5D_piece_info_t *new_piece_info; /* chunk information to insert into skip list */
|
||||
hsize_t chunk_points; /* Number of elements in chunk selection */
|
||||
|
||||
/* Create dataspace for chunk, 'AND'ing the overall selection with
|
||||
* the current chunk.
|
||||
*/
|
||||
if (H5S_combine_hyperslab(fm->file_space, H5S_SELECT_AND, coords, NULL, fm->chunk_dim, NULL,
|
||||
if (H5S_combine_hyperslab(dinfo->file_space, H5S_SELECT_AND, coords, NULL, fm->chunk_dim, NULL,
|
||||
&tmp_fchunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL,
|
||||
"unable to combine file space selection with chunk block")
|
||||
@@ -1879,42 +1873,42 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
/* Add temporary chunk to the list of chunks */
|
||||
|
||||
/* Allocate the file & memory chunk information */
|
||||
if (NULL == (new_chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
|
||||
if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk info")
|
||||
|
||||
/* Initialize the chunk information */
|
||||
|
||||
/* Set the chunk index */
|
||||
new_chunk_info->index = chunk_index;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Store chunk selection information, for multi-chunk I/O */
|
||||
if (io_info->using_mpi_vfd)
|
||||
fm->select_chunk[chunk_index] = new_chunk_info;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
new_piece_info->index = chunk_index;
|
||||
|
||||
/* Set the file chunk dataspace */
|
||||
new_chunk_info->fspace = tmp_fchunk;
|
||||
new_chunk_info->fspace_shared = FALSE;
|
||||
new_piece_info->fspace = tmp_fchunk;
|
||||
new_piece_info->fspace_shared = FALSE;
|
||||
tmp_fchunk = NULL;
|
||||
|
||||
/* Set the memory chunk dataspace */
|
||||
new_chunk_info->mspace = NULL;
|
||||
new_chunk_info->mspace_shared = FALSE;
|
||||
new_piece_info->mspace = NULL;
|
||||
new_piece_info->mspace_shared = FALSE;
|
||||
|
||||
/* Copy the chunk's scaled coordinates */
|
||||
H5MM_memcpy(new_chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
new_chunk_info->scaled[fm->f_ndims] = 0;
|
||||
H5MM_memcpy(new_piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
new_piece_info->scaled[fm->f_ndims] = 0;
|
||||
|
||||
/* Insert the new chunk into the skip list */
|
||||
if (H5SL_insert(fm->sel_chunks, new_chunk_info, &new_chunk_info->index) < 0) {
|
||||
H5D__free_chunk_info(new_chunk_info, NULL, NULL);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
|
||||
/* make connection to related dset info from this piece_info */
|
||||
new_piece_info->dset_info = dinfo;
|
||||
|
||||
/* Add piece to global piece_count */
|
||||
io_info->piece_count++;
|
||||
|
||||
/* Insert the new piece into the skip list */
|
||||
if (H5SL_insert(fm->dset_sel_pieces, new_piece_info, &new_piece_info->index) < 0) {
|
||||
H5D__free_piece_info(new_piece_info, NULL, NULL);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert piece into skip list")
|
||||
} /* end if */
|
||||
|
||||
/* Get number of elements selected in chunk */
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(new_chunk_info->fspace);
|
||||
H5_CHECKED_ASSIGN(new_chunk_info->chunk_points, uint32_t, chunk_points, hsize_t);
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(new_piece_info->fspace);
|
||||
new_piece_info->piece_points = chunk_points;
|
||||
|
||||
/* Decrement # of points left in file selection */
|
||||
sel_points -= chunk_points;
|
||||
@@ -1957,7 +1951,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t
|
||||
} while (curr_dim >= 0 && (coords[curr_dim] > sel_end[curr_dim]));
|
||||
|
||||
/* Re-calculate the index of this chunk */
|
||||
chunk_index = H5VM_array_offset_pre(fm->f_ndims, fm->layout->u.chunk.down_chunks, scaled);
|
||||
chunk_index = H5VM_array_offset_pre(fm->f_ndims, dinfo->layout->u.chunk.down_chunks, scaled);
|
||||
} /* end if */
|
||||
} /* end while */
|
||||
|
||||
@@ -1968,28 +1962,29 @@ done:
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't release temporary dataspace")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__create_chunk_file_map_hyper() */
|
||||
} /* end H5D__create_piece_file_map_hyper() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__create_chunk_mem_map_hyper
|
||||
* Function: H5D__create_piece_mem_map_hyper
|
||||
*
|
||||
* Purpose: Create all chunk selections in memory by copying the file
|
||||
* Purpose: Create all chunk selections in memory by copying the file
|
||||
* chunk selections and adjusting their offsets to be correct
|
||||
* for the memory.
|
||||
* or the memory.
|
||||
* This was derived from H5D__create_chunk_mem_map_hyper for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, May 29, 2003
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
* Assumptions: That the file and memory selections are the same shape.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
|
||||
H5D__create_piece_mem_map_hyper(const H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5D_piece_info_t *piece_info; /* Pointer to piece information */
|
||||
H5SL_node_t *curr_node; /* Current node in skip list */
|
||||
hsize_t file_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */
|
||||
hsize_t file_sel_end[H5S_MAX_RANK]; /* Offset of high bound of file selection */
|
||||
@@ -2002,30 +1997,33 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(fm->f_ndims > 0);
|
||||
HDassert(dinfo->layout_io_info.chunk_map->f_ndims > 0);
|
||||
|
||||
/* Set convenience pointer */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
|
||||
/* Check for all I/O going to a single chunk */
|
||||
if (H5SL_count(fm->sel_chunks) == 1) {
|
||||
if (H5SL_count(fm->dset_sel_pieces) == 1) {
|
||||
/* Get the node */
|
||||
curr_node = H5SL_first(fm->sel_chunks);
|
||||
curr_node = H5SL_first(fm->dset_sel_pieces);
|
||||
|
||||
/* Get pointer to chunk's information */
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
|
||||
HDassert(chunk_info);
|
||||
/* Get pointer to piece's information */
|
||||
piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
|
||||
HDassert(piece_info);
|
||||
|
||||
/* Just point at the memory dataspace & selection */
|
||||
chunk_info->mspace = fm->mem_space;
|
||||
piece_info->mspace = dinfo->mem_space;
|
||||
|
||||
/* Indicate that the chunk's memory space is shared */
|
||||
chunk_info->mspace_shared = TRUE;
|
||||
/* Indicate that the piece's memory space is shared */
|
||||
piece_info->mspace_shared = TRUE;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Get bounding box for file selection */
|
||||
if (H5S_SELECT_BOUNDS(fm->file_space, file_sel_start, file_sel_end) < 0)
|
||||
if (H5S_SELECT_BOUNDS(dinfo->file_space, file_sel_start, file_sel_end) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Get bounding box for memory selection */
|
||||
if (H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0)
|
||||
if (H5S_SELECT_BOUNDS(dinfo->mem_space, mem_sel_start, mem_sel_end) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Calculate the adjustment for memory selection from file selection */
|
||||
@@ -2037,28 +2035,29 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
|
||||
} /* end for */
|
||||
|
||||
/* Iterate over each chunk in the chunk list */
|
||||
curr_node = H5SL_first(fm->sel_chunks);
|
||||
HDassert(fm->dset_sel_pieces);
|
||||
curr_node = H5SL_first(fm->dset_sel_pieces);
|
||||
while (curr_node) {
|
||||
hsize_t coords[H5S_MAX_RANK]; /* Current coordinates of chunk */
|
||||
hssize_t chunk_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */
|
||||
hssize_t piece_adjust[H5S_MAX_RANK]; /* Adjustment to make to a particular chunk */
|
||||
H5S_sel_type chunk_sel_type; /* Chunk's selection type */
|
||||
|
||||
/* Get pointer to chunk's information */
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
|
||||
HDassert(chunk_info);
|
||||
/* Get pointer to piece's information */
|
||||
piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
|
||||
HDassert(piece_info);
|
||||
|
||||
/* Compute the chunk coordinates from the scaled coordinates */
|
||||
for (u = 0; u < fm->f_ndims; u++)
|
||||
coords[u] = chunk_info->scaled[u] * fm->layout->u.chunk.dim[u];
|
||||
coords[u] = piece_info->scaled[u] * dinfo->layout->u.chunk.dim[u];
|
||||
|
||||
/* Copy the information */
|
||||
|
||||
/* Copy the memory dataspace */
|
||||
if ((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
|
||||
if ((piece_info->mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
|
||||
|
||||
/* Get the chunk's selection type */
|
||||
if ((chunk_sel_type = H5S_GET_SELECT_TYPE(chunk_info->fspace)) < H5S_SEL_NONE)
|
||||
if ((chunk_sel_type = H5S_GET_SELECT_TYPE(piece_info->fspace)) < H5S_SEL_NONE)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to get type of selection")
|
||||
|
||||
/* Set memory selection for "all" chunk selections */
|
||||
@@ -2068,7 +2067,7 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
|
||||
coords[u] = (hsize_t)((hssize_t)coords[u] - adjust[u]);
|
||||
|
||||
/* Set to same shape as chunk */
|
||||
if (H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, coords, NULL, fm->chunk_dim,
|
||||
if (H5S_select_hyperslab(piece_info->mspace, H5S_SELECT_SET, coords, NULL, fm->chunk_dim,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection")
|
||||
} /* end if */
|
||||
@@ -2077,32 +2076,32 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm)
|
||||
HDassert(H5S_SEL_HYPERSLABS == chunk_sel_type);
|
||||
|
||||
/* Copy the file chunk's selection */
|
||||
if (H5S_SELECT_COPY(chunk_info->mspace, chunk_info->fspace, FALSE) < 0)
|
||||
if (H5S_SELECT_COPY(piece_info->mspace, piece_info->fspace, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection")
|
||||
|
||||
/* Compute the adjustment for this chunk */
|
||||
for (u = 0; u < fm->f_ndims; u++) {
|
||||
/* Compensate for the chunk offset */
|
||||
H5_CHECK_OVERFLOW(coords[u], hsize_t, hssize_t);
|
||||
chunk_adjust[u] = adjust[u] - (hssize_t)coords[u];
|
||||
piece_adjust[u] = adjust[u] - (hssize_t)coords[u];
|
||||
} /* end for */
|
||||
|
||||
/* Adjust the selection */
|
||||
if (H5S_SELECT_ADJUST_S(chunk_info->mspace, chunk_adjust) < 0)
|
||||
if (H5S_SELECT_ADJUST_S(piece_info->mspace, piece_adjust) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to adjust selection")
|
||||
} /* end else */
|
||||
|
||||
/* Get the next chunk node in the skip list */
|
||||
/* Get the next piece node in the skip list */
|
||||
curr_node = H5SL_next(curr_node);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__create_chunk_mem_map_hyper() */
|
||||
} /* end H5D__create_piece_mem_map_hyper() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__create_mem_map_1d
|
||||
* Function: H5D__create_piece_mem_map_1d
|
||||
*
|
||||
* Purpose: Create all chunk selections for 1-dimensional regular memory space
|
||||
* that has only one single block in the selection
|
||||
@@ -2115,31 +2114,36 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
|
||||
H5D__create_piece_mem_map_1d(const H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
H5D_chunk_info_t *chunk_info; /* Pointer to chunk information */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5D_piece_info_t *piece_info; /* Pointer to chunk information */
|
||||
H5SL_node_t *curr_node; /* Current node in skip list */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(fm->f_ndims > 0);
|
||||
HDassert(dinfo->layout_io_info.chunk_map->f_ndims > 0);
|
||||
|
||||
/* Set convenience pointer */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
HDassert(fm);
|
||||
|
||||
/* Check for all I/O going to a single chunk */
|
||||
if (H5SL_count(fm->sel_chunks) == 1) {
|
||||
if (H5SL_count(fm->dset_sel_pieces) == 1) {
|
||||
/* Get the node */
|
||||
curr_node = H5SL_first(fm->sel_chunks);
|
||||
curr_node = H5SL_first(fm->dset_sel_pieces);
|
||||
|
||||
/* Get pointer to chunk's information */
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
|
||||
HDassert(chunk_info);
|
||||
piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
|
||||
HDassert(piece_info);
|
||||
|
||||
/* Just point at the memory dataspace & selection */
|
||||
chunk_info->mspace = fm->mem_space;
|
||||
piece_info->mspace = dinfo->mem_space;
|
||||
|
||||
/* Indicate that the chunk's memory space is shared */
|
||||
chunk_info->mspace_shared = TRUE;
|
||||
piece_info->mspace_shared = TRUE;
|
||||
} /* end if */
|
||||
else {
|
||||
hsize_t mem_sel_start[H5S_MAX_RANK]; /* Offset of low bound of file selection */
|
||||
@@ -2147,26 +2151,26 @@ H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
|
||||
|
||||
HDassert(fm->m_ndims == 1);
|
||||
|
||||
if (H5S_SELECT_BOUNDS(fm->mem_space, mem_sel_start, mem_sel_end) < 0)
|
||||
if (H5S_SELECT_BOUNDS(dinfo->mem_space, mem_sel_start, mem_sel_end) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
|
||||
|
||||
/* Iterate over each chunk in the chunk list */
|
||||
curr_node = H5SL_first(fm->sel_chunks);
|
||||
curr_node = H5SL_first(fm->dset_sel_pieces);
|
||||
while (curr_node) {
|
||||
hsize_t chunk_points; /* Number of elements in chunk selection */
|
||||
hsize_t tmp_count = 1;
|
||||
|
||||
/* Get pointer to chunk's information */
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(curr_node);
|
||||
HDassert(chunk_info);
|
||||
piece_info = (H5D_piece_info_t *)H5SL_item(curr_node);
|
||||
HDassert(piece_info);
|
||||
|
||||
/* Copy the memory dataspace */
|
||||
if ((chunk_info->mspace = H5S_copy(fm->mem_space, TRUE, FALSE)) == NULL)
|
||||
if ((piece_info->mspace = H5S_copy(dinfo->mem_space, TRUE, FALSE)) == NULL)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
|
||||
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
|
||||
chunk_points = H5S_GET_SELECT_NPOINTS(piece_info->fspace);
|
||||
|
||||
if (H5S_select_hyperslab(chunk_info->mspace, H5S_SELECT_SET, mem_sel_start, NULL, &tmp_count,
|
||||
if (H5S_select_hyperslab(piece_info->mspace, H5S_SELECT_SET, mem_sel_start, NULL, &tmp_count,
|
||||
&chunk_points) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "can't create chunk memory selection")
|
||||
|
||||
@@ -2179,177 +2183,187 @@ H5D__create_chunk_mem_map_1d(const H5D_chunk_map_t *fm)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__create_chunk_mem_map_1d() */
|
||||
} /* end H5D__create_piece_mem_map_1d() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_file_cb
|
||||
* Function: H5D__piece_file_cb
|
||||
*
|
||||
* Purpose: Callback routine for file selection iterator. Used when
|
||||
* Purpose: Callback routine for file selection iterator. Used when
|
||||
* creating selections in file for each point selected.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Wednesday, July 23, 2003
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
|
||||
const hsize_t *coords, void *_udata)
|
||||
H5D__piece_file_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
|
||||
const hsize_t *coords, void *_opdata)
|
||||
{
|
||||
H5D_chunk_file_iter_ud_t *udata = (H5D_chunk_file_iter_ud_t *)_udata; /* User data for operation */
|
||||
H5D_chunk_map_t *fm = udata->fm; /* File<->memory chunk mapping info */
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
|
||||
hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
|
||||
hsize_t chunk_index; /* Chunk index */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_io_info_wrap_t *opdata = (H5D_io_info_wrap_t *)_opdata;
|
||||
H5D_io_info_t *io_info = (H5D_io_info_t *)opdata->io_info; /* io info for multi dset */
|
||||
H5D_dset_io_info_t *dinfo = (H5D_dset_io_info_t *)opdata->dinfo; /* File<->memory piece mapping info */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
H5D_piece_info_t *piece_info; /* Chunk information for current piece */
|
||||
hsize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
|
||||
hsize_t chunk_index; /* Chunk index */
|
||||
hsize_t scaled[H5S_MAX_RANK]; /* Scaled coordinates for this chunk */
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Set convenience pointer */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
chunk_index = H5VM_chunk_index_scaled(ndims, coords, fm->layout->u.chunk.dim,
|
||||
fm->layout->u.chunk.down_chunks, scaled);
|
||||
chunk_index = H5VM_chunk_index_scaled(ndims, coords, dinfo->layout->u.chunk.dim,
|
||||
dinfo->layout->u.chunk.down_chunks, scaled);
|
||||
|
||||
/* Find correct chunk in file & memory skip list */
|
||||
if (chunk_index == fm->last_index) {
|
||||
/* If the chunk index is the same as the last chunk index we used,
|
||||
* get the cached info to operate on.
|
||||
*/
|
||||
chunk_info = fm->last_chunk_info;
|
||||
piece_info = fm->last_piece_info;
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk index is not the same as the last chunk index we used,
|
||||
* find the chunk in the skip list.
|
||||
*/
|
||||
/* Get the chunk node from the skip list */
|
||||
if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index))) {
|
||||
* find the chunk in the skip list. If we do not find it, create
|
||||
* a new node. */
|
||||
if (NULL == (piece_info = (H5D_piece_info_t *)H5SL_search(fm->dset_sel_pieces, &chunk_index))) {
|
||||
H5S_t *fspace; /* Memory chunk's dataspace */
|
||||
|
||||
/* Allocate the file & memory chunk information */
|
||||
if (NULL == (chunk_info = H5FL_MALLOC(H5D_chunk_info_t)))
|
||||
if (NULL == (piece_info = H5FL_MALLOC(H5D_piece_info_t)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
|
||||
|
||||
/* Initialize the chunk information */
|
||||
|
||||
/* Set the chunk index */
|
||||
chunk_info->index = chunk_index;
|
||||
piece_info->index = chunk_index;
|
||||
|
||||
/* Create a dataspace for the chunk */
|
||||
if ((fspace = H5S_create_simple(fm->f_ndims, fm->chunk_dim, NULL)) == NULL) {
|
||||
chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
|
||||
piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace for chunk")
|
||||
} /* end if */
|
||||
|
||||
/* De-select the chunk space */
|
||||
if (H5S_select_none(fspace) < 0) {
|
||||
(void)H5S_close(fspace);
|
||||
chunk_info = H5FL_FREE(H5D_chunk_info_t, chunk_info);
|
||||
piece_info = H5FL_FREE(H5D_piece_info_t, piece_info);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select dataspace")
|
||||
} /* end if */
|
||||
|
||||
/* Set the file chunk dataspace */
|
||||
chunk_info->fspace = fspace;
|
||||
chunk_info->fspace_shared = FALSE;
|
||||
piece_info->fspace = fspace;
|
||||
piece_info->fspace_shared = FALSE;
|
||||
|
||||
/* Set the memory chunk dataspace */
|
||||
chunk_info->mspace = NULL;
|
||||
chunk_info->mspace_shared = FALSE;
|
||||
piece_info->mspace = NULL;
|
||||
piece_info->mspace_shared = FALSE;
|
||||
|
||||
/* Set the number of selected elements in chunk to zero */
|
||||
chunk_info->chunk_points = 0;
|
||||
piece_info->piece_points = 0;
|
||||
|
||||
/* Set the chunk's scaled coordinates */
|
||||
H5MM_memcpy(chunk_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
chunk_info->scaled[fm->f_ndims] = 0;
|
||||
H5MM_memcpy(piece_info->scaled, scaled, sizeof(hsize_t) * fm->f_ndims);
|
||||
piece_info->scaled[fm->f_ndims] = 0;
|
||||
|
||||
/* Make connection to related dset info from this piece_info */
|
||||
piece_info->dset_info = dinfo;
|
||||
|
||||
/* Insert the new chunk into the skip list */
|
||||
if (H5SL_insert(fm->sel_chunks, chunk_info, &chunk_info->index) < 0) {
|
||||
H5D__free_chunk_info(chunk_info, NULL, NULL);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into skip list")
|
||||
if (H5SL_insert(fm->dset_sel_pieces, piece_info, &piece_info->index) < 0) {
|
||||
H5D__free_piece_info(piece_info, NULL, NULL);
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert chunk into dataset skip list")
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Store chunk selection information, for collective multi-chunk I/O */
|
||||
if (udata->io_info->using_mpi_vfd)
|
||||
fm->select_chunk[chunk_index] = chunk_info;
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
/* Add piece to global piece_count */
|
||||
io_info->piece_count++;
|
||||
} /* end if */
|
||||
|
||||
/* Update the "last chunk seen" information */
|
||||
fm->last_index = chunk_index;
|
||||
fm->last_chunk_info = chunk_info;
|
||||
fm->last_piece_info = piece_info;
|
||||
} /* end else */
|
||||
|
||||
/* Get the offset of the element within the chunk */
|
||||
for (u = 0; u < fm->f_ndims; u++)
|
||||
coords_in_chunk[u] = coords[u] - (scaled[u] * fm->layout->u.chunk.dim[u]);
|
||||
coords_in_chunk[u] = coords[u] - (scaled[u] * dinfo->layout->u.chunk.dim[u]);
|
||||
|
||||
/* Add point to file selection for chunk */
|
||||
if (H5S_select_elements(chunk_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
|
||||
if (H5S_select_elements(piece_info->fspace, H5S_SELECT_APPEND, (size_t)1, coords_in_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element")
|
||||
|
||||
/* Increment the number of elemented selected in chunk */
|
||||
chunk_info->chunk_points++;
|
||||
piece_info->piece_points++;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_file_cb() */
|
||||
} /* end H5D__piece_file_cb */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_mem_cb
|
||||
* Function: H5D__piece_mem_cb
|
||||
*
|
||||
* Purpose: Callback routine for file selection iterator. Used when
|
||||
* creating selections in memory for each chunk.
|
||||
* Purpose: Callback routine for file selection iterator. Used when
|
||||
* creating selections in memory for each piece.
|
||||
* This was derived from H5D__chunk_mem_cb for multi-dset
|
||||
* work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Raymond Lu
|
||||
* Thursday, April 10, 2003
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
|
||||
const hsize_t *coords, void *_fm)
|
||||
H5D__piece_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, unsigned ndims,
|
||||
const hsize_t *coords, void *_opdata)
|
||||
{
|
||||
H5D_chunk_map_t *fm = (H5D_chunk_map_t *)_fm; /* File<->memory chunk mapping info */
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information for current chunk */
|
||||
hsize_t coords_in_mem[H5S_MAX_RANK]; /* Coordinates of element in memory */
|
||||
hsize_t chunk_index; /* Chunk index */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_io_info_wrap_t *opdata = (H5D_io_info_wrap_t *)_opdata;
|
||||
H5D_dset_io_info_t *dinfo = (H5D_dset_io_info_t *)opdata->dinfo; /* File<->memory chunk mapping info */
|
||||
H5D_piece_info_t *piece_info; /* Chunk information for current chunk */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
hsize_t coords_in_mem[H5S_MAX_RANK]; /* Coordinates of element in memory */
|
||||
hsize_t chunk_index; /* Chunk index */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Set convenience pointer */
|
||||
fm = dinfo->layout_io_info.chunk_map;
|
||||
|
||||
/* Calculate the index of this chunk */
|
||||
chunk_index = H5VM_chunk_index(ndims, coords, fm->layout->u.chunk.dim, fm->layout->u.chunk.down_chunks);
|
||||
chunk_index =
|
||||
H5VM_chunk_index(ndims, coords, dinfo->layout->u.chunk.dim, dinfo->layout->u.chunk.down_chunks);
|
||||
|
||||
/* Find correct chunk in file & memory skip list */
|
||||
if (chunk_index == fm->last_index) {
|
||||
/* If the chunk index is the same as the last chunk index we used,
|
||||
* get the cached spaces to operate on.
|
||||
*/
|
||||
chunk_info = fm->last_chunk_info;
|
||||
piece_info = fm->last_piece_info;
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk index is not the same as the last chunk index we used,
|
||||
* find the chunk in the skip list.
|
||||
* find the chunk in the dataset skip list.
|
||||
*/
|
||||
/* Get the chunk node from the skip list */
|
||||
if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_search(fm->sel_chunks, &chunk_index)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, H5_ITER_ERROR, "can't locate chunk in skip list")
|
||||
if (NULL == (piece_info = (H5D_piece_info_t *)H5SL_search(fm->dset_sel_pieces, &chunk_index)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, H5_ITER_ERROR, "can't locate piece in dataset skip list")
|
||||
|
||||
/* Check if the chunk already has a memory space */
|
||||
if (NULL == chunk_info->mspace)
|
||||
if (NULL == piece_info->mspace)
|
||||
/* Copy the template memory chunk dataspace */
|
||||
if (NULL == (chunk_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)))
|
||||
if (NULL == (piece_info->mspace = H5S_copy(fm->mchunk_tmpl, FALSE, FALSE)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy file space")
|
||||
|
||||
/* Update the "last chunk seen" information */
|
||||
fm->last_index = chunk_index;
|
||||
fm->last_chunk_info = chunk_info;
|
||||
fm->last_piece_info = piece_info;
|
||||
} /* end else */
|
||||
|
||||
/* Get coordinates of selection iterator for memory */
|
||||
@@ -2358,11 +2372,11 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u
|
||||
|
||||
/* Add point to memory selection for chunk */
|
||||
if (fm->msel_type == H5S_SEL_POINTS) {
|
||||
if (H5S_select_elements(chunk_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
|
||||
if (H5S_select_elements(piece_info->mspace, H5S_SELECT_APPEND, (size_t)1, coords_in_mem) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select element")
|
||||
} /* end if */
|
||||
else {
|
||||
if (H5S_hyper_add_span_element(chunk_info->mspace, fm->m_ndims, coords_in_mem) < 0)
|
||||
if (H5S_hyper_add_span_element(piece_info->mspace, fm->m_ndims, coords_in_mem) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, H5_ITER_ERROR, "unable to select element")
|
||||
} /* end else */
|
||||
|
||||
@@ -2372,7 +2386,62 @@ H5D__chunk_mem_cb(void H5_ATTR_UNUSED *elem, const H5T_t H5_ATTR_UNUSED *type, u
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_mem_cb() */
|
||||
} /* end H5D__piece_mem_cb() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_mdio_init
|
||||
*
|
||||
* Purpose: Performs second phase of initialization for multi-dataset
|
||||
* I/O. Currently looks up chunk addresses and adds chunks to
|
||||
* sel_pieces.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
H5SL_node_t *piece_node; /* Current node in chunk skip list */
|
||||
H5D_piece_info_t *piece_info; /* Piece information for current piece */
|
||||
H5D_chunk_ud_t udata; /* Chunk data from index */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Get first node in skip list. Note we don't check for failure since NULL
|
||||
* simply indicates an empty skip list. */
|
||||
piece_node = H5D_CHUNK_GET_FIRST_NODE(dinfo);
|
||||
|
||||
/* Iterate over skip list */
|
||||
while (piece_node) {
|
||||
/* Get piece info */
|
||||
if (NULL == (piece_info = (H5D_piece_info_t *)H5D_CHUNK_GET_NODE_INFO(dinfo, piece_node)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get piece info from list")
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(dinfo->dset, piece_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Save chunk file address */
|
||||
piece_info->faddr = udata.chunk_block.offset;
|
||||
|
||||
/* Add piece to MDIO operation if it has a file address */
|
||||
if (H5F_addr_defined(piece_info->faddr)) {
|
||||
HDassert(io_info->sel_pieces);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
/* Add to sel_pieces and update pieces_added */
|
||||
io_info->sel_pieces[io_info->pieces_added++] = piece_info;
|
||||
}
|
||||
|
||||
/* Advance to next skip list node */
|
||||
piece_node = H5D_CHUNK_GET_NEXT_NODE(dinfo, piece_node);
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_mdio_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_cacheable
|
||||
@@ -2388,16 +2457,19 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
htri_t
|
||||
H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op)
|
||||
H5D__chunk_cacheable(const H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, haddr_t caddr,
|
||||
hbool_t write_op)
|
||||
{
|
||||
const H5D_t *dataset = io_info->dset; /* Local pointer to dataset info */
|
||||
hbool_t has_filters = FALSE; /* Whether there are filters on the chunk or not */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
const H5D_t *dataset = NULL; /* Local pointer to dataset info */
|
||||
hbool_t has_filters = FALSE; /* Whether there are filters on the chunk or not */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
dataset = dset_info->dset;
|
||||
HDassert(dataset);
|
||||
|
||||
/* Must bring the whole chunk in if there are any filters on the chunk.
|
||||
@@ -2405,9 +2477,9 @@ H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_
|
||||
* chunk because it is a partial edge chunk. */
|
||||
if (dataset->shared->dcpl_cache.pline.nused > 0) {
|
||||
if (dataset->shared->layout.u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
|
||||
has_filters = !H5D__chunk_is_partial_edge_chunk(
|
||||
io_info->dset->shared->ndims, io_info->dset->shared->layout.u.chunk.dim,
|
||||
io_info->store->chunk.scaled, io_info->dset->shared->curr_dims);
|
||||
has_filters =
|
||||
!H5D__chunk_is_partial_edge_chunk(dataset->shared->ndims, dataset->shared->layout.u.chunk.dim,
|
||||
dset_info->store->chunk.scaled, dataset->shared->curr_dims);
|
||||
} /* end if */
|
||||
else
|
||||
has_filters = TRUE;
|
||||
@@ -2478,7 +2550,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static htri_t
|
||||
H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info)
|
||||
H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
const H5D_t *dataset = NULL; /* Local pointer to dataset info */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
@@ -2487,19 +2559,19 @@ H5D__chunk_may_use_select_io(const H5D_io_info_t *io_info)
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
|
||||
dataset = io_info->dset;
|
||||
dataset = dset_info->dset;
|
||||
HDassert(dataset);
|
||||
|
||||
/* Don't use selection I/O if it's globally disabled, there is a type
|
||||
* conversion, or if there are filters on the dataset (for now) */
|
||||
if (!H5_use_selection_io_g || io_info->io_ops.single_read != H5D__select_read ||
|
||||
dataset->shared->dcpl_cache.pline.nused > 0)
|
||||
if (dset_info->io_ops.single_read != H5D__select_read || dataset->shared->dcpl_cache.pline.nused > 0)
|
||||
ret_value = FALSE;
|
||||
else {
|
||||
hbool_t page_buf_enabled;
|
||||
|
||||
HDassert(io_info->io_ops.single_write == H5D__select_write);
|
||||
HDassert(dset_info->io_ops.single_write == H5D__select_write);
|
||||
|
||||
/* Check if the page buffer is enabled */
|
||||
if (H5PB_enabled(io_info->f_sh, H5FD_MEM_DRAW, &page_buf_enabled) < 0)
|
||||
@@ -2549,36 +2621,40 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
|
||||
H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
H5D__chunk_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
|
||||
uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
|
||||
H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t *chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
|
||||
H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t *chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
|
||||
haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t nonexistent_io_info; /* "nonexistent" I/O info object */
|
||||
H5D_dset_io_info_t nonexistent_dset_info; /* "nonexistent" I/O dset info object */
|
||||
H5D_dset_io_info_t ctg_dset_info; /* Contiguous I/O dset info object */
|
||||
H5D_dset_io_info_t cpt_dset_info; /* Compact I/O dset info object */
|
||||
uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
|
||||
H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t *chunk_mem_spaces_local[8]; /* Local buffer for chunk_mem_spaces */
|
||||
H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t *chunk_file_spaces_local[8]; /* Local buffer for chunk_file_spaces */
|
||||
haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_local[8]; /* Local buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.rbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->buf.vp);
|
||||
|
||||
/* Set up "nonexistent" I/O info object */
|
||||
H5MM_memcpy(&nonexistent_io_info, io_info, sizeof(nonexistent_io_info));
|
||||
nonexistent_io_info.layout_ops = *H5D_LOPS_NONEXISTENT;
|
||||
H5MM_memcpy(&nonexistent_dset_info, dset_info, sizeof(nonexistent_dset_info));
|
||||
nonexistent_dset_info.layout_ops = *H5D_LOPS_NONEXISTENT;
|
||||
nonexistent_io_info.dsets_info = &nonexistent_dset_info;
|
||||
nonexistent_io_info.count = 1;
|
||||
|
||||
{
|
||||
const H5O_fill_t *fill = &(io_info->dset->shared->dcpl_cache.fill); /* Fill value info */
|
||||
H5D_fill_value_t fill_status; /* Fill value status */
|
||||
const H5O_fill_t *fill = &(dset_info->dset->shared->dcpl_cache.fill); /* Fill value info */
|
||||
H5D_fill_value_t fill_status; /* Fill value status */
|
||||
|
||||
/* Check the fill value status */
|
||||
if (H5P_is_fill_value_defined(fill, &fill_status) < 0)
|
||||
@@ -2596,48 +2672,53 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
/* Different blocks depending on whether we're using selection I/O */
|
||||
if (io_info->use_select_io) {
|
||||
size_t num_chunks;
|
||||
size_t element_sizes[2] = {type_info->dst_type_size, 0};
|
||||
void *bufs[2] = {io_info->u.rbuf, NULL};
|
||||
size_t element_sizes[2] = {dset_info->type_info.src_type_size, 0};
|
||||
void *bufs[2] = {dset_info->buf.vp, NULL};
|
||||
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
|
||||
/* Only create selection I/O arrays if not performing multi dataset I/O,
|
||||
* otherwise the higher level will handle it */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(dset_info);
|
||||
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to static buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to local buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
|
||||
sizeof(chunk_file_spaces_local) / sizeof(chunk_file_spaces_local[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
|
||||
sizeof(chunk_addrs_local) / sizeof(chunk_addrs_local[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
} /* end if */
|
||||
else {
|
||||
chunk_mem_spaces = chunk_mem_spaces_local;
|
||||
chunk_file_spaces = chunk_file_spaces_local;
|
||||
chunk_addrs = chunk_addrs_local;
|
||||
} /* end else */
|
||||
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
} /* end if */
|
||||
else {
|
||||
chunk_mem_spaces = chunk_mem_spaces_static;
|
||||
chunk_file_spaces = chunk_file_spaces_static;
|
||||
chunk_addrs = chunk_addrs_static;
|
||||
} /* end else */
|
||||
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_piece_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chunk_ud_t udata; /* Chunk index pass-through */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* There should be no chunks cached */
|
||||
@@ -2649,45 +2730,66 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
|
||||
/* Check for non-existent chunk & skip it if appropriate */
|
||||
if (H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Add chunk to list for selection I/O */
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
/* Add chunk to list for selection I/O, if not performing multi dataset I/O */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Add to mdset selection I/O arrays */
|
||||
HDassert(io_info->mem_spaces);
|
||||
HDassert(io_info->file_spaces);
|
||||
HDassert(io_info->addrs);
|
||||
HDassert(io_info->element_sizes);
|
||||
HDassert(io_info->rbufs);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
io_info->mem_spaces[io_info->pieces_added] = chunk_info->mspace;
|
||||
io_info->file_spaces[io_info->pieces_added] = chunk_info->fspace;
|
||||
io_info->addrs[io_info->pieces_added] = udata.chunk_block.offset;
|
||||
io_info->element_sizes[io_info->pieces_added] = element_sizes[0];
|
||||
io_info->rbufs[io_info->pieces_added] = bufs[0];
|
||||
io_info->pieces_added++;
|
||||
}
|
||||
} /* end if */
|
||||
else if (!skip_missing_chunks) {
|
||||
/* Perform the actual read operation from the nonexistent chunk
|
||||
*/
|
||||
if ((io_info->io_ops.single_read)(&nonexistent_io_info, type_info,
|
||||
(hsize_t)chunk_info->chunk_points, chunk_info->fspace,
|
||||
chunk_info->mspace) < 0)
|
||||
nonexistent_dset_info.file_space = chunk_info->fspace;
|
||||
nonexistent_dset_info.mem_space = chunk_info->mspace;
|
||||
nonexistent_dset_info.nelmts = chunk_info->piece_points;
|
||||
if ((dset_info->io_ops.single_read)(&nonexistent_io_info, &nonexistent_dset_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
|
||||
} /* end if */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
|
||||
} /* end while */
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_read(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
|
||||
chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
|
||||
/* Only perform I/O if not performing multi dataset I/O, otherwise the
|
||||
* higher level will handle it after all datasets have been processed */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
H5_CHECK_OVERFLOW(num_chunks, size_t, uint32_t)
|
||||
if (H5F_shared_select_read(H5F_SHARED(dset_info->dset->oloc.file), H5FD_MEM_DRAW,
|
||||
(uint32_t)num_chunks, chunk_mem_spaces, chunk_file_spaces, chunk_addrs,
|
||||
element_sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
|
||||
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static) {
|
||||
HDassert(chunk_mem_spaces);
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_static);
|
||||
HDassert(chunk_addrs != chunk_addrs_static);
|
||||
H5MM_free(chunk_mem_spaces);
|
||||
chunk_mem_spaces = NULL;
|
||||
H5MM_free(chunk_file_spaces);
|
||||
chunk_file_spaces = NULL;
|
||||
H5MM_free(chunk_addrs);
|
||||
chunk_addrs = NULL;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_local) {
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_local);
|
||||
HDassert(chunk_addrs != chunk_addrs_local);
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
@@ -2697,33 +2799,39 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
HDmemcpy(&ctg_dset_info, dset_info, sizeof(ctg_dset_info));
|
||||
ctg_dset_info.store = &ctg_store;
|
||||
ctg_dset_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
ctg_io_info.dsets_info = &ctg_dset_info;
|
||||
ctg_io_info.count = 1;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, dset_info->dset->shared->layout.u.chunk.size,
|
||||
uint32_t);
|
||||
|
||||
/* Set up compact I/O info object */
|
||||
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
|
||||
cpt_io_info.store = &cpt_store;
|
||||
cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
HDmemcpy(&cpt_dset_info, dset_info, sizeof(cpt_dset_info));
|
||||
cpt_dset_info.store = &cpt_store;
|
||||
cpt_dset_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
cpt_io_info.dsets_info = &cpt_dset_info;
|
||||
cpt_io_info.count = 1;
|
||||
|
||||
/* Initialize temporary compact storage info */
|
||||
cpt_store.compact.dirty = &cpt_dirty;
|
||||
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_piece_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chunk_ud_t udata; /* Chunk index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
@@ -2737,20 +2845,23 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
void *chunk = NULL; /* Pointer to locked chunk buffer */
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
dset_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, FALSE)) < 0)
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, FALSE)) <
|
||||
0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache and lock it. */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size;
|
||||
H5_CHECK_OVERFLOW(dset_info->type_info.src_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
src_accessed_bytes =
|
||||
(uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.src_type_size;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, FALSE, FALSE)))
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, FALSE, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
@@ -2772,35 +2883,39 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_
|
||||
} /* end else */
|
||||
|
||||
/* Perform the actual read operation */
|
||||
if ((io_info->io_ops.single_read)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HDassert(chk_io_info->count == 1);
|
||||
chk_io_info->dsets_info[0].file_space = chunk_info->fspace;
|
||||
chk_io_info->dsets_info[0].mem_space = chunk_info->mspace;
|
||||
chk_io_info->dsets_info[0].nelmts = chunk_info->piece_points;
|
||||
if ((dset_info->io_ops.single_read)(chk_io_info, &chk_io_info->dsets_info[0]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
|
||||
|
||||
/* Release the cache lock on the chunk. */
|
||||
if (chunk && H5D__chunk_unlock(io_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
|
||||
if (chunk &&
|
||||
H5D__chunk_unlock(io_info, dset_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
/* Cleanup on failure */
|
||||
if (ret_value < 0) {
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static)
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_local)
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
if (chunk_file_spaces != chunk_file_spaces_static)
|
||||
if (chunk_file_spaces != chunk_file_spaces_local)
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
if (chunk_addrs != chunk_addrs_static)
|
||||
if (chunk_addrs != chunk_addrs_local)
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
|
||||
/* Make sure we cleaned up */
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_local);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_local);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_local);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5D__chunk_read() */
|
||||
@@ -2818,45 +2933,51 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t H5_ATTR_UNUSED nelmts,
|
||||
H5S_t H5_ATTR_UNUSED *file_space, H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
H5D__chunk_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t *chunk_mem_spaces_static[8]; /* Static buffer for chunk_mem_spaces */
|
||||
H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t *chunk_file_spaces_static[8]; /* Static buffer for chunk_file_spaces */
|
||||
haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_static[8]; /* Static buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_dset_io_info_t ctg_dset_info; /* Contiguous I/O dset info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_dset_io_info_t cpt_dset_info; /* Compact I/O dset info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
|
||||
H5S_t **chunk_mem_spaces = NULL; /* Array of chunk memory spaces */
|
||||
H5S_t *chunk_mem_spaces_local[8]; /* Local buffer for chunk_mem_spaces */
|
||||
H5S_t **chunk_file_spaces = NULL; /* Array of chunk file spaces */
|
||||
H5S_t *chunk_file_spaces_local[8]; /* Local buffer for chunk_file_spaces */
|
||||
haddr_t *chunk_addrs = NULL; /* Array of chunk addresses */
|
||||
haddr_t chunk_addrs_local[8]; /* Local buffer for chunk_addrs */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.wbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->buf.cvp);
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
HDmemcpy(&ctg_dset_info, dset_info, sizeof(ctg_dset_info));
|
||||
ctg_dset_info.store = &ctg_store;
|
||||
ctg_dset_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
ctg_io_info.dsets_info = &ctg_dset_info;
|
||||
ctg_io_info.count = 1;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, io_info->dset->shared->layout.u.chunk.size,
|
||||
H5_CHECKED_ASSIGN(ctg_store.contig.dset_size, hsize_t, dset_info->dset->shared->layout.u.chunk.size,
|
||||
uint32_t);
|
||||
|
||||
/* Set up compact I/O info object */
|
||||
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
|
||||
cpt_io_info.store = &cpt_store;
|
||||
cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
HDmemcpy(&cpt_dset_info, dset_info, sizeof(cpt_dset_info));
|
||||
cpt_dset_info.store = &cpt_store;
|
||||
cpt_dset_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
cpt_io_info.dsets_info = &cpt_dset_info;
|
||||
cpt_io_info.count = 1;
|
||||
|
||||
/* Initialize temporary compact storage info */
|
||||
cpt_store.compact.dirty = &cpt_dirty;
|
||||
@@ -2864,51 +2985,56 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
/* Different blocks depending on whether we're using selection I/O */
|
||||
if (io_info->use_select_io) {
|
||||
size_t num_chunks;
|
||||
size_t element_sizes[2] = {type_info->dst_type_size, 0};
|
||||
const void *bufs[2] = {io_info->u.wbuf, NULL};
|
||||
size_t element_sizes[2] = {dset_info->type_info.dst_type_size, 0};
|
||||
const void *bufs[2] = {dset_info->buf.cvp, NULL};
|
||||
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(fm);
|
||||
/* Only create selection I/O arrays if not performing multi dataset I/O,
|
||||
* otherwise the higher level will handle it */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
/* Cache number of chunks */
|
||||
num_chunks = H5D_CHUNK_GET_NODE_COUNT(dset_info);
|
||||
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to static buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_file_spaces_static) / sizeof(chunk_file_spaces_static[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]) ==
|
||||
sizeof(chunk_addrs_static) / sizeof(chunk_addrs_static[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_static) / sizeof(chunk_mem_spaces_static[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
/* Allocate arrays of dataspaces and offsets for use with selection I/O,
|
||||
* or point to local buffers */
|
||||
HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
|
||||
sizeof(chunk_file_spaces_local) / sizeof(chunk_file_spaces_local[0]));
|
||||
HDassert(sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]) ==
|
||||
sizeof(chunk_addrs_local) / sizeof(chunk_addrs_local[0]));
|
||||
if (num_chunks > (sizeof(chunk_mem_spaces_local) / sizeof(chunk_mem_spaces_local[0]))) {
|
||||
if (NULL == (chunk_mem_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (chunk_file_spaces = H5MM_malloc(num_chunks * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for file space list")
|
||||
if (NULL == (chunk_addrs = H5MM_malloc(num_chunks * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for chunk address list")
|
||||
} /* end if */
|
||||
else {
|
||||
chunk_mem_spaces = chunk_mem_spaces_local;
|
||||
chunk_file_spaces = chunk_file_spaces_local;
|
||||
chunk_addrs = chunk_addrs_local;
|
||||
} /* end else */
|
||||
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
} /* end if */
|
||||
else {
|
||||
chunk_mem_spaces = chunk_mem_spaces_static;
|
||||
chunk_file_spaces = chunk_file_spaces_static;
|
||||
chunk_addrs = chunk_addrs_static;
|
||||
} /* end else */
|
||||
|
||||
/* Reset num_chunks */
|
||||
num_chunks = 0;
|
||||
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_piece_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_chunk_ud_t udata; /* Index pass-through */
|
||||
htri_t cacheable; /* Whether the chunk is cacheable */
|
||||
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
|
||||
|
||||
/* Get the info for the chunk in the file */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* There should be no chunks cached */
|
||||
@@ -2919,10 +3045,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
dset_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache. But if the whole chunk is written,
|
||||
@@ -2931,42 +3057,47 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
|
||||
H5_CHECK_OVERFLOW(dset_info->type_info.dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes =
|
||||
(uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.dst_type_size;
|
||||
|
||||
/* Determine if we will access all the data in the chunk */
|
||||
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
|
||||
(chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
|
||||
fm->fsel_type == H5S_SEL_POINTS)
|
||||
(chunk_info->piece_points * dset_info->type_info.src_type_size) !=
|
||||
ctg_store.contig.dset_size ||
|
||||
dset_info->layout_io_info.chunk_map->fsel_type == H5S_SEL_POINTS)
|
||||
entire_chunk = FALSE;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, entire_chunk, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
cpt_store.compact.buf = chunk;
|
||||
|
||||
/* Perform the actual write operation */
|
||||
if ((io_info->io_ops.single_write)(&cpt_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
cpt_dset_info.file_space = chunk_info->fspace;
|
||||
cpt_dset_info.mem_space = chunk_info->mspace;
|
||||
cpt_dset_info.nelmts = chunk_info->piece_points;
|
||||
if ((dset_info->io_ops.single_write)(&cpt_io_info, &cpt_dset_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
|
||||
|
||||
/* Release the cache lock on the chunk */
|
||||
if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
if (H5D__chunk_unlock(io_info, dset_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
/* If the chunk hasn't been allocated on disk, do so now. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = io_info->dset->oloc.file;
|
||||
idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
|
||||
idx_info.f = dset_info->dset->oloc.file;
|
||||
idx_info.pline = &(dset_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(dset_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(dset_info->dset->shared->layout.storage.u.chunk);
|
||||
|
||||
/* Set up the size of chunk for user data */
|
||||
udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
|
||||
udata.chunk_block.length = dset_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Allocate the chunk */
|
||||
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
|
||||
@@ -2979,53 +3110,72 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
|
||||
|
||||
/* Cache the new chunk information */
|
||||
H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
|
||||
H5D__chunk_cinfo_cache_update(&dset_info->dset->shared->cache.chunk.last, &udata);
|
||||
|
||||
/* Insert chunk into index */
|
||||
if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
|
||||
NULL) < 0)
|
||||
if (need_insert && dset_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((dset_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert chunk addr into index")
|
||||
} /* end if */
|
||||
|
||||
/* Add chunk to list for selection I/O */
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
/* Add chunk to list for selection I/O, if not performing multi dataset I/O */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
chunk_mem_spaces[num_chunks] = chunk_info->mspace;
|
||||
chunk_file_spaces[num_chunks] = chunk_info->fspace;
|
||||
chunk_addrs[num_chunks] = udata.chunk_block.offset;
|
||||
num_chunks++;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Add to mdset selection I/O arrays */
|
||||
HDassert(io_info->mem_spaces);
|
||||
HDassert(io_info->file_spaces);
|
||||
HDassert(io_info->addrs);
|
||||
HDassert(io_info->element_sizes);
|
||||
HDassert(io_info->wbufs);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
io_info->mem_spaces[io_info->pieces_added] = chunk_info->mspace;
|
||||
io_info->file_spaces[io_info->pieces_added] = chunk_info->fspace;
|
||||
io_info->addrs[io_info->pieces_added] = udata.chunk_block.offset;
|
||||
io_info->element_sizes[io_info->pieces_added] = element_sizes[0];
|
||||
io_info->wbufs[io_info->pieces_added] = bufs[0];
|
||||
io_info->pieces_added++;
|
||||
}
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
|
||||
} /* end while */
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_write(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, (uint32_t)num_chunks,
|
||||
chunk_mem_spaces, chunk_file_spaces, chunk_addrs, element_sizes,
|
||||
bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunk selection read failed")
|
||||
/* Only perform I/O if not performing multi dataset I/O, otherwise the
|
||||
* higher level will handle it after all datasets have been processed */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
H5_CHECK_OVERFLOW(num_chunks, size_t, uint32_t)
|
||||
if (H5F_shared_select_write(H5F_SHARED(dset_info->dset->oloc.file), H5FD_MEM_DRAW,
|
||||
(uint32_t)num_chunks, chunk_mem_spaces, chunk_file_spaces,
|
||||
chunk_addrs, element_sizes, bufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "chunk selection write failed")
|
||||
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static) {
|
||||
HDassert(chunk_mem_spaces);
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_static);
|
||||
HDassert(chunk_addrs != chunk_addrs_static);
|
||||
H5MM_free(chunk_mem_spaces);
|
||||
chunk_mem_spaces = NULL;
|
||||
H5MM_free(chunk_file_spaces);
|
||||
chunk_file_spaces = NULL;
|
||||
H5MM_free(chunk_addrs);
|
||||
chunk_addrs = NULL;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
/* Clean up memory */
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_local) {
|
||||
HDassert(chunk_file_spaces != chunk_file_spaces_local);
|
||||
HDassert(chunk_addrs != chunk_addrs_local);
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
/* Iterate through nodes in chunk skip list */
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(fm);
|
||||
chunk_node = H5D_CHUNK_GET_FIRST_NODE(dset_info);
|
||||
while (chunk_node) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk information */
|
||||
H5D_piece_info_t *chunk_info; /* Chunk information */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
|
||||
void *chunk; /* Pointer to locked chunk buffer */
|
||||
@@ -3034,10 +3184,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
hbool_t need_insert = FALSE; /* Whether the chunk needs to be inserted into the index */
|
||||
|
||||
/* Get the actual chunk information from the skip list node */
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
|
||||
chunk_info = H5D_CHUNK_GET_NODE_INFO(dset_info, chunk_node);
|
||||
|
||||
/* Look up the chunk */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(dset_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Sanity check */
|
||||
@@ -3045,10 +3195,10 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
(!H5F_addr_defined(udata.chunk_block.offset) && udata.chunk_block.length == 0));
|
||||
|
||||
/* Set chunk's [scaled] coordinates */
|
||||
io_info->store->chunk.scaled = chunk_info->scaled;
|
||||
dset_info->store->chunk.scaled = chunk_info->scaled;
|
||||
|
||||
/* Determine if we should use the chunk cache */
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
if ((cacheable = H5D__chunk_cacheable(io_info, dset_info, udata.chunk_block.offset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
|
||||
if (cacheable) {
|
||||
/* Load the chunk into cache. But if the whole chunk is written,
|
||||
@@ -3056,17 +3206,20 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
hbool_t entire_chunk = TRUE; /* Whether whole chunk is selected */
|
||||
|
||||
/* Compute # of bytes accessed in chunk */
|
||||
H5_CHECK_OVERFLOW(type_info->dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->dst_type_size;
|
||||
H5_CHECK_OVERFLOW(dset_info->type_info.dst_type_size, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
H5_CHECK_OVERFLOW(chunk_info->piece_points, /*From:*/ size_t, /*To:*/ uint32_t);
|
||||
dst_accessed_bytes =
|
||||
(uint32_t)chunk_info->piece_points * (uint32_t)dset_info->type_info.dst_type_size;
|
||||
|
||||
/* Determine if we will access all the data in the chunk */
|
||||
if (dst_accessed_bytes != ctg_store.contig.dset_size ||
|
||||
(chunk_info->chunk_points * type_info->src_type_size) != ctg_store.contig.dset_size ||
|
||||
fm->fsel_type == H5S_SEL_POINTS)
|
||||
(chunk_info->piece_points * dset_info->type_info.src_type_size) !=
|
||||
ctg_store.contig.dset_size ||
|
||||
dset_info->layout_io_info.chunk_map->fsel_type == H5S_SEL_POINTS)
|
||||
entire_chunk = FALSE;
|
||||
|
||||
/* Lock the chunk into the cache */
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, &udata, entire_chunk, FALSE)))
|
||||
if (NULL == (chunk = H5D__chunk_lock(io_info, dset_info, &udata, entire_chunk, FALSE)))
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
|
||||
|
||||
/* Set up the storage buffer information for this chunk */
|
||||
@@ -3079,13 +3232,13 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
/* If the chunk hasn't been allocated on disk, do so now. */
|
||||
if (!H5F_addr_defined(udata.chunk_block.offset)) {
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = io_info->dset->oloc.file;
|
||||
idx_info.pline = &(io_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(io_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(io_info->dset->shared->layout.storage.u.chunk);
|
||||
idx_info.f = dset_info->dset->oloc.file;
|
||||
idx_info.pline = &(dset_info->dset->shared->dcpl_cache.pline);
|
||||
idx_info.layout = &(dset_info->dset->shared->layout.u.chunk);
|
||||
idx_info.storage = &(dset_info->dset->shared->layout.storage.u.chunk);
|
||||
|
||||
/* Set up the size of chunk for user data */
|
||||
udata.chunk_block.length = io_info->dset->shared->layout.u.chunk.size;
|
||||
udata.chunk_block.length = dset_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Allocate the chunk */
|
||||
if (H5D__chunk_file_alloc(&idx_info, NULL, &udata.chunk_block, &need_insert,
|
||||
@@ -3098,7 +3251,7 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined")
|
||||
|
||||
/* Cache the new chunk information */
|
||||
H5D__chunk_cinfo_cache_update(&io_info->dset->shared->cache.chunk.last, &udata);
|
||||
H5D__chunk_cinfo_cache_update(&dset_info->dset->shared->cache.chunk.last, &udata);
|
||||
} /* end if */
|
||||
|
||||
/* Set up the storage address information for this chunk */
|
||||
@@ -3112,43 +3265,46 @@ H5D__chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
} /* end else */
|
||||
|
||||
/* Perform the actual write operation */
|
||||
if ((io_info->io_ops.single_write)(chk_io_info, type_info, (hsize_t)chunk_info->chunk_points,
|
||||
chunk_info->fspace, chunk_info->mspace) < 0)
|
||||
HDassert(chk_io_info->count == 1);
|
||||
chk_io_info->dsets_info[0].file_space = chunk_info->fspace;
|
||||
chk_io_info->dsets_info[0].mem_space = chunk_info->mspace;
|
||||
chk_io_info->dsets_info[0].nelmts = chunk_info->piece_points;
|
||||
if ((dset_info->io_ops.single_write)(chk_io_info, &chk_io_info->dsets_info[0]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
|
||||
|
||||
/* Release the cache lock on the chunk, or insert chunk into index. */
|
||||
if (chunk) {
|
||||
if (H5D__chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
if (H5D__chunk_unlock(io_info, dset_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
if (need_insert && io_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((io_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata, NULL) <
|
||||
0)
|
||||
if (need_insert && dset_info->dset->shared->layout.storage.u.chunk.ops->insert)
|
||||
if ((dset_info->dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata,
|
||||
NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL,
|
||||
"unable to insert chunk addr into index")
|
||||
} /* end else */
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node);
|
||||
chunk_node = H5D_CHUNK_GET_NEXT_NODE(dset_info, chunk_node);
|
||||
} /* end while */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
/* Cleanup on failure */
|
||||
if (ret_value < 0) {
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_static)
|
||||
if (chunk_mem_spaces != chunk_mem_spaces_local)
|
||||
chunk_mem_spaces = H5MM_xfree(chunk_mem_spaces);
|
||||
if (chunk_file_spaces != chunk_file_spaces_static)
|
||||
if (chunk_file_spaces != chunk_file_spaces_local)
|
||||
chunk_file_spaces = H5MM_xfree(chunk_file_spaces);
|
||||
if (chunk_addrs != chunk_addrs_static)
|
||||
if (chunk_addrs != chunk_addrs_local)
|
||||
chunk_addrs = H5MM_xfree(chunk_addrs);
|
||||
} /* end if */
|
||||
|
||||
/* Make sure we cleaned up */
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_static);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_static);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_static);
|
||||
HDassert(!chunk_mem_spaces || chunk_mem_spaces == chunk_mem_spaces_local);
|
||||
HDassert(!chunk_file_spaces || chunk_file_spaces == chunk_file_spaces_local);
|
||||
HDassert(!chunk_addrs || chunk_addrs == chunk_addrs_local);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5D__chunk_write() */
|
||||
@@ -3199,44 +3355,56 @@ done:
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, May 17, 2003
|
||||
* Programmer: Jonathan Kim Nov, 2013
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_io_term(const H5D_chunk_map_t *fm)
|
||||
H5D__chunk_io_term(H5D_io_info_t H5_ATTR_UNUSED *io_info, H5D_dset_io_info_t *di)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
H5D_chunk_map_t *fm; /* Convenience pointer to chunk map */
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(di);
|
||||
|
||||
/* Set convenience pointer */
|
||||
fm = di->layout_io_info.chunk_map;
|
||||
|
||||
/* Single element I/O vs. multiple element I/O cleanup */
|
||||
if (fm->use_single) {
|
||||
/* Sanity checks */
|
||||
HDassert(fm->sel_chunks == NULL);
|
||||
HDassert(fm->single_chunk_info);
|
||||
HDassert(fm->single_chunk_info->fspace_shared);
|
||||
HDassert(fm->single_chunk_info->mspace_shared);
|
||||
HDassert(fm->dset_sel_pieces == NULL);
|
||||
HDassert(fm->last_piece_info == NULL);
|
||||
HDassert(fm->single_piece_info);
|
||||
HDassert(fm->single_piece_info->fspace_shared);
|
||||
HDassert(fm->single_piece_info->mspace_shared);
|
||||
|
||||
/* Reset the selection for the single element I/O */
|
||||
H5S_select_all(fm->single_space, TRUE);
|
||||
} /* end if */
|
||||
else {
|
||||
/* Release the nodes on the list of selected chunks */
|
||||
if (fm->sel_chunks)
|
||||
if (H5SL_free(fm->sel_chunks, H5D__free_chunk_info, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTNEXT, FAIL, "can't iterate over chunks")
|
||||
} /* end else */
|
||||
/* Release the nodes on the list of selected pieces, or the last (only)
|
||||
* piece if the skiplist is not available */
|
||||
if (fm->dset_sel_pieces) {
|
||||
if (H5SL_free(fm->dset_sel_pieces, H5D__free_piece_info, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTNEXT, FAIL, "can't free dataset skip list")
|
||||
} /* end if */
|
||||
else if (fm->last_piece_info) {
|
||||
if (H5D__free_piece_info(fm->last_piece_info, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't free piece info")
|
||||
fm->last_piece_info = NULL;
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
|
||||
/* Free the memory chunk dataspace template */
|
||||
/* Free the memory piece dataspace template */
|
||||
if (fm->mchunk_tmpl)
|
||||
if (H5S_close(fm->mchunk_tmpl) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release memory chunk dataspace template")
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if (fm->select_chunk)
|
||||
H5MM_xfree(fm->select_chunk);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Free chunk map */
|
||||
di->layout_io_info.chunk_map = H5FL_FREE(H5D_chunk_map_t, di->layout_io_info.chunk_map);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@@ -4099,20 +4267,19 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t relax, hbool_t prev_unfilt_chunk)
|
||||
H5D__chunk_lock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, H5D_chunk_ud_t *udata,
|
||||
hbool_t relax, hbool_t prev_unfilt_chunk)
|
||||
{
|
||||
const H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
|
||||
H5O_pline_t *pline =
|
||||
&(dset->shared->dcpl_cache
|
||||
.pline); /* I/O pipeline info - always equal to the pline passed to H5D__chunk_mem_alloc */
|
||||
H5O_pline_t *old_pline = pline; /* Old pipeline, i.e. pipeline used to read the chunk */
|
||||
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */
|
||||
const H5O_fill_t *fill = &(dset->shared->dcpl_cache.fill); /* Fill value info */
|
||||
H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
|
||||
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
|
||||
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache*/
|
||||
H5D_rdcc_ent_t *ent; /*cache entry */
|
||||
size_t chunk_size; /*size of a chunk */
|
||||
const H5D_t *dset; /* Convenience pointer to the dataset */
|
||||
H5O_pline_t *pline; /* I/O pipeline info - always equal to the pline passed to H5D__chunk_mem_alloc */
|
||||
H5O_pline_t *old_pline; /* Old pipeline, i.e. pipeline used to read the chunk */
|
||||
const H5O_layout_t *layout; /* Dataset layout */
|
||||
const H5O_fill_t *fill; /* Fill value info */
|
||||
H5D_fill_buf_info_t fb_info; /* Dataset's fill buffer info */
|
||||
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
|
||||
H5D_rdcc_t *rdcc; /*raw data chunk cache*/
|
||||
H5D_rdcc_ent_t *ent; /*cache entry */
|
||||
size_t chunk_size; /*size of a chunk */
|
||||
hbool_t disable_filters = FALSE; /* Whether to disable filters (when adding to cache) */
|
||||
void *chunk = NULL; /*the file chunk */
|
||||
void *ret_value = NULL; /* Return value */
|
||||
@@ -4121,10 +4288,20 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->store);
|
||||
HDassert(udata);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->store);
|
||||
dset = dset_info->dset;
|
||||
HDassert(dset);
|
||||
HDassert(udata);
|
||||
HDassert(!(udata->new_unfilt_chunk && prev_unfilt_chunk));
|
||||
|
||||
/* Set convenience pointers */
|
||||
pline = &(dset->shared->dcpl_cache.pline);
|
||||
old_pline = pline;
|
||||
layout = &(dset->shared->layout);
|
||||
fill = &(dset->shared->dcpl_cache.fill);
|
||||
rdcc = &(dset->shared->cache.chunk);
|
||||
|
||||
HDassert(!rdcc->tmp_head);
|
||||
|
||||
/* Get the chunk's size */
|
||||
@@ -4146,7 +4323,7 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
|
||||
|
||||
/* Make sure this is the right chunk */
|
||||
for (u = 0; u < layout->u.chunk.ndims - 1; u++)
|
||||
HDassert(io_info->store->chunk.scaled[u] == ent->scaled[u]);
|
||||
HDassert(dset_info->store->chunk.scaled[u] == ent->scaled[u]);
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
|
||||
@@ -4261,9 +4438,9 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
|
||||
} /* end if */
|
||||
else if (layout->u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
|
||||
/* Check if this is an edge chunk */
|
||||
if (H5D__chunk_is_partial_edge_chunk(io_info->dset->shared->ndims, layout->u.chunk.dim,
|
||||
io_info->store->chunk.scaled,
|
||||
io_info->dset->shared->curr_dims)) {
|
||||
if (H5D__chunk_is_partial_edge_chunk(dset->shared->ndims, layout->u.chunk.dim,
|
||||
dset_info->store->chunk.scaled,
|
||||
dset->shared->curr_dims)) {
|
||||
/* Disable the filters for both writing and reading */
|
||||
disable_filters = TRUE;
|
||||
old_pline = NULL;
|
||||
@@ -4388,17 +4565,17 @@ H5D__chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata, hbool_t rel
|
||||
/* See if the chunk can be cached */
|
||||
if (rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max) {
|
||||
/* Calculate the index */
|
||||
udata->idx_hint = H5D__chunk_hash_val(io_info->dset->shared, udata->common.scaled);
|
||||
udata->idx_hint = H5D__chunk_hash_val(dset->shared, udata->common.scaled);
|
||||
|
||||
/* Add the chunk to the cache only if the slot is not already locked */
|
||||
ent = rdcc->slot[udata->idx_hint];
|
||||
if (!ent || !ent->locked) {
|
||||
/* Preempt enough things from the cache to make room */
|
||||
if (ent) {
|
||||
if (H5D__chunk_cache_evict(io_info->dset, ent, TRUE) < 0)
|
||||
if (H5D__chunk_cache_evict(dset, ent, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk from cache")
|
||||
} /* end if */
|
||||
if (H5D__chunk_cache_prune(io_info->dset, chunk_size) < 0)
|
||||
if (H5D__chunk_cache_prune(dset, chunk_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache")
|
||||
|
||||
/* Create a new entry */
|
||||
@@ -4498,19 +4675,26 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk,
|
||||
uint32_t naccessed)
|
||||
H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk, uint32_t naccessed)
|
||||
{
|
||||
const H5O_layout_t *layout = &(io_info->dset->shared->layout); /* Dataset layout */
|
||||
const H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);
|
||||
const H5O_layout_t *layout; /* Dataset layout */
|
||||
const H5D_rdcc_t *rdcc;
|
||||
const H5D_t *dset; /* Local pointer to the dataset info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
HDassert(udata);
|
||||
|
||||
/* Set convenience pointers */
|
||||
layout = &(dset_info->dset->shared->layout);
|
||||
rdcc = &(dset_info->dset->shared->cache.chunk);
|
||||
dset = dset_info->dset;
|
||||
|
||||
if (UINT_MAX == udata->idx_hint) {
|
||||
/*
|
||||
* It's not in the cache, probably because it's too big. If it's
|
||||
@@ -4526,9 +4710,9 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbo
|
||||
} /* end if */
|
||||
else if (layout->u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS) {
|
||||
/* Check if the chunk is an edge chunk, and disable filters if so */
|
||||
is_unfiltered_edge_chunk = H5D__chunk_is_partial_edge_chunk(
|
||||
io_info->dset->shared->ndims, layout->u.chunk.dim, io_info->store->chunk.scaled,
|
||||
io_info->dset->shared->curr_dims);
|
||||
is_unfiltered_edge_chunk =
|
||||
H5D__chunk_is_partial_edge_chunk(dset->shared->ndims, layout->u.chunk.dim,
|
||||
dset_info->store->chunk.scaled, dset->shared->curr_dims);
|
||||
} /* end if */
|
||||
|
||||
if (dirty) {
|
||||
@@ -4547,13 +4731,13 @@ H5D__chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata, hbo
|
||||
fake_ent.chunk_block.length = udata->chunk_block.length;
|
||||
fake_ent.chunk = (uint8_t *)chunk;
|
||||
|
||||
if (H5D__chunk_flush_entry(io_info->dset, &fake_ent, TRUE) < 0)
|
||||
if (H5D__chunk_flush_entry(dset, &fake_ent, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer")
|
||||
} /* end if */
|
||||
else {
|
||||
if (chunk)
|
||||
chunk = H5D__chunk_mem_xfree(
|
||||
chunk, (is_unfiltered_edge_chunk ? NULL : &(io_info->dset->shared->dcpl_cache.pline)));
|
||||
chunk, (is_unfiltered_edge_chunk ? NULL : &(dset->shared->dcpl_cache.pline)));
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else {
|
||||
@@ -4676,9 +4860,8 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const hsize_t old_dim[])
|
||||
H5D__chunk_allocate(const H5D_t *dset, hbool_t full_overwrite, const hsize_t old_dim[])
|
||||
{
|
||||
const H5D_t *dset = io_info->dset; /* the dataset pointer */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
const H5D_chunk_ops_t *ops = dset->shared->layout.storage.u.chunk.ops; /* Chunk operations */
|
||||
hsize_t min_unalloc[H5O_LAYOUT_NDIMS]; /* First chunk in each dimension that is unallocated (in scaled
|
||||
@@ -5170,6 +5353,7 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
|
||||
H5D_io_info_t chk_io_info; /* Chunked I/O info object */
|
||||
H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
|
||||
H5D_storage_t chk_store; /* Chunk storage information */
|
||||
H5D_dset_io_info_t chk_dset_info; /* Chunked I/O dset info object */
|
||||
void *chunk; /* The file chunk */
|
||||
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
@@ -5203,7 +5387,13 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
|
||||
* Note that we only need to set chunk_offset once, as the array's address
|
||||
* will never change. */
|
||||
chk_store.chunk.scaled = chunk_sc;
|
||||
H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, &chk_store, NULL);
|
||||
|
||||
chk_io_info.op_type = H5D_IO_OP_READ;
|
||||
|
||||
chk_dset_info.dset = dset;
|
||||
chk_dset_info.store = &chk_store;
|
||||
chk_dset_info.buf.vp = NULL;
|
||||
chk_io_info.dsets_info = &chk_dset_info;
|
||||
|
||||
/*
|
||||
* Determine the edges of the dataset which need to be modified
|
||||
@@ -5268,11 +5458,12 @@ H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[])
|
||||
if (H5F_addr_defined(chk_udata.chunk_block.offset) || (UINT_MAX != chk_udata.idx_hint)) {
|
||||
/* Lock the chunk into cache. H5D__chunk_lock will take care of
|
||||
* updating the chunk to no longer be an edge chunk. */
|
||||
if (NULL == (chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_udata, FALSE, TRUE)))
|
||||
if (NULL ==
|
||||
(chunk = (void *)H5D__chunk_lock(&chk_io_info, &chk_dset_info, &chk_udata, FALSE, TRUE)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
|
||||
|
||||
/* Unlock the chunk */
|
||||
if (H5D__chunk_unlock(&chk_io_info, &chk_udata, TRUE, chunk, (uint32_t)0) < 0)
|
||||
if (H5D__chunk_unlock(&chk_io_info, &chk_dset_info, &chk_udata, TRUE, chunk, (uint32_t)0) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
|
||||
} /* end if */
|
||||
|
||||
@@ -5603,7 +5794,7 @@ static herr_t
|
||||
H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
|
||||
{
|
||||
const H5D_io_info_t *io_info = udata->io_info; /* Local pointer to I/O info */
|
||||
const H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
|
||||
const H5D_t *dset = udata->dset_info->dset; /* Local pointer to the dataset info */
|
||||
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
|
||||
unsigned rank = udata->common.layout->ndims - 1; /* Dataset rank */
|
||||
const hsize_t *scaled = udata->common.scaled; /* Scaled chunk offset */
|
||||
@@ -5658,7 +5849,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab")
|
||||
|
||||
/* Lock the chunk into the cache, to get a pointer to the chunk buffer */
|
||||
if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, &chk_udata, FALSE, FALSE)))
|
||||
if (NULL == (chunk = (void *)H5D__chunk_lock(io_info, udata->dset_info, &chk_udata, FALSE, FALSE)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
|
||||
|
||||
/* Fill the selection in the memory buffer */
|
||||
@@ -5695,7 +5886,7 @@ H5D__chunk_prune_fill(H5D_chunk_it_ud1_t *udata, hbool_t new_unfilt_chunk)
|
||||
bytes_accessed = (uint32_t)sel_nelmts * layout->u.chunk.dim[rank];
|
||||
|
||||
/* Release lock on chunk */
|
||||
if (H5D__chunk_unlock(io_info, &chk_udata, TRUE, chunk, bytes_accessed) < 0)
|
||||
if (H5D__chunk_unlock(io_info, udata->dset_info, &chk_udata, TRUE, chunk, bytes_accessed) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
|
||||
|
||||
done:
|
||||
@@ -5822,6 +6013,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
|
||||
unfiltered */
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_io_info_t chk_io_info; /* Chunked I/O info object */
|
||||
H5D_dset_io_info_t chk_dset_info; /* Chunked I/O dset info object */
|
||||
H5D_storage_t chk_store; /* Chunk storage information */
|
||||
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
|
||||
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
|
||||
@@ -5889,7 +6081,14 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
|
||||
* Note that we only need to set scaled once, as the array's address
|
||||
* will never change. */
|
||||
chk_store.chunk.scaled = scaled;
|
||||
H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, &chk_store, NULL);
|
||||
|
||||
chk_io_info.op_type = H5D_IO_OP_READ;
|
||||
|
||||
chk_dset_info.dset = dset;
|
||||
chk_dset_info.store = &chk_store;
|
||||
chk_dset_info.buf.vp = NULL;
|
||||
chk_io_info.dsets_info = &chk_dset_info;
|
||||
chk_io_info.count = 1;
|
||||
|
||||
/* Compose chunked index info struct */
|
||||
idx_info.f = dset->oloc.file;
|
||||
@@ -5903,6 +6102,7 @@ H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim)
|
||||
udata.common.storage = sc;
|
||||
udata.common.scaled = scaled;
|
||||
udata.io_info = &chk_io_info;
|
||||
udata.dset_info = &chk_dset_info;
|
||||
udata.idx_info = &idx_info;
|
||||
udata.space_dim = space_dim;
|
||||
udata.shrunk_dim = shrunk_dim;
|
||||
@@ -6183,18 +6383,18 @@ H5D__chunk_addrmap_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[])
|
||||
H5D__chunk_addrmap(const H5D_t *dset, haddr_t chunk_addr[])
|
||||
{
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
const H5D_t *dset = io_info->dset; /* Local pointer to dataset info */
|
||||
H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
|
||||
H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk);
|
||||
H5D_chk_idx_info_t idx_info; /* Chunked index info */
|
||||
H5D_chunk_it_ud2_t udata; /* User data for iteration callback */
|
||||
H5O_storage_chunk_t *sc;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(dset);
|
||||
HDassert(dset->shared);
|
||||
sc = &(dset->shared->layout.storage.u.chunk);
|
||||
H5D_CHUNK_STORAGE_INDEX_CHK(sc);
|
||||
HDassert(chunk_addr);
|
||||
|
||||
@@ -7254,9 +7454,10 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq, size_t *chunk_curr_seq,
|
||||
size_t chunk_len_arr[], hsize_t chunk_off_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
H5D__nonexistent_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[],
|
||||
hsize_t chunk_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
{
|
||||
H5D_chunk_readvv_ud_t udata; /* User data for H5VM_opvv() operator */
|
||||
ssize_t ret_value = -1; /* Return value */
|
||||
@@ -7273,8 +7474,8 @@ H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq, siz
|
||||
HDassert(mem_off_arr);
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.rbuf = (unsigned char *)io_info->u.rbuf;
|
||||
udata.dset = io_info->dset;
|
||||
udata.rbuf = (unsigned char *)dset_info->buf.vp;
|
||||
udata.dset = dset_info->dset;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value = H5VM_opvv(chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_off_arr, mem_max_nseq,
|
||||
|
||||
+40
-37
@@ -63,15 +63,16 @@ typedef struct H5D_compact_iovv_memmanage_ud_t {
|
||||
/* Layout operation callbacks */
|
||||
static herr_t H5D__compact_construct(H5F_t *f, H5D_t *dset);
|
||||
static hbool_t H5D__compact_is_space_alloc(const H5O_storage_t *storage);
|
||||
static herr_t H5D__compact_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static herr_t H5D__compact_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__compact_iovv_memmanage_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata);
|
||||
static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__compact_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_size_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__compact_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_size_arr[], hsize_t mem_offset_arr[]);
|
||||
static herr_t H5D__compact_flush(H5D_t *dset);
|
||||
static herr_t H5D__compact_dest(H5D_t *dset);
|
||||
|
||||
@@ -86,17 +87,14 @@ const H5D_layout_ops_t H5D_LOPS_COMPACT[1] = {{
|
||||
H5D__compact_is_space_alloc, /* is_space_alloc */
|
||||
NULL, /* is_data_cached */
|
||||
H5D__compact_io_init, /* io_init */
|
||||
NULL, /* mdio_init */
|
||||
H5D__contig_read, /* ser_read */
|
||||
H5D__contig_write, /* ser_write */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
NULL, /* par_read */
|
||||
NULL, /* par_write */
|
||||
#endif
|
||||
H5D__compact_readvv, /* readvv */
|
||||
H5D__compact_writevv, /* writevv */
|
||||
H5D__compact_flush, /* flush */
|
||||
NULL, /* io_term */
|
||||
H5D__compact_dest /* dest */
|
||||
H5D__compact_readvv, /* readvv */
|
||||
H5D__compact_writevv, /* writevv */
|
||||
H5D__compact_flush, /* flush */
|
||||
NULL, /* io_term */
|
||||
H5D__compact_dest /* dest */
|
||||
}};
|
||||
|
||||
/*******************/
|
||||
@@ -247,14 +245,15 @@ H5D__compact_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__compact_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
H5D__compact_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
io_info->store->compact.buf = io_info->dset->shared->layout.storage.u.compact.buf;
|
||||
io_info->store->compact.dirty = &io_info->dset->shared->layout.storage.u.compact.dirty;
|
||||
dinfo->store->compact.buf = dinfo->dset->shared->layout.storage.u.compact.buf;
|
||||
dinfo->store->compact.dirty = &dinfo->dset->shared->layout.storage.u.compact.dirty;
|
||||
|
||||
/* Disable selection I/O */
|
||||
io_info->use_select_io = FALSE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__compact_io_init() */
|
||||
@@ -320,15 +319,17 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
|
||||
H5D__compact_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
|
||||
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[],
|
||||
hsize_t mem_offset_arr[])
|
||||
{
|
||||
ssize_t ret_value = -1; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
|
||||
/* Check if file driver wishes to do its own memory management */
|
||||
if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
|
||||
@@ -336,8 +337,8 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
|
||||
|
||||
/* Set up udata for memory copy operation */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dstbuf = io_info->u.rbuf;
|
||||
udata.srcbuf = io_info->store->compact.buf;
|
||||
udata.dstbuf = dset_info->buf.vp;
|
||||
udata.srcbuf = dset_info->store->compact.buf;
|
||||
|
||||
/* Request that file driver does the memory copy */
|
||||
if ((ret_value = H5VM_opvv(mem_max_nseq, mem_curr_seq, mem_size_arr, mem_offset_arr, dset_max_nseq,
|
||||
@@ -347,8 +348,8 @@ H5D__compact_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
|
||||
}
|
||||
else {
|
||||
/* Use the vectorized memory copy routine to do actual work */
|
||||
if ((ret_value = H5VM_memcpyvv(io_info->u.rbuf, mem_max_nseq, mem_curr_seq, mem_size_arr,
|
||||
mem_offset_arr, io_info->store->compact.buf, dset_max_nseq,
|
||||
if ((ret_value = H5VM_memcpyvv(dset_info->buf.vp, mem_max_nseq, mem_curr_seq, mem_size_arr,
|
||||
mem_offset_arr, dset_info->store->compact.buf, dset_max_nseq,
|
||||
dset_curr_seq, dset_size_arr, dset_offset_arr)) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
|
||||
}
|
||||
@@ -379,15 +380,17 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_size_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[])
|
||||
H5D__compact_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
|
||||
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[],
|
||||
hsize_t mem_offset_arr[])
|
||||
{
|
||||
ssize_t ret_value = -1; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
|
||||
/* Check if file driver wishes to do its own memory management */
|
||||
if (H5F_SHARED_HAS_FEATURE(io_info->f_sh, H5FD_FEAT_MEMMANAGE)) {
|
||||
@@ -395,8 +398,8 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t
|
||||
|
||||
/* Set up udata for memory copy operation */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dstbuf = io_info->store->compact.buf;
|
||||
udata.srcbuf = io_info->u.wbuf;
|
||||
udata.dstbuf = dset_info->store->compact.buf;
|
||||
udata.srcbuf = dset_info->buf.cvp;
|
||||
|
||||
/* Request that file driver does the memory copy */
|
||||
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_size_arr, dset_offset_arr, mem_max_nseq,
|
||||
@@ -406,14 +409,14 @@ H5D__compact_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t
|
||||
}
|
||||
else {
|
||||
/* Use the vectorized memory copy routine to do actual work */
|
||||
if ((ret_value = H5VM_memcpyvv(io_info->store->compact.buf, dset_max_nseq, dset_curr_seq,
|
||||
dset_size_arr, dset_offset_arr, io_info->u.wbuf, mem_max_nseq,
|
||||
if ((ret_value = H5VM_memcpyvv(dset_info->store->compact.buf, dset_max_nseq, dset_curr_seq,
|
||||
dset_size_arr, dset_offset_arr, dset_info->buf.cvp, mem_max_nseq,
|
||||
mem_curr_seq, mem_size_arr, mem_offset_arr)) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed")
|
||||
}
|
||||
|
||||
/* Mark the compact dataset's buffer as dirty */
|
||||
*io_info->store->compact.dirty = TRUE;
|
||||
*dset_info->store->compact.dirty = TRUE;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
||||
+320
-102
@@ -91,19 +91,24 @@ typedef struct H5D_contig_writevv_ud_t {
|
||||
/* Layout operation callbacks */
|
||||
static herr_t H5D__contig_construct(H5F_t *f, H5D_t *dset);
|
||||
static herr_t H5D__contig_init(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static ssize_t H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static herr_t H5D__contig_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__contig_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static ssize_t H5D__contig_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dinfo,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__contig_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dinfo,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static herr_t H5D__contig_flush(H5D_t *dset);
|
||||
static herr_t H5D__contig_io_term(H5D_io_info_t *io_info, H5D_dset_io_info_t *di);
|
||||
|
||||
/* Helper routines */
|
||||
static herr_t H5D__contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size_t size);
|
||||
static htri_t H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, H5D_io_op_type_t op_type);
|
||||
static herr_t H5D__contig_write_one(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, hsize_t offset,
|
||||
size_t size);
|
||||
static htri_t H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
H5D_io_op_type_t op_type);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -116,17 +121,14 @@ const H5D_layout_ops_t H5D_LOPS_CONTIG[1] = {{
|
||||
H5D__contig_is_space_alloc, /* is_space_alloc */
|
||||
H5D__contig_is_data_cached, /* is_data_cached */
|
||||
H5D__contig_io_init, /* io_init */
|
||||
H5D__contig_mdio_init, /* mdio_init */
|
||||
H5D__contig_read, /* ser_read */
|
||||
H5D__contig_write, /* ser_write */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5D__contig_collective_read, /* par_read */
|
||||
H5D__contig_collective_write, /* par_write */
|
||||
#endif
|
||||
H5D__contig_readvv, /* readvv */
|
||||
H5D__contig_writevv, /* writevv */
|
||||
H5D__contig_flush, /* flush */
|
||||
NULL, /* io_term */
|
||||
NULL /* dest */
|
||||
H5D__contig_readvv, /* readvv */
|
||||
H5D__contig_writevv, /* writevv */
|
||||
H5D__contig_flush, /* flush */
|
||||
H5D__contig_io_term, /* io_term */
|
||||
NULL /* dest */
|
||||
}};
|
||||
|
||||
/*******************/
|
||||
@@ -139,6 +141,9 @@ H5FL_BLK_DEFINE(sieve_buf);
|
||||
/* Declare extern the free list to manage blocks of type conversion data */
|
||||
H5FL_BLK_EXTERN(type_conv);
|
||||
|
||||
/* Declare extern the free list to manage the H5D_piece_info_t struct */
|
||||
H5FL_EXTERN(H5D_piece_info_t);
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_alloc
|
||||
*
|
||||
@@ -183,15 +188,15 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__contig_fill(const H5D_io_info_t *io_info)
|
||||
H5D__contig_fill(H5D_t *dset)
|
||||
{
|
||||
const H5D_t *dset = io_info->dset; /* the dataset pointer */
|
||||
H5D_io_info_t ioinfo; /* Dataset I/O info */
|
||||
H5D_storage_t store; /* Union of storage info for dataset */
|
||||
hssize_t snpoints; /* Number of points in space (for error checking) */
|
||||
size_t npoints; /* Number of points in space */
|
||||
hsize_t offset; /* Offset of dataset */
|
||||
size_t max_temp_buf; /* Maximum size of temporary buffer */
|
||||
H5D_io_info_t ioinfo; /* Dataset I/O info */
|
||||
H5D_dset_io_info_t dset_info; /* Dset info */
|
||||
H5D_storage_t store; /* Union of storage info for dataset */
|
||||
hssize_t snpoints; /* Number of points in space (for error checking) */
|
||||
size_t npoints; /* Number of points in space */
|
||||
hsize_t offset; /* Offset of dataset */
|
||||
size_t max_temp_buf; /* Maximum size of temporary buffer */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
MPI_Comm mpi_comm = MPI_COMM_NULL; /* MPI communicator for file */
|
||||
int mpi_rank = (-1); /* This process's rank */
|
||||
@@ -252,7 +257,14 @@ H5D__contig_fill(const H5D_io_info_t *io_info)
|
||||
offset = 0;
|
||||
|
||||
/* Simple setup for dataset I/O info struct */
|
||||
H5D_BUILD_IO_INFO_WRT(&ioinfo, dset, &store, fb_info.fill_buf);
|
||||
ioinfo.op_type = H5D_IO_OP_WRITE;
|
||||
|
||||
dset_info.dset = (H5D_t *)dset;
|
||||
dset_info.store = &store;
|
||||
dset_info.buf.cvp = fb_info.fill_buf;
|
||||
dset_info.mem_space = NULL;
|
||||
ioinfo.dsets_info = &dset_info;
|
||||
ioinfo.f_sh = H5F_SHARED(dset->oloc.file);
|
||||
|
||||
/*
|
||||
* Fill the entire current extent with the fill value. We can do
|
||||
@@ -281,7 +293,7 @@ H5D__contig_fill(const H5D_io_info_t *io_info)
|
||||
/* Write the chunks out from only one process */
|
||||
/* !! Use the internal "independent" DXPL!! -QAK */
|
||||
if (H5_PAR_META_WRITE == mpi_rank) {
|
||||
if (H5D__contig_write_one(&ioinfo, offset, size) < 0) {
|
||||
if (H5D__contig_write_one(&ioinfo, &dset_info, offset, size) < 0) {
|
||||
/* If writing fails, push an error and stop writing, but
|
||||
* still participate in following MPI_Barrier.
|
||||
*/
|
||||
@@ -297,7 +309,7 @@ H5D__contig_fill(const H5D_io_info_t *io_info)
|
||||
else {
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5_CHECK_OVERFLOW(size, size_t, hsize_t);
|
||||
if (H5D__contig_write_one(&ioinfo, offset, size) < 0)
|
||||
if (H5D__contig_write_one(&ioinfo, &dset_info, offset, size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset")
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
} /* end else */
|
||||
@@ -562,32 +574,159 @@ H5D__contig_is_data_cached(const H5D_shared_t *shared_dset)
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, March 20, 2008
|
||||
* Programmer: Jonathan Kim
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__contig_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
H5D_t *dataset = dinfo->dset; /* Local pointer to dataset info */
|
||||
|
||||
hssize_t old_offset[H5O_LAYOUT_NDIMS]; /* Old selection offset */
|
||||
htri_t file_space_normalized = FALSE; /* File dataspace was normalized */
|
||||
|
||||
int sf_ndims; /* The number of dimensions of the file dataspace (signed) */
|
||||
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
dinfo->store->contig.dset_addr = dataset->shared->layout.storage.u.contig.addr;
|
||||
dinfo->store->contig.dset_size = dataset->shared->layout.storage.u.contig.size;
|
||||
|
||||
/* Initialize piece info */
|
||||
dinfo->layout_io_info.contig_piece_info = NULL;
|
||||
|
||||
/* Get layout for dataset */
|
||||
dinfo->layout = &(dataset->shared->layout);
|
||||
|
||||
/* Get dim number and dimensionality for each dataspace */
|
||||
if ((sf_ndims = H5S_GET_EXTENT_NDIMS(dinfo->file_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number")
|
||||
|
||||
/* Normalize hyperslab selections by adjusting them by the offset */
|
||||
/* (It might be worthwhile to normalize both the file and memory dataspaces
|
||||
* before any (contiguous, chunked, etc) file I/O operation, in order to
|
||||
* speed up hyperslab calculations by removing the extra checks and/or
|
||||
* additions involving the offset and the hyperslab selection -QAK)
|
||||
*/
|
||||
if ((file_space_normalized = H5S_hyper_normalize_offset(dinfo->file_space, old_offset)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset")
|
||||
|
||||
/* if selected elements exist */
|
||||
if (dinfo->nelmts) {
|
||||
int u;
|
||||
H5D_piece_info_t *new_piece_info; /* piece information to insert into skip list */
|
||||
|
||||
/* Get copy of dset file_space, so it can be changed temporarily
|
||||
* purpose
|
||||
* This tmp_fspace allows multiple write before close dset */
|
||||
H5S_t *tmp_fspace; /* Temporary file dataspace */
|
||||
|
||||
/* Create "temporary" chunk for selection operations (copy file space) */
|
||||
if (NULL == (tmp_fspace = H5S_copy(dinfo->file_space, TRUE, FALSE)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
|
||||
|
||||
/* Add temporary chunk to the list of pieces */
|
||||
/* collect piece_info into Skip List */
|
||||
/* Allocate the file & memory chunk information */
|
||||
if (NULL == (new_piece_info = H5FL_MALLOC(H5D_piece_info_t))) {
|
||||
(void)H5S_close(tmp_fspace);
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate chunk info")
|
||||
} /* end if */
|
||||
|
||||
/* Set the piece index */
|
||||
new_piece_info->index = 0;
|
||||
|
||||
/* Set the file chunk dataspace */
|
||||
new_piece_info->fspace = tmp_fspace;
|
||||
new_piece_info->fspace_shared = FALSE;
|
||||
|
||||
/* Set the memory chunk dataspace */
|
||||
/* same as one chunk, just use dset mem space */
|
||||
new_piece_info->mspace = dinfo->mem_space;
|
||||
|
||||
/* set true for sharing mem space with dset, which means
|
||||
* fspace gets free by application H5Sclose(), and
|
||||
* doesn't require providing layout_ops.io_term() for H5D_LOPS_CONTIG.
|
||||
*/
|
||||
new_piece_info->mspace_shared = TRUE;
|
||||
|
||||
/* Set the number of points */
|
||||
new_piece_info->piece_points = dinfo->nelmts;
|
||||
|
||||
/* Copy the piece's coordinates */
|
||||
for (u = 0; u < sf_ndims; u++)
|
||||
new_piece_info->scaled[u] = 0;
|
||||
new_piece_info->scaled[sf_ndims] = 0;
|
||||
|
||||
/* make connection to related dset info from this piece_info */
|
||||
new_piece_info->dset_info = dinfo;
|
||||
|
||||
/* get dset file address for piece */
|
||||
new_piece_info->faddr = dinfo->dset->shared->layout.storage.u.contig.addr;
|
||||
|
||||
/* Save piece to dataset info struct so it is freed at the end of the
|
||||
* operation */
|
||||
dinfo->layout_io_info.contig_piece_info = new_piece_info;
|
||||
|
||||
/* Add piece to piece_count */
|
||||
io_info->piece_count++;
|
||||
} /* end if */
|
||||
|
||||
/* Check if we're performing selection I/O if it hasn't been disabled
|
||||
* already */
|
||||
if (io_info->use_select_io) {
|
||||
if ((use_selection_io = H5D__contig_may_use_select_io(io_info, dinfo, H5D_IO_OP_READ)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ret_value < 0) {
|
||||
if (H5D__contig_io_term(io_info, dinfo) < 0)
|
||||
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataset I/O info")
|
||||
} /* end if */
|
||||
|
||||
if (file_space_normalized) {
|
||||
/* (Casting away const OK -QAK) */
|
||||
if (H5S_hyper_denormalize_offset(dinfo->file_space, old_offset) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_BADSELECT, FAIL, "unable to normalize dataspace by offset")
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_io_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_mdio_init
|
||||
*
|
||||
* Purpose: Performs second phase of initialization for multi-dataset
|
||||
* I/O. Currently just adds data block to sel_pieces.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__contig_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
H5D__contig_mdio_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
htri_t use_selection_io = FALSE; /* Whether to use selection I/O */
|
||||
htri_t ret_value = SUCCEED; /* Return value */
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
/* Add piece if it exists */
|
||||
if (dinfo->layout_io_info.contig_piece_info) {
|
||||
HDassert(io_info->sel_pieces);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
io_info->store->contig.dset_addr = io_info->dset->shared->layout.storage.u.contig.addr;
|
||||
io_info->store->contig.dset_size = io_info->dset->shared->layout.storage.u.contig.size;
|
||||
/* Add contiguous data block to sel_pieces */
|
||||
io_info->sel_pieces[io_info->pieces_added] = dinfo->layout_io_info.contig_piece_info;
|
||||
|
||||
/* Check if we're performing selection I/O */
|
||||
if ((use_selection_io = H5D__contig_may_use_select_io(io_info, H5D_IO_OP_READ)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check if selection I/O is possible")
|
||||
io_info->use_select_io = (hbool_t)use_selection_io;
|
||||
/* Update pieces_added */
|
||||
io_info->pieces_added++;
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_io_init() */
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__contig_mdio_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_may_use_select_io
|
||||
@@ -603,7 +742,8 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static htri_t
|
||||
H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, H5D_io_op_type_t op_type)
|
||||
H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
H5D_io_op_type_t op_type)
|
||||
{
|
||||
const H5D_t *dataset = NULL; /* Local pointer to dataset info */
|
||||
htri_t ret_value = FAIL; /* Return value */
|
||||
@@ -612,24 +752,25 @@ H5D__contig_may_use_select_io(const H5D_io_info_t *io_info, H5D_io_op_type_t op_
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->dset);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->dset);
|
||||
HDassert(op_type == H5D_IO_OP_READ || op_type == H5D_IO_OP_WRITE);
|
||||
|
||||
dataset = io_info->dset;
|
||||
dataset = dset_info->dset;
|
||||
|
||||
/* Don't use selection I/O if it's globally disabled, if there is a type
|
||||
* conversion, or if it's not a contiguous dataset, or if the sieve buffer
|
||||
* exists (write) or is dirty (read) */
|
||||
if (!H5_use_selection_io_g || io_info->io_ops.single_read != H5D__select_read ||
|
||||
io_info->layout_ops.readvv != H5D__contig_readvv ||
|
||||
if (dset_info->io_ops.single_read != H5D__select_read ||
|
||||
dset_info->layout_ops.readvv != H5D__contig_readvv ||
|
||||
(op_type == H5D_IO_OP_READ && dataset->shared->cache.contig.sieve_dirty) ||
|
||||
(op_type == H5D_IO_OP_WRITE && dataset->shared->cache.contig.sieve_buf))
|
||||
ret_value = FALSE;
|
||||
else {
|
||||
hbool_t page_buf_enabled;
|
||||
|
||||
HDassert(io_info->io_ops.single_write == H5D__select_write);
|
||||
HDassert(io_info->layout_ops.writevv == H5D__contig_writevv);
|
||||
HDassert(dset_info->io_ops.single_write == H5D__select_write);
|
||||
HDassert(dset_info->layout_ops.writevv == H5D__contig_writevv);
|
||||
|
||||
/* Check if the page buffer is enabled */
|
||||
if (H5PB_enabled(io_info->f_sh, H5FD_MEM_DRAW, &page_buf_enabled) < 0)
|
||||
@@ -657,8 +798,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
H5D__contig_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -666,25 +806,49 @@ H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.rbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(dinfo);
|
||||
HDassert(dinfo->buf.vp);
|
||||
HDassert(dinfo->mem_space);
|
||||
HDassert(dinfo->file_space);
|
||||
|
||||
if (io_info->use_select_io) {
|
||||
size_t dst_type_size = type_info->dst_type_size;
|
||||
/* Only perform I/O if not performing multi dataset I/O with selection
|
||||
* I/O, otherwise the higher level will handle it after all datasets
|
||||
* have been processed */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
size_t dst_type_size = dinfo->type_info.dst_type_size;
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_read(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, nelmts > 0 ? 1 : 0,
|
||||
&mem_space, &file_space, &(io_info->store->contig.dset_addr),
|
||||
&dst_type_size, &(io_info->u.rbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "contiguous selection read failed")
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_read(H5F_SHARED(dinfo->dset->oloc.file), H5FD_MEM_DRAW,
|
||||
dinfo->nelmts > 0 ? 1 : 0, &dinfo->mem_space, &dinfo->file_space,
|
||||
&(dinfo->store->contig.dset_addr), &dst_type_size,
|
||||
&(dinfo->buf.vp)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "contiguous selection read failed")
|
||||
}
|
||||
else {
|
||||
if (dinfo->layout_io_info.contig_piece_info) {
|
||||
/* Add to mdset selection I/O arrays */
|
||||
HDassert(io_info->mem_spaces);
|
||||
HDassert(io_info->file_spaces);
|
||||
HDassert(io_info->addrs);
|
||||
HDassert(io_info->element_sizes);
|
||||
HDassert(io_info->rbufs);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
io_info->mem_spaces[io_info->pieces_added] = dinfo->mem_space;
|
||||
io_info->file_spaces[io_info->pieces_added] = dinfo->file_space;
|
||||
io_info->addrs[io_info->pieces_added] = dinfo->store->contig.dset_addr;
|
||||
io_info->element_sizes[io_info->pieces_added] = dinfo->type_info.src_type_size;
|
||||
io_info->rbufs[io_info->pieces_added] = dinfo->buf.vp;
|
||||
io_info->pieces_added++;
|
||||
}
|
||||
}
|
||||
} /* end if */
|
||||
else
|
||||
/* Read data through legacy (non-selection I/O) pathway */
|
||||
if ((io_info->io_ops.single_read)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
if ((dinfo->io_ops.single_read)(io_info, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "contiguous read failed")
|
||||
|
||||
done:
|
||||
@@ -704,8 +868,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
H5D__contig_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -713,25 +876,49 @@ H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.wbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(dinfo);
|
||||
HDassert(dinfo->buf.cvp);
|
||||
HDassert(dinfo->mem_space);
|
||||
HDassert(dinfo->file_space);
|
||||
|
||||
if (io_info->use_select_io) {
|
||||
size_t dst_type_size = type_info->dst_type_size;
|
||||
/* Only perform I/O if not performing multi dataset I/O with selection
|
||||
* I/O, otherwise the higher level will handle it after all datasets
|
||||
* have been processed */
|
||||
if (H5D_LAYOUT_CB_PERFORM_IO(io_info)) {
|
||||
size_t dst_type_size = dinfo->type_info.dst_type_size;
|
||||
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_write(H5F_SHARED(io_info->dset->oloc.file), H5FD_MEM_DRAW, nelmts > 0 ? 1 : 0,
|
||||
&mem_space, &file_space, &(io_info->store->contig.dset_addr),
|
||||
&dst_type_size, &(io_info->u.wbuf)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "contiguous selection write failed")
|
||||
/* Issue selection I/O call (we can skip the page buffer because we've
|
||||
* already verified it won't be used, and the metadata accumulator
|
||||
* because this is raw data) */
|
||||
if (H5F_shared_select_write(H5F_SHARED(dinfo->dset->oloc.file), H5FD_MEM_DRAW,
|
||||
dinfo->nelmts > 0 ? 1 : 0, &dinfo->mem_space, &dinfo->file_space,
|
||||
&(dinfo->store->contig.dset_addr), &dst_type_size,
|
||||
&(dinfo->buf.cvp)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "contiguous selection write failed")
|
||||
}
|
||||
else {
|
||||
if (dinfo->layout_io_info.contig_piece_info) {
|
||||
/* Add to mdset selection I/O arrays */
|
||||
HDassert(io_info->mem_spaces);
|
||||
HDassert(io_info->file_spaces);
|
||||
HDassert(io_info->addrs);
|
||||
HDassert(io_info->element_sizes);
|
||||
HDassert(io_info->wbufs);
|
||||
HDassert(io_info->pieces_added < io_info->piece_count);
|
||||
|
||||
io_info->mem_spaces[io_info->pieces_added] = dinfo->mem_space;
|
||||
io_info->file_spaces[io_info->pieces_added] = dinfo->file_space;
|
||||
io_info->addrs[io_info->pieces_added] = dinfo->store->contig.dset_addr;
|
||||
io_info->element_sizes[io_info->pieces_added] = dinfo->type_info.dst_type_size;
|
||||
io_info->wbufs[io_info->pieces_added] = dinfo->buf.cvp;
|
||||
io_info->pieces_added++;
|
||||
}
|
||||
}
|
||||
} /* end if */
|
||||
else
|
||||
/* Write data through legacy (non-selection I/O) pathway */
|
||||
if ((io_info->io_ops.single_write)(io_info, type_info, nelmts, file_space, mem_space) < 0)
|
||||
if ((dinfo->io_ops.single_write)(io_info, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "contiguous write failed")
|
||||
|
||||
done:
|
||||
@@ -753,7 +940,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size_t size)
|
||||
H5D__contig_write_one(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, hsize_t offset, size_t size)
|
||||
{
|
||||
hsize_t dset_off = offset; /* Offset in dataset */
|
||||
size_t dset_len = size; /* Length in dataset */
|
||||
@@ -767,7 +954,7 @@ H5D__contig_write_one(H5D_io_info_t *io_info, hsize_t offset, size_t size)
|
||||
|
||||
HDassert(io_info);
|
||||
|
||||
if (H5D__contig_writevv(io_info, (size_t)1, &dset_curr_seq, &dset_len, &dset_off, (size_t)1,
|
||||
if (H5D__contig_writevv(io_info, dset_info, (size_t)1, &dset_curr_seq, &dset_len, &dset_off, (size_t)1,
|
||||
&mem_curr_seq, &mem_len, &mem_off) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed")
|
||||
|
||||
@@ -990,9 +1177,9 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
H5D__contig_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
{
|
||||
ssize_t ret_value = -1; /* Return value */
|
||||
|
||||
@@ -1000,6 +1187,7 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *d
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_curr_seq);
|
||||
HDassert(dset_len_arr);
|
||||
HDassert(dset_off_arr);
|
||||
@@ -1013,9 +1201,9 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *d
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dset_contig = &(io_info->dset->shared->cache.contig);
|
||||
udata.store_contig = &(io_info->store->contig);
|
||||
udata.rbuf = (unsigned char *)io_info->u.rbuf;
|
||||
udata.dset_contig = &(dset_info->dset->shared->cache.contig);
|
||||
udata.store_contig = &(dset_info->store->contig);
|
||||
udata.rbuf = (unsigned char *)dset_info->buf.vp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value =
|
||||
@@ -1028,8 +1216,8 @@ H5D__contig_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *d
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dset_addr = io_info->store->contig.dset_addr;
|
||||
udata.rbuf = (unsigned char *)io_info->u.rbuf;
|
||||
udata.dset_addr = dset_info->store->contig.dset_addr;
|
||||
udata.rbuf = (unsigned char *)dset_info->buf.vp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, mem_max_nseq,
|
||||
@@ -1308,9 +1496,9 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
H5D__contig_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
{
|
||||
ssize_t ret_value = -1; /* Return value (Size of sequence in bytes) */
|
||||
|
||||
@@ -1318,6 +1506,7 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_curr_seq);
|
||||
HDassert(dset_len_arr);
|
||||
HDassert(dset_off_arr);
|
||||
@@ -1331,9 +1520,9 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dset_contig = &(io_info->dset->shared->cache.contig);
|
||||
udata.store_contig = &(io_info->store->contig);
|
||||
udata.wbuf = (const unsigned char *)io_info->u.wbuf;
|
||||
udata.dset_contig = &(dset_info->dset->shared->cache.contig);
|
||||
udata.store_contig = &(dset_info->store->contig);
|
||||
udata.wbuf = (const unsigned char *)dset_info->buf.cvp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value =
|
||||
@@ -1346,8 +1535,8 @@ H5D__contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.f_sh = io_info->f_sh;
|
||||
udata.dset_addr = io_info->store->contig.dset_addr;
|
||||
udata.wbuf = (const unsigned char *)io_info->u.wbuf;
|
||||
udata.dset_addr = dset_info->store->contig.dset_addr;
|
||||
udata.wbuf = (const unsigned char *)dset_info->buf.cvp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, mem_max_nseq,
|
||||
@@ -1390,6 +1579,35 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_flush() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_io_term
|
||||
*
|
||||
* Purpose: Destroy I/O operation information.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__contig_io_term(H5D_io_info_t H5_ATTR_UNUSED *io_info, H5D_dset_io_info_t *di)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /*return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(di);
|
||||
|
||||
/* Free piece info */
|
||||
if (di->layout_io_info.contig_piece_info) {
|
||||
if (H5D__free_piece_info(di->layout_io_info.contig_piece_info, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't free piece info")
|
||||
di->layout_io_info.contig_piece_info = NULL;
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_io_term() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_copy
|
||||
*
|
||||
|
||||
+42
-41
@@ -61,14 +61,15 @@ typedef struct H5D_efl_writevv_ud_t {
|
||||
|
||||
/* Layout operation callbacks */
|
||||
static herr_t H5D__efl_construct(H5F_t *f, H5D_t *dset);
|
||||
static herr_t H5D__efl_io_init(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *cm);
|
||||
static ssize_t H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__efl_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static herr_t H5D__efl_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static ssize_t H5D__efl_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
static ssize_t H5D__efl_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_offset_arr[]);
|
||||
|
||||
/* Helper routines */
|
||||
static herr_t H5D__efl_read(const H5O_efl_t *efl, const H5D_t *dset, haddr_t addr, size_t size, uint8_t *buf);
|
||||
@@ -86,17 +87,14 @@ const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
|
||||
H5D__efl_is_space_alloc, /* is_space_alloc */
|
||||
NULL, /* is_data_cached */
|
||||
H5D__efl_io_init, /* io_init */
|
||||
NULL, /* mdio_init */
|
||||
H5D__contig_read, /* ser_read */
|
||||
H5D__contig_write, /* ser_write */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
NULL, /* par_read */
|
||||
NULL, /* par_write */
|
||||
#endif
|
||||
H5D__efl_readvv, /* readvv */
|
||||
H5D__efl_writevv, /* writevv */
|
||||
NULL, /* flush */
|
||||
NULL, /* io_term */
|
||||
NULL /* dest */
|
||||
H5D__efl_readvv, /* readvv */
|
||||
H5D__efl_writevv, /* writevv */
|
||||
NULL, /* flush */
|
||||
NULL, /* io_term */
|
||||
NULL /* dest */
|
||||
}};
|
||||
|
||||
/*******************/
|
||||
@@ -209,13 +207,14 @@ H5D__efl_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__efl_io_init(H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *cm)
|
||||
H5D__efl_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
H5MM_memcpy(&io_info->store->efl, &(io_info->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t));
|
||||
H5MM_memcpy(&dinfo->store->efl, &(dinfo->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t));
|
||||
|
||||
/* Disable selection I/O */
|
||||
io_info->use_select_io = FALSE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__efl_io_init() */
|
||||
@@ -443,9 +442,9 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
H5D__efl_readvv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
{
|
||||
H5D_efl_readvv_ud_t udata; /* User data for H5VM_opvv() operator */
|
||||
ssize_t ret_value = -1; /* Return value (Total size of sequence in bytes) */
|
||||
@@ -454,10 +453,11 @@ H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->store->efl.nused > 0);
|
||||
HDassert(io_info->u.rbuf);
|
||||
HDassert(io_info->dset);
|
||||
HDassert(io_info->dset->shared);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->store->efl.nused > 0);
|
||||
HDassert(dset_info->buf.vp);
|
||||
HDassert(dset_info->dset);
|
||||
HDassert(dset_info->dset->shared);
|
||||
HDassert(dset_curr_seq);
|
||||
HDassert(dset_len_arr);
|
||||
HDassert(dset_off_arr);
|
||||
@@ -466,9 +466,9 @@ H5D__efl_readvv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset
|
||||
HDassert(mem_off_arr);
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.efl = &(io_info->store->efl);
|
||||
udata.dset = io_info->dset;
|
||||
udata.rbuf = (unsigned char *)io_info->u.rbuf;
|
||||
udata.efl = &(dset_info->store->efl);
|
||||
udata.dset = dset_info->dset;
|
||||
udata.rbuf = (unsigned char *)dset_info->buf.vp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, mem_max_nseq,
|
||||
@@ -523,9 +523,9 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static ssize_t
|
||||
H5D__efl_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq,
|
||||
size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq, size_t *mem_curr_seq,
|
||||
size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
H5D__efl_writevv(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
|
||||
{
|
||||
H5D_efl_writevv_ud_t udata; /* User data for H5VM_opvv() operator */
|
||||
ssize_t ret_value = -1; /* Return value (Total size of sequence in bytes) */
|
||||
@@ -534,10 +534,11 @@ H5D__efl_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dse
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->store->efl.nused > 0);
|
||||
HDassert(io_info->u.wbuf);
|
||||
HDassert(io_info->dset);
|
||||
HDassert(io_info->dset->shared);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->store->efl.nused > 0);
|
||||
HDassert(dset_info->buf.cvp);
|
||||
HDassert(dset_info->dset);
|
||||
HDassert(dset_info->dset->shared);
|
||||
HDassert(dset_curr_seq);
|
||||
HDassert(dset_len_arr);
|
||||
HDassert(dset_off_arr);
|
||||
@@ -546,9 +547,9 @@ H5D__efl_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dse
|
||||
HDassert(mem_off_arr);
|
||||
|
||||
/* Set up user data for H5VM_opvv() */
|
||||
udata.efl = &(io_info->store->efl);
|
||||
udata.dset = io_info->dset;
|
||||
udata.wbuf = (const unsigned char *)io_info->u.wbuf;
|
||||
udata.efl = &(dset_info->store->efl);
|
||||
udata.dset = dset_info->dset;
|
||||
udata.wbuf = (const unsigned char *)dset_info->buf.cvp;
|
||||
|
||||
/* Call generic sequence operation routine */
|
||||
if ((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr, mem_max_nseq,
|
||||
|
||||
+42
-45
@@ -61,7 +61,7 @@ typedef struct {
|
||||
/* Internal data structure for computing variable-length dataset's total size */
|
||||
/* (Used for generic 'get vlen buf size' operation) */
|
||||
typedef struct {
|
||||
H5VL_object_t *dset_vol_obj; /* VOL object for the dataset */
|
||||
const H5VL_object_t *dset_vol_obj; /* VOL object for the dataset */
|
||||
hid_t fspace_id; /* Dataset dataspace ID of the dataset we are working on */
|
||||
H5S_t *fspace; /* Dataset's dataspace for operation */
|
||||
hid_t mspace_id; /* Memory dataspace ID of the dataset we are working on */
|
||||
@@ -81,7 +81,7 @@ static herr_t H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t
|
||||
static herr_t H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__build_file_prefix(const H5D_t *dset, H5F_prefix_open_t prefix_type, char **file_prefix);
|
||||
static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id);
|
||||
static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]);
|
||||
static herr_t H5D__init_storage(H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[]);
|
||||
static herr_t H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id);
|
||||
static herr_t H5D__close_cb(H5VL_object_t *dset_vol_obj, void **request);
|
||||
static herr_t H5D__use_minimized_dset_headers(H5F_t *file, hbool_t *minimize);
|
||||
@@ -119,8 +119,8 @@ H5FL_DEFINE_STATIC(H5D_shared_t);
|
||||
/* Declare the external PQ free list for the sieve buffer information */
|
||||
H5FL_BLK_EXTERN(sieve_buf);
|
||||
|
||||
/* Declare the external free list to manage the H5D_chunk_info_t struct */
|
||||
H5FL_EXTERN(H5D_chunk_info_t);
|
||||
/* Declare the external free list to manage the H5D_piece_info_t struct */
|
||||
H5FL_EXTERN(H5D_piece_info_t);
|
||||
|
||||
/* Declare extern the free list to manage blocks of type conversion data */
|
||||
H5FL_BLK_EXTERN(type_conv);
|
||||
@@ -1793,14 +1793,9 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id)
|
||||
*/
|
||||
if ((H5F_INTENT(dataset->oloc.file) & H5F_ACC_RDWR) &&
|
||||
!(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) &&
|
||||
H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_ALLOCATE_EARLY)) {
|
||||
H5D_io_info_t io_info;
|
||||
|
||||
io_info.dset = dataset;
|
||||
|
||||
if (H5D__alloc_storage(&io_info, H5D_ALLOC_OPEN, FALSE, NULL) < 0)
|
||||
H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_ALLOCATE_EARLY))
|
||||
if (H5D__alloc_storage(dataset, H5D_ALLOC_OPEN, FALSE, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
if (ret_value < 0) {
|
||||
@@ -1894,10 +1889,10 @@ H5D_close(H5D_t *dataset)
|
||||
} /* end if */
|
||||
|
||||
/* Check for cached single element chunk info */
|
||||
if (dataset->shared->cache.chunk.single_chunk_info) {
|
||||
dataset->shared->cache.chunk.single_chunk_info =
|
||||
H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info);
|
||||
dataset->shared->cache.chunk.single_chunk_info = NULL;
|
||||
if (dataset->shared->cache.chunk.single_piece_info) {
|
||||
dataset->shared->cache.chunk.single_piece_info =
|
||||
H5FL_FREE(H5D_piece_info_t, dataset->shared->cache.chunk.single_piece_info);
|
||||
dataset->shared->cache.chunk.single_piece_info = NULL;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
@@ -2088,10 +2083,10 @@ H5D_mult_refresh_close(hid_t dset_id)
|
||||
} /* end if */
|
||||
|
||||
/* Check for cached single element chunk info */
|
||||
if (dataset->shared->cache.chunk.single_chunk_info) {
|
||||
dataset->shared->cache.chunk.single_chunk_info =
|
||||
H5FL_FREE(H5D_chunk_info_t, dataset->shared->cache.chunk.single_chunk_info);
|
||||
dataset->shared->cache.chunk.single_chunk_info = NULL;
|
||||
if (dataset->shared->cache.chunk.single_piece_info) {
|
||||
dataset->shared->cache.chunk.single_piece_info =
|
||||
H5FL_FREE(H5D_piece_info_t, dataset->shared->cache.chunk.single_piece_info);
|
||||
dataset->shared->cache.chunk.single_piece_info = NULL;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
@@ -2209,11 +2204,9 @@ H5D_nameof(H5D_t *dataset)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t time_alloc, hbool_t full_overwrite,
|
||||
hsize_t old_dim[])
|
||||
H5D__alloc_storage(H5D_t *dset, H5D_time_alloc_t time_alloc, hbool_t full_overwrite, hsize_t old_dim[])
|
||||
{
|
||||
const H5D_t *dset = io_info->dset; /* The dataset object */
|
||||
H5F_t *f = dset->oloc.file; /* The dataset's file pointer */
|
||||
H5F_t *f; /* The dataset's file pointer */
|
||||
H5O_layout_t *layout; /* The dataset's layout information */
|
||||
hbool_t must_init_space = FALSE; /* Flag to indicate that space should be initialized */
|
||||
hbool_t addr_set = FALSE; /* Flag to indicate that the dataset's storage address was set */
|
||||
@@ -2223,6 +2216,7 @@ H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t time_alloc, hb
|
||||
|
||||
/* check args */
|
||||
HDassert(dset);
|
||||
f = dset->oloc.file;
|
||||
HDassert(f);
|
||||
|
||||
/* If the data is stored in external files, don't set an address for the layout
|
||||
@@ -2333,7 +2327,7 @@ H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t time_alloc, hb
|
||||
*/
|
||||
if (!(dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR &&
|
||||
time_alloc == H5D_ALLOC_WRITE))
|
||||
if (H5D__init_storage(io_info, full_overwrite, old_dim) < 0)
|
||||
if (H5D__init_storage(dset, full_overwrite, old_dim) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"unable to initialize dataset with fill value")
|
||||
} /* end if */
|
||||
@@ -2349,7 +2343,7 @@ H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t time_alloc, hb
|
||||
if (dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC ||
|
||||
(dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET &&
|
||||
fill_status == H5D_FILL_VALUE_USER_DEFINED))
|
||||
if (H5D__init_storage(io_info, full_overwrite, old_dim) < 0)
|
||||
if (H5D__init_storage(dset, full_overwrite, old_dim) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"unable to initialize dataset with fill value")
|
||||
} /* end else */
|
||||
@@ -2383,10 +2377,9 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[])
|
||||
H5D__init_storage(H5D_t *dset, hbool_t full_overwrite, hsize_t old_dim[])
|
||||
{
|
||||
const H5D_t *dset = io_info->dset; /* dataset pointer */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@@ -2408,7 +2401,7 @@ H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t
|
||||
/* If we will be immediately overwriting the values, don't bother to clear them */
|
||||
if ((dset->shared->dcpl_cache.efl.nused == 0 || dset->shared->dcpl_cache.fill.buf) &&
|
||||
!full_overwrite)
|
||||
if (H5D__contig_fill(io_info) < 0)
|
||||
if (H5D__contig_fill(dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset")
|
||||
break;
|
||||
|
||||
@@ -2424,7 +2417,7 @@ H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t
|
||||
if (old_dim == NULL)
|
||||
old_dim = zero_dim;
|
||||
|
||||
if (H5D__chunk_allocate(io_info, full_overwrite, old_dim) < 0)
|
||||
if (H5D__chunk_allocate(dset, full_overwrite, old_dim) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset")
|
||||
break;
|
||||
} /* end block */
|
||||
@@ -2599,7 +2592,8 @@ H5D__vlen_get_buf_size_cb(void H5_ATTR_UNUSED *elem, hid_t type_id, unsigned H5_
|
||||
const hsize_t *point, void *op_data)
|
||||
{
|
||||
H5D_vlen_bufsize_native_t *vlen_bufsize = (H5D_vlen_bufsize_native_t *)op_data;
|
||||
herr_t ret_value = H5_ITER_CONT; /* Return value */
|
||||
H5D_dset_io_info_t dset_info; /* Internal multi-dataset info placeholder */
|
||||
herr_t ret_value = H5_ITER_CONT; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@@ -2612,10 +2606,17 @@ H5D__vlen_get_buf_size_cb(void H5_ATTR_UNUSED *elem, hid_t type_id, unsigned H5_
|
||||
if (H5S_select_elements(vlen_bufsize->fspace, H5S_SELECT_SET, (size_t)1, point) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5_ITER_ERROR, "can't select point")
|
||||
|
||||
/* Read in the point (with the custom VL memory allocator) */
|
||||
if (H5D__read(vlen_bufsize->dset, type_id, vlen_bufsize->mspace, vlen_bufsize->fspace,
|
||||
vlen_bufsize->common.fl_tbuf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, H5_ITER_ERROR, "can't read point")
|
||||
{
|
||||
dset_info.dset = vlen_bufsize->dset;
|
||||
dset_info.mem_space = vlen_bufsize->mspace;
|
||||
dset_info.file_space = vlen_bufsize->fspace;
|
||||
dset_info.buf.vp = vlen_bufsize->common.fl_tbuf;
|
||||
dset_info.mem_type_id = type_id;
|
||||
|
||||
/* Read in the point (with the custom VL memory allocator) */
|
||||
if (H5D__read(1, &dset_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@@ -2767,8 +2768,8 @@ H5D__vlen_get_buf_size_gen_cb(void H5_ATTR_UNUSED *elem, hid_t type_id, unsigned
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't select point")
|
||||
|
||||
/* Read in the point (with the custom VL memory allocator) */
|
||||
if (H5VL_dataset_read(vlen_bufsize->dset_vol_obj, type_id, vlen_bufsize->mspace_id,
|
||||
vlen_bufsize->fspace_id, vlen_bufsize->dxpl_id, vlen_bufsize->common.fl_tbuf,
|
||||
if (H5VL_dataset_read(1, &vlen_bufsize->dset_vol_obj, &type_id, &vlen_bufsize->mspace_id,
|
||||
&vlen_bufsize->fspace_id, vlen_bufsize->dxpl_id, &vlen_bufsize->common.fl_tbuf,
|
||||
H5_REQUEST_NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read point")
|
||||
|
||||
@@ -2814,7 +2815,7 @@ H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
|
||||
|
||||
/* Save the dataset */
|
||||
vlen_bufsize.dset_vol_obj = vol_obj;
|
||||
vlen_bufsize.dset_vol_obj = (const H5VL_object_t *)vol_obj;
|
||||
|
||||
/* Set up VOL callback arguments */
|
||||
vol_cb_args.op_type = H5VL_DATASET_GET_SPACE;
|
||||
@@ -3095,14 +3096,10 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size)
|
||||
} /* end if */
|
||||
|
||||
/* Allocate space for the new parts of the dataset, if appropriate */
|
||||
if (expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY) {
|
||||
H5D_io_info_t io_info;
|
||||
|
||||
io_info.dset = dset;
|
||||
|
||||
if (H5D__alloc_storage(&io_info, H5D_ALLOC_EXTEND, FALSE, curr_dims) < 0)
|
||||
if (expand && dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_EARLY)
|
||||
if (H5D__alloc_storage(dset, H5D_ALLOC_EXTEND, FALSE, curr_dims) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to extend dataset storage")
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Remove chunk information in the case of chunked datasets
|
||||
* This removal takes place only in case we are shrinking the dataset
|
||||
|
||||
+869
-494
@@ -44,15 +44,14 @@
|
||||
/********************/
|
||||
|
||||
/* Setup/teardown routines */
|
||||
static herr_t H5D__ioinfo_init(H5D_t *dset, const H5D_type_info_t *type_info, H5D_storage_t *store,
|
||||
H5D_io_info_t *io_info);
|
||||
static herr_t H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write,
|
||||
H5D_type_info_t *type_info);
|
||||
static herr_t H5D__ioinfo_init(size_t count, H5D_dset_io_info_t *dset_info, H5D_io_info_t *io_info);
|
||||
static herr_t H5D__dset_ioinfo_init(H5D_t *dset, H5D_dset_io_info_t *dset_info, H5D_storage_t *store);
|
||||
static herr_t H5D__typeinfo_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, hid_t mem_type_id);
|
||||
static herr_t H5D__typeinfo_init_phase2(H5D_io_info_t *io_info);
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
static herr_t H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_space,
|
||||
const H5S_t *mem_space, const H5D_type_info_t *type_info);
|
||||
static herr_t H5D__ioinfo_adjust(H5D_io_info_t *io_info);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
static herr_t H5D__typeinfo_term(const H5D_type_info_t *type_info);
|
||||
static herr_t H5D__typeinfo_term(H5D_io_info_t *io_info, size_t type_info_init);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -65,66 +64,63 @@ static herr_t H5D__typeinfo_term(const H5D_type_info_t *type_info);
|
||||
/* Declare a free list to manage blocks of type conversion data */
|
||||
H5FL_BLK_DEFINE(type_conv);
|
||||
|
||||
/* Declare a free list to manage the H5D_chunk_map_t struct */
|
||||
H5FL_DEFINE(H5D_chunk_map_t);
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__read
|
||||
*
|
||||
* Purpose: Reads (part of) a DATASET into application memory BUF. See
|
||||
* H5Dread() for complete details.
|
||||
* Purpose: Reads multiple (parts of) DATASETs into application memory BUFs.
|
||||
* See H5Dread_multi() for complete details.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, December 4, 1997
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__read(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space, void *buf /*out*/)
|
||||
H5D__read(size_t count, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5D_chunk_map_t *fm = NULL; /* Chunk file<->memory mapping */
|
||||
H5D_io_info_t io_info; /* Dataset I/O info */
|
||||
H5D_type_info_t type_info; /* Datatype info for operation */
|
||||
H5D_layout_t layout_type; /* Dataset's layout type (contig, chunked, compact, etc.) */
|
||||
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
|
||||
H5S_t *projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
|
||||
/* projection of the supplied mem_space to a new */
|
||||
/* dataspace with rank equal to that of */
|
||||
/* file_space. */
|
||||
/* */
|
||||
/* This field is only used if */
|
||||
/* H5S_select_shape_same() returns TRUE when */
|
||||
/* comparing the mem_space and the data_space, */
|
||||
/* and the mem_space have different rank. */
|
||||
/* */
|
||||
/* Note that if this variable is used, the */
|
||||
/* projected mem space must be discarded at the */
|
||||
/* end of the function to avoid a memory leak. */
|
||||
H5D_storage_t store; /* union of EFL and chunk pointer in file space */
|
||||
hsize_t nelmts; /* total number of elmts */
|
||||
hbool_t io_op_init = FALSE; /* Whether the I/O op has been initialized */
|
||||
char fake_char; /* Temporary variable for NULL buffer pointers */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_io_info_t io_info; /* Dataset I/O info for multi dsets */
|
||||
size_t type_info_init = 0; /* Number of datatype info structs that have been initialized */
|
||||
H5S_t *orig_mem_space_local; /* Local buffer for orig_mem_space */
|
||||
H5S_t **orig_mem_space = NULL; /* If not NULL, ptr to an array of dataspaces */
|
||||
/* containing the original memory spaces contained */
|
||||
/* in dset_info. This is needed in order to */
|
||||
/* restore the original state of dset_info if we */
|
||||
/* replaced any mem spaces with equivalents */
|
||||
/* projected to a rank equal to that of file_space. */
|
||||
/* */
|
||||
/* This field is only used if */
|
||||
/* H5S_select_shape_same() returns TRUE when */
|
||||
/* comparing at least one mem_space and data_space, */
|
||||
/* and the mem_space has a different rank. */
|
||||
/* */
|
||||
/* Note that this is a temporary variable - the */
|
||||
/* projected memory space is stored in dset_info, */
|
||||
/* and will be freed when that structure is */
|
||||
/* freed. */
|
||||
H5D_storage_t store_local; /* Local buffer for store */
|
||||
H5D_storage_t *store = &store_local; /* Union of EFL and chunk pointer in file space */
|
||||
size_t io_op_init = 0; /* Number I/O ops that have been initialized */
|
||||
size_t io_skipped =
|
||||
0; /* Number I/O ops that have been skipped (due to the dataset not being allocated) */
|
||||
size_t i; /* Local index variable */
|
||||
char fake_char; /* Temporary variable for NULL buffer pointers */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE_TAG(dataset->oloc.addr)
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(dataset && dataset->oloc.file);
|
||||
HDassert(file_space);
|
||||
HDassert(mem_space);
|
||||
/* Init io_info */
|
||||
if (H5D__ioinfo_init(count, dset_info, &io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
|
||||
io_info.op_type = H5D_IO_OP_READ;
|
||||
|
||||
layout_type = dataset->shared->layout.type;
|
||||
|
||||
/* Set up datatype info for operation */
|
||||
if (H5D__typeinfo_init(dataset, mem_type_id, FALSE, &type_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info")
|
||||
type_info_init = TRUE;
|
||||
/* Allocate store buffer if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (store = (H5D_storage_t *)H5MM_malloc(count * sizeof(H5D_storage_t))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dset storage info array buffer")
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Check for non-MPI-based VFD */
|
||||
if (!(H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI))) {
|
||||
/* Check for non-MPI-based VFD. Only need to check first dataset since all
|
||||
* share the same file. */
|
||||
if (!(H5F_HAS_FEATURE(dset_info[0].dset->oloc.file, H5FD_FEAT_HAS_MPI))) {
|
||||
H5FD_mpio_xfer_t io_xfer_mode; /* MPI I/O transfer mode */
|
||||
|
||||
/* Get I/O transfer mode */
|
||||
@@ -137,363 +133,626 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space
|
||||
} /* end if */
|
||||
#endif /*H5_HAVE_PARALLEL*/
|
||||
|
||||
/* Make certain that the number of elements in each selection is the same */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(mem_space);
|
||||
if (nelmts != H5S_GET_SELECT_NPOINTS(file_space))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"src and dest dataspaces have different number of elements selected")
|
||||
/* iterate over all dsets and construct I/O information necessary to do I/O */
|
||||
for (i = 0; i < count; i++) {
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
/* Check for a NULL buffer */
|
||||
if (NULL == buf) {
|
||||
/* Check for any elements selected (which is invalid) */
|
||||
if (nelmts > 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
|
||||
/* check args */
|
||||
if (NULL == dset_info[i].dset)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
|
||||
if (NULL == dset_info[i].dset->oloc.file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
|
||||
|
||||
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
|
||||
* This is for some MPI package like ChaMPIon on NCSA's tungsten which
|
||||
* doesn't support this feature.
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* Set up datatype info for operation */
|
||||
if (H5D__typeinfo_init(&io_info, &(dset_info[i]), dset_info[i].mem_type_id) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info")
|
||||
type_info_init++;
|
||||
|
||||
/* Make certain that the number of elements in each selection is the same, and cache nelmts in
|
||||
* dset_info */
|
||||
dset_info[i].nelmts = H5S_GET_SELECT_NPOINTS(dset_info[i].mem_space);
|
||||
if (dset_info[i].nelmts != H5S_GET_SELECT_NPOINTS(dset_info[i].file_space))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"src and dest dataspaces have different number of elements selected")
|
||||
|
||||
/* Check for a NULL buffer */
|
||||
if (NULL == dset_info[i].buf.vp) {
|
||||
/* Check for any elements selected (which is invalid) */
|
||||
if (dset_info[i].nelmts > 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
|
||||
|
||||
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
|
||||
* This is for some MPI package like ChaMPIon on NCSA's tungsten which
|
||||
* doesn't support this feature.
|
||||
*/
|
||||
dset_info[i].buf.vp = &fake_char;
|
||||
} /* end if */
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if (!(H5S_has_extent(dset_info[i].file_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if (!(H5S_has_extent(dset_info[i].mem_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
|
||||
/* H5S_select_shape_same() has been modified to accept topologically identical
|
||||
* selections with different rank as having the same shape (if the most
|
||||
* rapidly changing coordinates match up), but the I/O code still has
|
||||
* difficulties with the notion.
|
||||
*
|
||||
* To solve this, we check to see if H5S_select_shape_same() returns true,
|
||||
* and if the ranks of the mem and file spaces are different. If they are,
|
||||
* construct a new mem space that is equivalent to the old mem space, and
|
||||
* use that instead.
|
||||
*
|
||||
* Note that in general, this requires us to touch up the memory buffer as
|
||||
* well.
|
||||
*/
|
||||
buf = &fake_char;
|
||||
} /* end if */
|
||||
if (dset_info[i].nelmts > 0 &&
|
||||
TRUE == H5S_SELECT_SHAPE_SAME(dset_info[i].mem_space, dset_info[i].file_space) &&
|
||||
H5S_GET_EXTENT_NDIMS(dset_info[i].mem_space) != H5S_GET_EXTENT_NDIMS(dset_info[i].file_space)) {
|
||||
ptrdiff_t buf_adj = 0;
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if (!(H5S_has_extent(file_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if (!(H5S_has_extent(mem_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
/* Allocate original memory space buffer if necessary */
|
||||
if (!orig_mem_space) {
|
||||
if (count > 1) {
|
||||
/* Allocate buffer */
|
||||
if (NULL == (orig_mem_space = (H5S_t **)H5MM_calloc(count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
"couldn't allocate original memory space array buffer")
|
||||
}
|
||||
else
|
||||
/* Use local buffer */
|
||||
orig_mem_space = &orig_mem_space_local;
|
||||
}
|
||||
|
||||
/* H5S_select_shape_same() has been modified to accept topologically identical
|
||||
* selections with different rank as having the same shape (if the most
|
||||
* rapidly changing coordinates match up), but the I/O code still has
|
||||
* difficulties with the notion.
|
||||
*
|
||||
* To solve this, we check to see if H5S_select_shape_same() returns true,
|
||||
* and if the ranks of the mem and file spaces are different. If they are,
|
||||
* construct a new mem space that is equivalent to the old mem space, and
|
||||
* use that instead.
|
||||
*
|
||||
* Note that in general, this requires us to touch up the memory buffer as
|
||||
* well.
|
||||
*/
|
||||
if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) &&
|
||||
H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) {
|
||||
ptrdiff_t buf_adj = 0;
|
||||
/* Save original memory space */
|
||||
orig_mem_space[i] = dset_info[i].mem_space;
|
||||
dset_info[i].mem_space = NULL;
|
||||
|
||||
/* Attempt to construct projected dataspace for memory dataspace */
|
||||
if (H5S_select_construct_projection(mem_space, &projected_mem_space,
|
||||
(unsigned)H5S_GET_EXTENT_NDIMS(file_space),
|
||||
type_info.dst_type_size, &buf_adj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
|
||||
HDassert(projected_mem_space);
|
||||
/* Attempt to construct projected dataspace for memory dataspace */
|
||||
if (H5S_select_construct_projection(orig_mem_space[i], &dset_info[i].mem_space,
|
||||
(unsigned)H5S_GET_EXTENT_NDIMS(dset_info[i].file_space),
|
||||
(hsize_t)dset_info[i].type_info.dst_type_size, &buf_adj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
|
||||
HDassert(dset_info[i].mem_space);
|
||||
|
||||
/* Adjust the buffer by the given amount */
|
||||
buf = (void *)(((uint8_t *)buf) + buf_adj);
|
||||
/* Adjust the buffer by the given amount */
|
||||
dset_info[i].buf.vp = (void *)(((uint8_t *)dset_info[i].buf.vp) + buf_adj);
|
||||
} /* end if */
|
||||
|
||||
/* Switch to using projected memory dataspace & adjusted buffer */
|
||||
mem_space = projected_mem_space;
|
||||
} /* end if */
|
||||
/* If space hasn't been allocated and not using external storage,
|
||||
* return fill value to buffer if fill time is upon allocation, or
|
||||
* do nothing if fill time is never. If the dataset is compact and
|
||||
* fill time is NEVER, there is no way to tell whether part of data
|
||||
* has been overwritten. So just proceed in reading.
|
||||
*/
|
||||
if (dset_info[i].nelmts > 0 && dset_info[i].dset->shared->dcpl_cache.efl.nused == 0 &&
|
||||
!(*dset_info[i].dset->shared->layout.ops->is_space_alloc)(
|
||||
&dset_info[i].dset->shared->layout.storage) &&
|
||||
!(dset_info[i].dset->shared->layout.ops->is_data_cached &&
|
||||
(*dset_info[i].dset->shared->layout.ops->is_data_cached)(dset_info[i].dset->shared))) {
|
||||
H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
|
||||
|
||||
/* Retrieve dataset properties */
|
||||
/* <none needed in the general case> */
|
||||
/* Retrieve dataset's fill-value properties */
|
||||
if (H5P_is_fill_value_defined(&dset_info[i].dset->shared->dcpl_cache.fill, &fill_status) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
|
||||
|
||||
/* If space hasn't been allocated and not using external storage,
|
||||
* return fill value to buffer if fill time is upon allocation, or
|
||||
* do nothing if fill time is never. If the dataset is compact and
|
||||
* fill time is NEVER, there is no way to tell whether part of data
|
||||
* has been overwritten. So just proceed in reading.
|
||||
*/
|
||||
if (nelmts > 0 && dataset->shared->dcpl_cache.efl.nused == 0 &&
|
||||
!(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) &&
|
||||
!(dataset->shared->layout.ops->is_data_cached &&
|
||||
(*dataset->shared->layout.ops->is_data_cached)(dataset->shared))) {
|
||||
H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
|
||||
/* Should be impossible, but check anyway... */
|
||||
if (fill_status == H5D_FILL_VALUE_UNDEFINED &&
|
||||
(dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC ||
|
||||
dset_info[i].dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL,
|
||||
"read failed: dataset doesn't exist, no data can be read")
|
||||
|
||||
/* Retrieve dataset's fill-value properties */
|
||||
if (H5P_is_fill_value_defined(&dataset->shared->dcpl_cache.fill, &fill_status) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
|
||||
/* If we're never going to fill this dataset, just leave the junk in the user's buffer */
|
||||
if (dset_info[i].dset->shared->dcpl_cache.fill.fill_time != H5D_FILL_TIME_NEVER)
|
||||
/* Go fill the user's selection with the dataset's fill value */
|
||||
if (H5D__fill(dset_info[i].dset->shared->dcpl_cache.fill.buf, dset_info[i].dset->shared->type,
|
||||
dset_info[i].buf.vp, dset_info[i].type_info.mem_type,
|
||||
dset_info[i].mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed")
|
||||
|
||||
/* Should be impossible, but check anyway... */
|
||||
if (fill_status == H5D_FILL_VALUE_UNDEFINED &&
|
||||
(dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC ||
|
||||
dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL,
|
||||
"read failed: dataset doesn't exist, no data can be read")
|
||||
/* No need to perform any more I/O for this dataset */
|
||||
dset_info[i].skip_io = TRUE;
|
||||
io_skipped++;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Set up I/O operation */
|
||||
if (H5D__dset_ioinfo_init(dset_info[i].dset, &(dset_info[i]), &(store[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation")
|
||||
|
||||
/* If we're never going to fill this dataset, just leave the junk in the user's buffer */
|
||||
if (dataset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_NEVER)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
/* Sanity check that space is allocated, if there are elements */
|
||||
if (dset_info[i].nelmts > 0)
|
||||
HDassert(
|
||||
(*dset_info[i].dset->shared->layout.ops->is_space_alloc)(
|
||||
&dset_info[i].dset->shared->layout.storage) ||
|
||||
(dset_info[i].dset->shared->layout.ops->is_data_cached &&
|
||||
(*dset_info[i].dset->shared->layout.ops->is_data_cached)(dset_info[i].dset->shared)) ||
|
||||
dset_info[i].dset->shared->dcpl_cache.efl.nused > 0 ||
|
||||
dset_info[i].dset->shared->layout.type == H5D_COMPACT);
|
||||
|
||||
/* Go fill the user's selection with the dataset's fill value */
|
||||
if (H5D__fill(dataset->shared->dcpl_cache.fill.buf, dataset->shared->type, buf, type_info.mem_type,
|
||||
mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed")
|
||||
else
|
||||
HGOTO_DONE(SUCCEED)
|
||||
} /* end if */
|
||||
/* Call storage method's I/O initialization routine */
|
||||
if (dset_info[i].layout_ops.io_init &&
|
||||
(dset_info[i].layout_ops.io_init)(&io_info, &(dset_info[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
|
||||
dset_info[i].skip_io = FALSE;
|
||||
io_op_init++;
|
||||
|
||||
/* Set up I/O operation */
|
||||
io_info.op_type = H5D_IO_OP_READ;
|
||||
io_info.u.rbuf = buf;
|
||||
if (H5D__ioinfo_init(dataset, &type_info, &store, &io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation")
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
}
|
||||
} /* end of for loop */
|
||||
|
||||
/* Sanity check that space is allocated, if there are elements */
|
||||
if (nelmts > 0)
|
||||
HDassert((*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage) ||
|
||||
(dataset->shared->layout.ops->is_data_cached &&
|
||||
(*dataset->shared->layout.ops->is_data_cached)(dataset->shared)) ||
|
||||
dataset->shared->dcpl_cache.efl.nused > 0 || layout_type == H5D_COMPACT);
|
||||
HDassert(type_info_init == count);
|
||||
HDassert(io_op_init + io_skipped == count);
|
||||
|
||||
/* Allocate the chunk map */
|
||||
if (H5D_CONTIGUOUS != layout_type && H5D_COMPACT != layout_type) {
|
||||
if (NULL == (fm = H5FL_CALLOC(H5D_chunk_map_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk map")
|
||||
}
|
||||
/* If no datasets have I/O, we're done */
|
||||
if (io_op_init == 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Call storage method's I/O initialization routine */
|
||||
if (io_info.layout_ops.io_init &&
|
||||
(*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, fm) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
|
||||
io_op_init = TRUE;
|
||||
/* Perform second phase of type info initialization */
|
||||
if (H5D__typeinfo_init_phase2(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info (second phase)")
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Adjust I/O info for any parallel I/O */
|
||||
if (H5D__ioinfo_adjust(&io_info, dataset, file_space, mem_space, &type_info) < 0)
|
||||
if (H5D__ioinfo_adjust(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
|
||||
#endif /*H5_HAVE_PARALLEL*/
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*io_info.io_ops.multi_read)(&io_info, &type_info, nelmts, file_space, mem_space, fm) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
/* If multi dataset I/O callback is not provided, perform read IO via
|
||||
* single-dset path with looping */
|
||||
if (io_info.md_io_ops.multi_read_md) {
|
||||
/* Create sel_pieces array if any pieces are selected */
|
||||
if (io_info.piece_count > 0) {
|
||||
HDassert(!io_info.sel_pieces);
|
||||
HDassert(io_info.pieces_added == 0);
|
||||
|
||||
/* Allocate sel_pieces array */
|
||||
if (NULL ==
|
||||
(io_info.sel_pieces = H5MM_malloc(io_info.piece_count * sizeof(io_info.sel_pieces[0]))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate array of selected pieces")
|
||||
}
|
||||
|
||||
/* MDIO-specific second phase initialization */
|
||||
for (i = 0; i < count; i++)
|
||||
if (dset_info[i].layout_ops.mdio_init) {
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* Make second phase IO init call */
|
||||
if ((dset_info[i].layout_ops.mdio_init)(&io_info, &(dset_info[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't populate array of selected pieces")
|
||||
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
}
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*io_info.md_io_ops.multi_read_md)(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
} /* end if */
|
||||
else {
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
if (!H5D_LAYOUT_CB_PERFORM_IO(&io_info) && io_info.piece_count > 0) {
|
||||
if (NULL == (io_info.mem_spaces = H5MM_malloc(io_info.piece_count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (io_info.file_spaces = H5MM_malloc(io_info.piece_count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (io_info.addrs = H5MM_malloc(io_info.piece_count * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for piece address list")
|
||||
if (NULL == (io_info.element_sizes = H5MM_malloc(io_info.piece_count * sizeof(size_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for element size list")
|
||||
if (NULL == (io_info.rbufs = H5MM_malloc(io_info.piece_count * sizeof(void *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for read buffer list")
|
||||
}
|
||||
|
||||
/* Loop with serial & single-dset read IO path */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Check for skipped I/O */
|
||||
if (dset_info[i].skip_io)
|
||||
continue;
|
||||
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*dset_info[i].io_ops.multi_read)(&io_info, &dset_info[i]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
}
|
||||
|
||||
/* Make final multi dataset selection I/O call if we are using both
|
||||
* features - in this case the multi_read callbacks did not perform the
|
||||
* actual I/O */
|
||||
H5_CHECK_OVERFLOW(io_info.pieces_added, size_t, uint32_t)
|
||||
if (!H5D_LAYOUT_CB_PERFORM_IO(&io_info))
|
||||
if (H5F_shared_select_read(io_info.f_sh, H5FD_MEM_DRAW, (uint32_t)io_info.pieces_added,
|
||||
io_info.mem_spaces, io_info.file_spaces, io_info.addrs,
|
||||
io_info.element_sizes, io_info.rbufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "selection read failed")
|
||||
}
|
||||
|
||||
done:
|
||||
/* Shut down the I/O op information */
|
||||
if (io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(fm) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
|
||||
if (fm)
|
||||
fm = H5FL_FREE(H5D_chunk_map_t, fm);
|
||||
for (i = 0; i < io_op_init; i++)
|
||||
if (!dset_info[i].skip_io && dset_info[i].layout_ops.io_term &&
|
||||
(*dset_info[i].layout_ops.io_term)(&io_info, &(dset_info[i])) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
|
||||
|
||||
/* Shut down datatype info for operation */
|
||||
if (type_info_init && H5D__typeinfo_term(&type_info) < 0)
|
||||
if (H5D__typeinfo_term(&io_info, type_info_init) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info")
|
||||
|
||||
/* discard projected mem space if it was created */
|
||||
if (NULL != projected_mem_space)
|
||||
if (H5S_close(projected_mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace")
|
||||
/* Discard projected mem spaces and restore originals */
|
||||
if (orig_mem_space) {
|
||||
for (i = 0; i < count; i++)
|
||||
if (orig_mem_space[i]) {
|
||||
if (H5S_close(dset_info[i].mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL,
|
||||
"unable to shut down projected memory dataspace")
|
||||
dset_info[i].mem_space = orig_mem_space[i];
|
||||
}
|
||||
|
||||
FUNC_LEAVE_NOAPI_TAG(ret_value)
|
||||
/* Free orig_mem_space array if it was allocated */
|
||||
if (orig_mem_space != &orig_mem_space_local)
|
||||
H5MM_free(orig_mem_space);
|
||||
}
|
||||
|
||||
/* Free global piece array */
|
||||
H5MM_xfree(io_info.sel_pieces);
|
||||
|
||||
/* Free selection I/O arrays */
|
||||
H5MM_xfree(io_info.mem_spaces);
|
||||
H5MM_xfree(io_info.file_spaces);
|
||||
H5MM_xfree(io_info.addrs);
|
||||
H5MM_xfree(io_info.element_sizes);
|
||||
H5MM_xfree(io_info.rbufs);
|
||||
|
||||
/* Free store array if it was allocated */
|
||||
if (store != &store_local)
|
||||
H5MM_free(store);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__read() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__write
|
||||
*
|
||||
* Purpose: Writes (part of) a DATASET to a file from application memory
|
||||
* BUF. See H5Dwrite() for complete details.
|
||||
* Purpose: Writes multiple (part of) DATASETs to a file from application
|
||||
* memory BUFs. See H5Dwrite_multi() for complete details.
|
||||
*
|
||||
* This was referred from H5D__write for multi-dset work.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, December 4, 1997
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__write(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space, const void *buf)
|
||||
H5D__write(size_t count, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5D_chunk_map_t *fm = NULL; /* Chunk file<->memory mapping */
|
||||
H5D_io_info_t io_info; /* Dataset I/O info */
|
||||
H5D_type_info_t type_info; /* Datatype info for operation */
|
||||
H5D_layout_t layout_type; /* Dataset's layout type (contig, chunked, compact, etc.) */
|
||||
hbool_t type_info_init = FALSE; /* Whether the datatype info has been initialized */
|
||||
hbool_t should_alloc_space = FALSE; /* Whether or not to initialize dataset's storage */
|
||||
H5S_t *projected_mem_space = NULL; /* If not NULL, ptr to dataspace containing a */
|
||||
/* projection of the supplied mem_space to a new */
|
||||
/* dataspace with rank equal to that of */
|
||||
/* file_space. */
|
||||
/* */
|
||||
/* This field is only used if */
|
||||
/* H5S_select_shape_same() returns TRUE when */
|
||||
/* comparing the mem_space and the data_space, */
|
||||
/* and the mem_space have different rank. */
|
||||
/* */
|
||||
/* Note that if this variable is used, the */
|
||||
/* projected mem space must be discarded at the */
|
||||
/* end of the function to avoid a memory leak. */
|
||||
H5D_storage_t store; /* union of EFL and chunk pointer in file space */
|
||||
hsize_t nelmts; /* total number of elmts */
|
||||
hbool_t io_op_init = FALSE; /* Whether the I/O op has been initialized */
|
||||
char fake_char; /* Temporary variable for NULL buffer pointers */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_io_info_t io_info; /* Dataset I/O info for multi dsets */
|
||||
size_t type_info_init = 0; /* Number of datatype info structs that have been initialized */
|
||||
H5S_t *orig_mem_space_local; /* Local buffer for orig_mem_space */
|
||||
H5S_t **orig_mem_space = NULL; /* If not NULL, ptr to an array of dataspaces */
|
||||
/* containing the original memory spaces contained */
|
||||
/* in dset_info. This is needed in order to */
|
||||
/* restore the original state of dset_info if we */
|
||||
/* replaced any mem spaces with equivalents */
|
||||
/* projected to a rank equal to that of file_space. */
|
||||
/* */
|
||||
/* This field is only used if */
|
||||
/* H5S_select_shape_same() returns TRUE when */
|
||||
/* comparing at least one mem_space and data_space, */
|
||||
/* and the mem_space has a different rank. */
|
||||
/* */
|
||||
/* Note that this is a temporary variable - the */
|
||||
/* projected memory space is stored in dset_info, */
|
||||
/* and will be freed when that structure is */
|
||||
/* freed. */
|
||||
H5D_storage_t store_local; /* Local buffer for store */
|
||||
H5D_storage_t *store = &store_local; /* Union of EFL and chunk pointer in file space */
|
||||
size_t io_op_init = 0; /* Number I/O ops that have been initialized */
|
||||
size_t i; /* Local index variable */
|
||||
char fake_char; /* Temporary variable for NULL buffer pointers */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE_TAG(dataset->oloc.addr)
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(dataset && dataset->oloc.file);
|
||||
HDassert(file_space);
|
||||
HDassert(mem_space);
|
||||
|
||||
layout_type = dataset->shared->layout.type;
|
||||
|
||||
/* All filters in the DCPL must have encoding enabled. */
|
||||
if (!dataset->shared->checked_filters) {
|
||||
if (H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) < 0)
|
||||
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
|
||||
|
||||
dataset->shared->checked_filters = TRUE;
|
||||
} /* end if */
|
||||
|
||||
/* Check if we are allowed to write to this file */
|
||||
if (0 == (H5F_INTENT(dataset->oloc.file) & H5F_ACC_RDWR))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
|
||||
|
||||
/* Set up datatype info for operation */
|
||||
if (H5D__typeinfo_init(dataset, mem_type_id, TRUE, &type_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info")
|
||||
type_info_init = TRUE;
|
||||
|
||||
/* Various MPI based checks */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if (H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI)) {
|
||||
/* If MPI based VFD is used, no VL or region reference datatype support yet. */
|
||||
/* This is because they use the global heap in the file and we don't */
|
||||
/* support parallel access of that yet */
|
||||
if (H5T_is_vl_storage(type_info.mem_type) > 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
|
||||
"Parallel IO does not support writing VL or region reference datatypes yet")
|
||||
} /* end if */
|
||||
else {
|
||||
H5FD_mpio_xfer_t io_xfer_mode; /* MPI I/O transfer mode */
|
||||
|
||||
/* Get I/O transfer mode */
|
||||
if (H5CX_get_io_xfer_mode(&io_xfer_mode) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode")
|
||||
|
||||
/* Collective access is not permissible without a MPI based VFD */
|
||||
if (io_xfer_mode == H5FD_MPIO_COLLECTIVE)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based driver only")
|
||||
} /* end else */
|
||||
#endif /*H5_HAVE_PARALLEL*/
|
||||
|
||||
/* Make certain that the number of elements in each selection is the same */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(mem_space);
|
||||
if (nelmts != H5S_GET_SELECT_NPOINTS(file_space))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"src and dest dataspaces have different number of elements selected")
|
||||
|
||||
/* Check for a NULL buffer */
|
||||
if (NULL == buf) {
|
||||
/* Check for any elements selected (which is invalid) */
|
||||
if (nelmts > 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
|
||||
|
||||
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
|
||||
* This is for some MPI package like ChaMPIon on NCSA's tungsten which
|
||||
* doesn't support this feature.
|
||||
*/
|
||||
buf = &fake_char;
|
||||
} /* end if */
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if (!(H5S_has_extent(file_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if (!(H5S_has_extent(mem_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
|
||||
/* H5S_select_shape_same() has been modified to accept topologically
|
||||
* identical selections with different rank as having the same shape
|
||||
* (if the most rapidly changing coordinates match up), but the I/O
|
||||
* code still has difficulties with the notion.
|
||||
*
|
||||
* To solve this, we check to see if H5S_select_shape_same() returns
|
||||
* true, and if the ranks of the mem and file spaces are different.
|
||||
* If the are, construct a new mem space that is equivalent to the
|
||||
* old mem space, and use that instead.
|
||||
*
|
||||
* Note that in general, this requires us to touch up the memory buffer
|
||||
* as well.
|
||||
*/
|
||||
if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) &&
|
||||
H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) {
|
||||
ptrdiff_t buf_adj = 0;
|
||||
|
||||
/* Attempt to construct projected dataspace for memory dataspace */
|
||||
if (H5S_select_construct_projection(mem_space, &projected_mem_space,
|
||||
(unsigned)H5S_GET_EXTENT_NDIMS(file_space),
|
||||
type_info.src_type_size, &buf_adj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
|
||||
HDassert(projected_mem_space);
|
||||
|
||||
/* Adjust the buffer by the given amount */
|
||||
buf = (const void *)(((const uint8_t *)buf) + buf_adj);
|
||||
|
||||
/* Switch to using projected memory dataspace & adjusted buffer */
|
||||
mem_space = projected_mem_space;
|
||||
} /* end if */
|
||||
|
||||
/* Retrieve dataset properties */
|
||||
/* <none needed currently> */
|
||||
|
||||
/* Set up I/O operation */
|
||||
io_info.op_type = H5D_IO_OP_WRITE;
|
||||
io_info.u.wbuf = buf;
|
||||
if (H5D__ioinfo_init(dataset, &type_info, &store, &io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up I/O operation")
|
||||
|
||||
/* Allocate dataspace and initialize it if it hasn't been. */
|
||||
should_alloc_space = dataset->shared->dcpl_cache.efl.nused == 0 &&
|
||||
!(*dataset->shared->layout.ops->is_space_alloc)(&dataset->shared->layout.storage);
|
||||
|
||||
/*
|
||||
* If not using an MPI-based VFD, we only need to allocate
|
||||
* and initialize storage if there's a selection in the
|
||||
* dataset's dataspace. Otherwise, we always need to participate
|
||||
* in the storage allocation since this may use collective
|
||||
* operations and we will hang if we don't participate.
|
||||
*/
|
||||
if (!H5F_HAS_FEATURE(dataset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
should_alloc_space = should_alloc_space && (nelmts > 0);
|
||||
|
||||
if (should_alloc_space) {
|
||||
hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
|
||||
hbool_t full_overwrite; /* Whether we are over-writing all the elements */
|
||||
|
||||
/* Get the number of elements in file dataset's dataspace */
|
||||
if ((file_nelmts = H5S_GET_EXTENT_NPOINTS(file_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset")
|
||||
|
||||
/* Always allow fill values to be written if the dataset has a VL datatype */
|
||||
if (H5T_detect_class(dataset->shared->type, H5T_VLEN, FALSE))
|
||||
full_overwrite = FALSE;
|
||||
else
|
||||
full_overwrite = (hbool_t)((hsize_t)file_nelmts == nelmts ? TRUE : FALSE);
|
||||
|
||||
/* Allocate storage */
|
||||
if (H5D__alloc_storage(&io_info, H5D_ALLOC_WRITE, full_overwrite, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
|
||||
} /* end if */
|
||||
|
||||
/* Allocate the chunk map */
|
||||
if (H5D_CONTIGUOUS != layout_type && H5D_COMPACT != layout_type) {
|
||||
if (NULL == (fm = H5FL_CALLOC(H5D_chunk_map_t)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate chunk map")
|
||||
}
|
||||
|
||||
/* Call storage method's I/O initialization routine */
|
||||
if (io_info.layout_ops.io_init &&
|
||||
(*io_info.layout_ops.io_init)(&io_info, &type_info, nelmts, file_space, mem_space, fm) < 0)
|
||||
/* Init io_info */
|
||||
if (H5D__ioinfo_init(count, dset_info, &io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
|
||||
io_op_init = TRUE;
|
||||
io_info.op_type = H5D_IO_OP_WRITE;
|
||||
|
||||
/* Allocate store buffer if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (store = (H5D_storage_t *)H5MM_malloc(count * sizeof(H5D_storage_t))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dset storage info array buffer")
|
||||
|
||||
/* iterate over all dsets and construct I/O information */
|
||||
for (i = 0; i < count; i++) {
|
||||
hbool_t should_alloc_space = FALSE; /* Whether or not to initialize dataset's storage */
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
/* check args */
|
||||
if (NULL == dset_info[i].dset)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
|
||||
if (NULL == dset_info[i].dset->oloc.file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
|
||||
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* All filters in the DCPL must have encoding enabled. */
|
||||
if (!dset_info[i].dset->shared->checked_filters) {
|
||||
if (H5Z_can_apply(dset_info[i].dset->shared->dcpl_id, dset_info[i].dset->shared->type_id) < 0)
|
||||
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
|
||||
|
||||
dset_info[i].dset->shared->checked_filters = TRUE;
|
||||
} /* end if */
|
||||
|
||||
/* Check if we are allowed to write to this file */
|
||||
if (0 == (H5F_INTENT(dset_info[i].dset->oloc.file) & H5F_ACC_RDWR))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
|
||||
|
||||
/* Set up datatype info for operation */
|
||||
if (H5D__typeinfo_init(&io_info, &(dset_info[i]), dset_info[i].mem_type_id) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info")
|
||||
type_info_init++;
|
||||
|
||||
/* Various MPI based checks */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
if (H5F_HAS_FEATURE(dset_info[i].dset->oloc.file, H5FD_FEAT_HAS_MPI)) {
|
||||
/* If MPI based VFD is used, no VL or region reference datatype support yet. */
|
||||
/* This is because they use the global heap in the file and we don't */
|
||||
/* support parallel access of that yet */
|
||||
if (H5T_is_vl_storage(dset_info[i].type_info.mem_type) > 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
|
||||
"Parallel IO does not support writing VL or region reference datatypes yet")
|
||||
} /* end if */
|
||||
else {
|
||||
H5FD_mpio_xfer_t io_xfer_mode; /* MPI I/O transfer mode */
|
||||
|
||||
/* Get I/O transfer mode */
|
||||
if (H5CX_get_io_xfer_mode(&io_xfer_mode) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode")
|
||||
|
||||
/* Collective access is not permissible without a MPI based VFD */
|
||||
if (io_xfer_mode == H5FD_MPIO_COLLECTIVE)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based driver only")
|
||||
} /* end else */
|
||||
#endif /*H5_HAVE_PARALLEL*/
|
||||
|
||||
/* Make certain that the number of elements in each selection is the same, and cache nelmts in
|
||||
* dset_info */
|
||||
dset_info[i].nelmts = H5S_GET_SELECT_NPOINTS(dset_info[i].mem_space);
|
||||
if (dset_info[i].nelmts != H5S_GET_SELECT_NPOINTS(dset_info[i].file_space))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
|
||||
"src and dest dataspaces have different number of elements selected")
|
||||
|
||||
/* Check for a NULL buffer */
|
||||
if (NULL == dset_info[i].buf.cvp) {
|
||||
/* Check for any elements selected (which is invalid) */
|
||||
if (dset_info[i].nelmts > 0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
|
||||
|
||||
/* If the buffer is nil, and 0 element is selected, make a fake buffer.
|
||||
* This is for some MPI package like ChaMPIon on NCSA's tungsten which
|
||||
* doesn't support this feature.
|
||||
*/
|
||||
dset_info[i].buf.cvp = &fake_char;
|
||||
} /* end if */
|
||||
|
||||
/* Make sure that both selections have their extents set */
|
||||
if (!(H5S_has_extent(dset_info[i].file_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file dataspace does not have extent set")
|
||||
if (!(H5S_has_extent(dset_info[i].mem_space)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "memory dataspace does not have extent set")
|
||||
|
||||
/* H5S_select_shape_same() has been modified to accept topologically
|
||||
* identical selections with different rank as having the same shape
|
||||
* (if the most rapidly changing coordinates match up), but the I/O
|
||||
* code still has difficulties with the notion.
|
||||
*
|
||||
* To solve this, we check to see if H5S_select_shape_same() returns
|
||||
* true, and if the ranks of the mem and file spaces are different.
|
||||
* If they are, construct a new mem space that is equivalent to the
|
||||
* old mem space, and use that instead.
|
||||
*
|
||||
* Note that in general, this requires us to touch up the memory buffer
|
||||
* as well.
|
||||
*/
|
||||
if (dset_info[i].nelmts > 0 &&
|
||||
TRUE == H5S_SELECT_SHAPE_SAME(dset_info[i].mem_space, dset_info[i].file_space) &&
|
||||
H5S_GET_EXTENT_NDIMS(dset_info[i].mem_space) != H5S_GET_EXTENT_NDIMS(dset_info[i].file_space)) {
|
||||
ptrdiff_t buf_adj = 0;
|
||||
|
||||
/* Allocate original memory space buffer if necessary */
|
||||
if (!orig_mem_space) {
|
||||
if (count > 1) {
|
||||
/* Allocate buffer */
|
||||
if (NULL == (orig_mem_space = (H5S_t **)H5MM_calloc(count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
"couldn't allocate original memory space array buffer")
|
||||
}
|
||||
else
|
||||
/* Use local buffer */
|
||||
orig_mem_space = &orig_mem_space_local;
|
||||
}
|
||||
|
||||
/* Save original memory space */
|
||||
orig_mem_space[i] = dset_info[i].mem_space;
|
||||
dset_info[i].mem_space = NULL;
|
||||
|
||||
/* Attempt to construct projected dataspace for memory dataspace */
|
||||
if (H5S_select_construct_projection(orig_mem_space[i], &dset_info[i].mem_space,
|
||||
(unsigned)H5S_GET_EXTENT_NDIMS(dset_info[i].file_space),
|
||||
dset_info[i].type_info.src_type_size, &buf_adj) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to construct projected memory dataspace")
|
||||
HDassert(dset_info[i].mem_space);
|
||||
|
||||
/* Adjust the buffer by the given amount */
|
||||
dset_info[i].buf.cvp = (const void *)(((const uint8_t *)dset_info[i].buf.cvp) + buf_adj);
|
||||
} /* end if */
|
||||
|
||||
/* Retrieve dataset properties */
|
||||
/* <none needed currently> */
|
||||
|
||||
/* Set up I/O operation */
|
||||
if (H5D__dset_ioinfo_init(dset_info[i].dset, &(dset_info[i]), &(store[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up I/O operation")
|
||||
|
||||
/* Allocate dataspace and initialize it if it hasn't been. */
|
||||
should_alloc_space = dset_info[i].dset->shared->dcpl_cache.efl.nused == 0 &&
|
||||
!(*dset_info[i].dset->shared->layout.ops->is_space_alloc)(
|
||||
&dset_info[i].dset->shared->layout.storage);
|
||||
|
||||
/*
|
||||
* If not using an MPI-based VFD, we only need to allocate
|
||||
* and initialize storage if there's a selection in the
|
||||
* dataset's dataspace. Otherwise, we always need to participate
|
||||
* in the storage allocation since this may use collective
|
||||
* operations and we will hang if we don't participate.
|
||||
*/
|
||||
if (!H5F_HAS_FEATURE(dset_info[i].dset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
should_alloc_space = should_alloc_space && (dset_info[i].nelmts > 0);
|
||||
|
||||
if (should_alloc_space) {
|
||||
hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
|
||||
hbool_t full_overwrite; /* Whether we are over-writing all the elements */
|
||||
|
||||
/* Get the number of elements in file dataset's dataspace */
|
||||
if ((file_nelmts = H5S_GET_EXTENT_NPOINTS(dset_info[i].file_space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL,
|
||||
"can't retrieve number of elements in file dataset")
|
||||
|
||||
/* Always allow fill values to be written if the dataset has a VL datatype */
|
||||
if (H5T_detect_class(dset_info[i].dset->shared->type, H5T_VLEN, FALSE))
|
||||
full_overwrite = FALSE;
|
||||
else
|
||||
full_overwrite = (hbool_t)((hsize_t)file_nelmts == dset_info[i].nelmts ? TRUE : FALSE);
|
||||
|
||||
/* Allocate storage */
|
||||
if (H5D__alloc_storage(dset_info[i].dset, H5D_ALLOC_WRITE, full_overwrite, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
|
||||
} /* end if */
|
||||
|
||||
/* Call storage method's I/O initialization routine */
|
||||
/* Init io_info.dset_info[] and generate piece_info in skip list */
|
||||
if (dset_info[i].layout_ops.io_init &&
|
||||
(*dset_info[i].layout_ops.io_init)(&io_info, &(dset_info[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize I/O info")
|
||||
dset_info[i].skip_io = FALSE;
|
||||
io_op_init++;
|
||||
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
} /* end of for loop */
|
||||
|
||||
HDassert(type_info_init == count);
|
||||
HDassert(io_op_init == count);
|
||||
|
||||
/* Perform second phase of type info initialization */
|
||||
if (H5D__typeinfo_init_phase2(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up type info (second phase)")
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Adjust I/O info for any parallel I/O */
|
||||
if (H5D__ioinfo_adjust(&io_info, dataset, file_space, mem_space, &type_info) < 0)
|
||||
if (H5D__ioinfo_adjust(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to adjust I/O info for parallel I/O")
|
||||
#endif /*H5_HAVE_PARALLEL*/
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*io_info.io_ops.multi_write)(&io_info, &type_info, nelmts, file_space, mem_space, fm) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
|
||||
/* If multi dataset I/O callback is not provided, perform write IO via
|
||||
* single-dset path with looping */
|
||||
if (io_info.md_io_ops.multi_write_md) {
|
||||
/* Create sel_pieces array if any pieces are selected */
|
||||
if (io_info.piece_count > 0) {
|
||||
HDassert(!io_info.sel_pieces);
|
||||
HDassert(io_info.pieces_added == 0);
|
||||
|
||||
/* Allocate sel_pieces array */
|
||||
if (NULL ==
|
||||
(io_info.sel_pieces = H5MM_malloc(io_info.piece_count * sizeof(io_info.sel_pieces[0]))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate array of selected pieces")
|
||||
}
|
||||
|
||||
/* MDIO-specific second phase initialization */
|
||||
for (i = 0; i < count; i++)
|
||||
if (dset_info[i].layout_ops.mdio_init) {
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info[i].dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* Make second phase IO init call */
|
||||
if ((dset_info[i].layout_ops.mdio_init)(&io_info, &(dset_info[i])) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't populate array of selected pieces")
|
||||
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
}
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*io_info.md_io_ops.multi_write_md)(&io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
|
||||
} /* end if */
|
||||
else {
|
||||
haddr_t prev_tag = HADDR_UNDEF;
|
||||
|
||||
if (!H5D_LAYOUT_CB_PERFORM_IO(&io_info) && io_info.piece_count > 0) {
|
||||
if (NULL == (io_info.mem_spaces = H5MM_malloc(io_info.piece_count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for memory space list")
|
||||
if (NULL == (io_info.file_spaces = H5MM_malloc(io_info.piece_count * sizeof(H5S_t *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed for file space list")
|
||||
if (NULL == (io_info.addrs = H5MM_malloc(io_info.piece_count * sizeof(haddr_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for piece address list")
|
||||
if (NULL == (io_info.element_sizes = H5MM_malloc(io_info.piece_count * sizeof(size_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for element size list")
|
||||
if (NULL == (io_info.wbufs = H5MM_malloc(io_info.piece_count * sizeof(const void *))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL,
|
||||
"memory allocation failed for read buffer list")
|
||||
}
|
||||
|
||||
/* loop with serial & single-dset write IO path */
|
||||
for (i = 0; i < count; i++) {
|
||||
HDassert(!dset_info[i].skip_io);
|
||||
|
||||
/* set metadata tagging with dset oheader addr */
|
||||
H5AC_tag(dset_info->dset->oloc.addr, &prev_tag);
|
||||
|
||||
/* Invoke correct "high level" I/O routine */
|
||||
if ((*dset_info[i].io_ops.multi_write)(&io_info, &dset_info[i]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
|
||||
|
||||
/* Reset metadata tagging */
|
||||
H5AC_tag(prev_tag, NULL);
|
||||
}
|
||||
|
||||
/* Make final multi dataset selection I/O call if we are using both
|
||||
* features - in this case the multi_write callbacks did not perform the
|
||||
* actual I/O */
|
||||
H5_CHECK_OVERFLOW(io_info.pieces_added, size_t, uint32_t)
|
||||
if (!H5D_LAYOUT_CB_PERFORM_IO(&io_info))
|
||||
if (H5F_shared_select_write(io_info.f_sh, H5FD_MEM_DRAW, (uint32_t)io_info.pieces_added,
|
||||
io_info.mem_spaces, io_info.file_spaces, io_info.addrs,
|
||||
io_info.element_sizes, io_info.wbufs) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "selection write failed")
|
||||
}
|
||||
|
||||
#ifdef OLD_WAY
|
||||
/*
|
||||
@@ -515,88 +774,138 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_spac
|
||||
|
||||
done:
|
||||
/* Shut down the I/O op information */
|
||||
if (io_op_init && io_info.layout_ops.io_term && (*io_info.layout_ops.io_term)(fm) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
|
||||
if (fm)
|
||||
fm = H5FL_FREE(H5D_chunk_map_t, fm);
|
||||
for (i = 0; i < io_op_init; i++) {
|
||||
HDassert(!dset_info[i].skip_io);
|
||||
if (dset_info[i].layout_ops.io_term &&
|
||||
(*dset_info[i].layout_ops.io_term)(&io_info, &(dset_info[i])) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down I/O op info")
|
||||
}
|
||||
|
||||
/* Shut down datatype info for operation */
|
||||
if (type_info_init && H5D__typeinfo_term(&type_info) < 0)
|
||||
if (H5D__typeinfo_term(&io_info, type_info_init) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down type info")
|
||||
|
||||
/* discard projected mem space if it was created */
|
||||
if (NULL != projected_mem_space)
|
||||
if (H5S_close(projected_mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to shut down projected memory dataspace")
|
||||
/* Discard projected mem spaces and restore originals */
|
||||
if (orig_mem_space) {
|
||||
for (i = 0; i < count; i++)
|
||||
if (orig_mem_space[i]) {
|
||||
if (H5S_close(dset_info[i].mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL,
|
||||
"unable to shut down projected memory dataspace")
|
||||
dset_info[i].mem_space = orig_mem_space[i];
|
||||
}
|
||||
|
||||
FUNC_LEAVE_NOAPI_TAG(ret_value)
|
||||
} /* end H5D__write() */
|
||||
/* Free orig_mem_space array if it was allocated */
|
||||
if (orig_mem_space != &orig_mem_space_local)
|
||||
H5MM_free(orig_mem_space);
|
||||
}
|
||||
|
||||
/* Free global piece array */
|
||||
H5MM_xfree(io_info.sel_pieces);
|
||||
|
||||
/* Free store array if it was allocated */
|
||||
if (store != &store_local)
|
||||
H5MM_free(store);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__write */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__ioinfo_init
|
||||
*
|
||||
* Purpose: Routine for determining correct I/O operations for
|
||||
* each I/O action.
|
||||
* Purpose: General setup for H5D_io_info_t struct
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, September 30, 2004
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__ioinfo_init(H5D_t *dset, const H5D_type_info_t *type_info, H5D_storage_t *store, H5D_io_info_t *io_info)
|
||||
H5D__ioinfo_init(size_t count, H5D_dset_io_info_t *dset_info, H5D_io_info_t *io_info)
|
||||
{
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
/* check args */
|
||||
HDassert(count > 0);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info[0].dset->oloc.file);
|
||||
HDassert(io_info);
|
||||
|
||||
/* Zero out struct */
|
||||
HDmemset(io_info, 0, sizeof(*io_info));
|
||||
|
||||
/* Set up simple fields */
|
||||
io_info->f_sh = count > 0 ? H5F_SHARED(dset_info[0].dset->oloc.file) : NULL;
|
||||
io_info->count = count;
|
||||
|
||||
/* Start without multi-dataset I/O ops. If we're not using the collective
|
||||
* I/O path then we will call the single dataset callbacks in a loop. */
|
||||
|
||||
/* Use provided dset_info */
|
||||
io_info->dsets_info = dset_info;
|
||||
|
||||
/* Start with selection I/O on if the global is on, layout callback will
|
||||
* turn it off if appropriate */
|
||||
io_info->use_select_io = H5_use_selection_io_g;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Determine if the file was opened with an MPI VFD */
|
||||
if (count > 0)
|
||||
io_info->using_mpi_vfd = H5F_HAS_FEATURE(dset_info[0].dset->oloc.file, H5FD_FEAT_HAS_MPI);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__ioinfo_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__dset_ioinfo_init
|
||||
*
|
||||
* Purpose: Routine for determining correct I/O operations for each I/O action.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__dset_ioinfo_init(H5D_t *dset, H5D_dset_io_info_t *dset_info, H5D_storage_t *store)
|
||||
{
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
/* check args */
|
||||
HDassert(dset);
|
||||
HDassert(dset->oloc.file);
|
||||
HDassert(type_info);
|
||||
HDassert(type_info->tpath);
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info->type_info.tpath);
|
||||
|
||||
/* Set up "normal" I/O fields */
|
||||
io_info->dset = dset;
|
||||
io_info->f_sh = H5F_SHARED(dset->oloc.file);
|
||||
io_info->store = store;
|
||||
dset_info->dset = dset;
|
||||
dset_info->store = store;
|
||||
|
||||
/* Set I/O operations to initial values */
|
||||
io_info->layout_ops = *dset->shared->layout.ops;
|
||||
dset_info->layout_ops = *dset->shared->layout.ops;
|
||||
|
||||
/* Set the "high-level" I/O operations for the dataset */
|
||||
io_info->io_ops.multi_read = dset->shared->layout.ops->ser_read;
|
||||
io_info->io_ops.multi_write = dset->shared->layout.ops->ser_write;
|
||||
dset_info->io_ops.multi_read = dset->shared->layout.ops->ser_read;
|
||||
dset_info->io_ops.multi_write = dset->shared->layout.ops->ser_write;
|
||||
|
||||
/* Set the I/O operations for reading/writing single blocks on disk */
|
||||
if (type_info->is_xform_noop && type_info->is_conv_noop) {
|
||||
if (dset_info->type_info.is_xform_noop && dset_info->type_info.is_conv_noop) {
|
||||
/*
|
||||
* If there is no data transform or type conversion then read directly into
|
||||
* the application's buffer. This saves at least one mem-to-mem copy.
|
||||
* If there is no data transform or type conversion then read directly
|
||||
* into the application's buffer.
|
||||
* This saves at least one mem-to-mem copy.
|
||||
*/
|
||||
io_info->io_ops.single_read = H5D__select_read;
|
||||
io_info->io_ops.single_write = H5D__select_write;
|
||||
dset_info->io_ops.single_read = H5D__select_read;
|
||||
dset_info->io_ops.single_write = H5D__select_write;
|
||||
} /* end if */
|
||||
else {
|
||||
/*
|
||||
* This is the general case (type conversion, usually).
|
||||
*/
|
||||
io_info->io_ops.single_read = H5D__scatgath_read;
|
||||
io_info->io_ops.single_write = H5D__scatgath_write;
|
||||
dset_info->io_ops.single_read = H5D__scatgath_read;
|
||||
dset_info->io_ops.single_write = H5D__scatgath_write;
|
||||
} /* end else */
|
||||
|
||||
/* Start with selection I/O off, layout callback will turn it on if
|
||||
* appropriate */
|
||||
io_info->use_select_io = FALSE;
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Determine if the file was opened with an MPI VFD */
|
||||
io_info->using_mpi_vfd = H5F_HAS_FEATURE(dset->oloc.file, H5FD_FEAT_HAS_MPI);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__ioinfo_init() */
|
||||
} /* end H5D__dset_ioinfo_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__typeinfo_init
|
||||
@@ -612,8 +921,10 @@ H5D__ioinfo_init(H5D_t *dset, const H5D_type_info_t *type_info, H5D_storage_t *s
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_type_info_t *type_info)
|
||||
H5D__typeinfo_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, hid_t mem_type_id)
|
||||
{
|
||||
H5D_type_info_t *type_info;
|
||||
const H5D_t *dset;
|
||||
const H5T_t *src_type; /* Source datatype */
|
||||
const H5T_t *dst_type; /* Destination datatype */
|
||||
H5Z_data_xform_t *data_transform; /* Data transform info */
|
||||
@@ -622,7 +933,12 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* check args */
|
||||
HDassert(type_info);
|
||||
HDassert(io_info);
|
||||
HDassert(dset_info);
|
||||
|
||||
/* Set convenience pointers */
|
||||
type_info = &dset_info->type_info;
|
||||
dset = dset_info->dset;
|
||||
HDassert(dset);
|
||||
|
||||
/* Patch the top level file pointer for dt->shared->u.vlen.f if needed */
|
||||
@@ -637,7 +953,7 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
|
||||
type_info->dset_type = dset->shared->type;
|
||||
|
||||
if (do_write) {
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE) {
|
||||
src_type = type_info->mem_type;
|
||||
dst_type = dset->shared->type;
|
||||
type_info->src_type_id = mem_type_id;
|
||||
@@ -667,7 +983,6 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
/* Precompute some useful information */
|
||||
type_info->src_type_size = H5T_get_size(src_type);
|
||||
type_info->dst_type_size = H5T_get_size(dst_type);
|
||||
type_info->max_type_size = MAX(type_info->src_type_size, type_info->dst_type_size);
|
||||
type_info->is_conv_noop = H5T_path_noop(type_info->tpath);
|
||||
type_info->is_xform_noop = H5Z_xform_noop(data_transform);
|
||||
if (type_info->is_xform_noop && type_info->is_conv_noop) {
|
||||
@@ -675,27 +990,21 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
type_info->need_bkg = H5T_BKG_NO;
|
||||
} /* end if */
|
||||
else {
|
||||
void *tconv_buf; /* Temporary conversion buffer pointer */
|
||||
void *bkgr_buf; /* Background conversion buffer pointer */
|
||||
size_t max_temp_buf; /* Maximum temporary buffer size */
|
||||
H5T_bkg_t bkgr_buf_type; /* Background buffer type */
|
||||
size_t target_size; /* Desired buffer size */
|
||||
|
||||
/* Get info from API context */
|
||||
if (H5CX_get_max_temp_buf(&max_temp_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve max. temp. buf size")
|
||||
if (H5CX_get_tconv_buf(&tconv_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve temp. conversion buffer pointer")
|
||||
if (H5CX_get_bkgr_buf(&bkgr_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve background conversion buffer pointer")
|
||||
if (H5CX_get_bkgr_buf_type(&bkgr_buf_type) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve background buffer type")
|
||||
|
||||
/* Check if the datatypes are compound subsets of one another */
|
||||
type_info->cmpd_subset = H5T_path_compound_subset(type_info->tpath);
|
||||
|
||||
/* Update io_info->max_type_size */
|
||||
io_info->max_type_size =
|
||||
MAX3(io_info->max_type_size, type_info->src_type_size, type_info->dst_type_size);
|
||||
|
||||
/* Check if we need a background buffer */
|
||||
if (do_write && H5T_detect_class(dset->shared->type, H5T_VLEN, FALSE))
|
||||
if ((io_info->op_type == H5D_IO_OP_WRITE) && H5T_detect_class(dset->shared->type, H5T_VLEN, FALSE))
|
||||
type_info->need_bkg = H5T_BKG_YES;
|
||||
else {
|
||||
H5T_bkg_t path_bkg; /* Type conversion's background info */
|
||||
@@ -708,13 +1017,54 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
else
|
||||
type_info->need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__typeinfo_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__typeinfo_init_phase2
|
||||
*
|
||||
* Purpose: Finish initializing type info for all datasets after
|
||||
* calculating the max type size across all datasets.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__typeinfo_init_phase2(H5D_io_info_t *io_info)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* check args */
|
||||
HDassert(io_info);
|
||||
|
||||
/* Check if we need to allocate a shared type conversion buffer */
|
||||
if (io_info->max_type_size) {
|
||||
void *tconv_buf; /* Temporary conversion buffer pointer */
|
||||
void *bkgr_buf; /* Background conversion buffer pointer */
|
||||
size_t max_temp_buf; /* Maximum temporary buffer size */
|
||||
size_t target_size; /* Desired buffer size */
|
||||
size_t i; /* Local index variable */
|
||||
|
||||
/* Get info from API context */
|
||||
if (H5CX_get_max_temp_buf(&max_temp_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve max. temp. buf size")
|
||||
if (H5CX_get_tconv_buf(&tconv_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve temp. conversion buffer pointer")
|
||||
if (H5CX_get_bkgr_buf(&bkgr_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve background conversion buffer pointer")
|
||||
|
||||
/* Set up datatype conversion/background buffers */
|
||||
|
||||
target_size = max_temp_buf;
|
||||
|
||||
/* If the buffer is too small to hold even one element, try to make it bigger */
|
||||
if (target_size < type_info->max_type_size) {
|
||||
/* If the buffer is too small to hold even one element (in the dataset with the largest , try to make
|
||||
* it bigger */
|
||||
if (target_size < io_info->max_type_size) {
|
||||
hbool_t default_buffer_info; /* Whether the buffer information are the defaults */
|
||||
|
||||
/* Detect if we have all default settings for buffers */
|
||||
@@ -724,50 +1074,64 @@ H5D__typeinfo_init(const H5D_t *dset, hid_t mem_type_id, hbool_t do_write, H5D_t
|
||||
/* Check if we are using the default buffer info */
|
||||
if (default_buffer_info)
|
||||
/* OK to get bigger for library default settings */
|
||||
target_size = type_info->max_type_size;
|
||||
target_size = io_info->max_type_size;
|
||||
else
|
||||
/* Don't get bigger than the application has requested */
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small")
|
||||
} /* end if */
|
||||
|
||||
/* Compute the number of elements that will fit into buffer */
|
||||
type_info->request_nelmts = target_size / type_info->max_type_size;
|
||||
|
||||
/* Sanity check elements in temporary buffer */
|
||||
if (type_info->request_nelmts == 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small")
|
||||
|
||||
/* Get a temporary buffer for type conversion unless the app has already
|
||||
* supplied one through the xfer properties. Instead of allocating a
|
||||
* buffer which is the exact size, we allocate the target size.
|
||||
*/
|
||||
if (NULL == (type_info->tconv_buf = (uint8_t *)tconv_buf)) {
|
||||
* buffer which is the exact size, we allocate the target size. This
|
||||
* buffer is shared among all datasets in the operation, unlike for the
|
||||
* background buffer, where each dataset gets its own. */
|
||||
if (NULL == (io_info->tconv_buf = (uint8_t *)tconv_buf)) {
|
||||
/* Allocate temporary buffer */
|
||||
if (NULL == (type_info->tconv_buf = H5FL_BLK_CALLOC(type_conv, target_size)))
|
||||
if (NULL == (io_info->tconv_buf = H5FL_BLK_MALLOC(type_conv, target_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
|
||||
type_info->tconv_buf_allocated = TRUE;
|
||||
io_info->tconv_buf_allocated = TRUE;
|
||||
} /* end if */
|
||||
if (type_info->need_bkg && NULL == (type_info->bkg_buf = (uint8_t *)bkgr_buf)) {
|
||||
size_t bkg_size; /* Desired background buffer size */
|
||||
|
||||
/* Compute the background buffer size */
|
||||
/* (don't try to use buffers smaller than the default size) */
|
||||
bkg_size = type_info->request_nelmts * type_info->dst_type_size;
|
||||
if (bkg_size < max_temp_buf)
|
||||
bkg_size = max_temp_buf;
|
||||
/* Don't use API provided background buffer if there's more than one dataset, since each
|
||||
* dataset needs its own */
|
||||
if (io_info->count > 1)
|
||||
bkgr_buf = NULL;
|
||||
|
||||
/* Allocate background buffer */
|
||||
/* (Need calloc()-like call since memory needs to be initialized) */
|
||||
if (NULL == (type_info->bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
|
||||
"memory allocation failed for background conversion")
|
||||
type_info->bkg_buf_allocated = TRUE;
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
/* Iterate over datasets */
|
||||
for (i = 0; i < io_info->count; i++) {
|
||||
H5D_type_info_t *type_info = &io_info->dsets_info[i].type_info;
|
||||
|
||||
/* Compute the number of elements that will fit into buffer */
|
||||
type_info->request_nelmts = target_size / MAX(type_info->src_type_size, type_info->dst_type_size);
|
||||
;
|
||||
|
||||
/* Sanity check elements in temporary buffer */
|
||||
if (type_info->request_nelmts == 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small")
|
||||
|
||||
/* Allocate background buffer if necessary */
|
||||
if (type_info->need_bkg && NULL == (type_info->bkg_buf = (uint8_t *)bkgr_buf)) {
|
||||
size_t bkg_size; /* Desired background buffer size */
|
||||
|
||||
/* Compute the background buffer size */
|
||||
/* (don't try to use buffers smaller than the default size) */
|
||||
bkg_size = type_info->request_nelmts * type_info->dst_type_size;
|
||||
if (bkg_size < max_temp_buf)
|
||||
bkg_size = max_temp_buf;
|
||||
|
||||
/* Allocate background buffer */
|
||||
/* (Need calloc()-like call since memory needs to be initialized) */
|
||||
if (NULL == (type_info->bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
|
||||
"memory allocation failed for background conversion")
|
||||
type_info->bkg_buf_allocated = TRUE;
|
||||
} /* end if */
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__typeinfo_init() */
|
||||
} /* end H5D__typeinfo_init_phase2() */
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
|
||||
@@ -776,30 +1140,28 @@ done:
|
||||
*
|
||||
* Purpose: Adjust operation's I/O info for any parallel I/O
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* This was derived from H5D__ioinfo_adjust for multi-dset work.
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, March 27, 2008
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_space, const H5S_t *mem_space,
|
||||
const H5D_type_info_t *type_info)
|
||||
H5D__ioinfo_adjust(H5D_io_info_t *io_info)
|
||||
{
|
||||
H5D_t *dset0; /* only the first dset , also for single dsets case */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* check args */
|
||||
HDassert(dset);
|
||||
HDassert(dset->oloc.file);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(type_info);
|
||||
HDassert(type_info->tpath);
|
||||
HDassert(io_info);
|
||||
|
||||
/* check the first dset, should exist either single or multi dset cases */
|
||||
HDassert(io_info->dsets_info[0].dset);
|
||||
dset0 = io_info->dsets_info[0].dset;
|
||||
HDassert(dset0->oloc.file);
|
||||
|
||||
/* Reset the actual io mode properties to the default values in case
|
||||
* the DXPL (if it's non-default) was previously used in a collective
|
||||
* I/O operation.
|
||||
@@ -819,11 +1181,11 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O transfer mode")
|
||||
|
||||
/* Get MPI communicator */
|
||||
if (MPI_COMM_NULL == (io_info->comm = H5F_mpi_get_comm(dset->oloc.file)))
|
||||
if (MPI_COMM_NULL == (io_info->comm = H5F_mpi_get_comm(dset0->oloc.file)))
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator")
|
||||
|
||||
/* Check if we can set direct MPI-IO read/write functions */
|
||||
if ((opt = H5D__mpio_opt_possible(io_info, file_space, mem_space, type_info)) < 0)
|
||||
if ((opt = H5D__mpio_opt_possible(io_info)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "invalid check for direct IO dataspace ")
|
||||
|
||||
/* Check if we can use the optimized parallel I/O routines */
|
||||
@@ -833,10 +1195,10 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_
|
||||
* handle collective I/O */
|
||||
/* Check for selection/vector support in file driver? -NAF */
|
||||
if (!io_info->use_select_io) {
|
||||
io_info->io_ops.multi_read = dset->shared->layout.ops->par_read;
|
||||
io_info->io_ops.multi_write = dset->shared->layout.ops->par_write;
|
||||
io_info->io_ops.single_read = H5D__mpio_select_read;
|
||||
io_info->io_ops.single_write = H5D__mpio_select_write;
|
||||
io_info->md_io_ops.multi_read_md = H5D__collective_read;
|
||||
io_info->md_io_ops.multi_write_md = H5D__collective_write;
|
||||
io_info->md_io_ops.single_read_md = H5D__mpio_select_read;
|
||||
io_info->md_io_ops.single_write_md = H5D__mpio_select_write;
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
else {
|
||||
@@ -857,28 +1219,38 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_
|
||||
* with multiple ranks involved; otherwise, there will be metadata
|
||||
* inconsistencies in the file.
|
||||
*/
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
int comm_size = 0;
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE) {
|
||||
size_t i;
|
||||
|
||||
/* Retrieve size of MPI communicator used for file */
|
||||
if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size")
|
||||
/* Check all datasets for filters */
|
||||
for (i = 0; i < io_info->count; i++)
|
||||
if (io_info->dsets_info[i].dset->shared->dcpl_cache.pline.nused > 0)
|
||||
break;
|
||||
|
||||
if (comm_size > 1) {
|
||||
char local_no_coll_cause_string[512];
|
||||
char global_no_coll_cause_string[512];
|
||||
/* If the above loop didn't complete at least one dataset has a filter */
|
||||
if (i < io_info->count) {
|
||||
int comm_size = 0;
|
||||
|
||||
if (H5D__mpio_get_no_coll_cause_strings(local_no_coll_cause_string, 512,
|
||||
global_no_coll_cause_string, 512) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
|
||||
"can't get reasons for breaking collective I/O")
|
||||
/* Retrieve size of MPI communicator used for file */
|
||||
if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size")
|
||||
|
||||
HGOTO_ERROR(H5E_IO, H5E_NO_INDEPENDENT, FAIL,
|
||||
"Can't perform independent write with filters in pipeline.\n"
|
||||
" The following caused a break from collective I/O:\n"
|
||||
" Local causes: %s\n"
|
||||
" Global causes: %s",
|
||||
local_no_coll_cause_string, global_no_coll_cause_string);
|
||||
if (comm_size > 1) {
|
||||
char local_no_coll_cause_string[512];
|
||||
char global_no_coll_cause_string[512];
|
||||
|
||||
if (H5D__mpio_get_no_coll_cause_strings(local_no_coll_cause_string, 512,
|
||||
global_no_coll_cause_string, 512) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
|
||||
"can't get reasons for breaking collective I/O")
|
||||
|
||||
HGOTO_ERROR(H5E_IO, H5E_NO_INDEPENDENT, FAIL,
|
||||
"Can't perform independent write with filters in pipeline.\n"
|
||||
" The following caused a break from collective I/O:\n"
|
||||
" Local causes: %s\n"
|
||||
" Global causes: %s",
|
||||
local_no_coll_cause_string, global_no_coll_cause_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -899,31 +1271,34 @@ done:
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__typeinfo_term
|
||||
* Function: H5D__typeinfo_term
|
||||
*
|
||||
* Purpose: Common logic for terminating a type info object
|
||||
* Purpose: Common logic for terminating a type info object
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, March 6, 2008
|
||||
* Programmer: Quincey Koziol
|
||||
* Thursday, March 6, 2008
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__typeinfo_term(const H5D_type_info_t *type_info)
|
||||
H5D__typeinfo_term(H5D_io_info_t *io_info, size_t type_info_init)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
/* Check for releasing datatype conversion & background buffers */
|
||||
if (type_info->tconv_buf_allocated) {
|
||||
HDassert(type_info->tconv_buf);
|
||||
(void)H5FL_BLK_FREE(type_conv, type_info->tconv_buf);
|
||||
} /* end if */
|
||||
if (type_info->bkg_buf_allocated) {
|
||||
HDassert(type_info->bkg_buf);
|
||||
(void)H5FL_BLK_FREE(type_conv, type_info->bkg_buf);
|
||||
if (io_info->tconv_buf_allocated) {
|
||||
HDassert(io_info->tconv_buf);
|
||||
(void)H5FL_BLK_FREE(type_conv, io_info->tconv_buf);
|
||||
} /* end if */
|
||||
for (i = 0; i < type_info_init; i++)
|
||||
if (io_info->dsets_info[i].type_info.bkg_buf_allocated) {
|
||||
HDassert(io_info->dsets_info[i].type_info.bkg_buf);
|
||||
(void)H5FL_BLK_FREE(type_conv, io_info->dsets_info[i].type_info.bkg_buf);
|
||||
} /* end if */
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__typeinfo_term() */
|
||||
|
||||
+2
-7
@@ -489,14 +489,9 @@ H5D__layout_oh_create(H5F_t *file, H5O_t *oh, H5D_t *dset, hid_t dapl_id)
|
||||
* Allocate storage if space allocate time is early; otherwise delay
|
||||
* allocation until later.
|
||||
*/
|
||||
if (fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY) {
|
||||
H5D_io_info_t io_info;
|
||||
|
||||
io_info.dset = dset;
|
||||
|
||||
if (H5D__alloc_storage(&io_info, H5D_ALLOC_CREATE, FALSE, NULL) < 0)
|
||||
if (fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY)
|
||||
if (H5D__alloc_storage(dset, H5D_ALLOC_CREATE, FALSE, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
|
||||
}
|
||||
|
||||
/* Update external storage message, if it's used */
|
||||
if (dset->shared->dcpl_cache.efl.nused > 0) {
|
||||
|
||||
+799
-888
@@ -55,12 +55,15 @@
|
||||
#define H5D_MULTI_CHUNK_IO 1
|
||||
#define H5D_ONE_LINK_CHUNK_IO_MORE_OPT 2
|
||||
#define H5D_MULTI_CHUNK_IO_MORE_OPT 3
|
||||
#define H5D_NO_IO 4
|
||||
|
||||
/***** Macros for One linked collective IO case. *****/
|
||||
/* The default value to do one linked collective IO for all chunks.
|
||||
If the average number of chunks per process is greater than this value,
|
||||
the library will create an MPI derived datatype to link all chunks to do collective IO.
|
||||
The user can set this value through an API. */
|
||||
* If the average number of chunks per process is greater than this
|
||||
* value, the library will create an MPI derived datatype to link all
|
||||
* chunks to do collective IO. The user can set this value through an
|
||||
* API.
|
||||
*/
|
||||
|
||||
/* Macros to represent options on how to obtain chunk address for one linked-chunk IO case */
|
||||
#define H5D_OBTAIN_ONE_CHUNK_ADDR_IND 0
|
||||
@@ -71,10 +74,10 @@
|
||||
#define H5D_ALL_CHUNK_ADDR_THRES_COL_NUM 10000
|
||||
|
||||
/***** Macros for multi-chunk collective IO case. *****/
|
||||
/* The default value of the threshold to do collective IO for this chunk.
|
||||
If the average number of processes per chunk is greater than the default value,
|
||||
collective IO is done for this chunk.
|
||||
*/
|
||||
/* The default value of the threshold to do collective IO for this
|
||||
* chunk. If the average number of processes per chunk is greater
|
||||
* than the default value, collective IO is done for this chunk.
|
||||
*/
|
||||
|
||||
/* Macros to represent different IO modes(NONE, Independent or collective)for multiple chunk IO case */
|
||||
#define H5D_CHUNK_IO_MODE_COL 1
|
||||
@@ -107,12 +110,12 @@
|
||||
* structure, given a pointer to a H5D_io_info_t
|
||||
* structure
|
||||
*/
|
||||
#define H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info_ptr) \
|
||||
#define H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, dset) \
|
||||
do { \
|
||||
index_info.f = (io_info_ptr)->dset->oloc.file; \
|
||||
index_info.pline = &((io_info_ptr)->dset->shared->dcpl_cache.pline); \
|
||||
index_info.layout = &((io_info_ptr)->dset->shared->layout.u.chunk); \
|
||||
index_info.storage = &((io_info_ptr)->dset->shared->layout.storage.u.chunk); \
|
||||
index_info.f = (dset)->oloc.file; \
|
||||
index_info.pline = &((dset)->shared->dcpl_cache.pline); \
|
||||
index_info.layout = &((dset)->shared->layout.u.chunk); \
|
||||
index_info.storage = &((dset)->shared->layout.storage.u.chunk); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@@ -130,10 +133,12 @@
|
||||
/* Local Typedefs */
|
||||
/******************/
|
||||
|
||||
/* Combine chunk address and chunk info into a struct for better performance. */
|
||||
/* Combine chunk/piece address and chunk/piece info into a struct for
|
||||
* better performance. */
|
||||
typedef struct H5D_chunk_addr_info_t {
|
||||
haddr_t chunk_addr;
|
||||
H5D_chunk_info_t chunk_info;
|
||||
/* piece for multi-dset */
|
||||
haddr_t piece_addr;
|
||||
H5D_piece_info_t piece_info;
|
||||
} H5D_chunk_addr_info_t;
|
||||
|
||||
/* Rank 0 Bcast values */
|
||||
@@ -187,7 +192,7 @@ typedef struct H5D_chunk_index_info_t {
|
||||
* need_insert - A flag which determines whether or not a chunk needs to be re-inserted into
|
||||
* the chunk index after the write operation.
|
||||
*
|
||||
* chunk_info - A pointer to the chunk's H5D_chunk_info_t structure, which contains useful
|
||||
* chunk_info - A pointer to the chunk's H5D_piece_info_t structure, which contains useful
|
||||
* information like the dataspaces containing the selection in the chunk.
|
||||
*
|
||||
* chunk_current - The address in the file and size of this chunk before the filtering
|
||||
@@ -241,7 +246,7 @@ typedef struct H5D_chunk_index_info_t {
|
||||
typedef struct H5D_filtered_collective_io_info_t {
|
||||
H5D_chunk_index_info_t index_info;
|
||||
|
||||
H5D_chunk_info_t *chunk_info;
|
||||
H5D_piece_info_t *chunk_info;
|
||||
H5F_block_t chunk_current;
|
||||
H5F_block_t chunk_new;
|
||||
hbool_t need_read;
|
||||
@@ -281,65 +286,57 @@ typedef struct H5D_chunk_insert_info_t {
|
||||
/********************/
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
static herr_t H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
|
||||
static herr_t H5D__piece_io(H5D_io_info_t *io_info);
|
||||
static herr_t H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info,
|
||||
int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info,
|
||||
int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm, int sum_chunk, int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
static herr_t H5D__link_piece_collective_io(H5D_io_info_t *io_info, int mpi_rank);
|
||||
static herr_t H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info,
|
||||
int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_dset_io_info_t *di,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
static herr_t H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type);
|
||||
static herr_t H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
|
||||
H5D_chunk_addr_info_t chunk_addr_info_array[], int many_chunk_opt, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assign_io_mode[],
|
||||
static herr_t H5D__final_collective_io(H5D_io_info_t *io_info, hsize_t mpi_buf_count,
|
||||
MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type);
|
||||
static herr_t H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_dset_io_info_t *di, uint8_t assign_io_mode[],
|
||||
haddr_t chunk_addr[], int mpi_rank, int mpi_size);
|
||||
static herr_t H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
|
||||
int *sum_chunkf);
|
||||
static herr_t H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, int *sum_chunkf);
|
||||
static herr_t H5D__mpio_get_sum_chunk_dset(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
int *sum_chunkf);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info,
|
||||
const H5D_chunk_map_t *fm,
|
||||
const H5D_dset_io_info_t *di,
|
||||
H5D_filtered_collective_io_info_t **chunk_list,
|
||||
size_t *num_entries, int mpi_rank);
|
||||
static herr_t H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
|
||||
int mpi_rank, int mpi_size,
|
||||
const H5D_io_info_t *io_info, int mpi_rank, int mpi_size,
|
||||
size_t **rank_chunks_assigned_map);
|
||||
static herr_t H5D__mpio_redistribute_shared_chunks_int(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t *num_chunks_assigned_map,
|
||||
hbool_t all_ranks_involved,
|
||||
const H5D_io_info_t *io_info,
|
||||
const H5D_chunk_map_t *fm, int mpi_rank, int mpi_size);
|
||||
size_t *num_chunks_assigned_map,
|
||||
hbool_t all_ranks_involved,
|
||||
const H5D_io_info_t *io_info, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t *chunk_list_num_entries, H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_rank,
|
||||
H5D_dset_io_info_t *dset_info, int mpi_rank,
|
||||
int mpi_size,
|
||||
H5D_filtered_collective_io_info_t **chunk_hash_table,
|
||||
unsigned char ***chunk_msg_bufs,
|
||||
int *chunk_msg_bufs_len);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_size);
|
||||
size_t chunk_list_num_entries,
|
||||
const H5D_io_info_t *io_info, int mpi_size);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_rank,
|
||||
size_t chunk_list_num_entries,
|
||||
const H5D_io_info_t *io_info,
|
||||
const H5D_dset_io_info_t *di, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
H5D_filtered_collective_io_info_t *chunk_hash_table,
|
||||
unsigned char **chunk_msg_bufs,
|
||||
int chunk_msg_bufs_len, const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_rank,
|
||||
const H5D_dset_io_info_t *di, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_reallocate(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
@@ -348,9 +345,9 @@ static herr_t H5D__mpio_collective_filtered_chunk_reallocate(H5D_filtered_collec
|
||||
H5D_chk_idx_info_t *idx_info, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries,
|
||||
size_t *num_chunks_assigned_map,
|
||||
H5D_io_info_t *io_info,
|
||||
size_t chunk_list_num_entries,
|
||||
size_t *num_chunks_assigned_map,
|
||||
H5D_io_info_t *io_info, H5D_dset_io_info_t *di,
|
||||
H5D_chk_idx_info_t *idx_info, int mpi_rank,
|
||||
int mpi_size);
|
||||
static herr_t H5D__mpio_get_chunk_redistribute_info_types(MPI_Datatype *contig_type,
|
||||
@@ -366,7 +363,7 @@ static herr_t H5D__mpio_collective_filtered_io_type(H5D_filtered_collective_io_i
|
||||
size_t num_entries, H5D_io_op_type_t op_type,
|
||||
MPI_Datatype *new_mem_type, hbool_t *mem_type_derived,
|
||||
MPI_Datatype *new_file_type, hbool_t *file_type_derived);
|
||||
static int H5D__cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2);
|
||||
static int H5D__cmp_piece_addr(const void *chunk_addr_info1, const void *chunk_addr_info2);
|
||||
static int H5D__cmp_filtered_collective_io_info_entry(const void *filtered_collective_io_info_entry1,
|
||||
const void *filtered_collective_io_info_entry2);
|
||||
static int H5D__cmp_chunk_redistribute_info(const void *entry1, const void *entry2);
|
||||
@@ -572,34 +569,40 @@ H5D__mpio_debug_init(void)
|
||||
* Function: H5D__mpio_opt_possible
|
||||
*
|
||||
* Purpose: Checks if an direct I/O transfer is possible between memory and
|
||||
* the file.
|
||||
* the file.
|
||||
*
|
||||
* This was derived from H5D__mpio_opt_possible for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Return: Success: Non-negative: TRUE or FALSE
|
||||
* Failure: Negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Wednesday, April 3, 2002
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
htri_t
|
||||
H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space, const H5S_t *mem_space,
|
||||
const H5D_type_info_t *type_info)
|
||||
H5D__mpio_opt_possible(H5D_io_info_t *io_info)
|
||||
{
|
||||
H5FD_mpio_xfer_t io_xfer_mode; /* MPI I/O transfer mode */
|
||||
H5FD_mpio_xfer_t io_xfer_mode; /* MPI I/O transfer mode */
|
||||
size_t i;
|
||||
H5D_t *dset;
|
||||
const H5S_t *file_space;
|
||||
const H5S_t *mem_space;
|
||||
H5D_type_info_t *type_info;
|
||||
unsigned local_cause[2] = {0, 0}; /* [0] Local reason(s) for breaking collective mode */
|
||||
/* [1] Flag if dataset is both: H5S_ALL and small */
|
||||
unsigned global_cause[2] = {0, 0}; /* Global reason(s) for breaking collective mode */
|
||||
htri_t is_vl_storage; /* Whether the dataset's datatype is stored in a variable-length form */
|
||||
htri_t ret_value = SUCCEED; /* Return value */
|
||||
htri_t is_vl_storage; /* Whether the dataset's datatype is stored in a variable-length form */
|
||||
htri_t ret_value = TRUE; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(type_info);
|
||||
|
||||
for (i = 0; i < io_info->count; i++) {
|
||||
HDassert(io_info->dsets_info[i].file_space);
|
||||
HDassert(io_info->dsets_info[i].mem_space);
|
||||
}
|
||||
|
||||
/* For independent I/O, get out quickly and don't try to form consensus */
|
||||
if (H5CX_get_io_xfer_mode(&io_xfer_mode) < 0)
|
||||
@@ -608,90 +611,103 @@ H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space, co
|
||||
if (io_xfer_mode == H5FD_MPIO_INDEPENDENT)
|
||||
local_cause[0] |= H5D_MPIO_SET_INDEPENDENT;
|
||||
|
||||
/* Optimized MPI types flag must be set */
|
||||
/* (based on 'HDF5_MPI_OPT_TYPES' environment variable) */
|
||||
if (!H5FD_mpi_opt_types_g)
|
||||
local_cause[0] |= H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED;
|
||||
for (i = 0; i < io_info->count; i++) {
|
||||
/* Check for skipped I/O */
|
||||
if (io_info->dsets_info[i].skip_io)
|
||||
continue;
|
||||
|
||||
/* Don't allow collective operations if datatype conversions need to happen */
|
||||
if (!type_info->is_conv_noop)
|
||||
local_cause[0] |= H5D_MPIO_DATATYPE_CONVERSION;
|
||||
/* Set convenience pointers */
|
||||
dset = io_info->dsets_info[i].dset;
|
||||
file_space = io_info->dsets_info[i].file_space;
|
||||
mem_space = io_info->dsets_info[i].mem_space;
|
||||
type_info = &io_info->dsets_info[i].type_info;
|
||||
|
||||
/* Don't allow collective operations if data transform operations should occur */
|
||||
if (!type_info->is_xform_noop)
|
||||
local_cause[0] |= H5D_MPIO_DATA_TRANSFORMS;
|
||||
/* Optimized MPI types flag must be set */
|
||||
/* (based on 'HDF5_MPI_OPT_TYPES' environment variable) */
|
||||
if (!H5FD_mpi_opt_types_g)
|
||||
local_cause[0] |= H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED;
|
||||
|
||||
/* Check whether these are both simple or scalar dataspaces */
|
||||
if (!((H5S_SIMPLE == H5S_GET_EXTENT_TYPE(mem_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(mem_space)) &&
|
||||
(H5S_SIMPLE == H5S_GET_EXTENT_TYPE(file_space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(file_space))))
|
||||
local_cause[0] |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES;
|
||||
/* Don't allow collective operations if datatype conversions need to happen */
|
||||
if (!type_info->is_conv_noop)
|
||||
local_cause[0] |= H5D_MPIO_DATATYPE_CONVERSION;
|
||||
|
||||
/* Dataset storage must be contiguous or chunked */
|
||||
if (!(io_info->dset->shared->layout.type == H5D_CONTIGUOUS ||
|
||||
io_info->dset->shared->layout.type == H5D_CHUNKED))
|
||||
local_cause[0] |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
|
||||
/* Don't allow collective operations if data transform operations should occur */
|
||||
if (!type_info->is_xform_noop)
|
||||
local_cause[0] |= H5D_MPIO_DATA_TRANSFORMS;
|
||||
|
||||
/* check if external-file storage is used */
|
||||
if (io_info->dset->shared->dcpl_cache.efl.nused > 0)
|
||||
local_cause[0] |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
|
||||
/* Check whether these are both simple or scalar dataspaces */
|
||||
if (!((H5S_SIMPLE == H5S_GET_EXTENT_TYPE(mem_space) ||
|
||||
H5S_SCALAR == H5S_GET_EXTENT_TYPE(mem_space)) &&
|
||||
(H5S_SIMPLE == H5S_GET_EXTENT_TYPE(file_space) ||
|
||||
H5S_SCALAR == H5S_GET_EXTENT_TYPE(file_space))))
|
||||
local_cause[0] |= H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES;
|
||||
|
||||
/* The handling of memory space is different for chunking and contiguous
|
||||
* storage. For contiguous storage, mem_space and file_space won't change
|
||||
* when it it is doing disk IO. For chunking storage, mem_space will
|
||||
* change for different chunks. So for chunking storage, whether we can
|
||||
* use collective IO will defer until each chunk IO is reached.
|
||||
*/
|
||||
/* Dataset storage must be contiguous or chunked */
|
||||
if (!(dset->shared->layout.type == H5D_CONTIGUOUS || dset->shared->layout.type == H5D_CHUNKED))
|
||||
local_cause[0] |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
|
||||
|
||||
/* check if external-file storage is used */
|
||||
if (dset->shared->dcpl_cache.efl.nused > 0)
|
||||
local_cause[0] |= H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET;
|
||||
|
||||
/* The handling of memory space is different for chunking and contiguous
|
||||
* storage. For contiguous storage, mem_space and file_space won't change
|
||||
* when it it is doing disk IO. For chunking storage, mem_space will
|
||||
* change for different chunks. So for chunking storage, whether we can
|
||||
* use collective IO will defer until each chunk IO is reached.
|
||||
*/
|
||||
|
||||
#ifndef H5_HAVE_PARALLEL_FILTERED_WRITES
|
||||
/* Don't allow writes to filtered datasets if the functionality is disabled */
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0)
|
||||
local_cause[0] |= H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED;
|
||||
/* Don't allow writes to filtered datasets if the functionality is disabled */
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE && dset->shared->dcpl_cache.pline.nused > 0)
|
||||
local_cause[0] |= H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED;
|
||||
#endif
|
||||
|
||||
/* Check if we are able to do a MPI_Bcast of the data from one rank
|
||||
* instead of having all the processes involved in the collective I/O call.
|
||||
*/
|
||||
|
||||
/* Check to see if the process is reading the entire dataset */
|
||||
if (H5S_GET_SELECT_TYPE(file_space) != H5S_SEL_ALL)
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_H5S_ALL;
|
||||
/* Only perform this optimization for contiguous datasets, currently */
|
||||
else if (H5D_CONTIGUOUS != io_info->dset->shared->layout.type)
|
||||
/* Flag to do a MPI_Bcast of the data from one proc instead of
|
||||
* having all the processes involved in the collective I/O.
|
||||
/* Check if we are able to do a MPI_Bcast of the data from one rank
|
||||
* instead of having all the processes involved in the collective I/O call.
|
||||
*/
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_CONTIGUOUS;
|
||||
else if ((is_vl_storage = H5T_is_vl_storage(type_info->dset_type)) < 0)
|
||||
local_cause[0] |= H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE;
|
||||
else if (is_vl_storage)
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_FIXED_SIZE;
|
||||
else {
|
||||
size_t type_size; /* Size of dataset's datatype */
|
||||
|
||||
/* Retrieve the size of the dataset's datatype */
|
||||
if (0 == (type_size = H5T_GET_SIZE(type_info->dset_type)))
|
||||
/* Check to see if the process is reading the entire dataset */
|
||||
if (H5S_GET_SELECT_TYPE(file_space) != H5S_SEL_ALL)
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_H5S_ALL;
|
||||
/* Only perform this optimization for contiguous datasets, currently */
|
||||
else if (H5D_CONTIGUOUS != dset->shared->layout.type)
|
||||
/* Flag to do a MPI_Bcast of the data from one proc instead of
|
||||
* having all the processes involved in the collective I/O.
|
||||
*/
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_CONTIGUOUS;
|
||||
else if ((is_vl_storage = H5T_is_vl_storage(type_info->dset_type)) < 0)
|
||||
local_cause[0] |= H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE;
|
||||
else if (is_vl_storage)
|
||||
local_cause[1] |= H5D_MPIO_RANK0_NOT_FIXED_SIZE;
|
||||
else {
|
||||
hssize_t snelmts; /* [Signed] # of elements in dataset's dataspace */
|
||||
size_t type_size; /* Size of dataset's datatype */
|
||||
|
||||
/* Retrieve the size of the dataset's datatype */
|
||||
if ((snelmts = H5S_GET_EXTENT_NPOINTS(file_space)) < 0)
|
||||
if (0 == (type_size = H5T_GET_SIZE(type_info->dset_type)))
|
||||
local_cause[0] |= H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE;
|
||||
else {
|
||||
hsize_t dset_size;
|
||||
hssize_t snelmts; /* [Signed] # of elements in dataset's dataspace */
|
||||
|
||||
/* Determine dataset size */
|
||||
dset_size = ((hsize_t)snelmts) * type_size;
|
||||
/* Retrieve the size of the dataset's datatype */
|
||||
if ((snelmts = H5S_GET_EXTENT_NPOINTS(file_space)) < 0)
|
||||
local_cause[0] |= H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE;
|
||||
else {
|
||||
hsize_t dset_size;
|
||||
|
||||
/* If the size of the dataset is less than 2GB then do an MPI_Bcast
|
||||
* of the data from one process instead of having all the processes
|
||||
* involved in the collective I/O.
|
||||
*/
|
||||
if (dset_size > ((hsize_t)(2.0F * H5_GB) - 1))
|
||||
local_cause[1] |= H5D_MPIO_RANK0_GREATER_THAN_2GB;
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
/* Determine dataset size */
|
||||
dset_size = ((hsize_t)snelmts) * type_size;
|
||||
|
||||
/* If the size of the dataset is less than 2GB then do an MPI_Bcast
|
||||
* of the data from one process instead of having all the processes
|
||||
* involved in the collective I/O.
|
||||
*/
|
||||
if (dset_size > ((hsize_t)(2.0F * H5_GB) - 1))
|
||||
local_cause[1] |= H5D_MPIO_RANK0_GREATER_THAN_2GB;
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end else */
|
||||
} /* end for loop */
|
||||
|
||||
/* Check for independent I/O */
|
||||
if (local_cause[0] & H5D_MPIO_SET_INDEPENDENT)
|
||||
@@ -875,26 +891,29 @@ done:
|
||||
*
|
||||
* Purpose: MPI-IO function to read directly from app buffer to file.
|
||||
*
|
||||
* Return: non-negative on success, negative on failure.
|
||||
* This was referred from H5D__mpio_select_read for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Programmer:
|
||||
* Return: non-negative on success, negative on failure.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__mpio_select_read(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5D__mpio_select_read(const H5D_io_info_t *io_info, hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space)
|
||||
{
|
||||
const H5D_contig_storage_t *store_contig =
|
||||
&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
|
||||
void *rbuf = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* memory addr from a piece with lowest file addr */
|
||||
rbuf = io_info->base_maddr.vp;
|
||||
|
||||
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
|
||||
H5_CHECK_OVERFLOW(mpi_buf_count, hsize_t, size_t);
|
||||
if (H5F_shared_block_read(io_info->f_sh, H5FD_MEM_DRAW, store_contig->dset_addr, (size_t)mpi_buf_count,
|
||||
io_info->u.rbuf) < 0)
|
||||
if (H5F_shared_block_read(io_info->f_sh, H5FD_MEM_DRAW, io_info->store_faddr, (size_t)mpi_buf_count,
|
||||
rbuf) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't finish collective parallel read")
|
||||
|
||||
done:
|
||||
@@ -906,27 +925,29 @@ done:
|
||||
*
|
||||
* Purpose: MPI-IO function to write directly from app buffer to file.
|
||||
*
|
||||
* Return: non-negative on success, negative on failure.
|
||||
* This was referred from H5D__mpio_select_write for
|
||||
* multi-dset work.
|
||||
*
|
||||
* Programmer:
|
||||
* Return: non-negative on success, negative on failure.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__mpio_select_write(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
|
||||
hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5D__mpio_select_write(const H5D_io_info_t *io_info, hsize_t mpi_buf_count, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space)
|
||||
{
|
||||
const H5D_contig_storage_t *store_contig =
|
||||
&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
|
||||
herr_t ret_value = SUCCEED;
|
||||
const void *wbuf = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* memory addr from a piece with lowest file addr */
|
||||
wbuf = io_info->base_maddr.cvp;
|
||||
|
||||
/*OKAY: CAST DISCARDS CONST QUALIFIER*/
|
||||
H5_CHECK_OVERFLOW(mpi_buf_count, hsize_t, size_t);
|
||||
if (H5F_shared_block_write(io_info->f_sh, H5FD_MEM_DRAW, store_contig->dset_addr, (size_t)mpi_buf_count,
|
||||
io_info->u.wbuf) < 0)
|
||||
if (H5F_shared_block_write(io_info->f_sh, H5FD_MEM_DRAW, io_info->store_faddr, (size_t)mpi_buf_count,
|
||||
wbuf) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't finish collective parallel write")
|
||||
|
||||
done:
|
||||
@@ -937,17 +958,15 @@ done:
|
||||
* Function: H5D__mpio_get_sum_chunk
|
||||
*
|
||||
* Purpose: Routine for obtaining total number of chunks to cover
|
||||
* hyperslab selection selected by all processors.
|
||||
* hyperslab selection selected by all processors. Operates
|
||||
* on all datasets in the operation.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Muqun Yang
|
||||
* Monday, Feb. 13th, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm, int *sum_chunkf)
|
||||
H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, int *sum_chunkf)
|
||||
{
|
||||
int num_chunkf; /* Number of chunks to iterate over */
|
||||
size_t ori_num_chunkf;
|
||||
@@ -958,7 +977,7 @@ H5D__mpio_get_sum_chunk(const H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
|
||||
|
||||
/* Get the number of chunks to perform I/O on */
|
||||
num_chunkf = 0;
|
||||
ori_num_chunkf = H5SL_count(fm->sel_chunks);
|
||||
ori_num_chunkf = io_info->pieces_added;
|
||||
H5_CHECKED_ASSIGN(num_chunkf, int, ori_num_chunkf, size_t);
|
||||
|
||||
/* Determine the summation of number of chunks for all processes */
|
||||
@@ -971,85 +990,47 @@ done:
|
||||
} /* end H5D__mpio_get_sum_chunk() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_collective_read
|
||||
* Function: H5D__mpio_get_sum_chunk_dset
|
||||
*
|
||||
* Purpose: Reads directly from contiguous data in file into application
|
||||
* memory using collective I/O.
|
||||
* Purpose: Routine for obtaining total number of chunks to cover
|
||||
* hyperslab selection selected by all processors. Operates
|
||||
* on a single dataset.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, March 4, 2008
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__contig_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
static herr_t
|
||||
H5D__mpio_get_sum_chunk_dset(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
int *sum_chunkf)
|
||||
{
|
||||
H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
int num_chunkf; /* Number of chunks to iterate over */
|
||||
size_t ori_num_chunkf;
|
||||
int mpi_code; /* MPI return code */
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI));
|
||||
/* Check for non-chunked dataset, in this case we know the number of "chunks"
|
||||
* is simply the mpi size */
|
||||
HDassert(dset_info->layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Call generic internal collective I/O routine */
|
||||
if (H5D__inter_collective_io(io_info, type_info, file_space, mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
/* Get the number of chunks to perform I/O on */
|
||||
num_chunkf = 0;
|
||||
ori_num_chunkf = H5SL_count(dset_info->layout_io_info.chunk_map->dset_sel_pieces);
|
||||
H5_CHECKED_ASSIGN(num_chunkf, int, ori_num_chunkf, size_t);
|
||||
|
||||
/* Set the actual I/O mode property. internal_collective_io will not break to
|
||||
* independent I/O, so we set it here.
|
||||
*/
|
||||
H5CX_set_mpio_actual_io_mode(actual_io_mode);
|
||||
/* Determine the summation of number of chunks for all processes */
|
||||
if (MPI_SUCCESS !=
|
||||
(mpi_code = MPI_Allreduce(&num_chunkf, sum_chunkf, 1, MPI_INT, MPI_SUM, io_info->comm)))
|
||||
HMPI_GOTO_ERROR(FAIL, "MPI_Allreduce failed", mpi_code)
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_collective_read() */
|
||||
} /* end H5D__mpio_get_sum_chunk_dset() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__contig_collective_write
|
||||
*
|
||||
* Purpose: Write directly to contiguous data in file from application
|
||||
* memory using collective I/O.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, March 4, 2008
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__contig_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
{
|
||||
H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI));
|
||||
|
||||
/* Call generic internal collective I/O routine */
|
||||
if (H5D__inter_collective_io(io_info, type_info, file_space, mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
|
||||
/* Set the actual I/O mode property. internal_collective_io will not break to
|
||||
* independent I/O, so we set it here.
|
||||
*/
|
||||
H5CX_set_mpio_actual_io_mode(actual_io_mode);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__contig_collective_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_collective_io
|
||||
* Function: H5D__piece_io
|
||||
*
|
||||
* Purpose: Routine for
|
||||
* 1) choose an IO option:
|
||||
@@ -1085,34 +1066,34 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm)
|
||||
H5D__piece_io(H5D_io_info_t *io_info)
|
||||
{
|
||||
H5FD_mpio_chunk_opt_t chunk_opt_mode;
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
hbool_t log_file_flag = FALSE;
|
||||
FILE *debug_log_file = NULL;
|
||||
#endif
|
||||
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
|
||||
htri_t temp_not_link_io = FALSE;
|
||||
#endif
|
||||
int io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
|
||||
int sum_chunk = -1;
|
||||
int mpi_rank;
|
||||
int mpi_size;
|
||||
herr_t ret_value = SUCCEED;
|
||||
int io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
|
||||
hbool_t recalc_io_option = FALSE;
|
||||
hbool_t use_multi_dset = FALSE;
|
||||
unsigned one_link_chunk_io_threshold; /* Threshold to use single collective I/O for all chunks */
|
||||
int sum_chunk = -1;
|
||||
int mpi_rank;
|
||||
int mpi_size;
|
||||
size_t i;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->using_mpi_vfd);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
HDassert(io_info->count > 0);
|
||||
|
||||
/* Obtain the current rank of the process and the number of ranks */
|
||||
if ((mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file)) < 0)
|
||||
if ((mpi_rank = H5F_mpi_get_rank(io_info->dsets_info[0].dset->oloc.file)) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI rank")
|
||||
if ((mpi_size = H5F_mpi_get_size(io_info->dset->oloc.file)) < 0)
|
||||
if ((mpi_size = H5F_mpi_get_size(io_info->dsets_info[0].dset->oloc.file)) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI size")
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -1139,7 +1120,9 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check the optional property list for the collective chunk IO optimization option */
|
||||
/* Check the optional property list for the collective chunk IO optimization option.
|
||||
* Only set here if it's a static option, if it needs to be calculated using the
|
||||
* number of chunks per process delay that calculation until later. */
|
||||
if (H5CX_get_mpio_chunk_opt_mode(&chunk_opt_mode) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get chunk optimization option")
|
||||
|
||||
@@ -1148,81 +1131,190 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
/* direct request to multi-chunk-io */
|
||||
else if (H5FD_MPIO_CHUNK_MULTI_IO == chunk_opt_mode)
|
||||
io_option = H5D_MULTI_CHUNK_IO;
|
||||
/* via default path. branch by num threshold */
|
||||
else {
|
||||
unsigned one_link_chunk_io_threshold; /* Threshold to use single collective I/O for all chunks */
|
||||
else
|
||||
recalc_io_option = TRUE;
|
||||
|
||||
if (H5D__mpio_get_sum_chunk(io_info, fm, &sum_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL,
|
||||
"unable to obtain the total chunk number of all processes");
|
||||
/* Check if we can and should use multi dataset path */
|
||||
if (io_info->count > 1 && (io_option == H5D_ONE_LINK_CHUNK_IO || recalc_io_option)) {
|
||||
/* Use multi dataset path for now */
|
||||
use_multi_dset = TRUE;
|
||||
|
||||
/* Get the chunk optimization option threshold */
|
||||
if (H5CX_get_mpio_chunk_opt_num(&one_link_chunk_io_threshold) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
|
||||
"couldn't get chunk optimization option threshold value")
|
||||
/* Check for filtered datasets */
|
||||
for (i = 0; i < io_info->count; i++)
|
||||
if (io_info->dsets_info[i].dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
use_multi_dset = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* step 1: choose an IO option */
|
||||
/* If the average number of chunk per process is greater than a threshold, we will do one link chunked
|
||||
* IO. */
|
||||
if ((unsigned)sum_chunk / (unsigned)mpi_size >= one_link_chunk_io_threshold)
|
||||
io_option = H5D_ONE_LINK_CHUNK_IO_MORE_OPT;
|
||||
/* Check if this I/O exceeds one linked chunk threshold */
|
||||
if (recalc_io_option && use_multi_dset) {
|
||||
/* Get the chunk optimization option threshold */
|
||||
if (H5CX_get_mpio_chunk_opt_num(&one_link_chunk_io_threshold) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
|
||||
"couldn't get chunk optimization option threshold value")
|
||||
|
||||
/* If the threshold is 0, no need to check number of chunks */
|
||||
if (one_link_chunk_io_threshold > 0) {
|
||||
/* Get number of chunks for all processes */
|
||||
if (H5D__mpio_get_sum_chunk(io_info, &sum_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL,
|
||||
"unable to obtain the total chunk number of all processes");
|
||||
|
||||
/* If the average number of chunk per process is less than the threshold, we will do multi
|
||||
* chunk IO. If this threshold is not exceeded for all datasets, no need to check it again
|
||||
* for each individual dataset. */
|
||||
if ((unsigned)sum_chunk / (unsigned)mpi_size < one_link_chunk_io_threshold) {
|
||||
recalc_io_option = FALSE;
|
||||
use_multi_dset = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform multi dataset I/O if appropriate */
|
||||
if (use_multi_dset) {
|
||||
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
|
||||
else
|
||||
temp_not_link_io = TRUE;
|
||||
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
|
||||
} /* end else */
|
||||
/*** Set collective chunk user-input optimization API. ***/
|
||||
if (H5D_ONE_LINK_CHUNK_IO == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_hard(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
|
||||
|
||||
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
|
||||
{
|
||||
/*** Set collective chunk user-input optimization APIs. ***/
|
||||
if (H5D_ONE_LINK_CHUNK_IO == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_hard(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
else if (H5D_MULTI_CHUNK_IO == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_multi_hard(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end else-if */
|
||||
else if (H5D_ONE_LINK_CHUNK_IO_MORE_OPT == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_num_true(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
else if (temp_not_link_io) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_num_false(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
/* Perform unfiltered link chunk collective IO */
|
||||
if (H5D__link_piece_collective_io(io_info, mpi_rank) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO")
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_multi_dset) {
|
||||
/* Loop over datasets */
|
||||
for (i = 0; i < io_info->count; i++) {
|
||||
if (io_info->dsets_info[i].layout->type == H5D_CONTIGUOUS) {
|
||||
/* Contiguous: call H5D__inter_collective_io() directly */
|
||||
H5D_mpio_actual_io_mode_t actual_io_mode = H5D_MPIO_CONTIGUOUS_COLLECTIVE;
|
||||
|
||||
io_info->store_faddr = io_info->dsets_info[i].store->contig.dset_addr;
|
||||
io_info->base_maddr = io_info->dsets_info[i].buf;
|
||||
|
||||
if (H5D__inter_collective_io(io_info, &io_info->dsets_info[i],
|
||||
io_info->dsets_info[i].file_space,
|
||||
io_info->dsets_info[i].mem_space) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
|
||||
/* Set the actual I/O mode property. internal_collective_io will not break to
|
||||
* independent I/O, so we set it here.
|
||||
*/
|
||||
H5CX_set_mpio_actual_io_mode(actual_io_mode);
|
||||
}
|
||||
else {
|
||||
/* Chunked I/O path */
|
||||
HDassert(io_info->dsets_info[i].layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Recalculate io_option if necessary */
|
||||
if (recalc_io_option) {
|
||||
/* Get the chunk optimization option threshold */
|
||||
if (H5CX_get_mpio_chunk_opt_num(&one_link_chunk_io_threshold) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
|
||||
"couldn't get chunk optimization option threshold value")
|
||||
|
||||
/* If the threshold is 0, no need to check number of chunks */
|
||||
if (one_link_chunk_io_threshold == 0) {
|
||||
io_option = H5D_ONE_LINK_CHUNK_IO_MORE_OPT;
|
||||
recalc_io_option = FALSE;
|
||||
}
|
||||
else {
|
||||
/* Get number of chunks for all processes */
|
||||
if (H5D__mpio_get_sum_chunk_dset(io_info, &io_info->dsets_info[i], &sum_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL,
|
||||
"unable to obtain the total chunk number of all processes");
|
||||
|
||||
/* step 1: choose an IO option */
|
||||
/* If the average number of chunk per process is greater than a threshold, we will do
|
||||
* one link chunked IO. */
|
||||
if ((unsigned)sum_chunk / (unsigned)mpi_size >= one_link_chunk_io_threshold)
|
||||
io_option = H5D_ONE_LINK_CHUNK_IO_MORE_OPT;
|
||||
else
|
||||
io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
/* step 2: Go ahead to do IO.*/
|
||||
switch (io_option) {
|
||||
case H5D_ONE_LINK_CHUNK_IO:
|
||||
case H5D_ONE_LINK_CHUNK_IO_MORE_OPT:
|
||||
/* Check if there are any filters in the pipeline */
|
||||
if (io_info->dsets_info[i].dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
if (H5D__link_chunk_filtered_collective_io(io_info, &io_info->dsets_info[i],
|
||||
mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish filtered linked chunk MPI-IO")
|
||||
} /* end if */
|
||||
else {
|
||||
/* If there is more than one dataset we cannot make the multi dataset call here,
|
||||
* fall back to multi chunk */
|
||||
if (io_info->count > 1) {
|
||||
io_option = H5D_MULTI_CHUNK_IO_MORE_OPT;
|
||||
recalc_io_option = TRUE;
|
||||
|
||||
if (H5D__multi_chunk_collective_io(io_info, &io_info->dsets_info[i], mpi_rank,
|
||||
mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish optimized multiple chunk MPI-IO")
|
||||
}
|
||||
else {
|
||||
/* Perform unfiltered link chunk collective IO */
|
||||
if (H5D__link_piece_collective_io(io_info, mpi_rank) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish linked chunk MPI-IO")
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case H5D_MULTI_CHUNK_IO: /* direct request to do multi-chunk IO */
|
||||
default: /* multiple chunk IO via threshold */
|
||||
/* Check if there are any filters in the pipeline */
|
||||
if (io_info->dsets_info[i].dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
if (H5D__multi_chunk_filtered_collective_io(io_info, &io_info->dsets_info[i],
|
||||
mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish optimized multiple filtered chunk MPI-IO")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Perform unfiltered multi chunk collective IO */
|
||||
if (H5D__multi_chunk_collective_io(io_info, &io_info->dsets_info[i], mpi_rank,
|
||||
mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish optimized multiple chunk MPI-IO")
|
||||
}
|
||||
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
|
||||
{
|
||||
/*** Set collective chunk user-input optimization APIs. ***/
|
||||
if (H5D_ONE_LINK_CHUNK_IO == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_hard(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
else if (H5D_MULTI_CHUNK_IO == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_multi_hard(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end else-if */
|
||||
else if (H5D_ONE_LINK_CHUNK_IO_MORE_OPT == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_num_true(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
else if (H5D_MULTI_CHUNK_IO_MORE_OPT == io_option) {
|
||||
if (H5CX_test_set_mpio_coll_chunk_link_num_false(0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property value")
|
||||
} /* end if */
|
||||
}
|
||||
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
|
||||
|
||||
/* step 2: Go ahead to do IO.*/
|
||||
switch (io_option) {
|
||||
case H5D_ONE_LINK_CHUNK_IO:
|
||||
case H5D_ONE_LINK_CHUNK_IO_MORE_OPT:
|
||||
/* Check if there are any filters in the pipeline */
|
||||
if (io_info->dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
if (H5D__link_chunk_filtered_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish filtered linked chunk MPI-IO")
|
||||
} /* end if */
|
||||
else
|
||||
/* Perform unfiltered link chunk collective IO */
|
||||
if (H5D__link_chunk_collective_io(io_info, type_info, fm, sum_chunk, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO")
|
||||
break;
|
||||
|
||||
case H5D_MULTI_CHUNK_IO: /* direct request to do multi-chunk IO */
|
||||
default: /* multiple chunk IO via threshold */
|
||||
/* Check if there are any filters in the pipeline */
|
||||
if (io_info->dset->shared->dcpl_cache.pline.nused > 0) {
|
||||
if (H5D__multi_chunk_filtered_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
|
||||
"couldn't finish optimized multiple filtered chunk MPI-IO")
|
||||
} /* end if */
|
||||
else
|
||||
/* Perform unfiltered multi chunk collective IO */
|
||||
if (H5D__multi_chunk_collective_io(io_info, type_info, fm, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish optimized multiple chunk MPI-IO")
|
||||
break;
|
||||
} /* end switch */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -1236,13 +1328,13 @@ done:
|
||||
#endif
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_collective_io */
|
||||
} /* end H5D__piece_io */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_collective_read
|
||||
* Function: H5D__collective_read
|
||||
*
|
||||
* Purpose: Reads directly from chunks in file into application memory
|
||||
* using collective I/O.
|
||||
* Purpose: Read directly from pieces (chunks/contig) in file into
|
||||
* application memory using collective I/O.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@@ -1252,27 +1344,25 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__chunk_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
H5D__collective_read(H5D_io_info_t *io_info)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Call generic selection operation */
|
||||
if (H5D__chunk_collective_io(io_info, type_info, fm) < 0)
|
||||
if (H5D__piece_io(io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_collective_read() */
|
||||
} /* end H5D__collective_read() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__chunk_collective_write
|
||||
* Function: H5D__collective_write
|
||||
*
|
||||
* Purpose: Write directly to chunks in file from application memory
|
||||
* using collective I/O.
|
||||
* Purpose: Write directly to pieces (chunks/contig) in file into
|
||||
* application memory using collective I/O.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@@ -1282,31 +1372,30 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__chunk_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t H5_ATTR_UNUSED nelmts, H5S_t H5_ATTR_UNUSED *file_space,
|
||||
H5S_t H5_ATTR_UNUSED *mem_space, H5D_chunk_map_t *fm)
|
||||
H5D__collective_write(H5D_io_info_t *io_info)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Call generic selection operation */
|
||||
if (H5D__chunk_collective_io(io_info, type_info, fm) < 0)
|
||||
if (H5D__piece_io(io_info) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__chunk_collective_write() */
|
||||
} /* end H5D__collective_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__link_chunk_collective_io
|
||||
* Function: H5D__link_piece_collective_io
|
||||
*
|
||||
* Purpose: Routine for one collective IO with one MPI derived datatype to link with all chunks
|
||||
* Purpose: Routine for single collective IO with one MPI derived datatype
|
||||
* to link with all pieces (chunks + contig)
|
||||
*
|
||||
* 1. Sort the chunk address and chunk info
|
||||
* 2. Build up MPI derived datatype for each chunk
|
||||
* 3. Build up the final MPI derived datatype
|
||||
* 4. Use common collective IO routine to do MPI-IO
|
||||
* 1. Use the piece addresses and piece info sorted in skiplist
|
||||
* 2. Build up MPI derived datatype for each chunk
|
||||
* 3. Build up the final MPI derived datatype
|
||||
* 4. Use common collective IO routine to do MPI-IO
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@@ -1316,121 +1405,100 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
|
||||
int sum_chunk, int mpi_rank, int mpi_size)
|
||||
H5D__link_piece_collective_io(H5D_io_info_t *io_info, int mpi_rank)
|
||||
{
|
||||
H5D_chunk_addr_info_t *chunk_addr_info_array = NULL;
|
||||
MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with selection */
|
||||
hbool_t chunk_final_mtype_is_derived = FALSE;
|
||||
MPI_Datatype chunk_final_ftype; /* Final file MPI datatype for all chunks with selection */
|
||||
hbool_t chunk_final_ftype_is_derived = FALSE;
|
||||
H5D_storage_t ctg_store; /* Storage info for "fake" contiguous dataset */
|
||||
size_t total_chunks;
|
||||
MPI_Datatype *chunk_mtype = NULL;
|
||||
MPI_Datatype *chunk_ftype = NULL;
|
||||
MPI_Aint *chunk_disp_array = NULL;
|
||||
MPI_Aint *chunk_mem_disp_array = NULL;
|
||||
hbool_t *chunk_mft_is_derived_array =
|
||||
MPI_Datatype chunk_final_mtype; /* Final memory MPI datatype for all chunks with selection */
|
||||
hbool_t chunk_final_mtype_is_derived = FALSE;
|
||||
MPI_Datatype chunk_final_ftype; /* Final file MPI datatype for all chunks with selection */
|
||||
hbool_t chunk_final_ftype_is_derived = FALSE;
|
||||
H5D_storage_t ctg_store; /* Storage info for "fake" contiguous dataset */
|
||||
MPI_Datatype *chunk_mtype = NULL;
|
||||
MPI_Datatype *chunk_ftype = NULL;
|
||||
MPI_Aint *chunk_file_disp_array = NULL;
|
||||
MPI_Aint *chunk_mem_disp_array = NULL;
|
||||
hbool_t *chunk_mft_is_derived_array =
|
||||
NULL; /* Flags to indicate each chunk's MPI file datatype is derived */
|
||||
hbool_t *chunk_mbt_is_derived_array =
|
||||
NULL; /* Flags to indicate each chunk's MPI memory datatype is derived */
|
||||
int *chunk_mpi_file_counts = NULL; /* Count of MPI file datatype for each chunk */
|
||||
int *chunk_mpi_mem_counts = NULL; /* Count of MPI memory datatype for each chunk */
|
||||
int mpi_code; /* MPI return code */
|
||||
herr_t ret_value = SUCCEED;
|
||||
NULL; /* Flags to indicate each chunk's MPI memory datatype is derived */
|
||||
int *chunk_mpi_file_counts = NULL; /* Count of MPI file datatype for each chunk */
|
||||
int *chunk_mpi_mem_counts = NULL; /* Count of MPI memory datatype for each chunk */
|
||||
int mpi_code; /* MPI return code */
|
||||
H5D_mpio_actual_chunk_opt_mode_t actual_chunk_opt_mode = H5D_MPIO_LINK_CHUNK;
|
||||
H5D_mpio_actual_io_mode_t actual_io_mode = 0;
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* set actual_io_mode */
|
||||
for (i = 0; i < io_info->count; i++) {
|
||||
HDassert(io_info->dsets_info[i].dset->shared->dcpl_cache.pline.nused == 0);
|
||||
if (io_info->dsets_info[i].layout->type == H5D_CHUNKED)
|
||||
actual_io_mode |= H5D_MPIO_CHUNK_COLLECTIVE;
|
||||
else if (io_info->dsets_info[i].layout->type == H5D_CONTIGUOUS) {
|
||||
actual_io_mode |= H5D_MPIO_CONTIGUOUS_COLLECTIVE;
|
||||
|
||||
/* if only single-dset */
|
||||
if (1 == io_info->count)
|
||||
actual_chunk_opt_mode = H5D_MPIO_NO_CHUNK_OPTIMIZATION;
|
||||
}
|
||||
else
|
||||
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout")
|
||||
}
|
||||
|
||||
/* Set the actual-chunk-opt-mode property. */
|
||||
H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_LINK_CHUNK);
|
||||
H5CX_set_mpio_actual_chunk_opt(actual_chunk_opt_mode);
|
||||
|
||||
/* Set the actual-io-mode property.
|
||||
* Link chunk I/O does not break to independent, so can set right away */
|
||||
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
|
||||
H5CX_set_mpio_actual_io_mode(actual_io_mode);
|
||||
|
||||
/* Get the sum # of chunks, if not already available */
|
||||
if (sum_chunk < 0) {
|
||||
if (H5D__mpio_get_sum_chunk(io_info, fm, &sum_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL,
|
||||
"unable to obtain the total chunk number of all processes");
|
||||
} /* end if */
|
||||
|
||||
/* Retrieve total # of chunks in dataset */
|
||||
H5_CHECKED_ASSIGN(total_chunks, size_t, fm->layout->u.chunk.nchunks, hsize_t);
|
||||
|
||||
/* Handle special case when dataspace dimensions only allow one chunk in
|
||||
* the dataset. [This sometimes is used by developers who want the
|
||||
* equivalent of compressed contiguous datasets - QAK]
|
||||
*/
|
||||
if (total_chunks == 1) {
|
||||
H5SL_node_t *chunk_node; /* Pointer to chunk node for selection */
|
||||
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
|
||||
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
|
||||
|
||||
/* Check for this process having selection in this chunk */
|
||||
chunk_node = H5SL_first(fm->sel_chunks);
|
||||
|
||||
if (chunk_node == NULL) {
|
||||
/* Set the dataspace info for I/O to NULL, this process doesn't have any I/O to perform */
|
||||
fspace = mspace = NULL;
|
||||
|
||||
/* Initialize chunk address */
|
||||
ctg_store.contig.dset_addr = 0;
|
||||
} /* end if */
|
||||
else {
|
||||
H5D_chunk_ud_t udata; /* User data for querying chunk info */
|
||||
H5D_chunk_info_t *chunk_info; /* Info for chunk in skiplist */
|
||||
|
||||
/* Get the chunk info, for the selection in the chunk */
|
||||
if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node)))
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skip list")
|
||||
|
||||
/* Set the dataspace info for I/O */
|
||||
fspace = chunk_info->fspace;
|
||||
mspace = chunk_info->mspace;
|
||||
|
||||
/* Look up address of chunk */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk address")
|
||||
ctg_store.contig.dset_addr = udata.chunk_block.offset;
|
||||
} /* end else */
|
||||
|
||||
/* Set up the base storage address for this chunk */
|
||||
io_info->store = &ctg_store;
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "before inter_collective_io for total chunk = 1");
|
||||
#endif
|
||||
|
||||
/* Perform I/O */
|
||||
if (H5D__inter_collective_io(io_info, type_info, fspace, mspace) < 0)
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Code block for actual actions (Build a MPI Type, IO) */
|
||||
{
|
||||
hsize_t mpi_buf_count; /* Number of MPI types */
|
||||
size_t num_chunk; /* Number of chunks for this process */
|
||||
size_t u; /* Local index variable */
|
||||
|
||||
H5D_piece_info_t *piece_info;
|
||||
|
||||
/* local variable for base address for buffer */
|
||||
H5_flexible_const_ptr_t base_buf_addr;
|
||||
base_buf_addr.cvp = NULL;
|
||||
|
||||
/* Get the number of chunks with a selection */
|
||||
num_chunk = H5SL_count(fm->sel_chunks);
|
||||
num_chunk = io_info->pieces_added;
|
||||
H5_CHECK_OVERFLOW(num_chunk, size_t, int);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG_VA(mpi_rank, "total_chunks = %zu, num_chunk = %zu", total_chunks, num_chunk);
|
||||
H5D_MPIO_DEBUG_VA(mpi_rank, "num_chunk = %zu\n", num_chunk);
|
||||
#endif
|
||||
|
||||
/* Set up MPI datatype for chunks selected */
|
||||
if (num_chunk) {
|
||||
hbool_t need_sort = FALSE;
|
||||
|
||||
/* Check if sel_pieces array is sorted */
|
||||
HDassert(io_info->sel_pieces[0]->faddr != HADDR_UNDEF);
|
||||
for (i = 1; i < num_chunk; i++) {
|
||||
HDassert(io_info->sel_pieces[i]->faddr != HADDR_UNDEF);
|
||||
|
||||
if (io_info->sel_pieces[i]->faddr < io_info->sel_pieces[i - 1]->faddr) {
|
||||
need_sort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort sel_pieces if necessary */
|
||||
if (need_sort)
|
||||
HDqsort(io_info->sel_pieces, io_info->pieces_added, sizeof(io_info->sel_pieces[0]),
|
||||
H5D__cmp_piece_addr);
|
||||
|
||||
/* Allocate chunking information */
|
||||
if (NULL == (chunk_addr_info_array =
|
||||
(H5D_chunk_addr_info_t *)H5MM_malloc(num_chunk * sizeof(H5D_chunk_addr_info_t))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk array buffer")
|
||||
if (NULL == (chunk_mtype = (MPI_Datatype *)H5MM_malloc(num_chunk * sizeof(MPI_Datatype))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
"couldn't allocate chunk memory datatype buffer")
|
||||
if (NULL == (chunk_ftype = (MPI_Datatype *)H5MM_malloc(num_chunk * sizeof(MPI_Datatype))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate chunk file datatype buffer")
|
||||
if (NULL == (chunk_disp_array = (MPI_Aint *)H5MM_malloc(num_chunk * sizeof(MPI_Aint))))
|
||||
if (NULL == (chunk_file_disp_array = (MPI_Aint *)H5MM_malloc(num_chunk * sizeof(MPI_Aint))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
"couldn't allocate chunk file displacement buffer")
|
||||
if (NULL == (chunk_mem_disp_array = (MPI_Aint *)H5MM_calloc(num_chunk * sizeof(MPI_Aint))))
|
||||
@@ -1447,36 +1515,37 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
"couldn't allocate chunk file is derived datatype flags buffer")
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "before sorting chunk addresses");
|
||||
#endif
|
||||
/* save lowest file address */
|
||||
ctg_store.contig.dset_addr = io_info->sel_pieces[0]->faddr;
|
||||
|
||||
/* Sort the chunk address */
|
||||
if (H5D__sort_chunk(io_info, fm, chunk_addr_info_array, sum_chunk, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSWAP, FAIL, "unable to sort chunk address")
|
||||
ctg_store.contig.dset_addr = chunk_addr_info_array[0].chunk_addr;
|
||||
/* save base mem addr of piece for read/write */
|
||||
base_buf_addr = io_info->sel_pieces[0]->dset_info->buf;
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "after sorting chunk addresses");
|
||||
H5D_MPIO_DEBUG(mpi_rank, "before iterate over selected pieces\n");
|
||||
#endif
|
||||
|
||||
/* Obtain MPI derived datatype from all individual chunks */
|
||||
for (u = 0; u < num_chunk; u++) {
|
||||
/* Obtain MPI derived datatype from all individual pieces */
|
||||
/* Iterate over selected pieces for this process */
|
||||
for (i = 0; i < num_chunk; 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;
|
||||
|
||||
/* Assign convenience pointer to piece info */
|
||||
piece_info = io_info->sel_pieces[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(chunk_addr_info_array[u].chunk_info.fspace, type_info->src_type_size,
|
||||
&chunk_ftype[u], /* OUT: datatype created */
|
||||
&chunk_mpi_file_counts[u], /* OUT */
|
||||
&(chunk_mft_is_derived_array[u]), /* OUT */
|
||||
if (H5S_mpio_space_type(piece_info->fspace, piece_info->dset_info->type_info.src_type_size,
|
||||
&chunk_ftype[i], /* OUT: datatype created */
|
||||
&chunk_mpi_file_counts[i], /* OUT */
|
||||
&(chunk_mft_is_derived_array[i]), /* OUT */
|
||||
TRUE, /* this is a file space,
|
||||
so permute the
|
||||
datatype if the point
|
||||
@@ -1488,12 +1557,13 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
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)
|
||||
HDassert(permute_map);
|
||||
if (H5S_mpio_space_type(chunk_addr_info_array[u].chunk_info.mspace, type_info->dst_type_size,
|
||||
&chunk_mtype[u], &chunk_mpi_mem_counts[u],
|
||||
&(chunk_mbt_is_derived_array[u]), FALSE, /* this is a memory
|
||||
if (H5S_mpio_space_type(piece_info->mspace, piece_info->dset_info->type_info.dst_type_size,
|
||||
&chunk_mtype[i], &chunk_mpi_mem_counts[i],
|
||||
&(chunk_mbt_is_derived_array[i]), FALSE, /* this is a memory
|
||||
space, so if the file
|
||||
space is not
|
||||
permuted, there is no
|
||||
@@ -1512,19 +1582,27 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
if (is_permuted)
|
||||
HDassert(!permute_map);
|
||||
|
||||
/* Chunk address relative to the first chunk */
|
||||
chunk_addr_info_array[u].chunk_addr -= ctg_store.contig.dset_addr;
|
||||
/* Piece address relative to the first piece addr
|
||||
* Assign piece address to MPI displacement
|
||||
* (assume MPI_Aint big enough to hold it) */
|
||||
chunk_file_disp_array[i] = (MPI_Aint)piece_info->faddr - (MPI_Aint)ctg_store.contig.dset_addr;
|
||||
|
||||
/* Assign chunk address to MPI displacement */
|
||||
/* (assume MPI_Aint big enough to hold it) */
|
||||
chunk_disp_array[u] = (MPI_Aint)chunk_addr_info_array[u].chunk_addr;
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE) {
|
||||
chunk_mem_disp_array[i] =
|
||||
(MPI_Aint)piece_info->dset_info->buf.cvp - (MPI_Aint)base_buf_addr.cvp;
|
||||
}
|
||||
else if (io_info->op_type == H5D_IO_OP_READ) {
|
||||
chunk_mem_disp_array[i] =
|
||||
(MPI_Aint)piece_info->dset_info->buf.vp - (MPI_Aint)base_buf_addr.vp;
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
/* Create final MPI derived datatype for the file */
|
||||
if (MPI_SUCCESS !=
|
||||
(mpi_code = MPI_Type_create_struct((int)num_chunk, chunk_mpi_file_counts, chunk_disp_array,
|
||||
chunk_ftype, &chunk_final_ftype)))
|
||||
(mpi_code = MPI_Type_create_struct((int)num_chunk, chunk_mpi_file_counts,
|
||||
chunk_file_disp_array, chunk_ftype, &chunk_final_ftype)))
|
||||
HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
|
||||
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&chunk_final_ftype)))
|
||||
HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
|
||||
chunk_final_ftype_is_derived = TRUE;
|
||||
@@ -1539,13 +1617,13 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
chunk_final_mtype_is_derived = TRUE;
|
||||
|
||||
/* Free the file & memory MPI datatypes for each chunk */
|
||||
for (u = 0; u < num_chunk; u++) {
|
||||
if (chunk_mbt_is_derived_array[u])
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_mtype + u)))
|
||||
for (i = 0; i < num_chunk; i++) {
|
||||
if (chunk_mbt_is_derived_array[i])
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_mtype + i)))
|
||||
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
|
||||
|
||||
if (chunk_mft_is_derived_array[u])
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_ftype + u)))
|
||||
if (chunk_mft_is_derived_array[i])
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Type_free(chunk_ftype + i)))
|
||||
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
|
||||
} /* end for */
|
||||
|
||||
@@ -1555,6 +1633,9 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
else { /* no selection at all for this process */
|
||||
ctg_store.contig.dset_addr = 0;
|
||||
|
||||
/* just provide a valid mem address. no actual IO occur */
|
||||
base_buf_addr = io_info->dsets_info[0].buf;
|
||||
|
||||
/* Set the MPI datatype */
|
||||
chunk_final_ftype = MPI_BYTE;
|
||||
chunk_final_mtype = MPI_BYTE;
|
||||
@@ -1566,15 +1647,14 @@ H5D__link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *typ
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "before coming to final collective I/O");
|
||||
#endif
|
||||
|
||||
/* Set up the base storage address for this chunk */
|
||||
io_info->store = &ctg_store;
|
||||
/* Set up the base storage address for this piece */
|
||||
io_info->store_faddr = ctg_store.contig.dset_addr;
|
||||
io_info->base_maddr = base_buf_addr;
|
||||
|
||||
/* Perform final collective I/O operation */
|
||||
if (H5D__final_collective_io(io_info, type_info, mpi_buf_count, chunk_final_ftype,
|
||||
chunk_final_mtype) < 0)
|
||||
if (H5D__final_collective_io(io_info, mpi_buf_count, chunk_final_ftype, chunk_final_mtype) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO")
|
||||
} /* end else */
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -1583,14 +1663,12 @@ done:
|
||||
#endif
|
||||
|
||||
/* Release resources */
|
||||
if (chunk_addr_info_array)
|
||||
H5MM_xfree(chunk_addr_info_array);
|
||||
if (chunk_mtype)
|
||||
H5MM_xfree(chunk_mtype);
|
||||
if (chunk_ftype)
|
||||
H5MM_xfree(chunk_ftype);
|
||||
if (chunk_disp_array)
|
||||
H5MM_xfree(chunk_disp_array);
|
||||
if (chunk_file_disp_array)
|
||||
H5MM_xfree(chunk_file_disp_array);
|
||||
if (chunk_mem_disp_array)
|
||||
H5MM_xfree(chunk_mem_disp_array);
|
||||
if (chunk_mpi_mem_counts)
|
||||
@@ -1609,7 +1687,7 @@ done:
|
||||
HMPI_DONE_ERROR(FAIL, "MPI_Type_free failed", mpi_code)
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__link_chunk_collective_io */
|
||||
} /* end H5D__link_piece_collective_io */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__link_chunk_filtered_collective_io
|
||||
@@ -1680,29 +1758,27 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm, int mpi_rank, int mpi_size)
|
||||
H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, int mpi_rank,
|
||||
int mpi_size)
|
||||
{
|
||||
H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
|
||||
H5D_filtered_collective_io_info_t *chunk_hash_table = NULL;
|
||||
unsigned char **chunk_msg_bufs = NULL;
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
MPI_Datatype mem_type = MPI_BYTE;
|
||||
MPI_Datatype file_type = MPI_BYTE;
|
||||
hbool_t mem_type_is_derived = FALSE;
|
||||
H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
|
||||
H5D_filtered_collective_io_info_t *chunk_hash_table = NULL;
|
||||
unsigned char **chunk_msg_bufs = NULL;
|
||||
MPI_Datatype mem_type = MPI_BYTE;
|
||||
MPI_Datatype file_type = MPI_BYTE;
|
||||
hbool_t mem_type_is_derived = FALSE;
|
||||
hbool_t file_type_is_derived = FALSE;
|
||||
size_t *rank_chunks_assigned_map = NULL;
|
||||
size_t chunk_list_num_entries;
|
||||
size_t i;
|
||||
int chunk_msg_bufs_len = 0;
|
||||
int mpi_code;
|
||||
herr_t ret_value = SUCCEED;
|
||||
char fake_buf; /* Used as a fake buffer for ranks with no chunks, thus a NULL buf pointer */
|
||||
int mpi_code;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
FUNC_ENTER_PACKAGE_TAG(dset_info->dset->oloc.addr)
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
@@ -1720,12 +1796,12 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
|
||||
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
|
||||
|
||||
/* Build a list of selected chunks in the collective io operation */
|
||||
if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, type_info, fm, &chunk_list,
|
||||
&chunk_list_num_entries, mpi_rank) < 0)
|
||||
if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, dset_info, &chunk_list, &chunk_list_num_entries,
|
||||
mpi_rank) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list")
|
||||
|
||||
if (io_info->op_type == H5D_IO_OP_READ) { /* Filtered collective read */
|
||||
if (H5D__mpio_collective_filtered_chunk_read(chunk_list, chunk_list_num_entries, io_info, type_info,
|
||||
if (H5D__mpio_collective_filtered_chunk_read(chunk_list, chunk_list_num_entries, io_info, dset_info,
|
||||
mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't read filtered chunks")
|
||||
}
|
||||
@@ -1733,17 +1809,17 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
|
||||
H5D_chk_idx_info_t index_info;
|
||||
hsize_t mpi_buf_count;
|
||||
|
||||
H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info);
|
||||
H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, dset_info->dset);
|
||||
|
||||
if (mpi_size > 1) {
|
||||
/* Redistribute shared chunks being written to */
|
||||
if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, fm,
|
||||
mpi_rank, mpi_size, &rank_chunks_assigned_map) < 0)
|
||||
if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, mpi_rank,
|
||||
mpi_size, &rank_chunks_assigned_map) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to redistribute shared chunks")
|
||||
|
||||
/* Send any chunk modification messages for chunks this rank no longer owns */
|
||||
if (H5D__mpio_share_chunk_modification_data(chunk_list, &chunk_list_num_entries, io_info,
|
||||
type_info, mpi_rank, mpi_size, &chunk_hash_table,
|
||||
dset_info, mpi_rank, mpi_size, &chunk_hash_table,
|
||||
&chunk_msg_bufs, &chunk_msg_bufs_len) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
|
||||
"unable to send chunk modification data between MPI ranks")
|
||||
@@ -1758,7 +1834,7 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
|
||||
* must participate.
|
||||
*/
|
||||
if (H5D__mpio_collective_filtered_chunk_update(chunk_list, chunk_list_num_entries, chunk_hash_table,
|
||||
chunk_msg_bufs, chunk_msg_bufs_len, io_info, type_info,
|
||||
chunk_msg_bufs, chunk_msg_bufs_len, io_info, dset_info,
|
||||
mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't update modified chunks")
|
||||
|
||||
@@ -1790,20 +1866,21 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
|
||||
* Override the write buffer to point to the first
|
||||
* chunk's data buffer
|
||||
*/
|
||||
io_info->u.wbuf = chunk_list[0].buf;
|
||||
io_info->base_maddr.cvp = chunk_list[0].buf;
|
||||
|
||||
/*
|
||||
* Setup the base storage address for this operation
|
||||
* to be the first chunk's file address
|
||||
*/
|
||||
ctg_store.contig.dset_addr = chunk_list[0].chunk_new.offset;
|
||||
io_info->store_faddr = chunk_list[0].chunk_new.offset;
|
||||
}
|
||||
else {
|
||||
io_info->base_maddr.cvp = &fake_buf;
|
||||
io_info->store_faddr = 0;
|
||||
}
|
||||
else
|
||||
ctg_store.contig.dset_addr = 0;
|
||||
|
||||
/* Perform I/O */
|
||||
io_info->store = &ctg_store;
|
||||
if (H5D__final_collective_io(io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
if (H5D__final_collective_io(io_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO")
|
||||
|
||||
/* Free up resources in anticipation of following collective operation */
|
||||
@@ -1818,8 +1895,8 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
|
||||
* into the chunk index
|
||||
*/
|
||||
if (H5D__mpio_collective_filtered_chunk_reinsert(chunk_list, chunk_list_num_entries,
|
||||
rank_chunks_assigned_map, io_info, &index_info,
|
||||
mpi_rank, mpi_size) < 0)
|
||||
rank_chunks_assigned_map, io_info, dset_info,
|
||||
&index_info, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
|
||||
"couldn't collectively re-insert modified chunks into chunk index")
|
||||
}
|
||||
@@ -1857,7 +1934,7 @@ done:
|
||||
H5D_MPIO_TRACE_EXIT(mpi_rank);
|
||||
#endif
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
FUNC_LEAVE_NOAPI_TAG(ret_value)
|
||||
} /* end H5D__link_chunk_filtered_collective_io() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@@ -1878,33 +1955,39 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5D_chunk_map_t *fm,
|
||||
int mpi_rank, int mpi_size)
|
||||
H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, int mpi_rank,
|
||||
int mpi_size)
|
||||
{
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
H5D_io_info_t cpt_io_info; /* Compact I/O info object */
|
||||
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
|
||||
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
|
||||
uint8_t *chunk_io_option = NULL;
|
||||
haddr_t *chunk_addr = NULL;
|
||||
H5D_storage_t store; /* union of EFL and chunk pointer in file space */
|
||||
H5FD_mpio_collective_opt_t last_coll_opt_mode =
|
||||
H5FD_MPIO_COLLECTIVE_IO; /* Last parallel transfer with independent IO or collective IO with this mode
|
||||
*/
|
||||
H5FD_mpio_collective_opt_t orig_coll_opt_mode =
|
||||
H5FD_MPIO_COLLECTIVE_IO; /* Original parallel transfer property on entering this function */
|
||||
size_t total_chunk; /* Total # of chunks in dataset */
|
||||
size_t u; /* Local index variable */
|
||||
size_t num_chunk; /* Number of chunks for this process */
|
||||
H5SL_node_t *piece_node = NULL; /* Current node in chunk skip list */
|
||||
H5D_piece_info_t *next_chunk_info = NULL; /* Chunk info for next selected chunk */
|
||||
size_t u; /* Local index variable */
|
||||
H5D_mpio_actual_io_mode_t actual_io_mode =
|
||||
H5D_MPIO_NO_COLLECTIVE; /* Local variable for tracking the I/O mode used. */
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
FUNC_ENTER_PACKAGE_TAG(dset_info->dset->oloc.addr)
|
||||
|
||||
HDassert(dset_info->layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Get the current I/O collective opt mode so we can restore it later */
|
||||
if (H5CX_get_mpio_coll_opt(&orig_coll_opt_mode) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_op property")
|
||||
|
||||
/* Set the actual chunk opt mode property */
|
||||
H5CX_set_mpio_actual_chunk_opt(H5D_MPIO_MULTI_CHUNK);
|
||||
|
||||
/* Retrieve total # of chunks in dataset */
|
||||
H5_CHECKED_ASSIGN(total_chunk, size_t, fm->layout->u.chunk.nchunks, hsize_t);
|
||||
H5_CHECKED_ASSIGN(total_chunk, size_t, dset_info->layout->u.chunk.nchunks, hsize_t);
|
||||
HDassert(total_chunk != 0);
|
||||
|
||||
/* Allocate memories */
|
||||
@@ -1916,47 +1999,62 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
|
||||
#endif
|
||||
|
||||
/* Obtain IO option for each chunk */
|
||||
if (H5D__obtain_mpio_mode(io_info, fm, chunk_io_option, chunk_addr, mpi_rank, mpi_size) < 0)
|
||||
if (H5D__obtain_mpio_mode(io_info, dset_info, chunk_io_option, chunk_addr, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTRECV, FAIL, "unable to obtain MPIO mode")
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Set up compact I/O info object */
|
||||
H5MM_memcpy(&cpt_io_info, io_info, sizeof(cpt_io_info));
|
||||
cpt_io_info.store = &cpt_store;
|
||||
cpt_io_info.layout_ops = *H5D_LOPS_COMPACT;
|
||||
|
||||
/* Initialize temporary compact storage info */
|
||||
cpt_store.compact.dirty = &cpt_dirty;
|
||||
/* Set memory buffers */
|
||||
io_info->base_maddr = dset_info->buf;
|
||||
|
||||
/* Set dataset storage for I/O info */
|
||||
io_info->store = &store;
|
||||
dset_info->store = &store;
|
||||
|
||||
/* Get the number of chunks with a selection */
|
||||
num_chunk = H5SL_count(dset_info->layout_io_info.chunk_map->dset_sel_pieces);
|
||||
|
||||
if (num_chunk) {
|
||||
/* Start at the beginning of the chunk map skiplist. Since these chunks are
|
||||
* stored in index order and since we're iterating in index order we can
|
||||
* just check for each chunk being selected in order */
|
||||
if (NULL == (piece_node = H5SL_first(dset_info->layout_io_info.chunk_map->dset_sel_pieces)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get piece node from skip list")
|
||||
if (NULL == (next_chunk_info = (H5D_piece_info_t *)H5SL_item(piece_node)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get piece info from skip list")
|
||||
}
|
||||
|
||||
/* Loop over _all_ the chunks */
|
||||
for (u = 0; u < total_chunk; u++) {
|
||||
H5D_chunk_info_t *chunk_info; /* Chunk info for current chunk */
|
||||
H5D_piece_info_t *chunk_info; /* Chunk info for current chunk */
|
||||
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
|
||||
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG_VA(mpi_rank, "mpi_rank = %d, chunk index = %zu", mpi_rank, u);
|
||||
#endif
|
||||
/* Get the chunk info for this chunk, if there are elements selected */
|
||||
chunk_info = fm->select_chunk[u];
|
||||
|
||||
/* Set the storage information for chunks with selections */
|
||||
if (chunk_info) {
|
||||
HDassert(chunk_info->index == u);
|
||||
/* Check if this chunk is the next chunk in the skip list, if there are
|
||||
* selected chunks left to process */
|
||||
HDassert(!num_chunk || next_chunk_info);
|
||||
HDassert(!num_chunk || next_chunk_info->index >= u);
|
||||
if (num_chunk && next_chunk_info->index == u) {
|
||||
/* Next chunk is this chunk */
|
||||
chunk_info = next_chunk_info;
|
||||
|
||||
/* One less chunk to process */
|
||||
num_chunk--;
|
||||
|
||||
/* Advance next chunk to next node in skip list, if there are more chunks selected */
|
||||
if (num_chunk) {
|
||||
if (NULL == (piece_node = H5SL_next(piece_node)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk skip list terminated early")
|
||||
if (NULL == (next_chunk_info = (H5D_piece_info_t *)H5SL_item(piece_node)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get piece info from skip list")
|
||||
}
|
||||
|
||||
/* Pass in chunk's coordinates in a union. */
|
||||
store.chunk.scaled = chunk_info->scaled;
|
||||
} /* end if */
|
||||
}
|
||||
else
|
||||
chunk_info = NULL;
|
||||
|
||||
/* Collective IO for this chunk,
|
||||
* Note: even there is no selection for this process, the process still
|
||||
@@ -1994,10 +2092,10 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
|
||||
} /* end if */
|
||||
|
||||
/* Initialize temporary contiguous storage address */
|
||||
ctg_store.contig.dset_addr = chunk_addr[u];
|
||||
io_info->store_faddr = chunk_addr[u];
|
||||
|
||||
/* Perform the I/O */
|
||||
if (H5D__inter_collective_io(&ctg_io_info, type_info, fspace, mspace) < 0)
|
||||
if (H5D__inter_collective_io(io_info, dset_info, fspace, mspace) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
} /* end if */
|
||||
else { /* possible independent IO for this chunk */
|
||||
@@ -2028,10 +2126,10 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
|
||||
} /* end if */
|
||||
|
||||
/* Initialize temporary contiguous storage address */
|
||||
ctg_store.contig.dset_addr = chunk_addr[u];
|
||||
io_info->store_faddr = chunk_addr[u];
|
||||
|
||||
/* Perform the I/O */
|
||||
if (H5D__inter_collective_io(&ctg_io_info, type_info, fspace, mspace) < 0)
|
||||
if (H5D__inter_collective_io(io_info, dset_info, fspace, mspace) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish shared collective MPI-IO")
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "after inter collective IO");
|
||||
@@ -2043,12 +2141,17 @@ H5D__multi_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *ty
|
||||
H5CX_set_mpio_actual_io_mode(actual_io_mode);
|
||||
|
||||
done:
|
||||
/* Reset collective opt mode */
|
||||
if (H5CX_set_mpio_coll_opt(orig_coll_opt_mode) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't reset MPI-I/O collective_op property")
|
||||
|
||||
/* Free memory */
|
||||
if (chunk_io_option)
|
||||
H5MM_xfree(chunk_io_option);
|
||||
if (chunk_addr)
|
||||
H5MM_xfree(chunk_addr);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
FUNC_LEAVE_NOAPI_TAG(ret_value)
|
||||
} /* end H5D__multi_chunk_collective_io */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@@ -2130,14 +2233,13 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5D_chunk_map_t *fm, int mpi_rank, int mpi_size)
|
||||
H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, int mpi_rank,
|
||||
int mpi_size)
|
||||
{
|
||||
H5D_filtered_collective_io_info_t *chunk_list = NULL; /* The list of chunks being read/written */
|
||||
H5D_filtered_collective_io_info_t *chunk_hash_table = NULL;
|
||||
unsigned char **chunk_msg_bufs = NULL;
|
||||
H5D_io_info_t ctg_io_info; /* Contiguous I/O info object */
|
||||
H5D_storage_t ctg_store; /* Chunk storage information as contiguous dataset */
|
||||
MPI_Datatype mem_type = MPI_BYTE;
|
||||
MPI_Datatype file_type = MPI_BYTE;
|
||||
hbool_t mem_type_is_derived = FALSE;
|
||||
@@ -2150,11 +2252,9 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
int mpi_code;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
FUNC_ENTER_PACKAGE_TAG(dset_info->dset->oloc.addr)
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
@@ -2172,8 +2272,8 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
|
||||
|
||||
/* Build a list of selected chunks in the collective IO operation */
|
||||
if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, type_info, fm, &chunk_list,
|
||||
&chunk_list_num_entries, mpi_rank) < 0)
|
||||
if (H5D__mpio_collective_filtered_chunk_io_setup(io_info, dset_info, &chunk_list, &chunk_list_num_entries,
|
||||
mpi_rank) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list")
|
||||
|
||||
/* Retrieve the maximum number of chunks selected for any rank */
|
||||
@@ -2187,11 +2287,6 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
|
||||
/* Set up contiguous I/O info object */
|
||||
H5MM_memcpy(&ctg_io_info, io_info, sizeof(ctg_io_info));
|
||||
ctg_io_info.store = &ctg_store;
|
||||
ctg_io_info.layout_ops = *H5D_LOPS_CONTIG;
|
||||
|
||||
/* Initialize temporary contiguous storage info */
|
||||
ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
|
||||
|
||||
if (io_info->op_type == H5D_IO_OP_READ) { /* Filtered collective read */
|
||||
for (i = 0; i < max_num_chunks; i++) {
|
||||
@@ -2199,7 +2294,7 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
have_chunk_to_process = (i < chunk_list_num_entries);
|
||||
|
||||
if (H5D__mpio_collective_filtered_chunk_read(have_chunk_to_process ? &chunk_list[i] : NULL,
|
||||
have_chunk_to_process ? 1 : 0, io_info, type_info,
|
||||
have_chunk_to_process ? 1 : 0, io_info, dset_info,
|
||||
mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't read filtered chunks")
|
||||
|
||||
@@ -2214,17 +2309,17 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
hsize_t mpi_buf_count;
|
||||
|
||||
/* Construct chunked index info */
|
||||
H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, io_info);
|
||||
H5D_MPIO_INIT_CHUNK_IDX_INFO(index_info, dset_info->dset);
|
||||
|
||||
if (mpi_size > 1) {
|
||||
/* Redistribute shared chunks being written to */
|
||||
if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, fm,
|
||||
mpi_rank, mpi_size, NULL) < 0)
|
||||
if (H5D__mpio_redistribute_shared_chunks(chunk_list, chunk_list_num_entries, io_info, mpi_rank,
|
||||
mpi_size, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to redistribute shared chunks")
|
||||
|
||||
/* Send any chunk modification messages for chunks this rank no longer owns */
|
||||
if (H5D__mpio_share_chunk_modification_data(chunk_list, &chunk_list_num_entries, io_info,
|
||||
type_info, mpi_rank, mpi_size, &chunk_hash_table,
|
||||
dset_info, mpi_rank, mpi_size, &chunk_hash_table,
|
||||
&chunk_msg_bufs, &chunk_msg_bufs_len) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
|
||||
"unable to send chunk modification data between MPI ranks")
|
||||
@@ -2246,7 +2341,7 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
if (H5D__mpio_collective_filtered_chunk_update(have_chunk_to_process ? &chunk_list[i] : NULL,
|
||||
have_chunk_to_process ? 1 : 0, chunk_hash_table,
|
||||
chunk_msg_bufs, chunk_msg_bufs_len, io_info,
|
||||
type_info, mpi_rank, mpi_size) < 0)
|
||||
dset_info, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't update modified chunks")
|
||||
|
||||
/* All ranks now collectively re-allocate file space for all chunks */
|
||||
@@ -2276,19 +2371,21 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
* Override the write buffer to point to the
|
||||
* chunk's data buffer
|
||||
*/
|
||||
ctg_io_info.u.wbuf = chunk_list[i].buf;
|
||||
ctg_io_info.base_maddr.cvp = chunk_list[i].buf;
|
||||
|
||||
/*
|
||||
* Setup the base storage address for this
|
||||
* operation to be the chunk's file address
|
||||
*/
|
||||
ctg_store.contig.dset_addr = chunk_list[i].chunk_new.offset;
|
||||
ctg_io_info.store_faddr = chunk_list[i].chunk_new.offset;
|
||||
}
|
||||
else {
|
||||
ctg_io_info.store_faddr = 0;
|
||||
ctg_io_info.base_maddr = dset_info->buf;
|
||||
}
|
||||
else
|
||||
ctg_store.contig.dset_addr = 0;
|
||||
|
||||
/* Perform the I/O */
|
||||
if (H5D__final_collective_io(&ctg_io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
if (H5D__final_collective_io(&ctg_io_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish MPI-IO")
|
||||
|
||||
/* Free up resources in anticipation of following collective operation */
|
||||
@@ -2302,7 +2399,7 @@ H5D__multi_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_i
|
||||
*/
|
||||
if (H5D__mpio_collective_filtered_chunk_reinsert(have_chunk_to_process ? &chunk_list[i] : NULL,
|
||||
have_chunk_to_process ? 1 : 0, NULL, io_info,
|
||||
&index_info, mpi_rank, mpi_size) < 0)
|
||||
dset_info, &index_info, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL,
|
||||
"couldn't collectively re-insert modified chunks into chunk index")
|
||||
|
||||
@@ -2346,7 +2443,7 @@ done:
|
||||
H5D_MPIO_TRACE_EXIT(mpi_rank);
|
||||
#endif
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
FUNC_LEAVE_NOAPI_TAG(ret_value)
|
||||
} /* end H5D__multi_chunk_filtered_collective_io() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@@ -2363,7 +2460,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space,
|
||||
H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_dset_io_info_t *di, H5S_t *file_space,
|
||||
H5S_t *mem_space)
|
||||
{
|
||||
int mpi_buf_count; /* # of MPI types */
|
||||
@@ -2379,13 +2476,15 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
|
||||
mpi_rank = H5F_mpi_get_rank(di->dset->oloc.file);
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
H5D_MPIO_TIME_START(mpi_rank, "Inter collective I/O");
|
||||
if (mpi_rank < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_MPI, FAIL, "unable to obtain MPI rank")
|
||||
#endif
|
||||
|
||||
HDassert(io_info);
|
||||
|
||||
if ((file_space != NULL) && (mem_space != NULL)) {
|
||||
int mpi_file_count; /* Number of file "objects" to transfer */
|
||||
hsize_t *permute_map = NULL; /* array that holds the mapping from the old,
|
||||
@@ -2394,12 +2493,14 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
point selection of the file space */
|
||||
hbool_t is_permuted = FALSE;
|
||||
|
||||
HDassert(di);
|
||||
|
||||
/* 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_space, type_info->src_type_size, &mpi_file_type, &mpi_file_count,
|
||||
if (H5S_mpio_space_type(file_space, di->type_info.src_type_size, &mpi_file_type, &mpi_file_count,
|
||||
&mft_is_derived, /* OUT: datatype created */
|
||||
TRUE, /* this is a file space, so
|
||||
permute the datatype if the
|
||||
@@ -2415,7 +2516,7 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
/* Sanity check */
|
||||
if (is_permuted)
|
||||
HDassert(permute_map);
|
||||
if (H5S_mpio_space_type(mem_space, type_info->src_type_size, &mpi_buf_type, &mpi_buf_count,
|
||||
if (H5S_mpio_space_type(mem_space, di->type_info.src_type_size, &mpi_buf_type, &mpi_buf_count,
|
||||
&mbt_is_derived, /* OUT: datatype created */
|
||||
FALSE, /* this is a memory space, so if
|
||||
the file space is not
|
||||
@@ -2449,7 +2550,7 @@ H5D__inter_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
#endif
|
||||
|
||||
/* Perform final collective I/O operation */
|
||||
if (H5D__final_collective_io(io_info, type_info, (hsize_t)mpi_buf_count, mpi_file_type, mpi_buf_type) < 0)
|
||||
if (H5D__final_collective_io(io_info, (hsize_t)mpi_buf_count, mpi_file_type, mpi_buf_type) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish collective MPI-IO")
|
||||
|
||||
done:
|
||||
@@ -2481,8 +2582,8 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t mpi_buf_count,
|
||||
MPI_Datatype mpi_file_type, MPI_Datatype mpi_buf_type)
|
||||
H5D__final_collective_io(H5D_io_info_t *io_info, hsize_t mpi_buf_count, MPI_Datatype mpi_file_type,
|
||||
MPI_Datatype mpi_buf_type)
|
||||
{
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
int mpi_rank;
|
||||
@@ -2492,7 +2593,7 @@ H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
mpi_rank = H5F_mpi_get_rank(io_info->dset->oloc.file);
|
||||
mpi_rank = H5F_mpi_get_rank(io_info->dsets_info[0].dset->oloc.file);
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
H5D_MPIO_TIME_START(mpi_rank, "Final collective I/O");
|
||||
if (mpi_rank < 0)
|
||||
@@ -2504,11 +2605,11 @@ H5D__final_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set MPI-I/O collective I/O datatypes")
|
||||
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE) {
|
||||
if ((io_info->io_ops.single_write)(io_info, type_info, mpi_buf_count, NULL, NULL) < 0)
|
||||
if ((io_info->md_io_ops.single_write_md)(io_info, mpi_buf_count, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed")
|
||||
} /* end if */
|
||||
else {
|
||||
if ((io_info->io_ops.single_read)(io_info, type_info, mpi_buf_count, NULL, NULL) < 0)
|
||||
if ((io_info->md_io_ops.single_read_md)(io_info, mpi_buf_count, NULL, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed")
|
||||
} /* end else */
|
||||
|
||||
@@ -2523,28 +2624,26 @@ done:
|
||||
} /* end H5D__final_collective_io */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__cmp_chunk_addr
|
||||
* Function: H5D__cmp_piece_addr
|
||||
*
|
||||
* Purpose: Routine to compare chunk addresses
|
||||
* Purpose: Routine to compare piece addresses
|
||||
*
|
||||
* Description: Callback for qsort() to compare chunk addresses
|
||||
* Description: Callback for qsort() to compare piece addresses
|
||||
*
|
||||
* Return: -1, 0, 1
|
||||
*
|
||||
* Programmer: Muqun Yang
|
||||
* Monday, Feb. 13th, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
H5D__cmp_chunk_addr(const void *chunk_addr_info1, const void *chunk_addr_info2)
|
||||
H5D__cmp_piece_addr(const void *piece_info1, const void *piece_info2)
|
||||
{
|
||||
haddr_t addr1 = HADDR_UNDEF, addr2 = HADDR_UNDEF;
|
||||
haddr_t addr1;
|
||||
haddr_t addr2;
|
||||
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
addr1 = ((const H5D_chunk_addr_info_t *)chunk_addr_info1)->chunk_addr;
|
||||
addr2 = ((const H5D_chunk_addr_info_t *)chunk_addr_info2)->chunk_addr;
|
||||
addr1 = (*((const H5D_piece_info_t *const *)piece_info1))->faddr;
|
||||
addr2 = (*((const H5D_piece_info_t *const *)piece_info2))->faddr;
|
||||
|
||||
FUNC_LEAVE_NOAPI(H5F_addr_cmp(addr1, addr2))
|
||||
} /* end H5D__cmp_chunk_addr() */
|
||||
@@ -2704,178 +2803,6 @@ H5D__cmp_chunk_redistribute_info_orig_owner(const void *_entry1, const void *_en
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__cmp_chunk_redistribute_info_orig_owner() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__sort_chunk
|
||||
*
|
||||
* Purpose: Routine to sort chunks in increasing order of chunk address
|
||||
* Each chunk address is also obtained.
|
||||
*
|
||||
* Description:
|
||||
* For most cases, the chunk address has already been sorted in increasing order.
|
||||
* The special sorting flag is used to optimize this common case.
|
||||
* quick sort is used for necessary sorting.
|
||||
*
|
||||
* Parameters:
|
||||
* Input: H5D_io_info_t* io_info,
|
||||
* H5D_chunk_map_t *fm(global chunk map struct)
|
||||
* Input/Output: H5D_chunk_addr_info_t chunk_addr_info_array[] : array to store chunk address
|
||||
*and information many_chunk_opt : flag to optimize the way to obtain chunk addresses
|
||||
* for many chunks
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Muqun Yang
|
||||
* Monday, Feb. 13th, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__sort_chunk(H5D_io_info_t *io_info, const H5D_chunk_map_t *fm,
|
||||
H5D_chunk_addr_info_t chunk_addr_info_array[], int sum_chunk, int mpi_rank, int mpi_size)
|
||||
{
|
||||
H5SL_node_t *chunk_node; /* Current node in chunk skip list */
|
||||
H5D_chunk_info_t *chunk_info; /* Current chunking info. of this node. */
|
||||
haddr_t chunk_addr; /* Current chunking address of this node */
|
||||
haddr_t *total_chunk_addr_array = NULL; /* The array of chunk address for the total number of chunk */
|
||||
H5P_coll_md_read_flag_t md_reads_file_flag;
|
||||
hbool_t md_reads_context_flag;
|
||||
hbool_t restore_md_reads_state = FALSE;
|
||||
hbool_t do_sort = FALSE; /* Whether the addresses need to be sorted */
|
||||
int bsearch_coll_chunk_threshold;
|
||||
int many_chunk_opt = H5D_OBTAIN_ONE_CHUNK_ADDR_IND;
|
||||
int mpi_code; /* MPI return code */
|
||||
int i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Calculate the actual threshold to obtain all chunk addresses collectively
|
||||
* The bigger this number is, the more possible the use of obtaining chunk
|
||||
* address collectively.
|
||||
*/
|
||||
/* For non-optimization one-link IO, actual bsearch threshold is always
|
||||
* 0, we would always want to obtain the chunk addresses individually
|
||||
* for each process.
|
||||
*/
|
||||
bsearch_coll_chunk_threshold = (sum_chunk * 100) / ((int)fm->layout->u.chunk.nchunks * mpi_size);
|
||||
if ((bsearch_coll_chunk_threshold > H5D_ALL_CHUNK_ADDR_THRES_COL) &&
|
||||
((sum_chunk / mpi_size) >= H5D_ALL_CHUNK_ADDR_THRES_COL_NUM))
|
||||
many_chunk_opt = H5D_OBTAIN_ALL_CHUNK_ADDR_COL;
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG_VA(mpi_rank, "many_chunk_opt = %d", many_chunk_opt);
|
||||
#endif
|
||||
|
||||
/* If we need to optimize the way to obtain the chunk address */
|
||||
if (many_chunk_opt != H5D_OBTAIN_ONE_CHUNK_ADDR_IND) {
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "Coming inside H5D_OBTAIN_ALL_CHUNK_ADDR_COL");
|
||||
#endif
|
||||
/* Allocate array for chunk addresses */
|
||||
if (NULL == (total_chunk_addr_array =
|
||||
(haddr_t *)H5MM_malloc(sizeof(haddr_t) * (size_t)fm->layout->u.chunk.nchunks)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory chunk address array")
|
||||
|
||||
if (mpi_rank == 0) {
|
||||
herr_t result;
|
||||
|
||||
/*
|
||||
* If enabled, disable collective metadata reads here.
|
||||
* Since the chunk address mapping is done on rank 0
|
||||
* only here, it will cause problems if collective
|
||||
* metadata reads are enabled.
|
||||
*/
|
||||
if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
|
||||
md_reads_file_flag = H5P_FORCE_FALSE;
|
||||
md_reads_context_flag = FALSE;
|
||||
H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
|
||||
&md_reads_context_flag);
|
||||
restore_md_reads_state = TRUE;
|
||||
}
|
||||
|
||||
result = H5D__chunk_addrmap(io_info, total_chunk_addr_array);
|
||||
|
||||
/* Ensure that we restore the old collective metadata reads state */
|
||||
if (restore_md_reads_state) {
|
||||
H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
|
||||
&md_reads_context_flag);
|
||||
restore_md_reads_state = FALSE;
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
size_t u;
|
||||
|
||||
/* Clear total chunk address array */
|
||||
for (u = 0; u < (size_t)fm->layout->u.chunk.nchunks; u++)
|
||||
total_chunk_addr_array[u] = HADDR_UNDEF;
|
||||
|
||||
/* Push error, but still participate in following MPI_Bcast */
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
|
||||
}
|
||||
} /* end if */
|
||||
|
||||
/* Broadcasting the MPI_IO option info. and chunk address info. */
|
||||
if (MPI_SUCCESS != (mpi_code = MPI_Bcast(total_chunk_addr_array,
|
||||
(int)(sizeof(haddr_t) * fm->layout->u.chunk.nchunks),
|
||||
MPI_BYTE, (int)0, io_info->comm)))
|
||||
HMPI_GOTO_ERROR(FAIL, "MPI_BCast failed", mpi_code)
|
||||
} /* end if */
|
||||
|
||||
/* Start at first node in chunk skip list */
|
||||
i = 0;
|
||||
if (NULL == (chunk_node = H5SL_first(fm->sel_chunks)))
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk node from skipped list")
|
||||
|
||||
/* Iterate over all chunks for this process */
|
||||
while (chunk_node) {
|
||||
if (NULL == (chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node)))
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
|
||||
|
||||
if (many_chunk_opt == H5D_OBTAIN_ONE_CHUNK_ADDR_IND) {
|
||||
H5D_chunk_ud_t udata; /* User data for querying chunk info */
|
||||
|
||||
/* Get address of chunk */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
|
||||
chunk_addr = udata.chunk_block.offset;
|
||||
} /* end if */
|
||||
else
|
||||
chunk_addr = total_chunk_addr_array[chunk_info->index];
|
||||
|
||||
/* Check if chunk addresses are not in increasing order in the file */
|
||||
if (i > 0 && chunk_addr < chunk_addr_info_array[i - 1].chunk_addr)
|
||||
do_sort = TRUE;
|
||||
|
||||
/* Set the address & info for this chunk */
|
||||
chunk_addr_info_array[i].chunk_addr = chunk_addr;
|
||||
chunk_addr_info_array[i].chunk_info = *chunk_info;
|
||||
|
||||
/* Advance to next chunk in list */
|
||||
i++;
|
||||
chunk_node = H5SL_next(chunk_node);
|
||||
} /* end while */
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_DEBUG(mpi_rank, "before Qsort");
|
||||
#endif
|
||||
|
||||
if (do_sort) {
|
||||
size_t num_chunks = H5SL_count(fm->sel_chunks);
|
||||
|
||||
HDqsort(chunk_addr_info_array, num_chunks, sizeof(chunk_addr_info_array[0]), H5D__cmp_chunk_addr);
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
/* Re-enable collective metadata reads if we disabled them */
|
||||
if (restore_md_reads_state)
|
||||
H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
|
||||
|
||||
if (total_chunk_addr_array)
|
||||
H5MM_xfree(total_chunk_addr_array);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__sort_chunk() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__obtain_mpio_mode
|
||||
*
|
||||
@@ -2902,7 +2829,7 @@ done:
|
||||
* Parameters:
|
||||
*
|
||||
* Input: H5D_io_info_t* io_info,
|
||||
* H5D_chunk_map_t *fm,(global chunk map struct)
|
||||
* H5D_dset_io_info_t *di,(dataset info struct)
|
||||
* Output: uint8_t assign_io_mode[], : IO mode, collective, independent or none
|
||||
* haddr_t chunk_addr[], : chunk address array for each chunk
|
||||
*
|
||||
@@ -2914,7 +2841,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assign_io_mode[],
|
||||
H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_dset_io_info_t *di, uint8_t assign_io_mode[],
|
||||
haddr_t chunk_addr[], int mpi_rank, int mpi_size)
|
||||
{
|
||||
size_t total_chunks;
|
||||
@@ -2924,7 +2851,7 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
uint8_t *mergebuf = NULL;
|
||||
uint8_t *tempbuf;
|
||||
H5SL_node_t *chunk_node;
|
||||
H5D_chunk_info_t *chunk_info;
|
||||
H5D_piece_info_t *chunk_info;
|
||||
H5P_coll_md_read_flag_t md_reads_file_flag;
|
||||
hbool_t md_reads_context_flag;
|
||||
hbool_t restore_md_reads_state = FALSE;
|
||||
@@ -2936,17 +2863,19 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(di->layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Assign the rank 0 to the root */
|
||||
root = 0;
|
||||
comm = io_info->comm;
|
||||
|
||||
/* Setup parameters */
|
||||
H5_CHECKED_ASSIGN(total_chunks, size_t, fm->layout->u.chunk.nchunks, hsize_t);
|
||||
H5_CHECKED_ASSIGN(total_chunks, size_t, di->layout->u.chunk.nchunks, hsize_t);
|
||||
if (H5CX_get_mpio_chunk_opt_ratio(&percent_nproc_per_chunk) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't get percent nproc per chunk")
|
||||
/* if ratio is 0, perform collective io */
|
||||
if (0 == percent_nproc_per_chunk) {
|
||||
if (H5D__chunk_addrmap(io_info, chunk_addr) < 0)
|
||||
if (H5D__chunk_addrmap(di->dset, chunk_addr) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address");
|
||||
for (ic = 0; ic < total_chunks; ic++)
|
||||
assign_io_mode[ic] = H5D_CHUNK_IO_MODE_COL;
|
||||
@@ -2967,9 +2896,9 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate recv I/O mode info buffer")
|
||||
|
||||
/* Obtain the regularity and selection information for all chunks in this process. */
|
||||
chunk_node = H5SL_first(fm->sel_chunks);
|
||||
chunk_node = H5SL_first(di->layout_io_info.chunk_map->dset_sel_pieces);
|
||||
while (chunk_node) {
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node);
|
||||
chunk_info = (H5D_piece_info_t *)H5SL_item(chunk_node);
|
||||
|
||||
io_mode_info[chunk_info->index] = H5D_CHUNK_SELECT_REG; /* this chunk is selected and is "regular" */
|
||||
chunk_node = H5SL_next(chunk_node);
|
||||
@@ -2992,11 +2921,10 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
* only here, it will cause problems if collective
|
||||
* metadata reads are enabled.
|
||||
*/
|
||||
if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
|
||||
if (H5F_get_coll_metadata_reads(di->dset->oloc.file)) {
|
||||
md_reads_file_flag = H5P_FORCE_FALSE;
|
||||
md_reads_context_flag = FALSE;
|
||||
H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag,
|
||||
&md_reads_context_flag);
|
||||
H5F_set_coll_metadata_reads(di->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
|
||||
restore_md_reads_state = TRUE;
|
||||
}
|
||||
|
||||
@@ -3006,7 +2934,7 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate nproc_per_chunk buffer")
|
||||
|
||||
/* calculating the chunk address */
|
||||
if (H5D__chunk_addrmap(io_info, chunk_addr) < 0) {
|
||||
if (H5D__chunk_addrmap(di->dset, chunk_addr) < 0) {
|
||||
H5MM_free(nproc_per_chunk);
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk address")
|
||||
} /* end if */
|
||||
@@ -3068,7 +2996,7 @@ H5D__obtain_mpio_mode(H5D_io_info_t *io_info, H5D_chunk_map_t *fm, uint8_t assig
|
||||
done:
|
||||
/* Re-enable collective metadata reads if we disabled them */
|
||||
if (restore_md_reads_state)
|
||||
H5F_set_coll_metadata_reads(io_info->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
|
||||
H5F_set_coll_metadata_reads(di->dset->oloc.file, &md_reads_file_flag, &md_reads_context_flag);
|
||||
|
||||
if (io_mode_info)
|
||||
H5MM_free(io_mode_info);
|
||||
@@ -3098,8 +3026,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
const H5D_chunk_map_t *fm,
|
||||
H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *di,
|
||||
H5D_filtered_collective_io_info_t **chunk_list,
|
||||
size_t *num_entries, int mpi_rank)
|
||||
{
|
||||
@@ -3113,36 +3040,36 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(fm);
|
||||
HDassert(di);
|
||||
HDassert(chunk_list);
|
||||
HDassert(num_entries);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
H5D_MPIO_TIME_START(mpi_rank, "Filtered Collective I/O Setup");
|
||||
#endif
|
||||
|
||||
HDassert(di->layout->type == H5D_CHUNKED);
|
||||
|
||||
/* Each rank builds a local list of the chunks they have selected */
|
||||
if ((num_chunks_selected = H5SL_count(fm->sel_chunks))) {
|
||||
H5D_chunk_info_t *chunk_info;
|
||||
if ((num_chunks_selected = H5SL_count(di->layout_io_info.chunk_map->dset_sel_pieces))) {
|
||||
H5D_piece_info_t *chunk_info;
|
||||
H5SL_node_t *chunk_node;
|
||||
hsize_t select_npoints;
|
||||
hbool_t need_sort = FALSE;
|
||||
|
||||
/* Determine whether partial edge chunks should be filtered */
|
||||
filter_partial_edge_chunks = !(io_info->dset->shared->layout.u.chunk.flags &
|
||||
H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS);
|
||||
filter_partial_edge_chunks =
|
||||
!(di->dset->shared->layout.u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS);
|
||||
|
||||
if (NULL == (local_info_array = H5MM_malloc(num_chunks_selected * sizeof(*local_info_array))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate local io info array buffer")
|
||||
|
||||
chunk_node = H5SL_first(fm->sel_chunks);
|
||||
chunk_node = H5SL_first(di->layout_io_info.chunk_map->dset_sel_pieces);
|
||||
for (i = 0; chunk_node; i++) {
|
||||
chunk_info = (H5D_chunk_info_t *)H5SL_item(chunk_node);
|
||||
chunk_info = (H5D_piece_info_t *)H5SL_item(chunk_node);
|
||||
|
||||
/* Obtain this chunk's address */
|
||||
if (H5D__chunk_lookup(io_info->dset, chunk_info->scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(di->dset, chunk_info->scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
|
||||
/* Initialize rank-local chunk info */
|
||||
@@ -3154,7 +3081,7 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
local_info_array[i].buf = NULL;
|
||||
|
||||
select_npoints = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
|
||||
local_info_array[i].io_size = (size_t)select_npoints * type_info->dst_type_size;
|
||||
local_info_array[i].io_size = (size_t)select_npoints * di->type_info.dst_type_size;
|
||||
|
||||
/*
|
||||
* Determine whether this chunk will need to be read from the file. If this is
|
||||
@@ -3204,7 +3131,7 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
local_info_array[i].need_read = TRUE;
|
||||
else {
|
||||
local_info_array[i].need_read =
|
||||
local_info_array[i].io_size < (size_t)io_info->dset->shared->layout.u.chunk.size;
|
||||
local_info_array[i].io_size < (size_t)di->dset->shared->layout.u.chunk.size;
|
||||
}
|
||||
|
||||
local_info_array[i].skip_filter_pline = FALSE;
|
||||
@@ -3213,9 +3140,9 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
* If this is a partial edge chunk and the "don't filter partial edge
|
||||
* chunks" flag is set, make sure not to apply filters to the chunk.
|
||||
*/
|
||||
if (H5D__chunk_is_partial_edge_chunk(io_info->dset->shared->ndims,
|
||||
io_info->dset->shared->layout.u.chunk.dim,
|
||||
chunk_info->scaled, io_info->dset->shared->curr_dims))
|
||||
if (H5D__chunk_is_partial_edge_chunk(di->dset->shared->ndims,
|
||||
di->dset->shared->layout.u.chunk.dim, chunk_info->scaled,
|
||||
di->dset->shared->curr_dims))
|
||||
local_info_array[i].skip_filter_pline = TRUE;
|
||||
}
|
||||
|
||||
@@ -3244,7 +3171,7 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
* extensible array code calculated instead of what was calculated
|
||||
* in the chunk file mapping.
|
||||
*/
|
||||
if (io_info->dset->shared->layout.u.chunk.idx_type == H5D_CHUNK_IDX_EARRAY)
|
||||
if (di->dset->shared->layout.u.chunk.idx_type == H5D_CHUNK_IDX_EARRAY)
|
||||
local_info_array[i].index_info.chunk_idx = udata.chunk_idx;
|
||||
else
|
||||
local_info_array[i].index_info.chunk_idx = chunk_info->index;
|
||||
@@ -3264,7 +3191,7 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
H5D__mpio_dump_collective_filtered_chunk_list(local_info_array, num_chunks_selected, mpi_rank);
|
||||
#endif
|
||||
}
|
||||
else if (H5F_get_coll_metadata_reads(io_info->dset->oloc.file)) {
|
||||
else if (H5F_get_coll_metadata_reads(di->dset->oloc.file)) {
|
||||
hsize_t scaled[H5O_LAYOUT_NDIMS] = {0};
|
||||
|
||||
/*
|
||||
@@ -3281,7 +3208,7 @@ H5D__mpio_collective_filtered_chunk_io_setup(const H5D_io_info_t *io_info, const
|
||||
* callback that can be used to ensure collectivity between ranks
|
||||
* in a more natural way, but this hack should suffice for now.
|
||||
*/
|
||||
if (H5D__chunk_lookup(io_info->dset, scaled, &udata) < 0)
|
||||
if (H5D__chunk_lookup(di->dset, scaled, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
|
||||
}
|
||||
|
||||
@@ -3320,8 +3247,7 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
|
||||
const H5D_chunk_map_t *fm, int mpi_rank, int mpi_size,
|
||||
size_t **rank_chunks_assigned_map)
|
||||
int mpi_rank, int mpi_size, size_t **rank_chunks_assigned_map)
|
||||
{
|
||||
hbool_t redistribute_on_all_ranks;
|
||||
size_t *num_chunks_map = NULL;
|
||||
@@ -3334,7 +3260,6 @@ H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_li
|
||||
|
||||
HDassert(chunk_list || 0 == chunk_list_num_entries);
|
||||
HDassert(io_info);
|
||||
HDassert(fm);
|
||||
HDassert(mpi_size > 1); /* No chunk sharing is possible for MPI Comm size of 1 */
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -3368,7 +3293,7 @@ H5D__mpio_redistribute_shared_chunks(H5D_filtered_collective_io_info_t *chunk_li
|
||||
redistribute_on_all_ranks = coll_chunk_list_size < H5D_CHUNK_REDISTRIBUTE_THRES;
|
||||
|
||||
if (H5D__mpio_redistribute_shared_chunks_int(chunk_list, num_chunks_map, redistribute_on_all_ranks,
|
||||
io_info, fm, mpi_rank, mpi_size) < 0)
|
||||
io_info, mpi_rank, mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTREDISTRIBUTE, FAIL, "can't redistribute shared chunks")
|
||||
|
||||
/*
|
||||
@@ -3458,9 +3383,7 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_redistribute_shared_chunks_int(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t *num_chunks_assigned_map, hbool_t all_ranks_involved,
|
||||
const H5D_io_info_t *io_info,
|
||||
const H5D_chunk_map_t H5_ATTR_NDEBUG_UNUSED *fm, int mpi_rank,
|
||||
int mpi_size)
|
||||
const H5D_io_info_t *io_info, int mpi_rank, int mpi_size)
|
||||
{
|
||||
MPI_Datatype struct_type;
|
||||
MPI_Datatype packed_type;
|
||||
@@ -3481,7 +3404,6 @@ H5D__mpio_redistribute_shared_chunks_int(H5D_filtered_collective_io_info_t *chun
|
||||
HDassert(num_chunks_assigned_map);
|
||||
HDassert(chunk_list || 0 == num_chunks_assigned_map[mpi_rank]);
|
||||
HDassert(io_info);
|
||||
HDassert(fm);
|
||||
HDassert(mpi_size > 1);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -3789,7 +3711,7 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t *chunk_list_num_entries, H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_rank,
|
||||
H5D_dset_io_info_t *dset_info, int mpi_rank,
|
||||
int H5_ATTR_NDEBUG_UNUSED mpi_size,
|
||||
H5D_filtered_collective_io_info_t **chunk_hash_table,
|
||||
unsigned char ***chunk_msg_bufs, int *chunk_msg_bufs_len)
|
||||
@@ -3818,7 +3740,7 @@ H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk
|
||||
HDassert(chunk_list_num_entries);
|
||||
HDassert(chunk_list || 0 == *chunk_list_num_entries);
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(dset_info);
|
||||
HDassert(mpi_size > 1);
|
||||
HDassert(chunk_msg_bufs);
|
||||
HDassert(chunk_msg_bufs_len);
|
||||
@@ -3891,7 +3813,7 @@ H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk
|
||||
last_assigned_idx++;
|
||||
}
|
||||
else {
|
||||
H5D_chunk_info_t *chunk_info = chunk_entry->chunk_info;
|
||||
H5D_piece_info_t *chunk_info = chunk_entry->chunk_info;
|
||||
unsigned char *mod_data_p = NULL;
|
||||
hsize_t iter_nelmts;
|
||||
size_t mod_data_size = 0;
|
||||
@@ -3909,7 +3831,7 @@ H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk
|
||||
iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
|
||||
H5_CHECK_OVERFLOW(iter_nelmts, hsize_t, size_t);
|
||||
|
||||
mod_data_size += (size_t)iter_nelmts * type_info->src_type_size;
|
||||
mod_data_size += (size_t)iter_nelmts * dset_info->type_info.src_type_size;
|
||||
|
||||
if (NULL == (msg_send_bufs[num_send_requests] = H5MM_malloc(mod_data_size)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL,
|
||||
@@ -3926,14 +3848,14 @@ H5D__mpio_share_chunk_modification_data(H5D_filtered_collective_io_info_t *chunk
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "unable to encode dataspace")
|
||||
|
||||
/* Initialize iterator for memory selection */
|
||||
if (H5S_select_iter_init(mem_iter, chunk_info->mspace, type_info->src_type_size,
|
||||
if (H5S_select_iter_init(mem_iter, chunk_info->mspace, dset_info->type_info.src_type_size,
|
||||
H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"unable to initialize memory selection information")
|
||||
mem_iter_init = TRUE;
|
||||
|
||||
/* Collect the modification data into the buffer */
|
||||
if (0 == H5D__gather_mem(io_info->u.wbuf, mem_iter, (size_t)iter_nelmts, mod_data_p))
|
||||
if (0 == H5D__gather_mem(dset_info->buf.cvp, mem_iter, (size_t)iter_nelmts, mod_data_p))
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTGATHER, FAIL, "couldn't gather from write buffer")
|
||||
|
||||
/*
|
||||
@@ -4202,10 +4124,9 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_size)
|
||||
int mpi_size)
|
||||
{
|
||||
H5D_io_info_t coll_io_info;
|
||||
H5D_storage_t ctg_store;
|
||||
MPI_Datatype file_type = MPI_DATATYPE_NULL;
|
||||
MPI_Datatype mem_type = MPI_DATATYPE_NULL;
|
||||
hbool_t mem_type_is_derived = FALSE;
|
||||
@@ -4222,7 +4143,6 @@ H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t
|
||||
|
||||
HDassert(chunk_list || 0 == chunk_list_num_entries);
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
|
||||
/* Initialize temporary I/O info */
|
||||
coll_io_info = *io_info;
|
||||
@@ -4258,9 +4178,7 @@ H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t
|
||||
|
||||
/*
|
||||
* If this rank doesn't have a selection, it can
|
||||
* skip I/O if independent I/O was requested at
|
||||
* the low level, or if the MPI communicator size
|
||||
* is 1.
|
||||
* skip I/O if the MPI communicator size is 1.
|
||||
*
|
||||
* Otherwise, this rank has to participate in
|
||||
* collective I/O, but probably has a NULL buf
|
||||
@@ -4268,20 +4186,13 @@ H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t
|
||||
* write/read function expects one.
|
||||
*/
|
||||
if (num_chunks == 0) {
|
||||
H5FD_mpio_collective_opt_t coll_opt_mode;
|
||||
|
||||
/* 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_DATASET, H5E_CANTGET, FAIL, "can't get MPI-I/O collective_opt property")
|
||||
|
||||
if ((mpi_size == 1) || (H5FD_MPIO_INDIVIDUAL_IO == coll_opt_mode)) {
|
||||
if (mpi_size == 1)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
}
|
||||
else {
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE)
|
||||
coll_io_info.u.wbuf = &fake_buf;
|
||||
coll_io_info.base_maddr.cvp = &fake_buf;
|
||||
else
|
||||
coll_io_info.u.rbuf = &fake_buf;
|
||||
coll_io_info.base_maddr.vp = &fake_buf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4297,18 +4208,15 @@ H5D__mpio_collective_filtered_chunk_common_io(H5D_filtered_collective_io_info_t
|
||||
* to be the first chunk's file address
|
||||
*/
|
||||
if (io_info->op_type == H5D_IO_OP_WRITE)
|
||||
ctg_store.contig.dset_addr = chunk_list[0].chunk_new.offset;
|
||||
coll_io_info.store_faddr = chunk_list[0].chunk_new.offset;
|
||||
else
|
||||
ctg_store.contig.dset_addr = base_read_offset;
|
||||
coll_io_info.store_faddr = base_read_offset;
|
||||
}
|
||||
else
|
||||
ctg_store.contig.dset_addr = 0;
|
||||
|
||||
ctg_store.contig.dset_size = (hsize_t)io_info->dset->shared->layout.u.chunk.size;
|
||||
coll_io_info.store = &ctg_store;
|
||||
coll_io_info.store_faddr = 0;
|
||||
|
||||
/* Perform I/O */
|
||||
if (H5D__final_collective_io(&coll_io_info, type_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
if (H5D__final_collective_io(&coll_io_info, mpi_buf_count, file_type, mem_type) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish MPI I/O")
|
||||
|
||||
done:
|
||||
@@ -4335,10 +4243,10 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries, const H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, int mpi_rank, int mpi_size)
|
||||
const H5D_dset_io_info_t *di, int mpi_rank, int mpi_size)
|
||||
{
|
||||
H5D_fill_buf_info_t fb_info;
|
||||
H5D_chunk_info_t *chunk_info = NULL;
|
||||
H5D_piece_info_t *chunk_info = NULL;
|
||||
H5D_io_info_t coll_io_info;
|
||||
H5Z_EDC_t err_detect; /* Error detection info */
|
||||
H5Z_cb_t filter_cb; /* I/O filter callback function */
|
||||
@@ -4356,7 +4264,7 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
|
||||
HDassert(chunk_list || 0 == chunk_list_num_entries);
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(di);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
@@ -4366,8 +4274,8 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
#endif
|
||||
|
||||
/* Initialize temporary I/O info */
|
||||
coll_io_info = *io_info;
|
||||
coll_io_info.u.rbuf = NULL;
|
||||
coll_io_info = *io_info;
|
||||
coll_io_info.base_maddr.vp = NULL;
|
||||
|
||||
if (chunk_list_num_entries) {
|
||||
/* Retrieve filter settings from API context */
|
||||
@@ -4377,12 +4285,12 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O filter callback function")
|
||||
|
||||
/* Set size of full chunks in dataset */
|
||||
file_chunk_size = io_info->dset->shared->layout.u.chunk.size;
|
||||
file_chunk_size = di->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Determine if fill values should be "read" for unallocated chunks */
|
||||
should_fill = (io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
|
||||
((io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
|
||||
io_info->dset->shared->dcpl_cache.fill.fill_defined);
|
||||
should_fill = (di->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
|
||||
((di->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
|
||||
di->dset->shared->dcpl_cache.fill.fill_defined);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4436,22 +4344,21 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
if (!fb_info_init) {
|
||||
hsize_t chunk_dims[H5S_MAX_RANK];
|
||||
|
||||
HDassert(io_info->dset->shared->ndims == io_info->dset->shared->layout.u.chunk.ndims - 1);
|
||||
for (size_t j = 0; j < io_info->dset->shared->layout.u.chunk.ndims - 1; j++)
|
||||
chunk_dims[j] = (hsize_t)io_info->dset->shared->layout.u.chunk.dim[j];
|
||||
HDassert(di->dset->shared->ndims == di->dset->shared->layout.u.chunk.ndims - 1);
|
||||
for (size_t j = 0; j < di->dset->shared->layout.u.chunk.ndims - 1; j++)
|
||||
chunk_dims[j] = (hsize_t)di->dset->shared->layout.u.chunk.dim[j];
|
||||
|
||||
/* Get a dataspace for filling chunk memory buffers */
|
||||
if (NULL == (fill_space = H5S_create_simple(
|
||||
io_info->dset->shared->layout.u.chunk.ndims - 1, chunk_dims, NULL)))
|
||||
if (NULL == (fill_space = H5S_create_simple(di->dset->shared->layout.u.chunk.ndims - 1,
|
||||
chunk_dims, NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create chunk fill dataspace")
|
||||
|
||||
/* Initialize fill value buffer */
|
||||
if (H5D__fill_init(&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc,
|
||||
(void *)&io_info->dset->shared->dcpl_cache.pline,
|
||||
(H5MM_free_t)H5D__chunk_mem_free,
|
||||
(void *)&io_info->dset->shared->dcpl_cache.pline,
|
||||
&io_info->dset->shared->dcpl_cache.fill, io_info->dset->shared->type,
|
||||
io_info->dset->shared->type_id, 0, file_chunk_size) < 0)
|
||||
if (H5D__fill_init(
|
||||
&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc,
|
||||
(void *)&di->dset->shared->dcpl_cache.pline, (H5MM_free_t)H5D__chunk_mem_free,
|
||||
(void *)&di->dset->shared->dcpl_cache.pline, &di->dset->shared->dcpl_cache.fill,
|
||||
di->dset->shared->type, di->dset->shared->type_id, 0, file_chunk_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill value buffer")
|
||||
|
||||
fb_info_init = TRUE;
|
||||
@@ -4459,8 +4366,8 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
|
||||
/* Write fill value to memory buffer */
|
||||
HDassert(fb_info.fill_buf);
|
||||
if (H5D__fill(fb_info.fill_buf, io_info->dset->shared->type, chunk_list[i].buf,
|
||||
type_info->mem_type, fill_space) < 0)
|
||||
if (H5D__fill(fb_info.fill_buf, di->dset->shared->type, chunk_list[i].buf,
|
||||
di->type_info.mem_type, fill_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't fill chunk buffer with fill value")
|
||||
}
|
||||
}
|
||||
@@ -4472,8 +4379,8 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
* read of chunks is essentially a no-op, so avoid it here.
|
||||
*/
|
||||
index_empty = FALSE;
|
||||
if (io_info->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
|
||||
if (H5D__chunk_index_empty(io_info->dset, &index_empty) < 0)
|
||||
if (di->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
|
||||
if (H5D__chunk_index_empty(di->dset, &index_empty) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't determine if chunk index is empty")
|
||||
|
||||
if (!index_empty) {
|
||||
@@ -4482,11 +4389,11 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
* the first chunk data buffer being read into
|
||||
*/
|
||||
if (base_read_buf)
|
||||
coll_io_info.u.rbuf = base_read_buf;
|
||||
coll_io_info.base_maddr.vp = base_read_buf;
|
||||
|
||||
/* Perform collective chunk read */
|
||||
if (H5D__mpio_collective_filtered_chunk_common_io(chunk_list, chunk_list_num_entries, &coll_io_info,
|
||||
type_info, mpi_size) < 0)
|
||||
mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish collective filtered chunk read")
|
||||
}
|
||||
|
||||
@@ -4499,7 +4406,7 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
|
||||
/* Unfilter the chunk, unless we didn't read it from the file */
|
||||
if (chunk_list[i].need_read && !chunk_list[i].skip_filter_pline) {
|
||||
if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
|
||||
if (H5Z_pipeline(&di->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
|
||||
&(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
|
||||
(size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
|
||||
&chunk_list[i].buf) < 0)
|
||||
@@ -4509,8 +4416,8 @@ H5D__mpio_collective_filtered_chunk_read(H5D_filtered_collective_io_info_t *chun
|
||||
/* Scatter the chunk data to the read buffer */
|
||||
iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->fspace);
|
||||
|
||||
if (H5D_select_io_mem(io_info->u.rbuf, chunk_info->mspace, chunk_list[i].buf, chunk_info->fspace,
|
||||
type_info->src_type_size, (size_t)iter_nelmts) < 0)
|
||||
if (H5D_select_io_mem(di->buf.vp, chunk_info->mspace, chunk_list[i].buf, chunk_info->fspace,
|
||||
di->type_info.src_type_size, (size_t)iter_nelmts) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "couldn't copy chunk data to read buffer")
|
||||
}
|
||||
|
||||
@@ -4554,39 +4461,44 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
size_t chunk_list_num_entries,
|
||||
H5D_filtered_collective_io_info_t *chunk_hash_table,
|
||||
unsigned char **chunk_msg_bufs, int chunk_msg_bufs_len,
|
||||
const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
const H5D_io_info_t *io_info, const H5D_dset_io_info_t *di,
|
||||
int H5_ATTR_NDEBUG_UNUSED mpi_rank, int mpi_size)
|
||||
{
|
||||
H5D_fill_buf_info_t fb_info;
|
||||
H5D_chunk_info_t *chunk_info = NULL;
|
||||
H5S_sel_iter_t *sel_iter = NULL; /* Dataspace selection iterator for H5D__scatter_mem */
|
||||
H5D_io_info_t coll_io_info;
|
||||
H5Z_EDC_t err_detect; /* Error detection info */
|
||||
H5Z_cb_t filter_cb; /* I/O filter callback function */
|
||||
hsize_t file_chunk_size = 0;
|
||||
hsize_t iter_nelmts; /* Number of points to iterate over for the chunk IO operation */
|
||||
hbool_t should_fill = FALSE;
|
||||
hbool_t fb_info_init = FALSE;
|
||||
hbool_t sel_iter_init = FALSE;
|
||||
hbool_t index_empty = FALSE;
|
||||
size_t i;
|
||||
H5S_t *dataspace = NULL;
|
||||
H5S_t *fill_space = NULL;
|
||||
void *base_read_buf = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
const H5D_type_info_t *type_info = NULL;
|
||||
H5D_fill_buf_info_t fb_info;
|
||||
H5D_piece_info_t *chunk_info = NULL;
|
||||
H5S_sel_iter_t *sel_iter = NULL; /* Dataspace selection iterator for H5D__scatter_mem */
|
||||
H5D_io_info_t coll_io_info;
|
||||
H5Z_EDC_t err_detect; /* Error detection info */
|
||||
H5Z_cb_t filter_cb; /* I/O filter callback function */
|
||||
hsize_t file_chunk_size = 0;
|
||||
hsize_t iter_nelmts; /* Number of points to iterate over for the chunk IO operation */
|
||||
hbool_t should_fill = FALSE;
|
||||
hbool_t fb_info_init = FALSE;
|
||||
hbool_t sel_iter_init = FALSE;
|
||||
hbool_t index_empty = FALSE;
|
||||
size_t i;
|
||||
H5S_t *dataspace = NULL;
|
||||
H5S_t *fill_space = NULL;
|
||||
void *base_read_buf = NULL;
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
HDassert(chunk_list || 0 == chunk_list_num_entries);
|
||||
HDassert((chunk_msg_bufs && chunk_hash_table) || 0 == chunk_msg_bufs_len);
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(di);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
H5D_MPIO_TRACE_ENTER(mpi_rank);
|
||||
H5D_MPIO_TIME_START(mpi_rank, "Filtered collective chunk update");
|
||||
#endif
|
||||
|
||||
/* Set convenience pointers */
|
||||
type_info = &(di->type_info);
|
||||
HDassert(type_info);
|
||||
|
||||
if (chunk_list_num_entries) {
|
||||
/* Retrieve filter settings from API context */
|
||||
if (H5CX_get_err_detect(&err_detect) < 0)
|
||||
@@ -4595,12 +4507,12 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get I/O filter callback function")
|
||||
|
||||
/* Set size of full chunks in dataset */
|
||||
file_chunk_size = io_info->dset->shared->layout.u.chunk.size;
|
||||
file_chunk_size = di->dset->shared->layout.u.chunk.size;
|
||||
|
||||
/* Determine if fill values should be written to chunks */
|
||||
should_fill = (io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
|
||||
((io_info->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
|
||||
io_info->dset->shared->dcpl_cache.fill.fill_defined);
|
||||
should_fill = (di->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_ALLOC) ||
|
||||
((di->dset->shared->dcpl_cache.fill.fill_time == H5D_FILL_TIME_IFSET) &&
|
||||
di->dset->shared->dcpl_cache.fill.fill_defined);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4672,25 +4584,23 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
if (!fb_info_init) {
|
||||
hsize_t chunk_dims[H5S_MAX_RANK];
|
||||
|
||||
HDassert(io_info->dset->shared->ndims ==
|
||||
io_info->dset->shared->layout.u.chunk.ndims - 1);
|
||||
for (size_t j = 0; j < io_info->dset->shared->layout.u.chunk.ndims - 1; j++)
|
||||
chunk_dims[j] = (hsize_t)io_info->dset->shared->layout.u.chunk.dim[j];
|
||||
HDassert(di->dset->shared->ndims == di->dset->shared->layout.u.chunk.ndims - 1);
|
||||
for (size_t j = 0; j < di->dset->shared->layout.u.chunk.ndims - 1; j++)
|
||||
chunk_dims[j] = (hsize_t)di->dset->shared->layout.u.chunk.dim[j];
|
||||
|
||||
/* Get a dataspace for filling chunk memory buffers */
|
||||
if (NULL == (fill_space = H5S_create_simple(
|
||||
io_info->dset->shared->layout.u.chunk.ndims - 1, chunk_dims, NULL)))
|
||||
di->dset->shared->layout.u.chunk.ndims - 1, chunk_dims, NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"unable to create chunk fill dataspace")
|
||||
|
||||
/* Initialize fill value buffer */
|
||||
if (H5D__fill_init(&fb_info, NULL, (H5MM_allocate_t)H5D__chunk_mem_alloc,
|
||||
(void *)&io_info->dset->shared->dcpl_cache.pline,
|
||||
(void *)&di->dset->shared->dcpl_cache.pline,
|
||||
(H5MM_free_t)H5D__chunk_mem_free,
|
||||
(void *)&io_info->dset->shared->dcpl_cache.pline,
|
||||
&io_info->dset->shared->dcpl_cache.fill,
|
||||
io_info->dset->shared->type, io_info->dset->shared->type_id, 0,
|
||||
file_chunk_size) < 0)
|
||||
(void *)&di->dset->shared->dcpl_cache.pline,
|
||||
&di->dset->shared->dcpl_cache.fill, di->dset->shared->type,
|
||||
di->dset->shared->type_id, 0, file_chunk_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize fill value buffer")
|
||||
|
||||
fb_info_init = TRUE;
|
||||
@@ -4698,7 +4608,7 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
|
||||
/* Write fill value to memory buffer */
|
||||
HDassert(fb_info.fill_buf);
|
||||
if (H5D__fill(fb_info.fill_buf, io_info->dset->shared->type, chunk_list[i].buf,
|
||||
if (H5D__fill(fb_info.fill_buf, di->dset->shared->type, chunk_list[i].buf,
|
||||
type_info->mem_type, fill_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
|
||||
"couldn't fill chunk buffer with fill value")
|
||||
@@ -4715,8 +4625,8 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
* read of chunks is essentially a no-op, so avoid it here.
|
||||
*/
|
||||
index_empty = FALSE;
|
||||
if (io_info->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
|
||||
if (H5D__chunk_index_empty(io_info->dset, &index_empty) < 0)
|
||||
if (di->dset->shared->dcpl_cache.fill.alloc_time == H5D_ALLOC_TIME_INCR)
|
||||
if (H5D__chunk_index_empty(di->dset, &index_empty) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "couldn't determine if chunk index is empty")
|
||||
|
||||
if (!index_empty) {
|
||||
@@ -4731,12 +4641,13 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
/* Override the read buffer to point to the address of the first
|
||||
* chunk data buffer being read into
|
||||
*/
|
||||
if (base_read_buf)
|
||||
coll_io_info.u.rbuf = base_read_buf;
|
||||
if (base_read_buf) {
|
||||
coll_io_info.base_maddr.vp = base_read_buf;
|
||||
}
|
||||
|
||||
/* Read all chunks that need to be read from the file */
|
||||
if (H5D__mpio_collective_filtered_chunk_common_io(chunk_list, chunk_list_num_entries, &coll_io_info,
|
||||
type_info, mpi_size) < 0)
|
||||
mpi_size) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't finish collective filtered chunk read")
|
||||
}
|
||||
|
||||
@@ -4756,7 +4667,7 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
* the file, so we need to unfilter it
|
||||
*/
|
||||
if (chunk_list[i].need_read && !chunk_list[i].skip_filter_pline) {
|
||||
if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
|
||||
if (H5Z_pipeline(&di->dset->shared->dcpl_cache.pline, H5Z_FLAG_REVERSE,
|
||||
&(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
|
||||
(size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
|
||||
&chunk_list[i].buf) < 0)
|
||||
@@ -4765,7 +4676,7 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
|
||||
iter_nelmts = H5S_GET_SELECT_NPOINTS(chunk_info->mspace);
|
||||
|
||||
if (H5D_select_io_mem(chunk_list[i].buf, chunk_info->fspace, io_info->u.wbuf, chunk_info->mspace,
|
||||
if (H5D_select_io_mem(chunk_list[i].buf, chunk_info->fspace, di->buf.cvp, chunk_info->mspace,
|
||||
type_info->dst_type_size, (size_t)iter_nelmts) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "couldn't copy chunk data to write buffer")
|
||||
}
|
||||
@@ -4834,10 +4745,9 @@ H5D__mpio_collective_filtered_chunk_update(H5D_filtered_collective_io_info_t *ch
|
||||
/* Finally, filter all the chunks */
|
||||
for (i = 0; i < chunk_list_num_entries; i++) {
|
||||
if (!chunk_list[i].skip_filter_pline) {
|
||||
if (H5Z_pipeline(&io_info->dset->shared->dcpl_cache.pline, 0,
|
||||
&(chunk_list[i].index_info.filter_mask), err_detect, filter_cb,
|
||||
(size_t *)&chunk_list[i].chunk_new.length, &chunk_list[i].chunk_buf_size,
|
||||
&chunk_list[i].buf) < 0)
|
||||
if (H5Z_pipeline(&di->dset->shared->dcpl_cache.pline, 0, &(chunk_list[i].index_info.filter_mask),
|
||||
err_detect, filter_cb, (size_t *)&chunk_list[i].chunk_new.length,
|
||||
&chunk_list[i].chunk_buf_size, &chunk_list[i].buf) < 0)
|
||||
HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "output pipeline failed")
|
||||
}
|
||||
|
||||
@@ -5088,8 +4998,8 @@ done:
|
||||
static herr_t
|
||||
H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *chunk_list,
|
||||
size_t chunk_list_num_entries, size_t *num_chunks_assigned_map,
|
||||
H5D_io_info_t *io_info, H5D_chk_idx_info_t *idx_info,
|
||||
int mpi_rank, int mpi_size)
|
||||
H5D_io_info_t *io_info, H5D_dset_io_info_t *di,
|
||||
H5D_chk_idx_info_t *idx_info, int mpi_rank, int mpi_size)
|
||||
{
|
||||
H5D_chunk_ud_t chunk_ud;
|
||||
MPI_Datatype send_type;
|
||||
@@ -5110,6 +5020,7 @@ H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *
|
||||
|
||||
HDassert(chunk_list || 0 == chunk_list_num_entries);
|
||||
HDassert(io_info);
|
||||
HDassert(di);
|
||||
HDassert(idx_info);
|
||||
|
||||
#ifdef H5Dmpio_DEBUG
|
||||
@@ -5219,17 +5130,17 @@ H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *
|
||||
* callback that accepts a chunk index and provides the
|
||||
* caller with the scaled coordinates for that chunk.
|
||||
*/
|
||||
H5VM_array_calc_pre(chunk_ud.chunk_idx, io_info->dset->shared->ndims,
|
||||
H5VM_array_calc_pre(chunk_ud.chunk_idx, di->dset->shared->ndims,
|
||||
idx_info->layout->u.earray.swizzled_down_chunks, scaled_coords);
|
||||
|
||||
H5VM_unswizzle_coords(hsize_t, scaled_coords, idx_info->layout->u.earray.unlim_dim);
|
||||
}
|
||||
else {
|
||||
H5VM_array_calc_pre(chunk_ud.chunk_idx, io_info->dset->shared->ndims,
|
||||
io_info->dset->shared->layout.u.chunk.down_chunks, scaled_coords);
|
||||
H5VM_array_calc_pre(chunk_ud.chunk_idx, di->dset->shared->ndims,
|
||||
di->dset->shared->layout.u.chunk.down_chunks, scaled_coords);
|
||||
}
|
||||
|
||||
scaled_coords[io_info->dset->shared->ndims] = 0;
|
||||
scaled_coords[di->dset->shared->ndims] = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
@@ -5243,7 +5154,7 @@ H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *
|
||||
for (size_t dbg_idx = 0; dbg_idx < chunk_list_num_entries; dbg_idx++) {
|
||||
if (coll_entry->index_info.chunk_idx == chunk_list[dbg_idx].index_info.chunk_idx) {
|
||||
hbool_t coords_match = !HDmemcmp(scaled_coords, chunk_list[dbg_idx].chunk_info->scaled,
|
||||
io_info->dset->shared->ndims * sizeof(hsize_t));
|
||||
di->dset->shared->ndims * sizeof(hsize_t));
|
||||
|
||||
HDassert(coords_match && "Calculated scaled coordinates for chunk didn't match "
|
||||
"chunk's actual scaled coordinates!");
|
||||
@@ -5252,7 +5163,7 @@ H5D__mpio_collective_filtered_chunk_reinsert(H5D_filtered_collective_io_info_t *
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((idx_info->storage->ops->insert)(idx_info, &chunk_ud, io_info->dset) < 0)
|
||||
if ((idx_info->storage->ops->insert)(idx_info, &chunk_ud, di->dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert chunk address into index")
|
||||
}
|
||||
|
||||
|
||||
+167
-152
@@ -33,6 +33,7 @@
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5B2private.h" /* v2 B-trees */
|
||||
#include "H5Fprivate.h" /* File access */
|
||||
#include "H5FLprivate.h" /* Free Lists */
|
||||
#include "H5Gprivate.h" /* Groups */
|
||||
#include "H5SLprivate.h" /* Skip lists */
|
||||
#include "H5Tprivate.h" /* Datatypes */
|
||||
@@ -44,20 +45,6 @@
|
||||
/* Set the minimum object header size to create objects with */
|
||||
#define H5D_MINHDR_SIZE 256
|
||||
|
||||
/* [Simple] Macro to construct a H5D_io_info_t from it's components */
|
||||
#define H5D_BUILD_IO_INFO_WRT(io_info, ds, str, buf) \
|
||||
(io_info)->dset = ds; \
|
||||
(io_info)->f_sh = H5F_SHARED((ds)->oloc.file); \
|
||||
(io_info)->store = str; \
|
||||
(io_info)->op_type = H5D_IO_OP_WRITE; \
|
||||
(io_info)->u.wbuf = buf
|
||||
#define H5D_BUILD_IO_INFO_RD(io_info, ds, str, buf) \
|
||||
(io_info)->dset = ds; \
|
||||
(io_info)->f_sh = H5F_SHARED((ds)->oloc.file); \
|
||||
(io_info)->store = str; \
|
||||
(io_info)->op_type = H5D_IO_OP_READ; \
|
||||
(io_info)->u.rbuf = buf
|
||||
|
||||
/* Flags for marking aspects of a dataset dirty */
|
||||
#define H5D_MARK_SPACE 0x01
|
||||
#define H5D_MARK_LAYOUT 0x02
|
||||
@@ -83,6 +70,9 @@
|
||||
#define H5D_BT2_SPLIT_PERC 100
|
||||
#define H5D_BT2_MERGE_PERC 40
|
||||
|
||||
/* Macro to determine if the layout I/O callback should perform I/O */
|
||||
#define H5D_LAYOUT_CB_PERFORM_IO(IO_INFO) (!(IO_INFO)->use_select_io || (IO_INFO)->count == 1)
|
||||
|
||||
/****************************/
|
||||
/* Package Private Typedefs */
|
||||
/****************************/
|
||||
@@ -97,23 +87,20 @@ typedef struct H5D_type_info_t {
|
||||
hid_t dst_type_id; /* Destination datatype ID */
|
||||
|
||||
/* Computed/derived values */
|
||||
size_t src_type_size; /* Size of source type */
|
||||
size_t dst_type_size; /* Size of destination type */
|
||||
size_t max_type_size; /* Size of largest source/destination type */
|
||||
hbool_t is_conv_noop; /* Whether the type conversion is a NOOP */
|
||||
hbool_t is_xform_noop; /* Whether the data transform is a NOOP */
|
||||
const H5T_subset_info_t *cmpd_subset; /* Info related to the compound subset conversion functions */
|
||||
H5T_bkg_t need_bkg; /* Type of background buf needed */
|
||||
size_t request_nelmts; /* Requested strip mine */
|
||||
uint8_t *tconv_buf; /* Datatype conv buffer */
|
||||
hbool_t tconv_buf_allocated; /* Whether the type conversion buffer was allocated */
|
||||
uint8_t *bkg_buf; /* Background buffer */
|
||||
hbool_t bkg_buf_allocated; /* Whether the background buffer was allocated */
|
||||
size_t src_type_size; /* Size of source type */
|
||||
size_t dst_type_size; /* Size of destination type */
|
||||
hbool_t is_conv_noop; /* Whether the type conversion is a NOOP */
|
||||
hbool_t is_xform_noop; /* Whether the data transform is a NOOP */
|
||||
const H5T_subset_info_t *cmpd_subset; /* Info related to the compound subset conversion functions */
|
||||
H5T_bkg_t need_bkg; /* Type of background buf needed */
|
||||
size_t request_nelmts; /* Requested strip mine */
|
||||
uint8_t *bkg_buf; /* Background buffer */
|
||||
hbool_t bkg_buf_allocated; /* Whether the background buffer was allocated */
|
||||
} H5D_type_info_t;
|
||||
|
||||
/* Forward declaration of structs used below */
|
||||
struct H5D_io_info_t;
|
||||
struct H5D_chunk_map_t;
|
||||
struct H5D_dset_io_info_t;
|
||||
typedef struct H5D_shared_t H5D_shared_t;
|
||||
|
||||
/* Function pointers for I/O on particular types of dataset layouts */
|
||||
@@ -121,27 +108,27 @@ typedef herr_t (*H5D_layout_construct_func_t)(H5F_t *f, H5D_t *dset);
|
||||
typedef herr_t (*H5D_layout_init_func_t)(H5F_t *f, const H5D_t *dset, hid_t dapl_id);
|
||||
typedef hbool_t (*H5D_layout_is_space_alloc_func_t)(const H5O_storage_t *storage);
|
||||
typedef hbool_t (*H5D_layout_is_data_cached_func_t)(const H5D_shared_t *shared_dset);
|
||||
typedef herr_t (*H5D_layout_io_init_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
struct H5D_chunk_map_t *cm);
|
||||
typedef herr_t (*H5D_layout_read_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
struct H5D_chunk_map_t *fm);
|
||||
typedef herr_t (*H5D_layout_write_func_t)(struct H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
struct H5D_chunk_map_t *fm);
|
||||
typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info, size_t dset_max_nseq,
|
||||
typedef herr_t (*H5D_layout_io_init_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
|
||||
typedef herr_t (*H5D_layout_mdio_init_func_t)(struct H5D_io_info_t *io_info,
|
||||
struct H5D_dset_io_info_t *dinfo);
|
||||
typedef herr_t (*H5D_layout_read_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
|
||||
typedef herr_t (*H5D_layout_write_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *dinfo);
|
||||
typedef herr_t (*H5D_layout_read_md_func_t)(struct H5D_io_info_t *io_info);
|
||||
typedef herr_t (*H5D_layout_write_md_func_t)(struct H5D_io_info_t *io_info);
|
||||
typedef ssize_t (*H5D_layout_readvv_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const struct H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[],
|
||||
hsize_t mem_offset_arr[]);
|
||||
typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t *io_info, size_t dset_max_nseq,
|
||||
typedef ssize_t (*H5D_layout_writevv_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const struct H5D_dset_io_info_t *dset_info, size_t dset_max_nseq,
|
||||
size_t *dset_curr_seq, size_t dset_len_arr[],
|
||||
hsize_t dset_offset_arr[], size_t mem_max_nseq,
|
||||
size_t *mem_curr_seq, size_t mem_len_arr[],
|
||||
hsize_t mem_offset_arr[]);
|
||||
typedef herr_t (*H5D_layout_flush_func_t)(H5D_t *dataset);
|
||||
typedef herr_t (*H5D_layout_io_term_func_t)(const struct H5D_chunk_map_t *cm);
|
||||
typedef herr_t (*H5D_layout_io_term_func_t)(struct H5D_io_info_t *io_info, struct H5D_dset_io_info_t *di);
|
||||
typedef herr_t (*H5D_layout_dest_func_t)(H5D_t *dataset);
|
||||
|
||||
/* Typedef for grouping layout I/O routines */
|
||||
@@ -152,27 +139,28 @@ typedef struct H5D_layout_ops_t {
|
||||
H5D_layout_is_data_cached_func_t
|
||||
is_data_cached; /* Query routine to determine if any raw data is cached. If routine is not present
|
||||
then the layout type never caches raw data. */
|
||||
H5D_layout_io_init_func_t io_init; /* I/O initialization routine */
|
||||
H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */
|
||||
H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5D_layout_read_func_t par_read; /* High-level I/O routine for reading data in parallel */
|
||||
H5D_layout_write_func_t par_write; /* High-level I/O routine for writing data in parallel */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5D_layout_readvv_func_t readvv; /* Low-level I/O routine for reading data */
|
||||
H5D_layout_writevv_func_t writevv; /* Low-level I/O routine for writing data */
|
||||
H5D_layout_flush_func_t flush; /* Low-level I/O routine for flushing raw data */
|
||||
H5D_layout_io_term_func_t io_term; /* I/O shutdown routine */
|
||||
H5D_layout_dest_func_t dest; /* Destroy layout info */
|
||||
H5D_layout_io_init_func_t io_init; /* I/O initialization routine */
|
||||
H5D_layout_mdio_init_func_t mdio_init; /* Multi Dataset I/O initialization routine - called after all
|
||||
datasets have done io_init and sel_pieces has been allocated */
|
||||
H5D_layout_read_func_t ser_read; /* High-level I/O routine for reading data in serial */
|
||||
H5D_layout_write_func_t ser_write; /* High-level I/O routine for writing data in serial */
|
||||
H5D_layout_readvv_func_t readvv; /* Low-level I/O routine for reading data */
|
||||
H5D_layout_writevv_func_t writevv; /* Low-level I/O routine for writing data */
|
||||
H5D_layout_flush_func_t flush; /* Low-level I/O routine for flushing raw data */
|
||||
H5D_layout_io_term_func_t io_term; /* I/O shutdown routine for multi-dset */
|
||||
H5D_layout_dest_func_t dest; /* Destroy layout info */
|
||||
} H5D_layout_ops_t;
|
||||
|
||||
/* Function pointers for either multiple or single block I/O access */
|
||||
typedef herr_t (*H5D_io_single_read_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
typedef herr_t (*H5D_io_single_write_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
typedef herr_t (*H5D_io_single_read_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const struct H5D_dset_io_info_t *dset_info);
|
||||
typedef herr_t (*H5D_io_single_write_func_t)(const struct H5D_io_info_t *io_info,
|
||||
const struct H5D_dset_io_info_t *dset_info);
|
||||
|
||||
typedef herr_t (*H5D_io_single_read_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
typedef herr_t (*H5D_io_single_write_md_func_t)(const struct H5D_io_info_t *io_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
|
||||
/* Typedef for raw data I/O framework info */
|
||||
typedef struct H5D_io_ops_t {
|
||||
@@ -182,6 +170,14 @@ typedef struct H5D_io_ops_t {
|
||||
H5D_io_single_write_func_t single_write; /* I/O routine for writing single block */
|
||||
} H5D_io_ops_t;
|
||||
|
||||
/* Typedef for raw data I/O framework info (multi-dataset I/O) */
|
||||
typedef struct H5D_md_io_ops_t {
|
||||
H5D_layout_read_md_func_t multi_read_md; /* High-level I/O routine for reading data for multi-dset */
|
||||
H5D_layout_write_md_func_t multi_write_md; /* High-level I/O routine for writing data for multi-dset */
|
||||
H5D_io_single_read_md_func_t single_read_md; /* I/O routine for reading single block for multi-dset */
|
||||
H5D_io_single_write_md_func_t single_write_md; /* I/O routine for writing single block for multi-dset */
|
||||
} H5D_md_io_ops_t;
|
||||
|
||||
/* Typedefs for dataset storage information */
|
||||
typedef struct {
|
||||
haddr_t dset_addr; /* Address of dataset in file */
|
||||
@@ -210,25 +206,79 @@ typedef enum H5D_io_op_type_t {
|
||||
H5D_IO_OP_WRITE /* Write operation */
|
||||
} H5D_io_op_type_t;
|
||||
|
||||
/* Piece info for a data chunk/block during I/O */
|
||||
typedef struct H5D_piece_info_t {
|
||||
haddr_t faddr; /* File address */
|
||||
hsize_t index; /* "Index" of chunk in dataset */
|
||||
hsize_t piece_points; /* Number of elements selected in piece */
|
||||
hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates of chunk (in file dataset's dataspace) */
|
||||
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
|
||||
unsigned fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */
|
||||
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
|
||||
unsigned mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */
|
||||
struct H5D_dset_io_info_t *dset_info; /* Pointer to dset_info */
|
||||
} H5D_piece_info_t;
|
||||
|
||||
/* I/O info for a single dataset */
|
||||
typedef struct H5D_dset_io_info_t {
|
||||
H5D_t *dset; /* Pointer to dataset being operated on */
|
||||
H5D_storage_t *store; /* Dataset storage info */
|
||||
H5D_layout_ops_t layout_ops; /* Dataset layout I/O operation function pointers */
|
||||
H5_flexible_const_ptr_t buf; /* Buffer pointer */
|
||||
|
||||
H5D_io_ops_t io_ops; /* I/O operations for this dataset */
|
||||
|
||||
H5O_layout_t *layout; /* Dataset layout information*/
|
||||
hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */
|
||||
|
||||
H5S_t *file_space; /* Pointer to the file dataspace */
|
||||
H5S_t *mem_space; /* Pointer to the memory dataspace */
|
||||
|
||||
union {
|
||||
struct H5D_chunk_map_t *chunk_map; /* Chunk specific I/O info */
|
||||
H5D_piece_info_t *contig_piece_info; /* Piece info for contiguous dataset */
|
||||
} layout_io_info;
|
||||
|
||||
hid_t mem_type_id; /* memory datatype ID */
|
||||
H5D_type_info_t type_info;
|
||||
hbool_t skip_io; /* Whether to skip I/O for this dataset */
|
||||
} H5D_dset_io_info_t;
|
||||
|
||||
/* I/O info for entire I/O operation */
|
||||
typedef struct H5D_io_info_t {
|
||||
const H5D_t *dset; /* Pointer to dataset being operated on */
|
||||
/* QAK: Delete the f_sh field when oloc has a shared file pointer? */
|
||||
/* QAK: Delete the f_sh field when oloc has a shared file pointer? */
|
||||
H5F_shared_t *f_sh; /* Pointer to shared file struct that dataset is within */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
MPI_Comm comm; /* MPI communicator for file */
|
||||
hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5D_storage_t *store; /* Dataset storage info */
|
||||
H5D_layout_ops_t layout_ops; /* Dataset layout I/O operation function pointers */
|
||||
H5D_io_ops_t io_ops; /* I/O operation function pointers */
|
||||
H5D_io_op_type_t op_type;
|
||||
hbool_t use_select_io; /* Whether to use selection I/O */
|
||||
union {
|
||||
void *rbuf; /* Pointer to buffer for read */
|
||||
const void *wbuf; /* Pointer to buffer to write */
|
||||
} u;
|
||||
MPI_Comm comm; /* MPI communicator for file */
|
||||
hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5D_md_io_ops_t md_io_ops; /* Multi dataset I/O operation function pointers */
|
||||
H5D_io_op_type_t op_type;
|
||||
size_t count; /* Number of datasets in I/O request */
|
||||
H5D_dset_io_info_t *dsets_info; /* dsets info where I/O is done to/from */
|
||||
size_t piece_count; /* Number of pieces in I/O request */
|
||||
size_t pieces_added; /* Number of pieces added so far to arrays */
|
||||
H5D_piece_info_t **sel_pieces; /* Array of info struct for all pieces in I/O */
|
||||
H5S_t **mem_spaces; /* Array of chunk memory spaces */
|
||||
H5S_t **file_spaces; /* Array of chunk file spaces */
|
||||
haddr_t *addrs; /* Array of chunk addresses */
|
||||
size_t *element_sizes; /* Array of element sizes */
|
||||
void **rbufs; /* Array of read buffers */
|
||||
const void **wbufs; /* Array of write buffers */
|
||||
haddr_t store_faddr; /* lowest file addr for read/write */
|
||||
H5_flexible_const_ptr_t base_maddr; /* starting mem address */
|
||||
hbool_t use_select_io; /* Whether to use selection I/O */
|
||||
uint8_t *tconv_buf; /* Datatype conv buffer */
|
||||
hbool_t tconv_buf_allocated; /* Whether the type conversion buffer was allocated */
|
||||
size_t max_type_size; /* Largest of all source and destination type sizes */
|
||||
} H5D_io_info_t;
|
||||
|
||||
/* Created to pass both at once for callback func */
|
||||
typedef struct H5D_io_info_wrap_t {
|
||||
H5D_io_info_t *io_info;
|
||||
H5D_dset_io_info_t *dinfo;
|
||||
} H5D_io_info_wrap_t;
|
||||
|
||||
/******************/
|
||||
/* Chunk typedefs */
|
||||
/******************/
|
||||
@@ -330,46 +380,26 @@ typedef struct H5D_chunk_ops_t {
|
||||
H5D_chunk_dest_func_t dest; /* Routine to destroy indexing information in memory */
|
||||
} H5D_chunk_ops_t;
|
||||
|
||||
/* Structure holding information about a chunk's selection for mapping */
|
||||
typedef struct H5D_chunk_info_t {
|
||||
hsize_t index; /* "Index" of chunk in dataset */
|
||||
uint32_t chunk_points; /* Number of elements selected in chunk */
|
||||
hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Scaled coordinates of chunk (in file dataset's dataspace) */
|
||||
H5S_t *fspace; /* Dataspace describing chunk & selection in it */
|
||||
hbool_t fspace_shared; /* Indicate that the file space for a chunk is shared and shouldn't be freed */
|
||||
H5S_t *mspace; /* Dataspace describing selection in memory corresponding to this chunk */
|
||||
hbool_t mspace_shared; /* Indicate that the memory space for a chunk is shared and shouldn't be freed */
|
||||
} H5D_chunk_info_t;
|
||||
|
||||
/* Main structure holding the mapping between file chunks and memory */
|
||||
typedef struct H5D_chunk_map_t {
|
||||
H5O_layout_t *layout; /* Dataset layout information*/
|
||||
hsize_t nelmts; /* Number of elements selected in file & memory dataspaces */
|
||||
unsigned f_ndims; /* Number of dimensions for file dataspace */
|
||||
|
||||
H5S_t *file_space; /* Pointer to the file dataspace */
|
||||
unsigned f_ndims; /* Number of dimensions for file dataspace */
|
||||
|
||||
H5S_t *mem_space; /* Pointer to the memory dataspace */
|
||||
H5S_t *mchunk_tmpl; /* Dataspace template for new memory chunks */
|
||||
H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
|
||||
unsigned m_ndims; /* Number of dimensions for memory dataspace */
|
||||
H5S_sel_type msel_type; /* Selection type in memory */
|
||||
H5S_sel_type fsel_type; /* Selection type in file */
|
||||
|
||||
H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
|
||||
H5SL_t *dset_sel_pieces; /* Skip list containing information for each chunk selected */
|
||||
|
||||
H5S_t *single_space; /* Dataspace for single chunk */
|
||||
H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
|
||||
H5D_piece_info_t *single_piece_info; /* Pointer to single chunk's info */
|
||||
hbool_t use_single; /* Whether I/O is on a single element */
|
||||
|
||||
hsize_t last_index; /* Index of last chunk operated on */
|
||||
H5D_chunk_info_t *last_chunk_info; /* Pointer to last chunk's info */
|
||||
H5D_piece_info_t *last_piece_info; /* Pointer to last chunk's info */
|
||||
|
||||
hsize_t chunk_dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in each dimension */
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5D_chunk_info_t **select_chunk; /* Store the information about whether this chunk is selected or not */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
} H5D_chunk_map_t;
|
||||
|
||||
/* Cached information about a particular chunk */
|
||||
@@ -415,7 +445,7 @@ typedef struct H5D_rdcc_t {
|
||||
struct H5D_rdcc_ent_t **slot; /* Chunk slots, each points to a chunk*/
|
||||
H5SL_t *sel_chunks; /* Skip list containing information for each chunk selected */
|
||||
H5S_t *single_space; /* Dataspace for single element I/O on chunks */
|
||||
H5D_chunk_info_t *single_chunk_info; /* Pointer to single chunk's info */
|
||||
H5D_piece_info_t *single_piece_info; /* Pointer to single piece's info */
|
||||
|
||||
/* Cached information about scaled dataspace dimensions */
|
||||
hsize_t scaled_dims[H5S_MAX_RANK]; /* The scaled dim sizes */
|
||||
@@ -458,12 +488,13 @@ struct H5D_shared_t {
|
||||
|
||||
/* Buffered/cached information for types of raw data storage*/
|
||||
struct {
|
||||
H5D_rdcdc_t contig; /* Information about contiguous data */
|
||||
/* (Note that the "contig" cache
|
||||
* information can be used by a chunked
|
||||
* dataset in certain circumstances)
|
||||
*/
|
||||
H5D_rdcc_t chunk; /* Information about chunked data */
|
||||
H5D_rdcdc_t contig; /* Information about contiguous data */
|
||||
/* (Note that the "contig" cache
|
||||
* information can be used by a chunked
|
||||
* dataset in certain circumstances)
|
||||
*/
|
||||
H5D_rdcc_t chunk; /* Information about chunked data */
|
||||
H5SL_t *sel_pieces; /* Skip list containing information for each piece selected */
|
||||
} cache;
|
||||
|
||||
H5D_append_flush_t append_flush; /* Append flush property information */
|
||||
@@ -556,8 +587,8 @@ H5_DLL H5D_t *H5D__open_name(const H5G_loc_t *loc, const char *name, hid_t dapl
|
||||
H5_DLL hid_t H5D__get_space(const H5D_t *dset);
|
||||
H5_DLL hid_t H5D__get_type(const H5D_t *dset);
|
||||
H5_DLL herr_t H5D__get_space_status(const H5D_t *dset, H5D_space_status_t *allocation);
|
||||
H5_DLL herr_t H5D__alloc_storage(const H5D_io_info_t *io_info, H5D_time_alloc_t time_alloc,
|
||||
hbool_t full_overwrite, hsize_t old_dim[]);
|
||||
H5_DLL herr_t H5D__alloc_storage(H5D_t *dset, H5D_time_alloc_t time_alloc, hbool_t full_overwrite,
|
||||
hsize_t old_dim[]);
|
||||
H5_DLL herr_t H5D__get_storage_size(const H5D_t *dset, hsize_t *storage_size);
|
||||
H5_DLL herr_t H5D__get_chunk_storage_size(H5D_t *dset, const hsize_t *offset, hsize_t *storage_size);
|
||||
H5_DLL herr_t H5D__chunk_index_empty(const H5D_t *dset, hbool_t *empty);
|
||||
@@ -582,16 +613,12 @@ H5_DLL herr_t H5D__refresh(H5D_t *dataset, hid_t dset_id);
|
||||
H5_DLL herr_t H5D__format_convert(H5D_t *dataset);
|
||||
|
||||
/* Internal I/O routines */
|
||||
H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space,
|
||||
void *buf /*out*/);
|
||||
H5_DLL herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, H5S_t *mem_space, H5S_t *file_space,
|
||||
const void *buf);
|
||||
H5_DLL herr_t H5D__read(size_t count, H5D_dset_io_info_t *dset_info);
|
||||
H5_DLL herr_t H5D__write(size_t count, H5D_dset_io_info_t *dset_info);
|
||||
|
||||
/* Functions that perform direct serial I/O operations */
|
||||
H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space);
|
||||
H5_DLL herr_t H5D__select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
|
||||
H5_DLL herr_t H5D__select_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
|
||||
H5_DLL herr_t H5D__select_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
|
||||
|
||||
/* Functions that perform direct copying between memory buffers */
|
||||
H5_DLL herr_t H5D_select_io_mem(void *dst_buf, H5S_t *dst_space, const void *src_buf, H5S_t *src_space,
|
||||
@@ -601,10 +628,8 @@ H5_DLL herr_t H5D_select_io_mem(void *dst_buf, H5S_t *dst_space, const void *src
|
||||
H5_DLL herr_t H5D__scatter_mem(const void *_tscat_buf, H5S_sel_iter_t *iter, size_t nelmts, void *_buf);
|
||||
H5_DLL size_t H5D__gather_mem(const void *_buf, H5S_sel_iter_t *iter, size_t nelmts,
|
||||
void *_tgath_buf /*out*/);
|
||||
H5_DLL herr_t H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
|
||||
H5_DLL herr_t H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
|
||||
H5_DLL herr_t H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
|
||||
H5_DLL herr_t H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info);
|
||||
|
||||
/* Functions that operate on dataset's layout information */
|
||||
H5_DLL herr_t H5D__layout_set_io_ops(const H5D_t *dataset);
|
||||
@@ -620,25 +645,23 @@ H5_DLL herr_t H5D__layout_oh_write(const H5D_t *dataset, H5O_t *oh, unsigned upd
|
||||
H5_DLL herr_t H5D__contig_alloc(H5F_t *f, H5O_storage_contig_t *storage);
|
||||
H5_DLL hbool_t H5D__contig_is_space_alloc(const H5O_storage_t *storage);
|
||||
H5_DLL hbool_t H5D__contig_is_data_cached(const H5D_shared_t *shared_dset);
|
||||
H5_DLL herr_t H5D__contig_fill(const H5D_io_info_t *io_info);
|
||||
H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
H5_DLL herr_t H5D__contig_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
H5_DLL herr_t H5D__contig_fill(H5D_t *dset);
|
||||
H5_DLL herr_t H5D__contig_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
H5_DLL herr_t H5D__contig_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
H5_DLL herr_t H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, H5F_t *f_dst,
|
||||
H5O_storage_contig_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info);
|
||||
H5_DLL herr_t H5D__contig_delete(H5F_t *f, const H5O_storage_t *store);
|
||||
|
||||
/* Functions that operate on chunked dataset storage */
|
||||
H5_DLL htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr, hbool_t write_op);
|
||||
H5_DLL herr_t H5D__chunk_create(const H5D_t *dset /*in,out*/);
|
||||
H5_DLL herr_t H5D__chunk_set_info(const H5D_t *dset);
|
||||
H5_DLL htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info, haddr_t caddr,
|
||||
hbool_t write_op);
|
||||
H5_DLL herr_t H5D__chunk_create(const H5D_t *dset /*in,out*/);
|
||||
H5_DLL herr_t H5D__chunk_set_info(const H5D_t *dset);
|
||||
H5_DLL hbool_t H5D__chunk_is_space_alloc(const H5O_storage_t *storage);
|
||||
H5_DLL hbool_t H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset);
|
||||
H5_DLL herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata);
|
||||
H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes);
|
||||
H5_DLL herr_t H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite,
|
||||
const hsize_t old_dim[]);
|
||||
H5_DLL herr_t H5D__chunk_allocate(const H5D_t *dset, hbool_t full_overwrite, const hsize_t old_dim[]);
|
||||
H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk,
|
||||
H5F_block_t *new_chunk, hbool_t *need_insert, const hsize_t *scaled);
|
||||
H5_DLL void *H5D__chunk_mem_alloc(size_t size, void *pline);
|
||||
@@ -651,7 +674,7 @@ H5_DLL hbool_t H5D__chunk_is_partial_edge_chunk(unsigned dset_ndims, const uint3
|
||||
H5_DLL herr_t H5D__chunk_prune_by_extent(H5D_t *dset, const hsize_t *old_dim);
|
||||
H5_DLL herr_t H5D__chunk_set_sizes(H5D_t *dset);
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
H5_DLL herr_t H5D__chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]);
|
||||
H5_DLL herr_t H5D__chunk_addrmap(const H5D_t *dset, haddr_t chunk_addr[]);
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
H5_DLL herr_t H5D__chunk_update_cache(H5D_t *dset);
|
||||
H5_DLL herr_t H5D__chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, H5O_layout_chunk_t *layout_src,
|
||||
@@ -662,8 +685,8 @@ H5_DLL herr_t H5D__chunk_bh_info(const H5O_loc_t *loc, H5O_t *oh, H5O_layout_t *
|
||||
H5_DLL herr_t H5D__chunk_dump_index(H5D_t *dset, FILE *stream);
|
||||
H5_DLL herr_t H5D__chunk_delete(H5F_t *f, H5O_t *oh, H5O_storage_t *store);
|
||||
H5_DLL herr_t H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy);
|
||||
H5_DLL herr_t H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset,
|
||||
uint32_t data_size, const void *buf);
|
||||
H5_DLL herr_t H5D__chunk_direct_write(H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size,
|
||||
const void *buf);
|
||||
H5_DLL herr_t H5D__chunk_direct_read(const H5D_t *dset, hsize_t *offset, uint32_t *filters, void *buf);
|
||||
#ifdef H5D_CHUNK_DEBUG
|
||||
H5_DLL herr_t H5D__chunk_stats(const H5D_t *dset, hbool_t headers);
|
||||
@@ -711,39 +734,31 @@ H5_DLL herr_t H5D__fill_term(H5D_fill_buf_info_t *fb_info);
|
||||
#define H5Dmpio_DEBUG
|
||||
#endif /*H5Dmpio_DEBUG*/
|
||||
#endif /*H5D_DEBUG*/
|
||||
/* MPI-IO function to read, it will select either regular or irregular read */
|
||||
H5_DLL herr_t H5D__mpio_select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
|
||||
/* MPI-IO function to read multi-dsets (Chunk, Contig), it will select either
|
||||
* regular or irregular read */
|
||||
H5_DLL herr_t H5D__mpio_select_read(const H5D_io_info_t *io_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space);
|
||||
|
||||
/* MPI-IO function to write, it will select either regular or irregular read */
|
||||
H5_DLL herr_t H5D__mpio_select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space);
|
||||
/* MPI-IO function to write multi-dsets (Chunk, Contig), it will select either
|
||||
* regular or irregular write */
|
||||
H5_DLL herr_t H5D__mpio_select_write(const H5D_io_info_t *io_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space);
|
||||
|
||||
/* MPI-IO functions to handle contiguous collective IO */
|
||||
H5_DLL herr_t H5D__contig_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t *fm);
|
||||
H5_DLL herr_t H5D__contig_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t *fm);
|
||||
|
||||
/* MPI-IO functions to handle chunked collective IO */
|
||||
H5_DLL herr_t H5D__chunk_collective_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t *fm);
|
||||
H5_DLL herr_t H5D__chunk_collective_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
hsize_t nelmts, H5S_t *file_space, H5S_t *mem_space,
|
||||
H5D_chunk_map_t *fm);
|
||||
/* MPI-IO functions to handle collective IO for multiple dsets (CONTIG, CHUNK) */
|
||||
H5_DLL herr_t H5D__collective_read(H5D_io_info_t *io_info);
|
||||
H5_DLL herr_t H5D__collective_write(H5D_io_info_t *io_info);
|
||||
|
||||
/* MPI-IO function to check if a direct I/O transfer is possible between
|
||||
* memory and the file */
|
||||
H5_DLL htri_t H5D__mpio_opt_possible(const H5D_io_info_t *io_info, const H5S_t *file_space,
|
||||
const H5S_t *mem_space, const H5D_type_info_t *type_info);
|
||||
H5_DLL htri_t H5D__mpio_opt_possible(H5D_io_info_t *io_info);
|
||||
H5_DLL herr_t H5D__mpio_get_no_coll_cause_strings(char *local_cause, size_t local_cause_len,
|
||||
char *global_cause, size_t global_cause_len);
|
||||
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Free a piece (chunk or contiguous dataset data block) info struct */
|
||||
H5_DLL herr_t H5D__free_piece_info(void *item, void *key, void *opdata);
|
||||
|
||||
/* Testing functions */
|
||||
#ifdef H5D_TESTING
|
||||
H5_DLL herr_t H5D__layout_version_test(hid_t did, unsigned *version);
|
||||
|
||||
+111
@@ -850,6 +850,52 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id);
|
||||
H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, void *buf /*out*/);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup H5D
|
||||
*
|
||||
* \brief Reads raw data from a set of datasets into the provided buffers
|
||||
*
|
||||
* \param[in] count Number of datasets to read from
|
||||
* \param[in] dset_id Identifiers of the datasets to read from
|
||||
* \param[in] mem_type_id Identifiers of the memory datatypes
|
||||
* \param[in] mem_space_id Identifiers of the memory dataspaces
|
||||
* \param[in] file_space_id Identifiers of the datasets' dataspaces in the file
|
||||
* \param[in] dxpl_id Identifier of a transfer property list
|
||||
* \param[out] buf Buffers to receive data read from file
|
||||
*
|
||||
* \return \herr_t
|
||||
*
|
||||
* \details H5Dread_multi() reads data from \p count datasets, whose identifiers
|
||||
* are listed in the \p dset_id array, from the file into multiple
|
||||
* application memory buffers listed in the \p buf array. Data transfer
|
||||
* properties are defined by the argument \p dxpl_id. The memory
|
||||
* datatypes of each dataset are listed by identifier in the \p
|
||||
* mem_type_id array. The parts of each dataset to read are listed by
|
||||
* identifier in the \p file_space_id array, and the parts of each
|
||||
* application memory buffer to read to are listed by identifier in the
|
||||
* \p mem_space_id array. All array parameters have length \p count.
|
||||
*
|
||||
* This function will produce the same results as \p count calls to
|
||||
* H5Dread(). Information listed in that function about the specifics
|
||||
* of its behaviour also apply to H5Dread_multi(). By calling
|
||||
* H5Dread_multi() instead of multiple calls to H5Dread(), however, the
|
||||
* library can in some cases pass information about the entire I/O
|
||||
* operation to the file driver, which can improve performance.
|
||||
*
|
||||
* All datasets must be in the same HDF5 file, and each unique dataset
|
||||
* may only be listed once. If this function is called collectively in
|
||||
* parallel, each rank must pass exactly the same list of datasets in
|
||||
* \p dset_id , though the other parameters may differ.
|
||||
*
|
||||
* \since 1.13.3
|
||||
*
|
||||
* \see H5Dread()
|
||||
*
|
||||
*/
|
||||
H5_DLL herr_t H5Dread_multi(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[] /*out*/);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup ASYNC
|
||||
@@ -859,6 +905,15 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned
|
||||
hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
|
||||
void *buf /*out*/, hid_t es_id);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup ASYNC
|
||||
* \async_variant_of{H5Dread_multi}
|
||||
*/
|
||||
H5_DLL herr_t H5Dread_multi_async(const char *app_file, const char *app_func, unsigned app_line, size_t count,
|
||||
hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[] /*out*/, hid_t es_id);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup H5D
|
||||
@@ -975,6 +1030,53 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned
|
||||
H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup H5D
|
||||
*
|
||||
* \brief Writes raw data from a set buffers to a set of datasets
|
||||
*
|
||||
* \param[in] count Number of datasets to write to
|
||||
* \param[in] dset_id Identifiers of the datasets to write to
|
||||
* \param[in] mem_type_id Identifiers of the memory datatypes
|
||||
* \param[in] mem_space_id Identifiers of the memory dataspaces
|
||||
* \param[in] file_space_id Identifiers of the datasets' dataspaces in the file
|
||||
* \param[in] dxpl_id Identifier of a transfer property list
|
||||
* \param[in] buf Buffers with data to be written to the file
|
||||
*
|
||||
* \return \herr_t
|
||||
*
|
||||
* \details H5Dwrite_multi() writes data to \p count datasets, whose identifiers
|
||||
* are listed in the \p dset_id array, from multiple application memory
|
||||
* buffers listed in the \p buf array. Data transfer properties are
|
||||
* defined by the argument \p dxpl_id. The memory datatypes of each
|
||||
* dataset are listed by identifier in the \p mem_type_id array. The
|
||||
* parts of each dataset to write are listed by identifier in the \p
|
||||
* file_space_id array, and the parts of each application memory buffer
|
||||
* to write from are listed by identifier in the \p mem_space_id array.
|
||||
* All array parameters have length \p count.
|
||||
*
|
||||
* This function will produce the same results as \p count calls to
|
||||
* H5Dwrite(). Information listed in that function's documentation
|
||||
* about the specifics of its behaviour also apply to H5Dwrite_multi().
|
||||
* By calling H5Dwrite_multi() instead of multiple calls to H5Dwrite(),
|
||||
* however, the library can in some cases pass information about the
|
||||
* entire I/O operation to the file driver, which can improve
|
||||
* performance.
|
||||
*
|
||||
* All datasets must be in the same HDF5 file, and each unique dataset
|
||||
* may only be listed once. If this function is called collectively in
|
||||
* parallel, each rank must pass exactly the same list of datasets in
|
||||
* \p dset_id , though the other parameters may differ.
|
||||
*
|
||||
* \since 1.13.3
|
||||
*
|
||||
* \see H5Dwrite()
|
||||
*
|
||||
*/
|
||||
H5_DLL herr_t H5Dwrite_multi(size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[]);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup ASYNC
|
||||
@@ -984,6 +1086,15 @@ H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigne
|
||||
hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
|
||||
const void *buf, hid_t es_id);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup ASYNC
|
||||
* \async_variant_of{H5Dwrite_multi}
|
||||
*/
|
||||
H5_DLL herr_t H5Dwrite_multi_async(const char *app_file, const char *app_func, unsigned app_line,
|
||||
size_t count, hid_t dset_id[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], hid_t es_id);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* \ingroup H5D
|
||||
|
||||
+123
-102
@@ -39,13 +39,13 @@
|
||||
/********************/
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
static herr_t H5D__scatter_file(const H5D_io_info_t *io_info, H5S_sel_iter_t *file_iter, size_t nelmts,
|
||||
const void *buf);
|
||||
static size_t H5D__gather_file(const H5D_io_info_t *io_info, H5S_sel_iter_t *file_iter, size_t nelmts,
|
||||
void *buf);
|
||||
static herr_t H5D__scatter_file(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
H5S_sel_iter_t *file_iter, size_t nelmts, const void *buf);
|
||||
static size_t H5D__gather_file(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
H5S_sel_iter_t *file_iter, size_t nelmts, void *buf);
|
||||
static herr_t H5D__compound_opt_read(size_t nelmts, H5S_sel_iter_t *iter, const H5D_type_info_t *type_info,
|
||||
void *user_buf /*out*/);
|
||||
static herr_t H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info);
|
||||
uint8_t *tconv_buf, void *user_buf /*out*/);
|
||||
static herr_t H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info, uint8_t *tconv_buf);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -81,33 +81,40 @@ H5FL_SEQ_EXTERN(hsize_t);
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__scatter_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, size_t nelmts, const void *_buf)
|
||||
H5D__scatter_file(const H5D_io_info_t *_io_info, const H5D_dset_io_info_t *_dset_info, H5S_sel_iter_t *iter,
|
||||
size_t nelmts, const void *_buf)
|
||||
{
|
||||
H5D_io_info_t tmp_io_info; /* Temporary I/O info object */
|
||||
hsize_t *off = NULL; /* Pointer to sequence offsets */
|
||||
hsize_t mem_off; /* Offset in memory */
|
||||
size_t mem_curr_seq; /* "Current sequence" in memory */
|
||||
size_t dset_curr_seq; /* "Current sequence" in dataset */
|
||||
size_t *len = NULL; /* Array to store sequence lengths */
|
||||
size_t orig_mem_len, mem_len; /* Length of sequence in memory */
|
||||
size_t nseq; /* Number of sequences generated */
|
||||
size_t nelem; /* Number of elements used in sequences */
|
||||
size_t dxpl_vec_size; /* Vector length from API context's DXPL */
|
||||
size_t vec_size; /* Vector length */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_io_info_t tmp_io_info; /* Temporary I/O info object */
|
||||
H5D_dset_io_info_t tmp_dset_info; /* Temporary I/O info object */
|
||||
hsize_t *off = NULL; /* Pointer to sequence offsets */
|
||||
hsize_t mem_off; /* Offset in memory */
|
||||
size_t mem_curr_seq; /* "Current sequence" in memory */
|
||||
size_t dset_curr_seq; /* "Current sequence" in dataset */
|
||||
size_t *len = NULL; /* Array to store sequence lengths */
|
||||
size_t orig_mem_len, mem_len; /* Length of sequence in memory */
|
||||
size_t nseq; /* Number of sequences generated */
|
||||
size_t nelem; /* Number of elements used in sequences */
|
||||
size_t dxpl_vec_size; /* Vector length from API context's DXPL */
|
||||
size_t vec_size; /* Vector length */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check args */
|
||||
HDassert(_io_info);
|
||||
HDassert(_dset_info);
|
||||
HDassert(_dset_info->dset);
|
||||
HDassert(_dset_info->store);
|
||||
HDassert(iter);
|
||||
HDassert(nelmts > 0);
|
||||
HDassert(_buf);
|
||||
|
||||
/* Set up temporary I/O info object */
|
||||
H5MM_memcpy(&tmp_io_info, _io_info, sizeof(*_io_info));
|
||||
tmp_io_info.op_type = H5D_IO_OP_WRITE;
|
||||
tmp_io_info.u.wbuf = _buf;
|
||||
HDmemcpy(&tmp_dset_info, _dset_info, sizeof(*_dset_info));
|
||||
tmp_io_info.op_type = H5D_IO_OP_WRITE;
|
||||
tmp_dset_info.buf.cvp = _buf;
|
||||
tmp_io_info.dsets_info = &tmp_dset_info;
|
||||
|
||||
/* Get info from API context */
|
||||
if (H5CX_get_vec_size(&dxpl_vec_size) < 0)
|
||||
@@ -135,12 +142,12 @@ H5D__scatter_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, size_t ne
|
||||
mem_off = 0;
|
||||
|
||||
/* Write sequence list out */
|
||||
if ((*tmp_io_info.layout_ops.writevv)(&tmp_io_info, nseq, &dset_curr_seq, len, off, (size_t)1,
|
||||
&mem_curr_seq, &mem_len, &mem_off) < 0)
|
||||
if ((*tmp_dset_info.layout_ops.writevv)(&tmp_io_info, &tmp_dset_info, nseq, &dset_curr_seq, len, off,
|
||||
(size_t)1, &mem_curr_seq, &mem_len, &mem_off) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
|
||||
/* Update buffer */
|
||||
tmp_io_info.u.wbuf = (const uint8_t *)tmp_io_info.u.wbuf + orig_mem_len;
|
||||
tmp_dset_info.buf.cvp = (const uint8_t *)tmp_dset_info.buf.cvp + orig_mem_len;
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
nelmts -= nelem;
|
||||
@@ -178,35 +185,40 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5D__gather_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, size_t nelmts, void *_buf /*out*/)
|
||||
H5D__gather_file(const H5D_io_info_t *_io_info, const H5D_dset_io_info_t *_dset_info, H5S_sel_iter_t *iter,
|
||||
size_t nelmts, void *_buf /*out*/)
|
||||
{
|
||||
H5D_io_info_t tmp_io_info; /* Temporary I/O info object */
|
||||
hsize_t *off = NULL; /* Pointer to sequence offsets */
|
||||
hsize_t mem_off; /* Offset in memory */
|
||||
size_t mem_curr_seq; /* "Current sequence" in memory */
|
||||
size_t dset_curr_seq; /* "Current sequence" in dataset */
|
||||
size_t *len = NULL; /* Pointer to sequence lengths */
|
||||
size_t orig_mem_len, mem_len; /* Length of sequence in memory */
|
||||
size_t nseq; /* Number of sequences generated */
|
||||
size_t nelem; /* Number of elements used in sequences */
|
||||
size_t dxpl_vec_size; /* Vector length from API context's DXPL */
|
||||
size_t vec_size; /* Vector length */
|
||||
size_t ret_value = nelmts; /* Return value */
|
||||
H5D_io_info_t tmp_io_info; /* Temporary I/O info object */
|
||||
H5D_dset_io_info_t tmp_dset_info; /* Temporary I/O info object */
|
||||
hsize_t *off = NULL; /* Pointer to sequence offsets */
|
||||
hsize_t mem_off; /* Offset in memory */
|
||||
size_t mem_curr_seq; /* "Current sequence" in memory */
|
||||
size_t dset_curr_seq; /* "Current sequence" in dataset */
|
||||
size_t *len = NULL; /* Pointer to sequence lengths */
|
||||
size_t orig_mem_len, mem_len; /* Length of sequence in memory */
|
||||
size_t nseq; /* Number of sequences generated */
|
||||
size_t nelem; /* Number of elements used in sequences */
|
||||
size_t dxpl_vec_size; /* Vector length from API context's DXPL */
|
||||
size_t vec_size; /* Vector length */
|
||||
size_t ret_value = nelmts; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check args */
|
||||
HDassert(_io_info);
|
||||
HDassert(_io_info->dset);
|
||||
HDassert(_io_info->store);
|
||||
HDassert(_dset_info);
|
||||
HDassert(_dset_info->dset);
|
||||
HDassert(_dset_info->store);
|
||||
HDassert(iter);
|
||||
HDassert(nelmts > 0);
|
||||
HDassert(_buf);
|
||||
|
||||
/* Set up temporary I/O info object */
|
||||
H5MM_memcpy(&tmp_io_info, _io_info, sizeof(*_io_info));
|
||||
tmp_io_info.op_type = H5D_IO_OP_READ;
|
||||
tmp_io_info.u.rbuf = _buf;
|
||||
HDmemcpy(&tmp_dset_info, _dset_info, sizeof(*_dset_info));
|
||||
tmp_io_info.op_type = H5D_IO_OP_READ;
|
||||
tmp_dset_info.buf.vp = _buf;
|
||||
tmp_io_info.dsets_info = &tmp_dset_info;
|
||||
|
||||
/* Get info from API context */
|
||||
if (H5CX_get_vec_size(&dxpl_vec_size) < 0)
|
||||
@@ -234,12 +246,12 @@ H5D__gather_file(const H5D_io_info_t *_io_info, H5S_sel_iter_t *iter, size_t nel
|
||||
mem_off = 0;
|
||||
|
||||
/* Read sequence list in */
|
||||
if ((*tmp_io_info.layout_ops.readvv)(&tmp_io_info, nseq, &dset_curr_seq, len, off, (size_t)1,
|
||||
&mem_curr_seq, &mem_len, &mem_off) < 0)
|
||||
if ((*tmp_dset_info.layout_ops.readvv)(&tmp_io_info, &tmp_dset_info, nseq, &dset_curr_seq, len, off,
|
||||
(size_t)1, &mem_curr_seq, &mem_len, &mem_off) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error")
|
||||
|
||||
/* Update buffer */
|
||||
tmp_io_info.u.rbuf = (uint8_t *)tmp_io_info.u.rbuf + orig_mem_len;
|
||||
tmp_dset_info.buf.vp = (uint8_t *)tmp_dset_info.buf.vp + orig_mem_len;
|
||||
|
||||
/* Decrement number of elements left to process */
|
||||
nelmts -= nelem;
|
||||
@@ -436,11 +448,10 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space)
|
||||
H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
void *buf = io_info->u.rbuf; /* Local pointer to application buffer */
|
||||
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
|
||||
void *buf; /* Local pointer to application buffer */
|
||||
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
|
||||
hbool_t mem_iter_init = FALSE; /* Memory selection iteration info has been initialized */
|
||||
H5S_sel_iter_t *bkg_iter = NULL; /* Background iteration info*/
|
||||
hbool_t bkg_iter_init = FALSE; /* Background iteration info has been initialized */
|
||||
@@ -454,13 +465,16 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(buf);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->mem_space);
|
||||
HDassert(dset_info->file_space);
|
||||
HDassert(dset_info->buf.vp);
|
||||
|
||||
/* Set buf pointer */
|
||||
buf = dset_info->buf.vp;
|
||||
|
||||
/* Check for NOOP read */
|
||||
if (nelmts == 0)
|
||||
if (dset_info->nelmts == 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Allocate the iterators */
|
||||
@@ -472,24 +486,24 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator")
|
||||
|
||||
/* Figure out the strip mine size. */
|
||||
if (H5S_select_iter_init(file_iter, file_space, type_info->src_type_size,
|
||||
if (H5S_select_iter_init(file_iter, dset_info->file_space, dset_info->type_info.src_type_size,
|
||||
H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information")
|
||||
file_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
if (H5S_select_iter_init(mem_iter, mem_space, type_info->dst_type_size, 0) < 0)
|
||||
if (H5S_select_iter_init(mem_iter, dset_info->mem_space, dset_info->type_info.dst_type_size, 0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information")
|
||||
mem_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
if (H5S_select_iter_init(bkg_iter, mem_space, type_info->dst_type_size, 0) < 0)
|
||||
if (H5S_select_iter_init(bkg_iter, dset_info->mem_space, dset_info->type_info.dst_type_size, 0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information")
|
||||
bkg_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
|
||||
/* Start strip mining... */
|
||||
for (smine_start = 0; smine_start < nelmts; smine_start += smine_nelmts) {
|
||||
for (smine_start = 0; smine_start < dset_info->nelmts; smine_start += smine_nelmts) {
|
||||
size_t n; /* Elements operated on */
|
||||
|
||||
/* Go figure out how many elements to read from the file */
|
||||
HDassert(H5S_SELECT_ITER_NELMTS(file_iter) == (nelmts - smine_start));
|
||||
smine_nelmts = (size_t)MIN(type_info->request_nelmts, (nelmts - smine_start));
|
||||
HDassert(H5S_SELECT_ITER_NELMTS(file_iter) == (dset_info->nelmts - smine_start));
|
||||
smine_nelmts = (size_t)MIN(dset_info->type_info.request_nelmts, (dset_info->nelmts - smine_start));
|
||||
|
||||
/*
|
||||
* Gather the data from disk into the datatype conversion
|
||||
@@ -500,7 +514,7 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
/*
|
||||
* Gather data
|
||||
*/
|
||||
n = H5D__gather_file(io_info, file_iter, smine_nelmts, type_info->tconv_buf /*out*/);
|
||||
n = H5D__gather_file(io_info, dset_info, file_iter, smine_nelmts, io_info->tconv_buf /*out*/);
|
||||
if (n != smine_nelmts)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed")
|
||||
|
||||
@@ -508,13 +522,15 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
* and no conversion is needed, copy the data directly into user's buffer and
|
||||
* bypass the rest of steps.
|
||||
*/
|
||||
if (type_info->cmpd_subset && H5T_SUBSET_FALSE != type_info->cmpd_subset->subset) {
|
||||
if (H5D__compound_opt_read(smine_nelmts, mem_iter, type_info, buf /*out*/) < 0)
|
||||
if (dset_info->type_info.cmpd_subset &&
|
||||
H5T_SUBSET_FALSE != dset_info->type_info.cmpd_subset->subset) {
|
||||
if (H5D__compound_opt_read(smine_nelmts, mem_iter, &dset_info->type_info, io_info->tconv_buf,
|
||||
buf /*out*/) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed")
|
||||
} /* end if */
|
||||
else {
|
||||
if (H5T_BKG_YES == type_info->need_bkg) {
|
||||
n = H5D__gather_mem(buf, bkg_iter, smine_nelmts, type_info->bkg_buf /*out*/);
|
||||
if (H5T_BKG_YES == dset_info->type_info.need_bkg) {
|
||||
n = H5D__gather_mem(buf, bkg_iter, smine_nelmts, dset_info->type_info.bkg_buf /*out*/);
|
||||
if (n != smine_nelmts)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "mem gather failed")
|
||||
} /* end if */
|
||||
@@ -522,25 +538,26 @@ H5D__scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
|
||||
/*
|
||||
* Perform datatype conversion.
|
||||
*/
|
||||
if (H5T_convert(type_info->tpath, type_info->src_type_id, type_info->dst_type_id, smine_nelmts,
|
||||
(size_t)0, (size_t)0, type_info->tconv_buf, type_info->bkg_buf) < 0)
|
||||
if (H5T_convert(dset_info->type_info.tpath, dset_info->type_info.src_type_id,
|
||||
dset_info->type_info.dst_type_id, smine_nelmts, (size_t)0, (size_t)0,
|
||||
io_info->tconv_buf, dset_info->type_info.bkg_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
|
||||
|
||||
/* Do the data transform after the conversion (since we're using type mem_type) */
|
||||
if (!type_info->is_xform_noop) {
|
||||
if (!dset_info->type_info.is_xform_noop) {
|
||||
H5Z_data_xform_t *data_transform; /* Data transform info */
|
||||
|
||||
/* Retrieve info from API context */
|
||||
if (H5CX_get_data_transform(&data_transform) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data transform info")
|
||||
|
||||
if (H5Z_xform_eval(data_transform, type_info->tconv_buf, smine_nelmts, type_info->mem_type) <
|
||||
0)
|
||||
if (H5Z_xform_eval(data_transform, io_info->tconv_buf, smine_nelmts,
|
||||
dset_info->type_info.mem_type) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "Error performing data transform")
|
||||
}
|
||||
|
||||
/* Scatter the data into memory */
|
||||
if (H5D__scatter_mem(type_info->tconv_buf, mem_iter, smine_nelmts, buf /*out*/) < 0)
|
||||
if (H5D__scatter_mem(io_info->tconv_buf, mem_iter, smine_nelmts, buf /*out*/) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "scatter failed")
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
@@ -576,11 +593,10 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space)
|
||||
H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
const void *buf = io_info->u.wbuf; /* Local pointer to application buffer */
|
||||
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
|
||||
const void *buf; /* Local pointer to application buffer */
|
||||
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info*/
|
||||
hbool_t mem_iter_init = FALSE; /* Memory selection iteration info has been initialized */
|
||||
H5S_sel_iter_t *bkg_iter = NULL; /* Background iteration info*/
|
||||
hbool_t bkg_iter_init = FALSE; /* Background iteration info has been initialized */
|
||||
@@ -594,13 +610,16 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(buf);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->mem_space);
|
||||
HDassert(dset_info->file_space);
|
||||
HDassert(dset_info->buf.vp);
|
||||
|
||||
/* Set buf pointer */
|
||||
buf = dset_info->buf.cvp;
|
||||
|
||||
/* Check for NOOP write */
|
||||
if (nelmts == 0)
|
||||
if (dset_info->nelmts == 0)
|
||||
HGOTO_DONE(SUCCEED)
|
||||
|
||||
/* Allocate the iterators */
|
||||
@@ -612,32 +631,32 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator")
|
||||
|
||||
/* Figure out the strip mine size. */
|
||||
if (H5S_select_iter_init(file_iter, file_space, type_info->dst_type_size,
|
||||
if (H5S_select_iter_init(file_iter, dset_info->file_space, dset_info->type_info.dst_type_size,
|
||||
H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information")
|
||||
file_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
if (H5S_select_iter_init(mem_iter, mem_space, type_info->src_type_size, 0) < 0)
|
||||
if (H5S_select_iter_init(mem_iter, dset_info->mem_space, dset_info->type_info.src_type_size, 0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information")
|
||||
mem_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
if (H5S_select_iter_init(bkg_iter, file_space, type_info->dst_type_size,
|
||||
if (H5S_select_iter_init(bkg_iter, dset_info->file_space, dset_info->type_info.dst_type_size,
|
||||
H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information")
|
||||
bkg_iter_init = TRUE; /*file selection iteration info has been initialized */
|
||||
|
||||
/* Start strip mining... */
|
||||
for (smine_start = 0; smine_start < nelmts; smine_start += smine_nelmts) {
|
||||
for (smine_start = 0; smine_start < dset_info->nelmts; smine_start += smine_nelmts) {
|
||||
size_t n; /* Elements operated on */
|
||||
|
||||
/* Go figure out how many elements to read from the file */
|
||||
HDassert(H5S_SELECT_ITER_NELMTS(file_iter) == (nelmts - smine_start));
|
||||
smine_nelmts = (size_t)MIN(type_info->request_nelmts, (nelmts - smine_start));
|
||||
HDassert(H5S_SELECT_ITER_NELMTS(file_iter) == (dset_info->nelmts - smine_start));
|
||||
smine_nelmts = (size_t)MIN(dset_info->type_info.request_nelmts, (dset_info->nelmts - smine_start));
|
||||
|
||||
/*
|
||||
* Gather data from application buffer into the datatype conversion
|
||||
* buffer. Also gather data from the file into the background buffer
|
||||
* if necessary.
|
||||
*/
|
||||
n = H5D__gather_mem(buf, mem_iter, smine_nelmts, type_info->tconv_buf /*out*/);
|
||||
n = H5D__gather_mem(buf, mem_iter, smine_nelmts, io_info->tconv_buf /*out*/);
|
||||
if (n != smine_nelmts)
|
||||
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed")
|
||||
|
||||
@@ -647,44 +666,46 @@ H5D__scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_in
|
||||
* is a subset of the destination, the optimization is done in conversion
|
||||
* function H5T_conv_struct_opt to protect the background data.
|
||||
*/
|
||||
if (type_info->cmpd_subset && H5T_SUBSET_DST == type_info->cmpd_subset->subset &&
|
||||
type_info->dst_type_size == type_info->cmpd_subset->copy_size) {
|
||||
if (H5D__compound_opt_write(smine_nelmts, type_info) < 0)
|
||||
if (dset_info->type_info.cmpd_subset && H5T_SUBSET_DST == dset_info->type_info.cmpd_subset->subset &&
|
||||
dset_info->type_info.dst_type_size == dset_info->type_info.cmpd_subset->copy_size) {
|
||||
if (H5D__compound_opt_write(smine_nelmts, &dset_info->type_info, io_info->tconv_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed")
|
||||
} /* end if */
|
||||
else {
|
||||
if (H5T_BKG_YES == type_info->need_bkg) {
|
||||
n = H5D__gather_file(io_info, bkg_iter, smine_nelmts, type_info->bkg_buf /*out*/);
|
||||
if (H5T_BKG_YES == dset_info->type_info.need_bkg) {
|
||||
n = H5D__gather_file(io_info, dset_info, bkg_iter, smine_nelmts,
|
||||
dset_info->type_info.bkg_buf /*out*/);
|
||||
if (n != smine_nelmts)
|
||||
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed")
|
||||
} /* end if */
|
||||
|
||||
/* Do the data transform before the type conversion (since
|
||||
* transforms must be done in the memory type). */
|
||||
if (!type_info->is_xform_noop) {
|
||||
if (!dset_info->type_info.is_xform_noop) {
|
||||
H5Z_data_xform_t *data_transform; /* Data transform info */
|
||||
|
||||
/* Retrieve info from API context */
|
||||
if (H5CX_get_data_transform(&data_transform) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data transform info")
|
||||
|
||||
if (H5Z_xform_eval(data_transform, type_info->tconv_buf, smine_nelmts, type_info->mem_type) <
|
||||
0)
|
||||
if (H5Z_xform_eval(data_transform, io_info->tconv_buf, smine_nelmts,
|
||||
dset_info->type_info.mem_type) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "Error performing data transform")
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform datatype conversion.
|
||||
*/
|
||||
if (H5T_convert(type_info->tpath, type_info->src_type_id, type_info->dst_type_id, smine_nelmts,
|
||||
(size_t)0, (size_t)0, type_info->tconv_buf, type_info->bkg_buf) < 0)
|
||||
if (H5T_convert(dset_info->type_info.tpath, dset_info->type_info.src_type_id,
|
||||
dset_info->type_info.dst_type_id, smine_nelmts, (size_t)0, (size_t)0,
|
||||
io_info->tconv_buf, dset_info->type_info.bkg_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed")
|
||||
} /* end else */
|
||||
|
||||
/*
|
||||
* Scatter the data out to the file.
|
||||
*/
|
||||
if (H5D__scatter_file(io_info, file_iter, smine_nelmts, type_info->tconv_buf) < 0)
|
||||
if (H5D__scatter_file(io_info, dset_info, file_iter, smine_nelmts, io_info->tconv_buf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "scatter failed")
|
||||
} /* end for */
|
||||
|
||||
@@ -740,7 +761,7 @@ done:
|
||||
*/
|
||||
static herr_t
|
||||
H5D__compound_opt_read(size_t nelmts, H5S_sel_iter_t *iter, const H5D_type_info_t *type_info,
|
||||
void *user_buf /*out*/)
|
||||
uint8_t *tconv_buf, void *user_buf /*out*/)
|
||||
{
|
||||
uint8_t *ubuf = (uint8_t *)user_buf; /* Cast for pointer arithmetic */
|
||||
uint8_t *xdbuf; /* Pointer into dataset buffer */
|
||||
@@ -784,7 +805,7 @@ H5D__compound_opt_read(size_t nelmts, H5S_sel_iter_t *iter, const H5D_type_info_
|
||||
copy_size = type_info->cmpd_subset->copy_size;
|
||||
|
||||
/* Loop until all elements are written */
|
||||
xdbuf = type_info->tconv_buf;
|
||||
xdbuf = tconv_buf;
|
||||
while (nelmts > 0) {
|
||||
size_t nseq; /* Number of sequences generated */
|
||||
size_t curr_seq; /* Current sequence being processed */
|
||||
@@ -869,7 +890,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info)
|
||||
H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info, uint8_t *tconv_buf)
|
||||
{
|
||||
uint8_t *xsbuf, *xdbuf; /* Source & destination pointers into dataset buffer */
|
||||
size_t src_stride, dst_stride; /* Strides through source & destination datatypes */
|
||||
@@ -886,8 +907,8 @@ H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info)
|
||||
dst_stride = type_info->dst_type_size;
|
||||
|
||||
/* Loop until all elements are written */
|
||||
xsbuf = (uint8_t *)type_info->tconv_buf;
|
||||
xdbuf = (uint8_t *)type_info->tconv_buf;
|
||||
xsbuf = tconv_buf;
|
||||
xdbuf = tconv_buf;
|
||||
for (i = 0; i < nelmts; i++) {
|
||||
HDmemmove(xdbuf, xsbuf, dst_stride);
|
||||
|
||||
|
||||
+31
-31
@@ -44,8 +44,8 @@
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
|
||||
static herr_t H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space);
|
||||
static herr_t H5D__select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info,
|
||||
size_t elmt_size);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -77,8 +77,7 @@ H5FL_EXTERN(H5S_sel_iter_t);
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space)
|
||||
H5D__select_io(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info, size_t elmt_size)
|
||||
{
|
||||
H5S_sel_iter_t *mem_iter = NULL; /* Memory selection iteration info */
|
||||
hbool_t mem_iter_init = FALSE; /* Memory selection iteration info has been initialized */
|
||||
@@ -95,19 +94,23 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5
|
||||
size_t dxpl_vec_size; /* Vector length from API context's DXPL */
|
||||
size_t vec_size; /* Vector length */
|
||||
ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
|
||||
size_t nelmts; /* Number of elements to process */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check args */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->dset);
|
||||
HDassert(io_info->store);
|
||||
HDassert(io_info->u.rbuf);
|
||||
HDassert(dset_info->dset);
|
||||
HDassert(dset_info->store);
|
||||
HDassert(dset_info->buf.vp);
|
||||
|
||||
if (elmt_size == 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid elmt_size of 0")
|
||||
|
||||
/* Initialize nelmts */
|
||||
nelmts = dset_info->nelmts;
|
||||
|
||||
/* Check for only one element in selection */
|
||||
if (nelmts == 1) {
|
||||
hsize_t single_mem_off; /* Offset in memory */
|
||||
@@ -116,9 +119,9 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5
|
||||
size_t single_file_len; /* Length in the file */
|
||||
|
||||
/* Get offset of first element in selections */
|
||||
if (H5S_SELECT_OFFSET(file_space, &single_file_off) < 0)
|
||||
if (H5S_SELECT_OFFSET(dset_info->file_space, &single_file_off) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve file selection offset")
|
||||
if (H5S_SELECT_OFFSET(mem_space, &single_mem_off) < 0)
|
||||
if (H5S_SELECT_OFFSET(dset_info->mem_space, &single_mem_off) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "can't retrieve memory selection offset")
|
||||
|
||||
/* Set up necessary information for I/O operation */
|
||||
@@ -130,16 +133,16 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5
|
||||
|
||||
/* Perform I/O on memory and file sequences */
|
||||
if (io_info->op_type == H5D_IO_OP_READ) {
|
||||
if ((tmp_file_len = (*io_info->layout_ops.readvv)(
|
||||
io_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off, mem_nseq,
|
||||
&curr_mem_seq, &single_mem_len, &single_mem_off)) < 0)
|
||||
if ((tmp_file_len = (*dset_info->layout_ops.readvv)(
|
||||
io_info, dset_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off,
|
||||
mem_nseq, &curr_mem_seq, &single_mem_len, &single_mem_off)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
} /* end if */
|
||||
else {
|
||||
HDassert(io_info->op_type == H5D_IO_OP_WRITE);
|
||||
if ((tmp_file_len = (*io_info->layout_ops.writevv)(
|
||||
io_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off, mem_nseq,
|
||||
&curr_mem_seq, &single_mem_len, &single_mem_off)) < 0)
|
||||
if ((tmp_file_len = (*dset_info->layout_ops.writevv)(
|
||||
io_info, dset_info, file_nseq, &curr_file_seq, &single_file_len, &single_file_off,
|
||||
mem_nseq, &curr_mem_seq, &single_mem_len, &single_mem_off)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
} /* end else */
|
||||
|
||||
@@ -175,12 +178,13 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "can't allocate file iterator")
|
||||
|
||||
/* Initialize file iterator */
|
||||
if (H5S_select_iter_init(file_iter, file_space, elmt_size, H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0)
|
||||
if (H5S_select_iter_init(file_iter, dset_info->file_space, elmt_size,
|
||||
H5S_SEL_ITER_GET_SEQ_LIST_SORTED) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
||||
file_iter_init = 1; /* File selection iteration info has been initialized */
|
||||
|
||||
/* Initialize memory iterator */
|
||||
if (H5S_select_iter_init(mem_iter, mem_space, elmt_size, 0) < 0)
|
||||
if (H5S_select_iter_init(mem_iter, dset_info->mem_space, elmt_size, 0) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
|
||||
mem_iter_init = 1; /* Memory selection iteration info has been initialized */
|
||||
|
||||
@@ -214,16 +218,16 @@ H5D__select_io(const H5D_io_info_t *io_info, size_t elmt_size, size_t nelmts, H5
|
||||
|
||||
/* Perform I/O on memory and file sequences */
|
||||
if (io_info->op_type == H5D_IO_OP_READ) {
|
||||
if ((tmp_file_len =
|
||||
(*io_info->layout_ops.readvv)(io_info, file_nseq, &curr_file_seq, file_len, file_off,
|
||||
mem_nseq, &curr_mem_seq, mem_len, mem_off)) < 0)
|
||||
if ((tmp_file_len = (*dset_info->layout_ops.readvv)(
|
||||
io_info, dset_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq,
|
||||
&curr_mem_seq, mem_len, mem_off)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
} /* end if */
|
||||
else {
|
||||
HDassert(io_info->op_type == H5D_IO_OP_WRITE);
|
||||
if ((tmp_file_len = (*io_info->layout_ops.writevv)(io_info, file_nseq, &curr_file_seq,
|
||||
file_len, file_off, mem_nseq,
|
||||
&curr_mem_seq, mem_len, mem_off)) < 0)
|
||||
if ((tmp_file_len = (*dset_info->layout_ops.writevv)(
|
||||
io_info, dset_info, file_nseq, &curr_file_seq, file_len, file_off, mem_nseq,
|
||||
&curr_mem_seq, mem_len, mem_off)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
} /* end else */
|
||||
|
||||
@@ -452,16 +456,14 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__select_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space)
|
||||
H5D__select_read(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Call generic selection operation */
|
||||
H5_CHECK_OVERFLOW(nelmts, hsize_t, size_t);
|
||||
if (H5D__select_io(io_info, type_info->src_type_size, (size_t)nelmts, file_space, mem_space) < 0)
|
||||
if (H5D__select_io(io_info, dset_info, dset_info->type_info.src_type_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error")
|
||||
|
||||
done:
|
||||
@@ -481,16 +483,14 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5D__select_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space)
|
||||
H5D__select_write(const H5D_io_info_t *io_info, const H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Call generic selection operation */
|
||||
H5_CHECK_OVERFLOW(nelmts, hsize_t, size_t);
|
||||
if (H5D__select_io(io_info, type_info->dst_type_size, (size_t)nelmts, file_space, mem_space) < 0)
|
||||
if (H5D__select_io(io_info, dset_info, dset_info->type_info.dst_type_size) < 0)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error")
|
||||
|
||||
done:
|
||||
|
||||
+122
-80
@@ -83,10 +83,9 @@
|
||||
|
||||
/* Layout operation callbacks */
|
||||
static hbool_t H5D__virtual_is_data_cached(const H5D_shared_t *shared_dset);
|
||||
static herr_t H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t *fm);
|
||||
static herr_t H5D__virtual_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__virtual_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__virtual_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5D__virtual_flush(H5D_t *dset);
|
||||
|
||||
/* Other functions */
|
||||
@@ -103,13 +102,13 @@ static herr_t H5D__virtual_build_source_name(char
|
||||
size_t static_strlen, size_t nsubs, hsize_t blockno,
|
||||
char **built_name);
|
||||
static herr_t H5D__virtual_init_all(const H5D_t *dset);
|
||||
static herr_t H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_t *file_space,
|
||||
H5S_t *mem_space, hsize_t *tot_nelmts);
|
||||
static herr_t H5D__virtual_pre_io(H5D_dset_io_info_t *dset_info, H5O_storage_virtual_t *storage,
|
||||
H5S_t *file_space, H5S_t *mem_space, hsize_t *tot_nelmts);
|
||||
static herr_t H5D__virtual_post_io(H5O_storage_virtual_t *storage);
|
||||
static herr_t H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
|
||||
static herr_t H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
H5S_t *file_space, H5O_storage_virtual_srcdset_t *source_dset);
|
||||
static herr_t H5D__virtual_read_one(H5D_dset_io_info_t *dset_info,
|
||||
H5O_storage_virtual_srcdset_t *source_dset);
|
||||
static herr_t H5D__virtual_write_one(H5D_dset_io_info_t *dset_info,
|
||||
H5O_storage_virtual_srcdset_t *source_dset);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -121,18 +120,15 @@ const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1] = {{
|
||||
H5D__virtual_init, /* init */
|
||||
H5D__virtual_is_space_alloc, /* is_space_alloc */
|
||||
H5D__virtual_is_data_cached, /* is_data_cached */
|
||||
NULL, /* io_init */
|
||||
H5D__virtual_io_init, /* io_init */
|
||||
NULL, /* mdio_init */
|
||||
H5D__virtual_read, /* ser_read */
|
||||
H5D__virtual_write, /* ser_write */
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
NULL, /* par_read */
|
||||
NULL, /* par_write */
|
||||
#endif
|
||||
NULL, /* readvv */
|
||||
NULL, /* writevv */
|
||||
H5D__virtual_flush, /* flush */
|
||||
NULL, /* io_term */
|
||||
NULL /* dest */
|
||||
NULL, /* readvv */
|
||||
NULL, /* writevv */
|
||||
H5D__virtual_flush, /* flush */
|
||||
NULL, /* io_term */
|
||||
NULL /* dest */
|
||||
}};
|
||||
|
||||
/*******************/
|
||||
@@ -2370,6 +2366,29 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5D__virtual_is_data_cached() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__virtual_io_init
|
||||
*
|
||||
* Purpose: Performs initialization before any sort of I/O on the raw data
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Sunday, May 22, 2022
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_io_init(H5D_io_info_t *io_info, H5D_dset_io_info_t H5_ATTR_UNUSED *dinfo)
|
||||
{
|
||||
FUNC_ENTER_PACKAGE_NOERR
|
||||
|
||||
/* Disable selection I/O */
|
||||
io_info->use_select_io = FALSE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* end H5D__virtual_io_init() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5D__virtual_pre_io
|
||||
*
|
||||
@@ -2386,16 +2405,17 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_t *file_space,
|
||||
H5D__virtual_pre_io(H5D_dset_io_info_t *dset_info, H5O_storage_virtual_t *storage, H5S_t *file_space,
|
||||
H5S_t *mem_space, hsize_t *tot_nelmts)
|
||||
{
|
||||
hssize_t select_nelmts; /* Number of elements in selection */
|
||||
hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounds start */
|
||||
hsize_t bounds_end[H5S_MAX_RANK]; /* Selection bounds end */
|
||||
int rank = 0;
|
||||
hbool_t bounds_init = FALSE; /* Whether bounds_start, bounds_end, and rank are valid */
|
||||
size_t i, j, k; /* Local index variables */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
const H5D_t *dset = dset_info->dset; /* Local pointer to dataset info */
|
||||
hssize_t select_nelmts; /* Number of elements in selection */
|
||||
hsize_t bounds_start[H5S_MAX_RANK]; /* Selection bounds start */
|
||||
hsize_t bounds_end[H5S_MAX_RANK]; /* Selection bounds end */
|
||||
int rank = 0;
|
||||
hbool_t bounds_init = FALSE; /* Whether bounds_start, bounds_end, and rank are valid */
|
||||
size_t i, j, k; /* Local index variables */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@@ -2407,7 +2427,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
|
||||
/* Initialize layout if necessary */
|
||||
if (!storage->init)
|
||||
if (H5D__virtual_init_all(io_info->dset) < 0)
|
||||
if (H5D__virtual_init_all(dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize virtual layout")
|
||||
|
||||
/* Initialize tot_nelmts */
|
||||
@@ -2427,7 +2447,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
/* Get selection bounds if necessary */
|
||||
if (!bounds_init) {
|
||||
/* Get rank of VDS */
|
||||
if ((rank = H5S_GET_EXTENT_NDIMS(io_info->dset->shared->space)) < 0)
|
||||
if ((rank = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions")
|
||||
|
||||
/* Get selection bounds */
|
||||
@@ -2469,7 +2489,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
* open the source dataset to patch it */
|
||||
if (storage->list[i].source_space_status != H5O_VIRTUAL_STATUS_CORRECT) {
|
||||
HDassert(!storage->list[i].sub_dset[j].dset);
|
||||
if (H5D__virtual_open_source_dset(io_info->dset, &storage->list[i],
|
||||
if (H5D__virtual_open_source_dset(dset, &storage->list[i],
|
||||
&storage->list[i].sub_dset[j]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset")
|
||||
} /* end if */
|
||||
@@ -2499,7 +2519,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of dataspace")
|
||||
|
||||
/* Get current VDS dimensions */
|
||||
if (H5S_get_simple_extent_dims(io_info->dset->shared->space, tmp_dims, NULL) < 0)
|
||||
if (H5S_get_simple_extent_dims(dset->shared->space, tmp_dims, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions")
|
||||
|
||||
/* Copy virtual selection */
|
||||
@@ -2554,7 +2574,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
/* Open source dataset */
|
||||
if (!storage->list[i].sub_dset[j].dset)
|
||||
/* Try to open dataset */
|
||||
if (H5D__virtual_open_source_dset(io_info->dset, &storage->list[i],
|
||||
if (H5D__virtual_open_source_dset(dset, &storage->list[i],
|
||||
&storage->list[i].sub_dset[j]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL,
|
||||
"unable to open source dataset")
|
||||
@@ -2599,7 +2619,7 @@ H5D__virtual_pre_io(H5D_io_info_t *io_info, H5O_storage_virtual_t *storage, H5S_
|
||||
/* Open source dataset */
|
||||
if (!storage->list[i].source_dset.dset)
|
||||
/* Try to open dataset */
|
||||
if (H5D__virtual_open_source_dset(io_info->dset, &storage->list[i],
|
||||
if (H5D__virtual_open_source_dset(dset, &storage->list[i],
|
||||
&storage->list[i].source_dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset")
|
||||
|
||||
@@ -2697,11 +2717,11 @@ H5D__virtual_post_io(H5O_storage_virtual_t *storage)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space,
|
||||
H5O_storage_virtual_srcdset_t *source_dset)
|
||||
H5D__virtual_read_one(H5D_dset_io_info_t *dset_info, H5O_storage_virtual_srcdset_t *source_dset)
|
||||
{
|
||||
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
|
||||
H5D_dset_io_info_t source_dinfo; /* Dataset info for source dataset read */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@@ -2717,15 +2737,23 @@ H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
/* Project intersection of file space and mapping virtual space onto
|
||||
* mapping source space */
|
||||
if (H5S_select_project_intersection(source_dset->clipped_virtual_select,
|
||||
source_dset->clipped_source_select, file_space,
|
||||
source_dset->clipped_source_select, dset_info->file_space,
|
||||
&projected_src_space, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL,
|
||||
"can't project virtual intersection onto source space")
|
||||
|
||||
/* Perform read on source dataset */
|
||||
if (H5D__read(source_dset->dset, type_info->dst_type_id, source_dset->projected_mem_space,
|
||||
projected_src_space, io_info->u.rbuf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read source dataset")
|
||||
{
|
||||
/* Initialize source_dinfo */
|
||||
source_dinfo.dset = source_dset->dset;
|
||||
source_dinfo.mem_space = source_dset->projected_mem_space;
|
||||
source_dinfo.file_space = projected_src_space;
|
||||
source_dinfo.buf.vp = dset_info->buf.vp;
|
||||
source_dinfo.mem_type_id = dset_info->type_info.dst_type_id;
|
||||
|
||||
/* Read in the point (with the custom VL memory allocator) */
|
||||
if (H5D__read(1, &source_dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read source dataset")
|
||||
}
|
||||
|
||||
/* Close projected_src_space */
|
||||
if (H5S_close(projected_src_space) < 0)
|
||||
@@ -2734,7 +2762,7 @@ H5D__virtual_read_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
/* Release allocated resources on failure */
|
||||
/* Release allocated resources */
|
||||
if (projected_src_space) {
|
||||
HDassert(ret_value < 0);
|
||||
if (H5S_close(projected_src_space) < 0)
|
||||
@@ -2757,12 +2785,12 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, H5S_t *file_space,
|
||||
H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
H5D__virtual_read(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */
|
||||
hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */
|
||||
H5S_t *fill_space = NULL; /* Space to fill with fill value */
|
||||
size_t nelmts; /* Number of elements to process */
|
||||
size_t i, j; /* Local index variables */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -2770,22 +2798,25 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.rbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->buf.vp);
|
||||
HDassert(dset_info->mem_space);
|
||||
HDassert(dset_info->file_space);
|
||||
|
||||
storage = &io_info->dset->shared->layout.storage.u.virt;
|
||||
storage = &(dset_info->dset->shared->layout.storage.u.virt);
|
||||
HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE));
|
||||
|
||||
/* Initialize nelmts */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(dset_info->file_space);
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Parallel reads are not supported (yet) */
|
||||
if (H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
if (H5F_HAS_FEATURE(dset_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel reads not supported on virtual datasets")
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Prepare for I/O operation */
|
||||
if (H5D__virtual_pre_io(io_info, storage, file_space, mem_space, &tot_nelmts) < 0)
|
||||
if (H5D__virtual_pre_io(dset_info, storage, dset_info->file_space, dset_info->mem_space, &tot_nelmts) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to prepare for I/O operation")
|
||||
|
||||
/* Iterate over mappings */
|
||||
@@ -2797,12 +2828,12 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
if (storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) {
|
||||
/* Iterate over sub-source dsets */
|
||||
for (j = storage->list[i].sub_dset_io_start; j < storage->list[i].sub_dset_io_end; j++)
|
||||
if (H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0)
|
||||
if (H5D__virtual_read_one(dset_info, &storage->list[i].sub_dset[j]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset")
|
||||
} /* end if */
|
||||
else
|
||||
/* Read from source dataset */
|
||||
if (H5D__virtual_read_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0)
|
||||
if (H5D__virtual_read_one(dset_info, &storage->list[i].source_dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read source dataset")
|
||||
} /* end for */
|
||||
|
||||
@@ -2811,13 +2842,13 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
H5D_fill_value_t fill_status; /* Fill value status */
|
||||
|
||||
/* Check the fill value status */
|
||||
if (H5P_is_fill_value_defined(&io_info->dset->shared->dcpl_cache.fill, &fill_status) < 0)
|
||||
if (H5P_is_fill_value_defined(&dset_info->dset->shared->dcpl_cache.fill, &fill_status) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if fill value defined")
|
||||
|
||||
/* Always write fill value to memory buffer unless it is undefined */
|
||||
if (fill_status != H5D_FILL_VALUE_UNDEFINED) {
|
||||
/* Start with fill space equal to memory space */
|
||||
if (NULL == (fill_space = H5S_copy(mem_space, FALSE, TRUE)))
|
||||
if (NULL == (fill_space = H5S_copy(dset_info->mem_space, FALSE, TRUE)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy memory selection")
|
||||
|
||||
/* Iterate over mappings */
|
||||
@@ -2837,8 +2868,8 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsiz
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to clip fill selection")
|
||||
|
||||
/* Write fill values to memory buffer */
|
||||
if (H5D__fill(io_info->dset->shared->dcpl_cache.fill.buf, io_info->dset->shared->type,
|
||||
io_info->u.rbuf, type_info->mem_type, fill_space) < 0)
|
||||
if (H5D__fill(dset_info->dset->shared->dcpl_cache.fill.buf, dset_info->dset->shared->type,
|
||||
dset_info->buf.vp, dset_info->type_info.mem_type, fill_space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "filling buf failed")
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -2887,11 +2918,11 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, H5S_t *file_space,
|
||||
H5O_storage_virtual_srcdset_t *source_dset)
|
||||
H5D__virtual_write_one(H5D_dset_io_info_t *dset_info, H5O_storage_virtual_srcdset_t *source_dset)
|
||||
{
|
||||
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5S_t *projected_src_space = NULL; /* File space for selection in a single source dataset */
|
||||
H5D_dset_io_info_t source_dinfo; /* Dataset info for source dataset write */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
@@ -2909,15 +2940,23 @@ H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
/* Project intersection of file space and mapping virtual space onto
|
||||
* mapping source space */
|
||||
if (H5S_select_project_intersection(source_dset->clipped_virtual_select,
|
||||
source_dset->clipped_source_select, file_space,
|
||||
source_dset->clipped_source_select, dset_info->file_space,
|
||||
&projected_src_space, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL,
|
||||
"can't project virtual intersection onto source space")
|
||||
|
||||
/* Perform write on source dataset */
|
||||
if (H5D__write(source_dset->dset, type_info->dst_type_id, source_dset->projected_mem_space,
|
||||
projected_src_space, io_info->u.wbuf) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write to source dataset")
|
||||
{
|
||||
/* Initialize source_dinfo */
|
||||
source_dinfo.dset = source_dset->dset;
|
||||
source_dinfo.mem_space = source_dset->projected_mem_space;
|
||||
source_dinfo.file_space = projected_src_space;
|
||||
source_dinfo.buf.cvp = dset_info->buf.cvp;
|
||||
source_dinfo.mem_type_id = dset_info->type_info.dst_type_id;
|
||||
|
||||
/* Read in the point (with the custom VL memory allocator) */
|
||||
if (H5D__write(1, &source_dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read source dataset")
|
||||
}
|
||||
|
||||
/* Close projected_src_space */
|
||||
if (H5S_close(projected_src_space) < 0)
|
||||
@@ -2926,7 +2965,7 @@ H5D__virtual_write_one(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
/* Release allocated resources on failure */
|
||||
/* Release allocated resources */
|
||||
if (projected_src_space) {
|
||||
HDassert(ret_value < 0);
|
||||
if (H5S_close(projected_src_space) < 0)
|
||||
@@ -2949,11 +2988,11 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts,
|
||||
H5S_t *file_space, H5S_t *mem_space, H5D_chunk_map_t H5_ATTR_UNUSED *fm)
|
||||
H5D__virtual_write(H5D_io_info_t *io_info, H5D_dset_io_info_t *dset_info)
|
||||
{
|
||||
H5O_storage_virtual_t *storage; /* Convenient pointer into layout struct */
|
||||
hsize_t tot_nelmts; /* Total number of elements mapped to mem_space */
|
||||
size_t nelmts; /* Number of elements to process */
|
||||
size_t i, j; /* Local index variables */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -2961,22 +3000,25 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsi
|
||||
|
||||
/* Sanity check */
|
||||
HDassert(io_info);
|
||||
HDassert(io_info->u.wbuf);
|
||||
HDassert(type_info);
|
||||
HDassert(mem_space);
|
||||
HDassert(file_space);
|
||||
HDassert(dset_info);
|
||||
HDassert(dset_info->buf.cvp);
|
||||
HDassert(dset_info->mem_space);
|
||||
HDassert(dset_info->file_space);
|
||||
|
||||
storage = &io_info->dset->shared->layout.storage.u.virt;
|
||||
storage = &(dset_info->dset->shared->layout.storage.u.virt);
|
||||
HDassert((storage->view == H5D_VDS_FIRST_MISSING) || (storage->view == H5D_VDS_LAST_AVAILABLE));
|
||||
|
||||
/* Initialize nelmts */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(dset_info->file_space);
|
||||
|
||||
#ifdef H5_HAVE_PARALLEL
|
||||
/* Parallel writes are not supported (yet) */
|
||||
if (H5F_HAS_FEATURE(io_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
if (H5F_HAS_FEATURE(dset_info->dset->oloc.file, H5FD_FEAT_HAS_MPI))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "parallel writes not supported on virtual datasets")
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
/* Prepare for I/O operation */
|
||||
if (H5D__virtual_pre_io(io_info, storage, file_space, mem_space, &tot_nelmts) < 0)
|
||||
if (H5D__virtual_pre_io(dset_info, storage, dset_info->file_space, dset_info->mem_space, &tot_nelmts) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "unable to prepare for I/O operation")
|
||||
|
||||
/* Fail if there are unmapped parts of the selection as they would not be
|
||||
@@ -2994,12 +3036,12 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsi
|
||||
if (storage->list[i].psfn_nsubs || storage->list[i].psdn_nsubs) {
|
||||
/* Iterate over sub-source dsets */
|
||||
for (j = storage->list[i].sub_dset_io_start; j < storage->list[i].sub_dset_io_end; j++)
|
||||
if (H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].sub_dset[j]) < 0)
|
||||
if (H5D__virtual_write_one(dset_info, &storage->list[i].sub_dset[j]) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write to source dataset")
|
||||
} /* end if */
|
||||
else
|
||||
/* Write to source dataset */
|
||||
if (H5D__virtual_write_one(io_info, type_info, file_space, &storage->list[i].source_dset) < 0)
|
||||
if (H5D__virtual_write_one(dset_info, &storage->list[i].source_dset) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write to source dataset")
|
||||
} /* end for */
|
||||
|
||||
|
||||
+1
-1
@@ -400,7 +400,7 @@ done:
|
||||
PURPOSE
|
||||
Get the number of elements in current selection
|
||||
USAGE
|
||||
hssize_t H5Sget_select_npoints(space)
|
||||
hsize_t H5Sget_select_npoints(space)
|
||||
H5S_t *space; IN: Dataspace of selection to query
|
||||
RETURNS
|
||||
The number of elements in selection on success, 0 on failure
|
||||
|
||||
+215
-38
@@ -88,10 +88,12 @@ static void *H5VL__dataset_create(void *obj, const H5VL_loc_params_t *loc_param
|
||||
hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
static void *H5VL__dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls,
|
||||
const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
static herr_t H5VL__dataset_read(void *dset, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, void *buf, void **req);
|
||||
static herr_t H5VL__dataset_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req);
|
||||
static herr_t H5VL__dataset_read(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[],
|
||||
void **req);
|
||||
static herr_t H5VL__dataset_write(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
|
||||
const void *buf[], void **req);
|
||||
static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args,
|
||||
hid_t dxpl_id, void **req);
|
||||
static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args,
|
||||
@@ -2020,9 +2022,9 @@ done:
|
||||
} /* end H5VLdataset_open() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL__dataset_read
|
||||
* Function: H5VL__dataset_read
|
||||
*
|
||||
* Purpose: Reads data from dataset through the VOL
|
||||
* Purpose: Reads data from dataset through the VOL
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
@@ -2030,8 +2032,8 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL__dataset_read(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, void *buf, void **req)
|
||||
H5VL__dataset_read(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -2042,13 +2044,61 @@ H5VL__dataset_read(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t
|
||||
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset read' method")
|
||||
|
||||
/* Call the corresponding VOL callback */
|
||||
if ((cls->dataset_cls.read)(obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
if ((cls->dataset_cls.read)(count, obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "dataset read failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__dataset_read() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL_dataset_read_direct
|
||||
*
|
||||
* Purpose: Reads data from dataset through the VOL. This is like
|
||||
* H5VL_dataset_read, but takes an array of void * for the
|
||||
* objects and a class pointer instead of an array of
|
||||
* H5VL_object_t. This allows us to avoid allocating and
|
||||
* copying an extra array (of H5VL_object_ts).
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL_dataset_read_direct(size_t count, void *obj[], H5VL_t *connector, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req)
|
||||
{
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
H5VL_object_t tmp_vol_obj; /* Temporary VOL object for setting VOL wrapper */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
HDassert(obj);
|
||||
HDassert(connector);
|
||||
|
||||
/* Set wrapper info in API context */
|
||||
tmp_vol_obj.data = obj[0];
|
||||
tmp_vol_obj.connector = connector;
|
||||
tmp_vol_obj.rc = 1;
|
||||
if (H5VL_set_vol_wrapper(&tmp_vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
|
||||
vol_wrapper_set = TRUE;
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_read(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
|
||||
req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "dataset read failed")
|
||||
|
||||
done:
|
||||
/* Reset object wrapping info in API context */
|
||||
if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
|
||||
HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL_dataset_read_direct() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL_dataset_read
|
||||
*
|
||||
@@ -2060,21 +2110,44 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL_dataset_read(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, void *buf, void **req)
|
||||
H5VL_dataset_read(size_t count, const H5VL_object_t *vol_obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req)
|
||||
{
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
HDassert(vol_obj);
|
||||
HDassert(vol_obj[0]);
|
||||
|
||||
/* Set wrapper info in API context */
|
||||
if (H5VL_set_vol_wrapper(vol_obj) < 0)
|
||||
if (H5VL_set_vol_wrapper(vol_obj[0]) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
|
||||
vol_wrapper_set = TRUE;
|
||||
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)H5MM_malloc(count * sizeof(void *))))
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate space for object array")
|
||||
|
||||
/* Build obj array */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Get the object */
|
||||
obj[i] = vol_obj[i]->data;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (vol_obj[i]->connector->cls->value != vol_obj[0]->connector->cls->value)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
|
||||
"datasets are accessed through different VOL connectors and can't be used in the "
|
||||
"same I/O call")
|
||||
}
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_read(vol_obj->data, vol_obj->connector->cls, mem_type_id, mem_space_id, file_space_id,
|
||||
if (H5VL__dataset_read(count, obj, vol_obj[0]->connector->cls, mem_type_id, mem_space_id, file_space_id,
|
||||
dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "dataset read failed")
|
||||
|
||||
@@ -2083,6 +2156,10 @@ done:
|
||||
if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
|
||||
HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
|
||||
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
H5MM_free(obj);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL_dataset_read() */
|
||||
|
||||
@@ -2097,24 +2174,36 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VLdataset_read(void *obj, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, void *buf, void **req /*out*/)
|
||||
H5VLdataset_read(size_t count, void *obj[], hid_t connector_id, hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req /*out*/)
|
||||
{
|
||||
H5VL_class_t *cls; /* VOL connector's class struct */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API_NOINIT
|
||||
H5TRACE8("e", "*xiiiii*xx", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
|
||||
req);
|
||||
H5TRACE9("e", "z**xi*i*i*ii**xx", count, obj, connector_id, mem_type_id, mem_space_id, file_space_id,
|
||||
dxpl_id, buf, req);
|
||||
|
||||
/* Check args and get class pointer */
|
||||
if (NULL == obj)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj array not provided")
|
||||
for (i = 1; i < count; i++)
|
||||
if (NULL == obj[i])
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
|
||||
if (NULL == mem_type_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided")
|
||||
if (NULL == mem_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided")
|
||||
if (NULL == file_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided")
|
||||
if (NULL == buf)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided")
|
||||
if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_read(obj, cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
if (H5VL__dataset_read(count, obj, cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to read dataset")
|
||||
|
||||
done:
|
||||
@@ -2122,9 +2211,9 @@ done:
|
||||
} /* end H5VLdataset_read() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL__dataset_write
|
||||
* Function: H5VL__dataset_write
|
||||
*
|
||||
* Purpose: Writes data from dataset through the VOL
|
||||
* Purpose: Writes data from dataset through the VOL
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
@@ -2132,8 +2221,8 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL__dataset_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req)
|
||||
H5VL__dataset_write(size_t count, void *obj[], const H5VL_class_t *cls, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@@ -2144,13 +2233,62 @@ H5VL__dataset_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t
|
||||
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset write' method")
|
||||
|
||||
/* Call the corresponding VOL callback */
|
||||
if ((cls->dataset_cls.write)(obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
if ((cls->dataset_cls.write)(count, obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "dataset write failed")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__dataset_write() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL_dataset_write_direct
|
||||
*
|
||||
* Purpose: Writes data from dataset through the VOL. This is like
|
||||
* H5VL_dataset_write, but takes an array of void * for the
|
||||
* objects and a class pointer instead of an array of
|
||||
* H5VL_object_t. This allows us to avoid allocating and
|
||||
* copying an extra array (of H5VL_object_ts).
|
||||
*
|
||||
* Return: Success: Non-negative
|
||||
* Failure: Negative
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL_dataset_write_direct(size_t count, void *obj[], H5VL_t *connector, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, const void *buf[],
|
||||
void **req)
|
||||
{
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
H5VL_object_t tmp_vol_obj; /* Temporary VOL object for setting VOL wrapper */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
HDassert(obj);
|
||||
HDassert(connector);
|
||||
|
||||
/* Set wrapper info in API context */
|
||||
tmp_vol_obj.data = obj[0];
|
||||
tmp_vol_obj.connector = connector;
|
||||
tmp_vol_obj.rc = 1;
|
||||
if (H5VL_set_vol_wrapper(&tmp_vol_obj) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
|
||||
vol_wrapper_set = TRUE;
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_write(count, obj, connector->cls, mem_type_id, mem_space_id, file_space_id, dxpl_id,
|
||||
buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "dataset write failed")
|
||||
|
||||
done:
|
||||
/* Reset object wrapping info in API context */
|
||||
if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
|
||||
HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL_dataset_write_direct() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL_dataset_write
|
||||
*
|
||||
@@ -2162,21 +2300,44 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL_dataset_write(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf, void **req)
|
||||
H5VL_dataset_write(size_t count, const H5VL_object_t *vol_obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req)
|
||||
{
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
HDassert(vol_obj);
|
||||
HDassert(vol_obj[0]);
|
||||
|
||||
/* Set wrapper info in API context */
|
||||
if (H5VL_set_vol_wrapper(vol_obj) < 0)
|
||||
if (H5VL_set_vol_wrapper(vol_obj[0]) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
|
||||
vol_wrapper_set = TRUE;
|
||||
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)H5MM_malloc(count * sizeof(void *))))
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate space for object array")
|
||||
|
||||
/* Build obj array */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Get the object */
|
||||
obj[i] = vol_obj[i]->data;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (vol_obj[i]->connector->cls->value != vol_obj[0]->connector->cls->value)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
|
||||
"datasets are accessed through different VOL connectors and can't be used in the "
|
||||
"same I/O call")
|
||||
}
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_write(vol_obj->data, vol_obj->connector->cls, mem_type_id, mem_space_id, file_space_id,
|
||||
if (H5VL__dataset_write(count, obj, vol_obj[0]->connector->cls, mem_type_id, mem_space_id, file_space_id,
|
||||
dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "dataset write failed")
|
||||
|
||||
@@ -2185,6 +2346,10 @@ done:
|
||||
if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
|
||||
HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
|
||||
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
H5MM_free(obj);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL_dataset_write() */
|
||||
|
||||
@@ -2199,24 +2364,36 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VLdataset_write(void *obj, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf, void **req /*out*/)
|
||||
H5VLdataset_write(size_t count, void *obj[], hid_t connector_id, hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req /*out*/)
|
||||
{
|
||||
H5VL_class_t *cls; /* VOL connector's class struct */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API_NOINIT
|
||||
H5TRACE8("e", "*xiiiii*xx", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
|
||||
req);
|
||||
H5TRACE9("e", "z**xi*i*i*ii**xx", count, obj, connector_id, mem_type_id, mem_space_id, file_space_id,
|
||||
dxpl_id, buf, req);
|
||||
|
||||
/* Check args and get class pointer */
|
||||
if (NULL == obj)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "obj array not provided")
|
||||
for (i = 1; i < count; i++)
|
||||
if (NULL == obj[i])
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
|
||||
if (NULL == mem_type_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_type_id array not provided")
|
||||
if (NULL == mem_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_space_id array not provided")
|
||||
if (NULL == file_space_id)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_space_id array not provided")
|
||||
if (NULL == buf)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf array not provided")
|
||||
if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
|
||||
|
||||
/* Call the corresponding internal VOL routine */
|
||||
if (H5VL__dataset_write(obj, cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
if (H5VL__dataset_write(count, obj, cls, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req) < 0)
|
||||
HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to write dataset")
|
||||
|
||||
done:
|
||||
|
||||
+4
-4
@@ -879,10 +879,10 @@ typedef struct H5VL_dataset_class_t {
|
||||
hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
void *(*open)(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t dapl_id,
|
||||
hid_t dxpl_id, void **req);
|
||||
herr_t (*read)(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
|
||||
void *buf, void **req);
|
||||
herr_t (*write)(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
|
||||
const void *buf, void **req);
|
||||
herr_t (*read)(size_t count, void *dset[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req);
|
||||
herr_t (*write)(size_t count, void *dset[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req);
|
||||
herr_t (*get)(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req);
|
||||
herr_t (*specific)(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, void **req);
|
||||
herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req);
|
||||
|
||||
@@ -107,10 +107,12 @@ H5_DLL void *H5VLdataset_create(void *obj, const H5VL_loc_params_t *loc_params,
|
||||
hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL void *H5VLdataset_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id,
|
||||
const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL herr_t H5VLdataset_read(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, void *buf, void **req);
|
||||
H5_DLL herr_t H5VLdataset_write(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
|
||||
H5_DLL herr_t H5VLdataset_read(size_t count, void *dset[], hid_t connector_id, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t plist_id, void *buf[],
|
||||
void **req);
|
||||
H5_DLL herr_t H5VLdataset_write(size_t count, void *dset[], hid_t connector_id, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t plist_id,
|
||||
const void *buf[], void **req);
|
||||
H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id,
|
||||
void **req);
|
||||
H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args,
|
||||
|
||||
+178
-119
@@ -50,8 +50,11 @@
|
||||
/********************/
|
||||
|
||||
/* Helper routines for read/write API calls */
|
||||
static herr_t H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id,
|
||||
hid_t mem_space_id, H5S_t **file_space, H5S_t **mem_space);
|
||||
static herr_t H5VL__native_dataset_io_setup(size_t count, void *obj[], hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
|
||||
H5_flexible_const_ptr_t buf[], H5D_dset_io_info_t *dinfo);
|
||||
static herr_t H5VL__native_dataset_io_cleanup(size_t count, hid_t mem_space_id[], hid_t file_space_id[],
|
||||
H5D_dset_io_info_t *dinfo);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@@ -75,89 +78,153 @@ static herr_t H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t fi
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL__native_dataset_io_setup(H5D_t *dset, hid_t dxpl_id, hid_t file_space_id, hid_t mem_space_id,
|
||||
H5S_t **file_space, H5S_t **mem_space)
|
||||
H5VL__native_dataset_io_setup(size_t count, void *obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, H5_flexible_const_ptr_t buf[],
|
||||
H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
H5F_shared_t *f_sh;
|
||||
size_t i;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(dinfo);
|
||||
|
||||
/* Get shared file */
|
||||
f_sh = H5F_SHARED(((H5D_t *)obj[0])->oloc.file);
|
||||
|
||||
/* Iterate over datasets */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Set up dset */
|
||||
dinfo[i].dset = (H5D_t *)obj[i];
|
||||
HDassert(dinfo[i].dset);
|
||||
|
||||
/* Check dataset's file pointer is valid */
|
||||
if (NULL == dinfo[i].dset->oloc.file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file")
|
||||
if (f_sh != H5F_SHARED(dinfo[i].dset->oloc.file))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL,
|
||||
"different files detected in multi dataset I/O request")
|
||||
|
||||
/* Set up memory type */
|
||||
dinfo[i].mem_type_id = mem_type_id[i];
|
||||
|
||||
/* Set up file dataspace */
|
||||
if (H5S_ALL == file_space_id[i])
|
||||
/* Use dataspace for dataset */
|
||||
dinfo[i].file_space = dinfo[i].dset->shared->space;
|
||||
else if (H5S_BLOCK == file_space_id[i])
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_BLOCK is not allowed for file dataspace")
|
||||
else if (H5S_PLIST == file_space_id[i]) {
|
||||
H5P_genplist_t *plist; /* Property list pointer */
|
||||
H5S_t *space; /* Dataspace to hold selection */
|
||||
|
||||
/* Get the plist structure */
|
||||
if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADID, FAIL, "bad dataset transfer property list")
|
||||
|
||||
/* Get a pointer to the file space in the property list */
|
||||
if (H5P_peek(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error getting dataset I/O selection")
|
||||
|
||||
/* Use dataspace for dataset */
|
||||
dinfo[i].file_space = dinfo[i].dset->shared->space;
|
||||
|
||||
/* Copy, but share, selection from property list to dataset's dataspace */
|
||||
if (H5S_SELECT_COPY(dinfo[i].file_space, space, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataset I/O selection")
|
||||
} /* end else-if */
|
||||
else {
|
||||
/* Get the dataspace pointer */
|
||||
if (NULL == (dinfo[i].file_space = (H5S_t *)H5I_object_verify(file_space_id[i], H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "file_space_id is not a dataspace ID")
|
||||
} /* end else */
|
||||
|
||||
/* Get dataspace for memory buffer */
|
||||
if (H5S_ALL == mem_space_id[i])
|
||||
dinfo[i].mem_space = dinfo[i].file_space;
|
||||
else if (H5S_BLOCK == mem_space_id[i]) {
|
||||
hsize_t nelmts; /* # of selected elements in file */
|
||||
|
||||
/* Get the # of elements selected */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(dinfo[i].file_space);
|
||||
|
||||
/* Check for any elements */
|
||||
if (nelmts > 0) {
|
||||
/* Create a 1-D dataspace of the same # of elements */
|
||||
if (NULL == (dinfo[i].mem_space = H5S_create_simple(1, &nelmts, NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create simple memory dataspace")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Create a NULL dataspace of the same # of elements */
|
||||
if (NULL == (dinfo[i].mem_space = H5S_create(H5S_NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create NULL memory dataspace")
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else if (H5S_PLIST == mem_space_id[i])
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_PLIST is not allowed for memory dataspace")
|
||||
else {
|
||||
/* Get the dataspace pointer */
|
||||
if (NULL == (dinfo[i].mem_space = (H5S_t *)H5I_object_verify(mem_space_id[i], H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "mem_space_id is not a dataspace ID")
|
||||
} /* end else */
|
||||
|
||||
/* Check for valid selections */
|
||||
if (H5S_SELECT_VALID(dinfo[i].file_space) != TRUE)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
|
||||
"selection + offset not within extent for file dataspace")
|
||||
if (H5S_SELECT_VALID(dinfo[i].mem_space) != TRUE)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
|
||||
"selection + offset not within extent for memory dataspace")
|
||||
|
||||
/* Set up buf */
|
||||
dinfo[i].buf = buf[i];
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__native_dataset_io_setup() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL__native_dataset_io_cleanup
|
||||
*
|
||||
* Purpose: Frees memory allocated by H5VL__native_dataset_io_setup()
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL__native_dataset_io_cleanup(size_t count, hid_t mem_space_id[], hid_t file_space_id[],
|
||||
H5D_dset_io_info_t *dinfo)
|
||||
{
|
||||
size_t i;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Sanity checks */
|
||||
HDassert(dset);
|
||||
HDassert(file_space && NULL == *file_space);
|
||||
HDassert(mem_space && NULL == *mem_space);
|
||||
HDassert(dinfo);
|
||||
|
||||
/* Set up file dataspace */
|
||||
if (H5S_ALL == file_space_id)
|
||||
/* Use dataspace for dataset */
|
||||
*file_space = dset->shared->space;
|
||||
else if (H5S_BLOCK == file_space_id)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_BLOCK is not allowed for file dataspace")
|
||||
else if (H5S_PLIST == file_space_id) {
|
||||
H5P_genplist_t *plist; /* Property list pointer */
|
||||
H5S_t *space; /* Dataspace to hold selection */
|
||||
/* Iterate over datasets */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Free memory dataspace if it was created. Use HDONE_ERROR in this function so we always
|
||||
* try to free everything we can. */
|
||||
if (H5S_BLOCK == mem_space_id[i] && dinfo[i].mem_space)
|
||||
if (H5S_close(dinfo[i].mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release temporary memory dataspace for H5S_BLOCK")
|
||||
|
||||
/* Get the plist structure */
|
||||
if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADID, FAIL, "bad dataset transfer property list")
|
||||
/* Reset file dataspace selection if it was copied from the property list */
|
||||
if (H5S_PLIST == file_space_id[i] && dinfo[i].file_space)
|
||||
if (H5S_select_all(dinfo[i].file_space, TRUE) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release file dataspace selection for H5S_PLIST")
|
||||
}
|
||||
|
||||
/* See if a dataset I/O selection is already set, and free it if it is */
|
||||
if (H5P_peek(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error getting dataset I/O selection")
|
||||
|
||||
/* Use dataspace for dataset */
|
||||
*file_space = dset->shared->space;
|
||||
|
||||
/* Copy, but share, selection from property list to dataset's dataspace */
|
||||
if (H5S_SELECT_COPY(*file_space, space, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataset I/O selection")
|
||||
} /* end else-if */
|
||||
else {
|
||||
/* Get the dataspace pointer */
|
||||
if (NULL == (*file_space = (H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "file_space_id is not a dataspace ID")
|
||||
} /* end else */
|
||||
|
||||
/* Get dataspace for memory buffer */
|
||||
if (H5S_ALL == mem_space_id)
|
||||
*mem_space = *file_space;
|
||||
else if (H5S_BLOCK == mem_space_id) {
|
||||
hsize_t nelmts; /* # of selected elements in file */
|
||||
|
||||
/* Get the # of elements selected */
|
||||
nelmts = H5S_GET_SELECT_NPOINTS(*file_space);
|
||||
|
||||
/* Check for any elements */
|
||||
if (nelmts > 0) {
|
||||
/* Create a 1-D dataspace of the same # of elements */
|
||||
if (NULL == (*mem_space = H5S_create_simple(1, &nelmts, NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create simple memory dataspace")
|
||||
} /* end if */
|
||||
else {
|
||||
/* Create a NULL dataspace of the same # of elements */
|
||||
if (NULL == (*mem_space = H5S_create(H5S_NULL)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create NULL memory dataspace")
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
else if (H5S_PLIST == mem_space_id)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "H5S_PLIST is not allowed for memory dataspace")
|
||||
else {
|
||||
/* Get the dataspace pointer */
|
||||
if (NULL == (*mem_space = (H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "mem_space_id is not a dataspace ID")
|
||||
} /* end else */
|
||||
|
||||
/* Check for valid selections */
|
||||
if (H5S_SELECT_VALID(*file_space) != TRUE)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
|
||||
"selection + offset not within extent for file dataspace")
|
||||
if (H5S_SELECT_VALID(*mem_space) != TRUE)
|
||||
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL,
|
||||
"selection + offset not within extent for memory dataspace")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__native_dataset_io_setup() */
|
||||
} /* end H5VL__native_dataset_io_cleanup() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5VL__native_dataset_create
|
||||
@@ -267,43 +334,39 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL__native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, void *buf, void H5_ATTR_UNUSED **req)
|
||||
H5VL__native_dataset_read(size_t count, void *obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void H5_ATTR_UNUSED **req)
|
||||
{
|
||||
H5D_t *dset = (H5D_t *)obj;
|
||||
H5S_t *mem_space = NULL;
|
||||
H5S_t *file_space = NULL;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_dset_io_info_t dinfo_local;
|
||||
H5D_dset_io_info_t *dinfo = &dinfo_local;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* Check arguments */
|
||||
if (NULL == dset->oloc.file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file")
|
||||
/* Allocate dataset info array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (dinfo = (H5D_dset_io_info_t *)H5MM_malloc(count * sizeof(H5D_dset_io_info_t))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dset info array buffer")
|
||||
|
||||
/* Get file & memory dataspaces */
|
||||
if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) <
|
||||
0)
|
||||
if (H5VL__native_dataset_io_setup(count, obj, mem_type_id, mem_space_id, file_space_id, dxpl_id,
|
||||
(H5_flexible_const_ptr_t *)buf, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces")
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Read raw data */
|
||||
if (H5D__read(dset, mem_type_id, mem_space, file_space, buf /*out*/) < 0)
|
||||
/* Read raw data. Call H5D__read directly in single dset case. */
|
||||
if (H5D__read(count, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
|
||||
|
||||
done:
|
||||
/* Clean up */
|
||||
if (H5S_BLOCK == mem_space_id && mem_space) {
|
||||
if (H5S_close(mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release temporary memory dataspace for H5S_BLOCK")
|
||||
} /* end if */
|
||||
else if (H5S_PLIST == file_space_id && file_space)
|
||||
if (H5S_select_all(file_space, TRUE) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release file dataspace selection for H5S_PLIST")
|
||||
if (H5VL__native_dataset_io_cleanup(count, mem_space_id, file_space_id, dinfo) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release dataset info")
|
||||
|
||||
if (dinfo != &dinfo_local)
|
||||
H5MM_xfree(dinfo);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__native_dataset_read() */
|
||||
@@ -318,43 +381,39 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5VL__native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t dxpl_id, const void *buf, void H5_ATTR_UNUSED **req)
|
||||
H5VL__native_dataset_write(size_t count, void *obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void H5_ATTR_UNUSED **req)
|
||||
{
|
||||
H5D_t *dset = (H5D_t *)obj;
|
||||
H5S_t *mem_space = NULL;
|
||||
H5S_t *file_space = NULL;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5D_dset_io_info_t dinfo_local;
|
||||
H5D_dset_io_info_t *dinfo = &dinfo_local;
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_PACKAGE
|
||||
|
||||
/* check arguments */
|
||||
if (NULL == dset->oloc.file)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dataset is not associated with a file")
|
||||
/* Allocate dataset info array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (dinfo = (H5D_dset_io_info_t *)H5MM_malloc(count * sizeof(H5D_dset_io_info_t))))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "couldn't allocate dset info array buffer")
|
||||
|
||||
/* Get file & memory dataspaces */
|
||||
if (H5VL__native_dataset_io_setup(dset, dxpl_id, file_space_id, mem_space_id, &file_space, &mem_space) <
|
||||
0)
|
||||
if (H5VL__native_dataset_io_setup(count, obj, mem_type_id, mem_space_id, file_space_id, dxpl_id,
|
||||
(H5_flexible_const_ptr_t *)buf, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set up file and memory dataspaces")
|
||||
|
||||
/* Set DXPL for operation */
|
||||
H5CX_set_dxpl(dxpl_id);
|
||||
|
||||
/* Write the data */
|
||||
if (H5D__write(dset, mem_type_id, mem_space, file_space, buf) < 0)
|
||||
/* Write raw data. Call H5D__write directly in single dset case. */
|
||||
if (H5D__write(count, dinfo) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
|
||||
|
||||
done:
|
||||
/* Clean up */
|
||||
if (H5S_BLOCK == mem_space_id && mem_space) {
|
||||
if (H5S_close(mem_space) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release temporary memory dataspace for H5S_BLOCK")
|
||||
} /* end if */
|
||||
else if (H5S_PLIST == file_space_id && file_space)
|
||||
if (H5S_select_all(file_space, TRUE) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL,
|
||||
"unable to release file dataspace selection for H5S_PLIST")
|
||||
if (H5VL__native_dataset_io_cleanup(count, mem_space_id, file_space_id, dinfo) < 0)
|
||||
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release dataset info")
|
||||
|
||||
if (dinfo != &dinfo_local)
|
||||
H5MM_xfree(dinfo);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5VL__native_dataset_write() */
|
||||
|
||||
@@ -61,10 +61,10 @@ H5_DLL void *H5VL__native_dataset_create(void *obj, const H5VL_loc_params_t *lo
|
||||
hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL void *H5VL__native_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
|
||||
hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, void *buf, void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_read(size_t count, void *obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, void *buf[], void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_write(size_t count, void *obj[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t dxpl_id, const void *buf[], void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req);
|
||||
H5_DLL herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_args_t *args, hid_t dxpl_id,
|
||||
void **req);
|
||||
|
||||
+62
-19
@@ -121,11 +121,12 @@ static void *H5VL_pass_through_dataset_create(void *obj, const H5VL_loc_params_
|
||||
hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
static void *H5VL_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
|
||||
hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
static herr_t H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, void *buf, void **req);
|
||||
static herr_t H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t plist_id, const void *buf,
|
||||
void **req);
|
||||
static herr_t H5VL_pass_through_dataset_read(size_t count, void *dset[], hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t plist_id,
|
||||
void *buf[], void **req);
|
||||
static herr_t H5VL_pass_through_dataset_write(size_t count, void *dset[], hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t plist_id,
|
||||
const void *buf[], void **req);
|
||||
static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id,
|
||||
void **req);
|
||||
static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id,
|
||||
@@ -1197,22 +1198,43 @@ H5VL_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, c
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t plist_id, void *buf, void **req)
|
||||
H5VL_pass_through_dataset_read(size_t count, void *dset[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t plist_id, void *buf[], void **req)
|
||||
{
|
||||
H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
|
||||
herr_t ret_value;
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value;
|
||||
|
||||
#ifdef ENABLE_PASSTHRU_LOGGING
|
||||
printf("------- PASS THROUGH VOL DATASET Read\n");
|
||||
#endif
|
||||
|
||||
ret_value = H5VLdataset_read(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id,
|
||||
plist_id, buf, req);
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)malloc(count * sizeof(void *))))
|
||||
return -1;
|
||||
|
||||
/* Build obj array */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Get the object */
|
||||
obj[i] = ((H5VL_pass_through_t *)dset[i])->under_object;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (((H5VL_pass_through_t *)dset[i])->under_vol_id != ((H5VL_pass_through_t *)dset[0])->under_vol_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret_value = H5VLdataset_read(count, obj, ((H5VL_pass_through_t *)dset[0])->under_vol_id, mem_type_id,
|
||||
mem_space_id, file_space_id, plist_id, buf, req);
|
||||
|
||||
/* Check for async request */
|
||||
if (req && *req)
|
||||
*req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
|
||||
*req = H5VL_pass_through_new_obj(*req, ((H5VL_pass_through_t *)dset[0])->under_vol_id);
|
||||
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
free(obj);
|
||||
|
||||
return ret_value;
|
||||
} /* end H5VL_pass_through_dataset_read() */
|
||||
@@ -1228,22 +1250,43 @@ H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
|
||||
hid_t plist_id, const void *buf, void **req)
|
||||
H5VL_pass_through_dataset_write(size_t count, void *dset[], hid_t mem_type_id[], hid_t mem_space_id[],
|
||||
hid_t file_space_id[], hid_t plist_id, const void *buf[], void **req)
|
||||
{
|
||||
H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
|
||||
herr_t ret_value;
|
||||
void *obj_local; /* Local buffer for obj */
|
||||
void **obj = &obj_local; /* Array of object pointers */
|
||||
size_t i; /* Local index variable */
|
||||
herr_t ret_value;
|
||||
|
||||
#ifdef ENABLE_PASSTHRU_LOGGING
|
||||
printf("------- PASS THROUGH VOL DATASET Write\n");
|
||||
#endif
|
||||
|
||||
ret_value = H5VLdataset_write(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id,
|
||||
plist_id, buf, req);
|
||||
/* Allocate obj array if necessary */
|
||||
if (count > 1)
|
||||
if (NULL == (obj = (void **)malloc(count * sizeof(void *))))
|
||||
return -1;
|
||||
|
||||
/* Build obj array */
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Get the object */
|
||||
obj[i] = ((H5VL_pass_through_t *)dset[i])->under_object;
|
||||
|
||||
/* Make sure the class matches */
|
||||
if (((H5VL_pass_through_t *)dset[i])->under_vol_id != ((H5VL_pass_through_t *)dset[0])->under_vol_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret_value = H5VLdataset_write(count, obj, ((H5VL_pass_through_t *)dset[0])->under_vol_id, mem_type_id,
|
||||
mem_space_id, file_space_id, plist_id, buf, req);
|
||||
|
||||
/* Check for async request */
|
||||
if (req && *req)
|
||||
*req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
|
||||
*req = H5VL_pass_through_new_obj(*req, ((H5VL_pass_through_t *)dset[0])->under_vol_id);
|
||||
|
||||
/* Free memory */
|
||||
if (obj != &obj_local)
|
||||
free(obj);
|
||||
|
||||
return ret_value;
|
||||
} /* end H5VL_pass_through_dataset_write() */
|
||||
|
||||
+12
-4
@@ -177,10 +177,18 @@ H5_DLL void *H5VL_dataset_create(const H5VL_object_t *vol_obj, const H5VL_loc_p
|
||||
hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL void *H5VL_dataset_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params,
|
||||
const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
|
||||
H5_DLL herr_t H5VL_dataset_read(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, void *buf, void **req);
|
||||
H5_DLL herr_t H5VL_dataset_write(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id,
|
||||
hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req);
|
||||
H5_DLL herr_t H5VL_dataset_read(size_t count, const H5VL_object_t *vol_obj[], hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id, void *buf[],
|
||||
void **req);
|
||||
H5_DLL herr_t H5VL_dataset_read_direct(size_t count, void *obj[], H5VL_t *connector, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
|
||||
void *buf[], void **req);
|
||||
H5_DLL herr_t H5VL_dataset_write(size_t count, const H5VL_object_t *vol_obj[], hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
|
||||
const void *buf[], void **req);
|
||||
H5_DLL herr_t H5VL_dataset_write_direct(size_t count, void *obj[], H5VL_t *connector, hid_t mem_type_id[],
|
||||
hid_t mem_space_id[], hid_t file_space_id[], hid_t dxpl_id,
|
||||
const void *buf[], void **req);
|
||||
H5_DLL herr_t H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id,
|
||||
void **req);
|
||||
H5_DLL herr_t H5VL_dataset_specific(const H5VL_object_t *cls, H5VL_dataset_specific_args_t *args,
|
||||
|
||||
+3
-1
@@ -2512,7 +2512,9 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props);
|
||||
|
||||
/* Union for const/non-const pointer for use by functions that manipulate
|
||||
* pointers but do not write to their targets or return pointers to const
|
||||
* specified locations. This helps us avoid compiler warnings. */
|
||||
* specified locations. Also used for I/O functions that work for read and
|
||||
* write - these functions are expected to never write to these locations in the
|
||||
* write case. This helps us avoid compiler warnings. */
|
||||
typedef union {
|
||||
void *vp;
|
||||
const void *cvp;
|
||||
|
||||
@@ -339,6 +339,7 @@ set (H5_TESTS
|
||||
dsets
|
||||
chunk_info # compression lib link
|
||||
cmpd_dset
|
||||
mdset
|
||||
filter_fail
|
||||
extend
|
||||
direct_chunk # compression lib link
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@ TEST_PROG= testhdf5 \
|
||||
cache cache_api cache_image cache_tagging lheap ohdr \
|
||||
stab gheap evict_on_close farray earray btree2 fheap \
|
||||
accum hyperslab istore bittests dt_arith page_buffer \
|
||||
dtypes dsets chunk_info cmpd_dset cmpd_dtransform filter_fail extend direct_chunk \
|
||||
dtypes dsets chunk_info cmpd_dset mdset cmpd_dtransform filter_fail extend direct_chunk \
|
||||
external efc objcopy objcopy_ref links unlink twriteorder big mtime \
|
||||
fillval mount \
|
||||
flush1 flush2 app_ref enum set_extent ttsafe enc_dec_plist \
|
||||
@@ -184,7 +184,7 @@ flush2.chkexe_: flush1.chkexe_
|
||||
# specifying a file prefix or low-level driver. Changing the file
|
||||
# prefix or low-level driver with environment variables will influence
|
||||
# the temporary file name in ways that the makefile is not aware of.
|
||||
CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offset.h5 \
|
||||
CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 mdset.h5 compact_dataset.h5 dataset.h5 dset_offset.h5 \
|
||||
max_compact_dataset.h5 simple.h5 set_local.h5 random_chunks.h5 \
|
||||
huge_chunks.h5 chunk_cache.h5 big_chunk.h5 chunk_fast.h5 chunk_expand.h5 \
|
||||
chunk_fixed.h5 copy_dcpl_newfile.h5 partial_chunks.h5 layout_extend.h5 \
|
||||
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Programmer: Neil Fortner
|
||||
* March 10, 2014
|
||||
*
|
||||
* Purpose: Test H5Dwrite_multi() and H5Dread_multi using randomized
|
||||
* parameters. Also tests H5Dwrite() and H5Dread() using a similar
|
||||
* method.
|
||||
*/
|
||||
|
||||
#include "h5test.h"
|
||||
|
||||
#define NAME_BUF_SIZE 1024
|
||||
#define MAX_DSETS 6
|
||||
#define MAX_DSET_X 10
|
||||
#define MAX_DSET_Y 10
|
||||
#define MAX_CHUNK_X 4
|
||||
#define MAX_CHUNK_Y 4
|
||||
#define MAX_HS_X 6
|
||||
#define MAX_HS_Y 6
|
||||
#define MAX_HS 3
|
||||
#define MAX_POINTS 6
|
||||
#define OPS_PER_FILE 50
|
||||
#define DSET_MAX_NAME_LEN 8
|
||||
#define EXT_FILENAME "mdset_ext.h5"
|
||||
#define SOURCE_DS_NAME "vds_source"
|
||||
|
||||
/* Option flags */
|
||||
#define MDSET_FLAG_CHUNK 0x01u
|
||||
#define MDSET_FLAG_MLAYOUT 0x02u
|
||||
#define MDSET_FLAG_SHAPESAME 0x04u
|
||||
#define MDSET_FLAG_MDSET 0x08u
|
||||
#define MDSET_FLAG_TCONV 0x10u
|
||||
#define MDSET_FLAG_FILTER 0x20u
|
||||
#define MDSET_ALL_FLAGS \
|
||||
(MDSET_FLAG_CHUNK | MDSET_FLAG_MLAYOUT | MDSET_FLAG_SHAPESAME | MDSET_FLAG_MDSET | MDSET_FLAG_TCONV | \
|
||||
MDSET_FLAG_FILTER)
|
||||
|
||||
const char *FILENAME[] = {"mdset", "mdset1", "mdset2", NULL};
|
||||
|
||||
/* Names for datasets */
|
||||
char dset_name[MAX_DSETS][DSET_MAX_NAME_LEN];
|
||||
|
||||
/* Whether these filters are available */
|
||||
htri_t deflate_avail = FALSE;
|
||||
htri_t fletcher32_avail = FALSE;
|
||||
|
||||
static int
|
||||
test_mdset_location(hid_t fapl_id)
|
||||
{
|
||||
hid_t file_id1, file_id2;
|
||||
herr_t ret;
|
||||
hid_t dset_ids[2];
|
||||
hid_t mem_type_ids[2];
|
||||
hid_t mem_space_ids[2];
|
||||
hid_t file_space_ids[2];
|
||||
void *rbufs[2];
|
||||
const void *wbufs[2];
|
||||
hsize_t dset_dims[2];
|
||||
int *buf = NULL;
|
||||
char filename1[NAME_BUF_SIZE];
|
||||
char filename2[NAME_BUF_SIZE];
|
||||
|
||||
TESTING("mdset location");
|
||||
|
||||
h5_fixname(FILENAME[1], fapl_id, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[2], fapl_id, filename2, sizeof filename2);
|
||||
|
||||
/* Create files */
|
||||
if ((file_id1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
||||
TEST_ERROR;
|
||||
if ((file_id2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
if (NULL == (buf = (int *)HDcalloc(2 * MAX_DSET_X * MAX_DSET_Y, sizeof(int))))
|
||||
TEST_ERROR;
|
||||
|
||||
/* Generate memory dataspace */
|
||||
dset_dims[0] = MAX_DSET_X;
|
||||
dset_dims[1] = MAX_DSET_Y;
|
||||
if ((file_space_ids[0] = H5Screate_simple(2, dset_dims, NULL)) < 0)
|
||||
TEST_ERROR;
|
||||
if ((file_space_ids[1] = H5Screate_simple(2, dset_dims, NULL)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
mem_space_ids[0] = H5S_ALL;
|
||||
mem_space_ids[1] = H5S_ALL;
|
||||
|
||||
mem_type_ids[0] = H5T_NATIVE_UINT;
|
||||
mem_type_ids[1] = H5T_NATIVE_UINT;
|
||||
|
||||
if ((dset_ids[0] = H5Dcreate2(file_id1, dset_name[0], H5T_NATIVE_UINT, file_space_ids[0], H5P_DEFAULT,
|
||||
H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
if ((dset_ids[1] = H5Dcreate2(file_id2, dset_name[1], H5T_NATIVE_UINT, file_space_ids[1], H5P_DEFAULT,
|
||||
H5P_DEFAULT, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
wbufs[0] = buf;
|
||||
wbufs[1] = buf + (MAX_DSET_X * MAX_DSET_Y);
|
||||
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
ret = H5Dwrite_multi(2, dset_ids, mem_type_ids, mem_space_ids, file_space_ids, H5P_DEFAULT, wbufs);
|
||||
}
|
||||
H5E_END_TRY
|
||||
|
||||
if (ret >= 0) {
|
||||
fprintf(stderr, "H5Dmulti_write with datasets in multiple files should fail.\n");
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
rbufs[0] = buf;
|
||||
rbufs[1] = buf + (MAX_DSET_X * MAX_DSET_Y);
|
||||
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
ret = H5Dread_multi(2, dset_ids, mem_type_ids, mem_space_ids, file_space_ids, H5P_DEFAULT, rbufs);
|
||||
}
|
||||
H5E_END_TRY
|
||||
|
||||
if (ret >= 0) {
|
||||
fprintf(stderr, "H5Dmulti_read with datasets in multiple files should fail.\n");
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
H5Dclose(dset_ids[0]);
|
||||
H5Sclose(file_space_ids[0]);
|
||||
H5Dclose(dset_ids[1]);
|
||||
H5Sclose(file_space_ids[1]);
|
||||
H5Fclose(file_id1);
|
||||
H5Fclose(file_id2);
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (buf)
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_mdset
|
||||
*
|
||||
* Purpose: Test randomized I/O using one or more datasets. Creates a
|
||||
* file, runs OPS_PER_FILE read or write operations verifying
|
||||
* that reads return the expected data, then closes the file.
|
||||
* Runs the test with a new file niter times.
|
||||
*
|
||||
* The operations can use either hyperslab or point
|
||||
* selections. Options are available for chunked or
|
||||
* contiguous layout, use of multiple datasets and H5D*_multi
|
||||
* calls, and use of the "shapesame" algorithm code path. To
|
||||
* avoid the shapesame path when that option is not set, this
|
||||
* function simply adds a dimension to the memory buffer in a
|
||||
* way that the shapesame code is not designed to handle.
|
||||
*
|
||||
* Return: Number of errors
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Monday, March 10, 2014
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_mdset(size_t niter, unsigned flags, hid_t fapl_id)
|
||||
{
|
||||
hid_t dset_ids[MAX_DSETS];
|
||||
hid_t mem_type_ids[MAX_DSETS];
|
||||
hid_t mem_space_ids[MAX_DSETS];
|
||||
hid_t file_space_ids[MAX_DSETS];
|
||||
void *rbufs[MAX_DSETS];
|
||||
const void *wbufs[MAX_DSETS];
|
||||
size_t max_dsets;
|
||||
size_t buf_size;
|
||||
size_t ndsets;
|
||||
hid_t file_id = -1;
|
||||
hid_t dcpl_id[MAX_DSETS];
|
||||
hsize_t dset_dims[MAX_DSETS][3];
|
||||
hsize_t chunk_dims[2];
|
||||
hsize_t max_dims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
|
||||
unsigned *rbuf = NULL;
|
||||
unsigned *rbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *erbuf = NULL;
|
||||
unsigned *erbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *wbuf = NULL;
|
||||
unsigned *wbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *efbuf = NULL;
|
||||
unsigned *efbufi[MAX_DSETS][MAX_DSET_X];
|
||||
hbool_t do_read;
|
||||
hsize_t start[3];
|
||||
hsize_t count[3];
|
||||
hsize_t points[3 * MAX_POINTS];
|
||||
char filename[NAME_BUF_SIZE];
|
||||
size_t i, j, k, l, m, n;
|
||||
|
||||
TESTING("random I/O");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
|
||||
|
||||
/* Calculate maximum number of datasets */
|
||||
max_dsets = (flags & MDSET_FLAG_MDSET) ? MAX_DSETS : 1;
|
||||
|
||||
/* Calculate buffer size */
|
||||
buf_size = max_dsets * MAX_DSET_X * MAX_DSET_Y * sizeof(unsigned);
|
||||
|
||||
/* Initialize dcpl_id array */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
dcpl_id[i] = -1;
|
||||
|
||||
/* Allocate buffers */
|
||||
if (NULL == (rbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
TEST_ERROR;
|
||||
if (NULL == (erbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
TEST_ERROR;
|
||||
if (NULL == (wbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
TEST_ERROR;
|
||||
if (NULL == (efbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
TEST_ERROR;
|
||||
|
||||
/* Initialize buffer indices */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
for (j = 0; j < MAX_DSET_X; j++) {
|
||||
rbufi[i][j] = rbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
erbufi[i][j] = erbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
wbufi[i][j] = wbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
efbufi[i][j] = efbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
} /* end for */
|
||||
|
||||
/* Initialize 3rd dimension information (for tricking library into using
|
||||
* non-"shapesame" code */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
dset_dims[i][2] = 1;
|
||||
start[2] = 0;
|
||||
count[2] = 1;
|
||||
|
||||
/* Initialize IDs */
|
||||
for (i = 0; i < max_dsets; i++) {
|
||||
dset_ids[i] = -1;
|
||||
file_space_ids[i] = -1;
|
||||
mem_type_ids[i] = H5T_NATIVE_UINT;
|
||||
mem_space_ids[i] = -1;
|
||||
} /* end for */
|
||||
|
||||
/* Generate memory dataspace */
|
||||
dset_dims[0][0] = MAX_DSET_X;
|
||||
dset_dims[0][1] = MAX_DSET_Y;
|
||||
if ((mem_space_ids[0] = H5Screate_simple((flags & MDSET_FLAG_SHAPESAME) ? 2 : 3, dset_dims[0], NULL)) < 0)
|
||||
TEST_ERROR;
|
||||
for (i = 1; i < max_dsets; i++)
|
||||
if ((mem_space_ids[i] = H5Scopy(mem_space_ids[0])) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Create dcpl 0 */
|
||||
if ((dcpl_id[0] = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Set fill time to alloc, and alloc time to early (so we always know
|
||||
* what's in the file) */
|
||||
if (H5Pset_fill_time(dcpl_id[0], H5D_FILL_TIME_ALLOC) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Pset_alloc_time(dcpl_id[0], H5D_ALLOC_TIME_EARLY) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Set filters if requested */
|
||||
if (flags & MDSET_FLAG_FILTER) {
|
||||
if (fletcher32_avail)
|
||||
if (H5Pset_fletcher32(dcpl_id[0]) < 0)
|
||||
TEST_ERROR;
|
||||
if (deflate_avail)
|
||||
if (H5Pset_deflate(dcpl_id[0], 1) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
/* Copy dcpl 0 to other slots in dcpl_id array */
|
||||
for (i = 1; i < MAX_DSETS; i++)
|
||||
if ((dcpl_id[i] = H5Pcopy(dcpl_id[0])) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* If this is a multi layout run, set up different filters and layouts. Chunked and virtual
|
||||
* datasets will be set every iteration (with different dims), and contiguous is the default, so
|
||||
* no need to set either of those. */
|
||||
if (flags & MDSET_FLAG_MLAYOUT) {
|
||||
/* Set filters on dataset 2 */
|
||||
if (fletcher32_avail)
|
||||
if (H5Pset_fletcher32(dcpl_id[2]) < 0)
|
||||
TEST_ERROR;
|
||||
if (deflate_avail)
|
||||
if (H5Pset_deflate(dcpl_id[2], 1) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Dataset 3 is compact */
|
||||
if (H5Pset_layout(dcpl_id[3], H5D_COMPACT) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Dataset 4 is external */
|
||||
if (H5Pset_external(dcpl_id[4], EXT_FILENAME, 0, H5F_UNLIMITED) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < niter; i++) {
|
||||
/* Determine number of datasets */
|
||||
ndsets = (flags & MDSET_FLAG_MLAYOUT) ? 6
|
||||
: (flags & MDSET_FLAG_MDSET) ? (size_t)((size_t)HDrandom() % max_dsets) + 1
|
||||
: 1;
|
||||
|
||||
/* Create file */
|
||||
if ((file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Create datasets */
|
||||
for (j = 0; j < ndsets; j++) {
|
||||
hid_t source_dset;
|
||||
|
||||
hbool_t use_chunk =
|
||||
(flags & MDSET_FLAG_CHUNK) || ((flags & MDSET_FLAG_MLAYOUT) && (j == 1 || j == 2));
|
||||
|
||||
/* Generate file dataspace */
|
||||
dset_dims[j][0] = (hsize_t)((HDrandom() % MAX_DSET_X) + 1);
|
||||
dset_dims[j][1] = (hsize_t)((HDrandom() % MAX_DSET_Y) + 1);
|
||||
if ((file_space_ids[j] = H5Screate_simple(2, dset_dims[j], use_chunk ? max_dims : NULL)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Generate chunk if called for by configuration (multi layout uses chunked for datasets
|
||||
* 1 and 2) */
|
||||
if (use_chunk) {
|
||||
chunk_dims[0] = (hsize_t)((HDrandom() % MAX_CHUNK_X) + 1);
|
||||
chunk_dims[1] = (hsize_t)((HDrandom() % MAX_CHUNK_Y) + 1);
|
||||
if (H5Pset_chunk(dcpl_id[j], 2, chunk_dims) < 0)
|
||||
TEST_ERROR;
|
||||
} /* end if */
|
||||
else if ((flags & MDSET_FLAG_CHUNK) && j == 5) {
|
||||
/* Dataset 5 is virtual in multi layout case */
|
||||
/* Set to contiguous to clear previous VDS settings */
|
||||
if (H5Pset_layout(dcpl_id[j], H5D_CONTIGUOUS) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Set virtual dataset layout, ALL<>ALL mapping */
|
||||
if (H5Pset_virtual(dcpl_id[j], file_space_ids[j], ".", SOURCE_DS_NAME, file_space_ids[j]) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
|
||||
/* Create dataset */
|
||||
/* If MDSET_FLAG_TCONV is set, use a different datatype with 50% probability, so
|
||||
* some datasets require type conversion and others do not */
|
||||
if ((dset_ids[j] = H5Dcreate2(file_id, dset_name[j],
|
||||
(flags & MDSET_FLAG_TCONV && HDrandom() % 2) ? H5T_NATIVE_LONG
|
||||
: H5T_NATIVE_UINT,
|
||||
file_space_ids[j], H5P_DEFAULT, dcpl_id[j], H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Create virtual source dataset if necessary. Use dcpl_id[0] for a contiguous dataset
|
||||
*/
|
||||
if ((flags & MDSET_FLAG_MLAYOUT) && (j == 6)) {
|
||||
if ((source_dset = H5Dcreate2(file_id, SOURCE_DS_NAME,
|
||||
(flags & MDSET_FLAG_TCONV && HDrandom() % 2) ? H5T_NATIVE_LONG
|
||||
: H5T_NATIVE_UINT,
|
||||
file_space_ids[j], H5P_DEFAULT, dcpl_id[0], H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Dclose(source_dset) < 0)
|
||||
TEST_ERROR;
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
/* Initialize read buffer and expected read buffer */
|
||||
(void)HDmemset(rbuf, 0, buf_size);
|
||||
(void)HDmemset(erbuf, 0, buf_size);
|
||||
|
||||
/* Initialize write buffer */
|
||||
for (j = 0; j < max_dsets; j++)
|
||||
for (k = 0; k < MAX_DSET_X; k++)
|
||||
for (l = 0; l < MAX_DSET_Y; l++)
|
||||
wbufi[j][k][l] = (unsigned)((j * MAX_DSET_X * MAX_DSET_Y) + (k * MAX_DSET_Y) + l);
|
||||
|
||||
/* Initialize expected file buffer */
|
||||
(void)HDmemset(efbuf, 0, buf_size);
|
||||
|
||||
/* Perform read/write operations */
|
||||
for (j = 0; j < OPS_PER_FILE; j++) {
|
||||
/* Decide whether to read or write. Can't read on the first iteration with external
|
||||
* layout because the write is needed to create the external file. */
|
||||
do_read = (j == 0 && flags & MDSET_FLAG_MLAYOUT) ? FALSE : (hbool_t)(HDrandom() % 2);
|
||||
|
||||
/* Loop over datasets */
|
||||
for (k = 0; k < ndsets; k++) {
|
||||
int sel_type;
|
||||
|
||||
/* Reset selection */
|
||||
if (H5Sselect_none(mem_space_ids[k]) < 0)
|
||||
TEST_ERROR;
|
||||
if (H5Sselect_none(file_space_ids[k]) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Decide whether to do a hyperslab, point, or all selection */
|
||||
sel_type = HDrandom() % 3;
|
||||
if (sel_type == 0) {
|
||||
/* Hyperslab */
|
||||
size_t nhs = (size_t)((HDrandom() % MAX_HS) + 1); /* Number of hyperslabs */
|
||||
size_t max_hs_x = (MAX_HS_X <= dset_dims[k][0])
|
||||
? MAX_HS_X
|
||||
: dset_dims[k][0]; /* Determine maximum hyperslab size in X */
|
||||
size_t max_hs_y = (MAX_HS_Y <= dset_dims[k][1])
|
||||
? MAX_HS_Y
|
||||
: dset_dims[k][1]; /* Determine maximum hyperslab size in Y */
|
||||
|
||||
for (l = 0; l < nhs; l++) {
|
||||
/* Generate hyperslab */
|
||||
count[0] = (hsize_t)(((hsize_t)HDrandom() % max_hs_x) + 1);
|
||||
count[1] = (hsize_t)(((hsize_t)HDrandom() % max_hs_y) + 1);
|
||||
start[0] = (count[0] == dset_dims[k][0])
|
||||
? 0
|
||||
: (hsize_t)HDrandom() % (dset_dims[k][0] - count[0] + 1);
|
||||
start[1] = (count[1] == dset_dims[k][1])
|
||||
? 0
|
||||
: (hsize_t)HDrandom() % (dset_dims[k][1] - count[1] + 1);
|
||||
|
||||
/* Select hyperslab */
|
||||
if (H5Sselect_hyperslab(mem_space_ids[k], H5S_SELECT_OR, start, NULL, count, NULL) <
|
||||
0)
|
||||
TEST_ERROR;
|
||||
if (H5Sselect_hyperslab(file_space_ids[k], H5S_SELECT_OR, start, NULL, count, NULL) <
|
||||
0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Update expected buffers */
|
||||
if (do_read) {
|
||||
for (m = start[0]; m < (start[0] + count[0]); m++)
|
||||
for (n = start[1]; n < (start[1] + count[1]); n++)
|
||||
erbufi[k][m][n] = efbufi[k][m][n];
|
||||
} /* end if */
|
||||
else
|
||||
for (m = start[0]; m < (start[0] + count[0]); m++)
|
||||
for (n = start[1]; n < (start[1] + count[1]); n++)
|
||||
efbufi[k][m][n] = wbufi[k][m][n];
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
else if (sel_type == 1) {
|
||||
/* Point selection */
|
||||
size_t npoints = (size_t)(((size_t)HDrandom() % MAX_POINTS) + 1); /* Number of points */
|
||||
|
||||
/* Generate points */
|
||||
for (l = 0; l < npoints; l++) {
|
||||
points[2 * l] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][0]);
|
||||
points[(2 * l) + 1] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][1]);
|
||||
} /* end for */
|
||||
|
||||
/* Select points in file */
|
||||
if (H5Sselect_elements(file_space_ids[k], H5S_SELECT_APPEND, npoints, points) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Update expected buffers */
|
||||
if (do_read) {
|
||||
for (l = 0; l < npoints; l++)
|
||||
erbufi[k][points[2 * l]][points[(2 * l) + 1]] =
|
||||
efbufi[k][points[2 * l]][points[(2 * l) + 1]];
|
||||
} /* end if */
|
||||
else
|
||||
for (l = 0; l < npoints; l++)
|
||||
efbufi[k][points[2 * l]][points[(2 * l) + 1]] =
|
||||
wbufi[k][points[2 * l]][points[(2 * l) + 1]];
|
||||
|
||||
/* Convert to 3D for memory selection, if not using
|
||||
* "shapesame" */
|
||||
if (!(flags & MDSET_FLAG_SHAPESAME)) {
|
||||
for (l = npoints - 1; l > 0; l--) {
|
||||
points[(3 * l) + 2] = 0;
|
||||
points[(3 * l) + 1] = points[(2 * l) + 1];
|
||||
points[3 * l] = points[2 * l];
|
||||
} /* end for */
|
||||
points[2] = 0;
|
||||
} /* end if */
|
||||
|
||||
/* Select points in memory */
|
||||
if (H5Sselect_elements(mem_space_ids[k], H5S_SELECT_APPEND, npoints, points) < 0)
|
||||
TEST_ERROR;
|
||||
} /* end else */
|
||||
else {
|
||||
/* All selection */
|
||||
/* Select entire dataset in file */
|
||||
if (H5Sselect_all(file_space_ids[k]) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Select entire dataset in memory using hyperslab */
|
||||
start[0] = 0;
|
||||
start[1] = 0;
|
||||
count[0] = dset_dims[k][0];
|
||||
count[1] = dset_dims[k][1];
|
||||
if (H5Sselect_hyperslab(mem_space_ids[k], H5S_SELECT_SET, start, NULL, count, NULL) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Update expected buffers */
|
||||
if (do_read) {
|
||||
for (m = 0; m < dset_dims[k][0]; m++)
|
||||
for (n = 0; n < dset_dims[k][1]; n++)
|
||||
erbufi[k][m][n] = efbufi[k][m][n];
|
||||
} /* end if */
|
||||
else
|
||||
for (m = 0; m < dset_dims[k][0]; m++)
|
||||
for (n = 0; n < dset_dims[k][1]; n++)
|
||||
efbufi[k][m][n] = wbufi[k][m][n];
|
||||
}
|
||||
} /* end for */
|
||||
|
||||
/* Perform I/O */
|
||||
if (do_read) {
|
||||
if (flags & MDSET_FLAG_MDSET) {
|
||||
/* Set buffers */
|
||||
for (k = 0; k < ndsets; k++)
|
||||
rbufs[k] = rbufi[k][0];
|
||||
|
||||
/* Read datasets */
|
||||
if (H5Dread_multi(ndsets, dset_ids, mem_type_ids, mem_space_ids, file_space_ids,
|
||||
H5P_DEFAULT, rbufs) < 0)
|
||||
TEST_ERROR;
|
||||
} /* end if */
|
||||
else
|
||||
/* Read */
|
||||
if (H5Dread(dset_ids[0], mem_type_ids[0], mem_space_ids[0], file_space_ids[0],
|
||||
H5P_DEFAULT, rbuf) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Verify data */
|
||||
if (0 != memcmp(rbuf, erbuf, buf_size))
|
||||
TEST_ERROR;
|
||||
} /* end if */
|
||||
else {
|
||||
if (flags & MDSET_FLAG_MDSET) {
|
||||
/* Set buffers */
|
||||
for (k = 0; k < ndsets; k++)
|
||||
wbufs[k] = wbufi[k][0];
|
||||
|
||||
/* Write datasets */
|
||||
if (H5Dwrite_multi(ndsets, dset_ids, mem_type_ids, mem_space_ids, file_space_ids,
|
||||
H5P_DEFAULT, wbufs) < 0)
|
||||
TEST_ERROR;
|
||||
} /* end if */
|
||||
else
|
||||
/* Write */
|
||||
if (H5Dwrite(dset_ids[0], mem_type_ids[0], mem_space_ids[0], file_space_ids[0],
|
||||
H5P_DEFAULT, wbuf) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
/* Update wbuf */
|
||||
for (l = 0; l < max_dsets; l++)
|
||||
for (m = 0; m < MAX_DSET_X; m++)
|
||||
for (n = 0; n < MAX_DSET_Y; n++)
|
||||
wbufi[l][m][n] += (unsigned)max_dsets * MAX_DSET_X * MAX_DSET_Y;
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
|
||||
/* Close */
|
||||
for (j = 0; j < ndsets; j++) {
|
||||
if (H5Dclose(dset_ids[j]) < 0)
|
||||
TEST_ERROR;
|
||||
dset_ids[j] = -1;
|
||||
if (H5Sclose(file_space_ids[j]) < 0)
|
||||
TEST_ERROR;
|
||||
file_space_ids[j] = -1;
|
||||
} /* end for */
|
||||
if (H5Fclose(file_id) < 0)
|
||||
TEST_ERROR;
|
||||
file_id = -1;
|
||||
|
||||
/* Cleanup external file. Need to do this because otherwise there is garbage when the
|
||||
* dataset is created, even with early allocation and fill time. */
|
||||
HDremove(EXT_FILENAME);
|
||||
} /* end for */
|
||||
|
||||
/* Close */
|
||||
for (i = 0; i < max_dsets; i++) {
|
||||
if (H5Sclose(mem_space_ids[i]) < 0)
|
||||
TEST_ERROR;
|
||||
mem_space_ids[i] = -1;
|
||||
} /* end for */
|
||||
for (i = 0; i < MAX_DSETS; i++) {
|
||||
if (H5Pclose(dcpl_id[i]) < 0)
|
||||
TEST_ERROR;
|
||||
dcpl_id[i] = -1;
|
||||
}
|
||||
free(rbuf);
|
||||
rbuf = NULL;
|
||||
free(erbuf);
|
||||
erbuf = NULL;
|
||||
free(wbuf);
|
||||
wbuf = NULL;
|
||||
free(efbuf);
|
||||
efbuf = NULL;
|
||||
|
||||
PASSED();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY
|
||||
{
|
||||
for (i = 0; i < max_dsets; i++) {
|
||||
H5Dclose(dset_ids[i]);
|
||||
H5Sclose(mem_space_ids[i]);
|
||||
H5Sclose(file_space_ids[i]);
|
||||
H5Pclose(dcpl_id[i]);
|
||||
} /* end for */
|
||||
H5Fclose(file_id);
|
||||
}
|
||||
H5E_END_TRY
|
||||
if (rbuf)
|
||||
free(rbuf);
|
||||
if (erbuf)
|
||||
free(erbuf);
|
||||
if (wbuf)
|
||||
free(wbuf);
|
||||
if (efbuf)
|
||||
free(efbuf);
|
||||
|
||||
return -1;
|
||||
} /* end test_mdset() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose: Runs all tests with all combinations of configuration
|
||||
* flags.
|
||||
*
|
||||
* Return: Success: 0
|
||||
* Failure: 1
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Monday, March 10, 2014
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
hid_t fapl_id;
|
||||
int nerrors = 0;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
h5_reset();
|
||||
fapl_id = h5_fileaccess();
|
||||
|
||||
/* Initialize random number seed */
|
||||
HDsrandom((unsigned)HDtime(NULL));
|
||||
|
||||
/* Fill dset_name array */
|
||||
for (i = 0; i < MAX_DSETS; i++) {
|
||||
if ((ret = snprintf(dset_name[i], DSET_MAX_NAME_LEN, "dset%u", i)) < 0)
|
||||
TEST_ERROR;
|
||||
if (ret >= DSET_MAX_NAME_LEN)
|
||||
TEST_ERROR;
|
||||
} /* end for */
|
||||
|
||||
/* Check if deflate and fletcher32 filters are available */
|
||||
if ((deflate_avail = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0)
|
||||
TEST_ERROR;
|
||||
if ((fletcher32_avail = H5Zfilter_avail(H5Z_FILTER_FLETCHER32)) < 0)
|
||||
TEST_ERROR;
|
||||
|
||||
for (i = 0; i <= MDSET_ALL_FLAGS; i++) {
|
||||
/* Skip incompatible flag combinations */
|
||||
if (((i & MDSET_FLAG_MLAYOUT) && (i & MDSET_FLAG_CHUNK)) ||
|
||||
((i & MDSET_FLAG_MLAYOUT) && !(i & MDSET_FLAG_MDSET)) ||
|
||||
((i & MDSET_FLAG_FILTER) && !(i & MDSET_FLAG_CHUNK)))
|
||||
continue;
|
||||
|
||||
/* Print flag configuration */
|
||||
puts("\nConfiguration:");
|
||||
printf(" Layout: %s\n", (i & MDSET_FLAG_MLAYOUT) ? "Multi"
|
||||
: (i & MDSET_FLAG_CHUNK) ? "Chunked"
|
||||
: "Contiguous");
|
||||
printf(" Shape same: %s\n", (i & MDSET_FLAG_SHAPESAME) ? "Yes" : "No");
|
||||
printf(" I/O type: %s\n", (i & MDSET_FLAG_MDSET) ? "Multi" : "Single");
|
||||
printf(" Type conversion: %s\n", (i & MDSET_FLAG_TCONV) ? "Yes" : "No");
|
||||
printf(" Data filter: %s\n", (i & MDSET_FLAG_MLAYOUT) ? "Mixed"
|
||||
: (i & MDSET_FLAG_FILTER) ? "Yes"
|
||||
: "No");
|
||||
|
||||
nerrors += test_mdset(50, i, fapl_id);
|
||||
}
|
||||
|
||||
/* test all datasets in same container */
|
||||
nerrors += test_mdset_location(fapl_id);
|
||||
|
||||
h5_cleanup(FILENAME, fapl_id);
|
||||
|
||||
if (nerrors)
|
||||
goto error;
|
||||
puts("All multi dataset tests passed.");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
nerrors = MAX(1, nerrors);
|
||||
printf("***** %d multi dataset TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S");
|
||||
return 1;
|
||||
} /* end main() */
|
||||
@@ -50,7 +50,7 @@ HDF5-DIAG: Error detected in HDF5 (version (number)) thread (IDs):
|
||||
#001: (file name) line (number) in H5D__read_api_common(): can't read data
|
||||
major: Dataset
|
||||
minor: Read failed
|
||||
#002: (file name) line (number) in H5VL_dataset_read(): dataset read failed
|
||||
#002: (file name) line (number) in H5VL_dataset_read_direct(): dataset read failed
|
||||
major: Virtual Object Layer
|
||||
minor: Read failed
|
||||
#003: (file name) line (number) in H5VL__dataset_read(): dataset read failed
|
||||
|
||||
@@ -95,6 +95,7 @@ set (H5P_TESTS
|
||||
t_pshutdown
|
||||
t_prestart
|
||||
t_init_term
|
||||
t_pmulti_dset
|
||||
t_shapesame
|
||||
t_filters_parallel
|
||||
t_subfiling_vfd
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ check_SCRIPTS = $(TEST_SCRIPT_PARA)
|
||||
|
||||
# Test programs. These are our main targets.
|
||||
#
|
||||
TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel t_2Gio t_vfd
|
||||
TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pread t_pshutdown t_prestart t_init_term t_pmulti_dset t_shapesame t_filters_parallel t_2Gio t_vfd
|
||||
|
||||
if SUBFILING_VFD_CONDITIONAL
|
||||
TEST_PROG_PARA += t_subfiling_vfd
|
||||
@@ -59,6 +59,6 @@ LDADD = $(LIBH5TEST) $(LIBHDF5)
|
||||
# after_mpi_fin.h5 is from t_init_term
|
||||
# go is used for debugging. See testphdf5.c.
|
||||
CHECK_CLEANFILES+=MPItest.h5 Para*.h5 bigio_test.h5 CacheTestDummy.h5 \
|
||||
ShapeSameTest.h5 shutdown.h5 after_mpi_fin.h5 go
|
||||
ShapeSameTest.h5 shutdown.h5 pmulti_dset.h5 after_mpi_fin.h5 go
|
||||
|
||||
include $(top_srcdir)/config/conclude.am
|
||||
|
||||
@@ -0,0 +1,767 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* Copyright by The HDF Group. *
|
||||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||||
* terms governing use, modification, and redistribution, is contained in *
|
||||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||||
* of the source code distribution tree; Copyright.html can be found at the *
|
||||
* root level of an installed copy of the electronic HDF5 document set and *
|
||||
* is linked from the top-level documents page. It can also be found at *
|
||||
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
||||
* access to either file, you may request a copy from help@hdfgroup.org. *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/*
|
||||
* Programmer: Neil Fortner
|
||||
* March 10, 2014
|
||||
*
|
||||
* Purpose: Test H5Dwrite_multi() and H5Dread_multi using randomized
|
||||
* parameters in parallel. Also tests H5Dwrite() and H5Dread()
|
||||
* using a similar method.
|
||||
*
|
||||
* Note that this test currently relies on all processes generating
|
||||
* the same sequence of random numbers after using a shared seed
|
||||
* value, therefore it may not work across multiple machines.
|
||||
*/
|
||||
|
||||
#include "h5test.h"
|
||||
#include "testpar.h"
|
||||
|
||||
#define T_PMD_ERROR \
|
||||
do { \
|
||||
nerrors++; \
|
||||
H5_FAILED(); \
|
||||
AT(); \
|
||||
printf("seed = %u\n", seed); \
|
||||
} while (0)
|
||||
|
||||
#define FILENAME "pmulti_dset.h5"
|
||||
#define MAX_DSETS 5
|
||||
#define MAX_DSET_X 15
|
||||
#define MAX_DSET_Y 10
|
||||
#define MAX_CHUNK_X 8
|
||||
#define MAX_CHUNK_Y 6
|
||||
#define MAX_HS_X 4
|
||||
#define MAX_HS_Y 2
|
||||
#define MAX_HS 2
|
||||
#define MAX_POINTS 6
|
||||
#define MAX_SEL_RETRIES 10
|
||||
#define OPS_PER_FILE 25
|
||||
#define DSET_MAX_NAME_LEN 8
|
||||
|
||||
/* Option flags */
|
||||
#define MDSET_FLAG_CHUNK 0x01u
|
||||
#define MDSET_FLAG_MLAYOUT 0x02u
|
||||
#define MDSET_FLAG_SHAPESAME 0x04u
|
||||
#define MDSET_FLAG_MDSET 0x08u
|
||||
#define MDSET_FLAG_COLLECTIVE 0x10u
|
||||
#define MDSET_FLAG_COLLECTIVE_OPT 0x20u
|
||||
#define MDSET_FLAG_TCONV 0x40u
|
||||
#define MDSET_FLAG_FILTER 0x80u
|
||||
#define MDSET_ALL_FLAGS \
|
||||
(MDSET_FLAG_CHUNK | MDSET_FLAG_MLAYOUT | MDSET_FLAG_SHAPESAME | MDSET_FLAG_MDSET | \
|
||||
MDSET_FLAG_COLLECTIVE | MDSET_FLAG_COLLECTIVE_OPT | MDSET_FLAG_TCONV | MDSET_FLAG_FILTER)
|
||||
|
||||
/* MPI variables */
|
||||
int mpi_size;
|
||||
int mpi_rank;
|
||||
|
||||
/* Names for datasets */
|
||||
char dset_name[MAX_DSETS][DSET_MAX_NAME_LEN];
|
||||
|
||||
/* Random number seed */
|
||||
unsigned seed;
|
||||
|
||||
/* Number of errors */
|
||||
int nerrors = 0;
|
||||
|
||||
/* Whether these filters are available */
|
||||
htri_t deflate_avail = FALSE;
|
||||
htri_t fletcher32_avail = FALSE;
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_pmdset
|
||||
*
|
||||
* Purpose: Test randomized I/O using one or more datasets. Creates a
|
||||
* file, runs OPS_PER_FILE read or write operations verifying
|
||||
* that reads return the expected data, then closes the file.
|
||||
* Runs the test with a new file niter times.
|
||||
*
|
||||
* The operations can use either hyperslab or point
|
||||
* selections. Options are available for chunked or
|
||||
* contiguous layout, use of multiple datasets and H5D*_multi
|
||||
* calls, and use of the "shapesame" algorithm code path. To
|
||||
* avoid the shapesame path when that option is not set, this
|
||||
* function simply adds a dimension to the memory buffer in a
|
||||
* way that the shapesame code is not designed to handle.
|
||||
*
|
||||
* Return: Number of errors
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Monday, March 10, 2014
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
test_pmdset(size_t niter, unsigned flags)
|
||||
{
|
||||
hid_t dset_ids[MAX_DSETS];
|
||||
hid_t mem_type_ids[MAX_DSETS];
|
||||
hid_t mem_space_ids[MAX_DSETS];
|
||||
hid_t file_space_ids[MAX_DSETS];
|
||||
void *rbufs[MAX_DSETS];
|
||||
const void *wbufs[MAX_DSETS];
|
||||
size_t max_dsets;
|
||||
size_t buf_size;
|
||||
size_t ndsets;
|
||||
hid_t file_id = -1;
|
||||
hid_t fapl_id = -1;
|
||||
hid_t dcpl_id[MAX_DSETS];
|
||||
hid_t dxpl_id = -1;
|
||||
hsize_t dset_dims[MAX_DSETS][3];
|
||||
hsize_t chunk_dims[2];
|
||||
hsize_t max_dims[2] = {H5S_UNLIMITED, H5S_UNLIMITED};
|
||||
unsigned *rbuf = NULL;
|
||||
unsigned *rbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *erbuf = NULL;
|
||||
unsigned *erbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *wbuf = NULL;
|
||||
unsigned *wbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned *efbuf = NULL;
|
||||
unsigned *efbufi[MAX_DSETS][MAX_DSET_X];
|
||||
unsigned char *dset_usage;
|
||||
unsigned char *dset_usagei[MAX_DSETS][MAX_DSET_X];
|
||||
hbool_t do_read;
|
||||
hbool_t last_read;
|
||||
hbool_t overlap;
|
||||
hsize_t start[MAX_HS][3];
|
||||
hsize_t count[MAX_HS][3];
|
||||
hsize_t points[3 * MAX_POINTS];
|
||||
int rank_data_diff;
|
||||
unsigned op_data_incr;
|
||||
size_t i, j, k, l, m, n, o, p;
|
||||
|
||||
if (mpi_rank == 0)
|
||||
TESTING("random I/O");
|
||||
|
||||
/* Skipped configurations */
|
||||
if (!(flags & MDSET_FLAG_COLLECTIVE_OPT)) {
|
||||
if (mpi_rank == 0)
|
||||
SKIPPED();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate maximum number of datasets */
|
||||
max_dsets = (flags & MDSET_FLAG_MDSET) ? MAX_DSETS : 1;
|
||||
|
||||
/* Calculate data increment per write operation */
|
||||
op_data_incr = (unsigned)max_dsets * MAX_DSET_X * MAX_DSET_Y * (unsigned)mpi_size;
|
||||
|
||||
/* Calculate buffer size */
|
||||
buf_size = max_dsets * MAX_DSET_X * MAX_DSET_Y * sizeof(unsigned);
|
||||
|
||||
/* Initialize dcpl_id array */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
dcpl_id[i] = -1;
|
||||
|
||||
/* Allocate buffers */
|
||||
if (NULL == (rbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
T_PMD_ERROR;
|
||||
if (NULL == (erbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
T_PMD_ERROR;
|
||||
if (NULL == (wbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
T_PMD_ERROR;
|
||||
if (NULL == (efbuf = (unsigned *)HDmalloc(buf_size)))
|
||||
T_PMD_ERROR;
|
||||
if (NULL == (dset_usage = (unsigned char *)HDmalloc(max_dsets * MAX_DSET_X * MAX_DSET_Y)))
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Initialize buffer indices */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
for (j = 0; j < MAX_DSET_X; j++) {
|
||||
rbufi[i][j] = rbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
erbufi[i][j] = erbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
wbufi[i][j] = wbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
efbufi[i][j] = efbuf + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
dset_usagei[i][j] = dset_usage + (i * MAX_DSET_X * MAX_DSET_Y) + (j * MAX_DSET_Y);
|
||||
} /* end for */
|
||||
|
||||
/* Initialize 3rd dimension information (for tricking library into using
|
||||
* non-"shapesame" code */
|
||||
for (i = 0; i < max_dsets; i++)
|
||||
dset_dims[i][2] = 1;
|
||||
for (i = 0; i < MAX_HS; i++) {
|
||||
start[i][2] = 0;
|
||||
count[i][2] = 1;
|
||||
} /* end for */
|
||||
|
||||
/* Initialize IDs */
|
||||
for (i = 0; i < max_dsets; i++) {
|
||||
dset_ids[i] = -1;
|
||||
file_space_ids[i] = -1;
|
||||
mem_type_ids[i] = H5T_NATIVE_UINT;
|
||||
mem_space_ids[i] = -1;
|
||||
} /* end for */
|
||||
|
||||
/* Generate memory dataspace */
|
||||
dset_dims[0][0] = MAX_DSET_X;
|
||||
dset_dims[0][1] = MAX_DSET_Y;
|
||||
if ((mem_space_ids[0] = H5Screate_simple((flags & MDSET_FLAG_SHAPESAME) ? 2 : 3, dset_dims[0], NULL)) < 0)
|
||||
T_PMD_ERROR;
|
||||
for (i = 1; i < max_dsets; i++)
|
||||
if ((mem_space_ids[i] = H5Scopy(mem_space_ids[0])) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Create fapl */
|
||||
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Set MPIO file driver */
|
||||
if ((H5Pset_fapl_mpio(fapl_id, MPI_COMM_WORLD, MPI_INFO_NULL)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Create dcpl 0 */
|
||||
if ((dcpl_id[0] = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Set fill time to alloc, and alloc time to early (so we always know
|
||||
* what's in the file) */
|
||||
if (H5Pset_fill_time(dcpl_id[0], H5D_FILL_TIME_ALLOC) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (H5Pset_alloc_time(dcpl_id[0], H5D_ALLOC_TIME_EARLY) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Set filters if requested */
|
||||
if (flags & MDSET_FLAG_FILTER) {
|
||||
if (fletcher32_avail)
|
||||
if (H5Pset_fletcher32(dcpl_id[0]) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (deflate_avail)
|
||||
if (H5Pset_deflate(dcpl_id[0], 1) < 0)
|
||||
T_PMD_ERROR;
|
||||
}
|
||||
|
||||
/* Copy dcpl 0 to other slots in dcpl_id array */
|
||||
for (i = 1; i < MAX_DSETS; i++)
|
||||
if ((dcpl_id[i] = H5Pcopy(dcpl_id[0])) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* If this is a multi layout run, dataset 2 will use filters, set them now */
|
||||
if (flags & MDSET_FLAG_MLAYOUT) {
|
||||
if (fletcher32_avail)
|
||||
if (H5Pset_fletcher32(dcpl_id[2]) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (deflate_avail)
|
||||
if (H5Pset_deflate(dcpl_id[2], 1) < 0)
|
||||
T_PMD_ERROR;
|
||||
}
|
||||
|
||||
/* Create dxpl */
|
||||
if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Set collective or independent I/O */
|
||||
if (flags & MDSET_FLAG_COLLECTIVE) {
|
||||
if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Set low level I/O mode */
|
||||
if (flags & MDSET_FLAG_COLLECTIVE_OPT) {
|
||||
if (H5Pset_dxpl_mpio_collective_opt(dxpl_id, H5FD_MPIO_COLLECTIVE_IO) < 0)
|
||||
T_PMD_ERROR;
|
||||
}
|
||||
else if (H5Pset_dxpl_mpio_collective_opt(dxpl_id, H5FD_MPIO_INDIVIDUAL_IO) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
else if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_INDEPENDENT) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
for (i = 0; i < niter; i++) {
|
||||
/* Determine number of datasets */
|
||||
ndsets = (flags & MDSET_FLAG_MLAYOUT) ? 3
|
||||
: (flags & MDSET_FLAG_MDSET) ? (size_t)((size_t)HDrandom() % max_dsets) + 1
|
||||
: 1;
|
||||
|
||||
/* Create file */
|
||||
if ((file_id = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Create datasets */
|
||||
for (j = 0; j < ndsets; j++) {
|
||||
hbool_t use_chunk =
|
||||
(flags & MDSET_FLAG_CHUNK) || ((flags & MDSET_FLAG_MLAYOUT) && (j == 1 || j == 2));
|
||||
|
||||
/* Generate file dataspace */
|
||||
dset_dims[j][0] = (hsize_t)((HDrandom() % MAX_DSET_X) + 1);
|
||||
dset_dims[j][1] = (hsize_t)((HDrandom() % MAX_DSET_Y) + 1);
|
||||
if ((file_space_ids[j] = H5Screate_simple(2, dset_dims[j], use_chunk ? max_dims : NULL)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Generate chunk if called for by configuration (multi layout uses chunked for datasets
|
||||
* 1 and 2) */
|
||||
if (use_chunk) {
|
||||
chunk_dims[0] = (hsize_t)((HDrandom() % MAX_CHUNK_X) + 1);
|
||||
chunk_dims[1] = (hsize_t)((HDrandom() % MAX_CHUNK_Y) + 1);
|
||||
if (H5Pset_chunk(dcpl_id[j], 2, chunk_dims) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
|
||||
/* Create dataset */
|
||||
/* If MDSET_FLAG_TCONV is set, use a different datatype with 50% probability, so
|
||||
* some datasets require type conversion and others do not */
|
||||
if ((dset_ids[j] = H5Dcreate2(file_id, dset_name[j],
|
||||
(flags & MDSET_FLAG_TCONV && HDrandom() % 2) ? H5T_NATIVE_LONG
|
||||
: H5T_NATIVE_UINT,
|
||||
file_space_ids[j], H5P_DEFAULT, dcpl_id[j], H5P_DEFAULT)) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end for */
|
||||
|
||||
/* Initialize read buffer and expected read buffer */
|
||||
(void)HDmemset(rbuf, 0, buf_size);
|
||||
(void)HDmemset(erbuf, 0, buf_size);
|
||||
|
||||
/* Initialize write buffer */
|
||||
for (j = 0; j < max_dsets; j++)
|
||||
for (k = 0; k < MAX_DSET_X; k++)
|
||||
for (l = 0; l < MAX_DSET_Y; l++)
|
||||
wbufi[j][k][l] = (unsigned)(((unsigned)mpi_rank * max_dsets * MAX_DSET_X * MAX_DSET_Y) +
|
||||
(j * MAX_DSET_X * MAX_DSET_Y) + (k * MAX_DSET_Y) + l);
|
||||
|
||||
/* Initialize expected file buffer */
|
||||
(void)HDmemset(efbuf, 0, buf_size);
|
||||
|
||||
/* Set last_read to TRUE so we don't reopen the file on the first
|
||||
* iteration */
|
||||
last_read = TRUE;
|
||||
|
||||
/* Perform read/write operations */
|
||||
for (j = 0; j < OPS_PER_FILE; j++) {
|
||||
/* Decide whether to read or write */
|
||||
do_read = (hbool_t)(HDrandom() % 2);
|
||||
|
||||
/* Barrier to ensure processes have finished the previous operation
|
||||
*/
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
/* If the last operation was a write we must close and reopen the
|
||||
* file to ensure consistency */
|
||||
/* Possibly change to MPI_FILE_SYNC at some point? -NAF */
|
||||
if (!last_read) {
|
||||
/* Close datasets */
|
||||
for (k = 0; k < ndsets; k++) {
|
||||
if (H5Dclose(dset_ids[k]) < 0)
|
||||
T_PMD_ERROR;
|
||||
dset_ids[k] = -1;
|
||||
} /* end for */
|
||||
|
||||
/* Close file */
|
||||
if (H5Fclose(file_id) < 0)
|
||||
T_PMD_ERROR;
|
||||
file_id = -1;
|
||||
|
||||
/* Barrier */
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
|
||||
/* Reopen file */
|
||||
if ((file_id = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl_id)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Reopen datasets */
|
||||
for (k = 0; k < ndsets; k++) {
|
||||
if ((dset_ids[k] = H5Dopen2(file_id, dset_name[k], H5P_DEFAULT)) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end for */
|
||||
|
||||
/* Barrier */
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
} /* end if */
|
||||
|
||||
/* Keep track of whether the last operation was a read */
|
||||
last_read = do_read;
|
||||
|
||||
/* Loop over datasets */
|
||||
for (k = 0; k < ndsets; k++) {
|
||||
/* Reset selection */
|
||||
if (H5Sselect_none(mem_space_ids[k]) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (H5Sselect_none(file_space_ids[k]) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Reset dataset usage array, if writing */
|
||||
if (!do_read)
|
||||
HDmemset(dset_usage, 0, max_dsets * MAX_DSET_X * MAX_DSET_Y);
|
||||
|
||||
/* Iterate over processes */
|
||||
for (l = 0; l < (size_t)mpi_size; l++) {
|
||||
/* Calculate difference between data in process being
|
||||
* iterated over and that in this process */
|
||||
rank_data_diff =
|
||||
(int)((unsigned)max_dsets * MAX_DSET_X * MAX_DSET_Y) * ((int)l - (int)mpi_rank);
|
||||
|
||||
/* Decide whether to do a hyperslab or point selection */
|
||||
if (HDrandom() % 2) {
|
||||
/* Hyperslab */
|
||||
size_t nhs = (size_t)((HDrandom() % MAX_HS) + 1); /* Number of hyperslabs */
|
||||
size_t max_hs_x = (MAX_HS_X <= dset_dims[k][0])
|
||||
? MAX_HS_X
|
||||
: dset_dims[k][0]; /* Determine maximum hyperslab size in X */
|
||||
size_t max_hs_y = (MAX_HS_Y <= dset_dims[k][1])
|
||||
? MAX_HS_Y
|
||||
: dset_dims[k][1]; /* Determine maximum hyperslab size in Y */
|
||||
|
||||
for (m = 0; m < nhs; m++) {
|
||||
overlap = TRUE;
|
||||
for (n = 0; overlap && (n < MAX_SEL_RETRIES); n++) {
|
||||
/* Generate hyperslab */
|
||||
count[m][0] = (hsize_t)(((hsize_t)HDrandom() % max_hs_x) + 1);
|
||||
count[m][1] = (hsize_t)(((hsize_t)HDrandom() % max_hs_y) + 1);
|
||||
start[m][0] = (count[m][0] == dset_dims[k][0])
|
||||
? 0
|
||||
: (hsize_t)HDrandom() % (dset_dims[k][0] - count[m][0] + 1);
|
||||
start[m][1] = (count[m][1] == dset_dims[k][1])
|
||||
? 0
|
||||
: (hsize_t)HDrandom() % (dset_dims[k][1] - count[m][1] + 1);
|
||||
|
||||
/* If writing, check for overlap with other processes */
|
||||
overlap = FALSE;
|
||||
if (!do_read)
|
||||
for (o = start[m][0]; (o < (start[m][0] + count[m][0])) && !overlap; o++)
|
||||
for (p = start[m][1]; (p < (start[m][1] + count[m][1])) && !overlap;
|
||||
p++)
|
||||
if (dset_usagei[k][o][p])
|
||||
overlap = TRUE;
|
||||
} /* end for */
|
||||
|
||||
/* If we did not find a non-overlapping hyperslab
|
||||
* quit trying to generate new ones */
|
||||
if (overlap) {
|
||||
nhs = m;
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
/* Select hyperslab if this is the current process
|
||||
*/
|
||||
if (l == (size_t)mpi_rank) {
|
||||
if (H5Sselect_hyperslab(mem_space_ids[k], H5S_SELECT_OR, start[m], NULL,
|
||||
count[m], NULL) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (H5Sselect_hyperslab(file_space_ids[k], H5S_SELECT_OR, start[m], NULL,
|
||||
count[m], NULL) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
|
||||
/* Update expected buffers */
|
||||
if (do_read) {
|
||||
if (l == (size_t)mpi_rank)
|
||||
for (n = start[m][0]; n < (start[m][0] + count[m][0]); n++)
|
||||
for (o = start[m][1]; o < (start[m][1] + count[m][1]); o++)
|
||||
erbufi[k][n][o] = efbufi[k][n][o];
|
||||
} /* end if */
|
||||
else
|
||||
for (n = start[m][0]; n < (start[m][0] + count[m][0]); n++)
|
||||
for (o = start[m][1]; o < (start[m][1] + count[m][1]); o++)
|
||||
efbufi[k][n][o] = (unsigned)((int)wbufi[k][n][o] + rank_data_diff);
|
||||
} /* end for */
|
||||
|
||||
/* Update dataset usage array if writing */
|
||||
if (!do_read)
|
||||
for (m = 0; m < nhs; m++)
|
||||
for (n = start[m][0]; n < (start[m][0] + count[m][0]); n++)
|
||||
for (o = start[m][1]; o < (start[m][1] + count[m][1]); o++)
|
||||
dset_usagei[k][n][o] = (unsigned char)1;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Point selection */
|
||||
size_t npoints =
|
||||
(size_t)(((size_t)HDrandom() % MAX_POINTS) + 1); /* Number of points */
|
||||
|
||||
/* Reset dataset usage array if reading, since in this case we don't care
|
||||
* about overlapping selections between processes */
|
||||
if (do_read)
|
||||
HDmemset(dset_usage, 0, max_dsets * MAX_DSET_X * MAX_DSET_Y);
|
||||
|
||||
/* Generate points */
|
||||
for (m = 0; m < npoints; m++) {
|
||||
overlap = TRUE;
|
||||
for (n = 0; overlap && (n < MAX_SEL_RETRIES); n++) {
|
||||
/* Generate point */
|
||||
points[2 * m] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][0]);
|
||||
points[(2 * m) + 1] = (unsigned)((hsize_t)HDrandom() % dset_dims[k][1]);
|
||||
|
||||
/* Check for overlap with other processes (write) or this process
|
||||
* (always) */
|
||||
overlap = FALSE;
|
||||
if (dset_usagei[k][points[2 * m]][points[(2 * m) + 1]])
|
||||
overlap = TRUE;
|
||||
} /* end for */
|
||||
|
||||
/* If we did not find a non-overlapping point quit
|
||||
* trying to generate new ones */
|
||||
if (overlap) {
|
||||
npoints = m;
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
/* Update dataset usage array after each point to prevent the same point
|
||||
* being selected twice by a single process, since this is not supported
|
||||
* by MPI */
|
||||
dset_usagei[k][points[2 * m]][points[(2 * m) + 1]] = (unsigned char)1;
|
||||
} /* end for */
|
||||
|
||||
/* Select points in file if this is the current process
|
||||
*/
|
||||
if ((l == (size_t)mpi_rank) && (npoints > 0))
|
||||
if (H5Sselect_elements(file_space_ids[k], H5S_SELECT_APPEND, npoints, points) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Update expected buffers */
|
||||
if (do_read) {
|
||||
if (l == (size_t)mpi_rank)
|
||||
for (m = 0; m < npoints; m++)
|
||||
erbufi[k][points[2 * m]][points[(2 * m) + 1]] =
|
||||
efbufi[k][points[2 * m]][points[(2 * m) + 1]];
|
||||
} /* end if */
|
||||
else
|
||||
for (m = 0; m < npoints; m++)
|
||||
efbufi[k][points[2 * m]][points[(2 * m) + 1]] =
|
||||
(unsigned)((int)wbufi[k][points[2 * m]][points[(2 * m) + 1]] +
|
||||
rank_data_diff);
|
||||
|
||||
/* Select points in memory if this is the current
|
||||
* process */
|
||||
if ((l == (size_t)mpi_rank) && (npoints > 0)) {
|
||||
/* Convert to 3D for memory selection, if not using
|
||||
* "shapesame" */
|
||||
if (!(flags & MDSET_FLAG_SHAPESAME)) {
|
||||
for (m = npoints - 1; m > 0; m--) {
|
||||
points[(3 * m) + 2] = 0;
|
||||
points[(3 * m) + 1] = points[(2 * m) + 1];
|
||||
points[3 * m] = points[2 * m];
|
||||
} /* end for */
|
||||
points[2] = 0;
|
||||
} /* end if */
|
||||
|
||||
/* Select elements */
|
||||
if (H5Sselect_elements(mem_space_ids[k], H5S_SELECT_APPEND, npoints, points) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
} /* end for */
|
||||
|
||||
/* Perform I/O */
|
||||
if (do_read) {
|
||||
if (flags & MDSET_FLAG_MDSET) {
|
||||
/* Set buffers */
|
||||
for (k = 0; k < ndsets; k++)
|
||||
rbufs[k] = rbufi[k][0];
|
||||
|
||||
/* Read datasets */
|
||||
if (H5Dread_multi(ndsets, dset_ids, mem_type_ids, mem_space_ids, file_space_ids, dxpl_id,
|
||||
rbufs) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
else
|
||||
/* Read */
|
||||
if (H5Dread(dset_ids[0], mem_type_ids[0], mem_space_ids[0], file_space_ids[0], dxpl_id,
|
||||
rbuf) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Verify data */
|
||||
if (0 != memcmp(rbuf, erbuf, buf_size))
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
else {
|
||||
if (flags & MDSET_FLAG_MDSET) {
|
||||
/* Set buffers */
|
||||
for (k = 0; k < ndsets; k++)
|
||||
wbufs[k] = wbufi[k][0];
|
||||
|
||||
/* Write datasets */
|
||||
if (H5Dwrite_multi(ndsets, dset_ids, mem_type_ids, mem_space_ids, file_space_ids, dxpl_id,
|
||||
wbufs) < 0)
|
||||
T_PMD_ERROR;
|
||||
} /* end if */
|
||||
else
|
||||
/* Write */
|
||||
if (H5Dwrite(dset_ids[0], mem_type_ids[0], mem_space_ids[0], file_space_ids[0], dxpl_id,
|
||||
wbuf) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Update wbuf */
|
||||
for (l = 0; l < max_dsets; l++)
|
||||
for (m = 0; m < MAX_DSET_X; m++)
|
||||
for (n = 0; n < MAX_DSET_Y; n++)
|
||||
wbufi[l][m][n] += op_data_incr;
|
||||
} /* end else */
|
||||
} /* end for */
|
||||
|
||||
/* Close */
|
||||
for (j = 0; j < ndsets; j++) {
|
||||
if (H5Dclose(dset_ids[j]) < 0)
|
||||
T_PMD_ERROR;
|
||||
dset_ids[j] = -1;
|
||||
if (H5Sclose(file_space_ids[j]) < 0)
|
||||
T_PMD_ERROR;
|
||||
file_space_ids[j] = -1;
|
||||
} /* end for */
|
||||
if (H5Fclose(file_id) < 0)
|
||||
T_PMD_ERROR;
|
||||
file_id = -1;
|
||||
} /* end for */
|
||||
|
||||
/* Close */
|
||||
for (i = 0; i < max_dsets; i++) {
|
||||
if (H5Sclose(mem_space_ids[i]) < 0)
|
||||
T_PMD_ERROR;
|
||||
mem_space_ids[i] = -1;
|
||||
} /* end for */
|
||||
if (H5Pclose(dxpl_id) < 0)
|
||||
T_PMD_ERROR;
|
||||
dxpl_id = -1;
|
||||
for (i = 0; i < MAX_DSETS; i++) {
|
||||
if (H5Pclose(dcpl_id[i]) < 0)
|
||||
T_PMD_ERROR;
|
||||
dcpl_id[i] = -1;
|
||||
}
|
||||
if (H5Pclose(fapl_id) < 0)
|
||||
T_PMD_ERROR;
|
||||
fapl_id = -1;
|
||||
free(rbuf);
|
||||
rbuf = NULL;
|
||||
free(erbuf);
|
||||
erbuf = NULL;
|
||||
free(wbuf);
|
||||
wbuf = NULL;
|
||||
free(efbuf);
|
||||
efbuf = NULL;
|
||||
free(dset_usage);
|
||||
dset_usage = NULL;
|
||||
|
||||
if (mpi_rank == 0)
|
||||
PASSED();
|
||||
|
||||
return;
|
||||
} /* end test_mdset() */
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose: Runs all tests with all combinations of configuration
|
||||
* flags.
|
||||
*
|
||||
* Return: Success: 0
|
||||
* Failure: 1
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Monday, March 10, 2014
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
h5_reset();
|
||||
|
||||
/* Initialize MPI */
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
|
||||
|
||||
/* Generate random number seed, if rank 0 */
|
||||
if (MAINPROCESS)
|
||||
seed = (unsigned)HDtime(NULL);
|
||||
|
||||
/* Broadcast seed from rank 0 (other ranks will receive rank 0's seed) */
|
||||
if (MPI_SUCCESS != MPI_Bcast(&seed, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD))
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Seed random number generator with shared seed (so all ranks generate the
|
||||
* same sequence) */
|
||||
HDsrandom(seed);
|
||||
|
||||
/* Fill dset_name array */
|
||||
for (i = 0; i < MAX_DSETS; i++) {
|
||||
if ((ret = snprintf(dset_name[i], DSET_MAX_NAME_LEN, "dset%u", i)) < 0)
|
||||
T_PMD_ERROR;
|
||||
if (ret >= DSET_MAX_NAME_LEN)
|
||||
T_PMD_ERROR;
|
||||
} /* end for */
|
||||
|
||||
/* Check if deflate and fletcher32 filters are available */
|
||||
if ((deflate_avail = H5Zfilter_avail(H5Z_FILTER_DEFLATE)) < 0)
|
||||
T_PMD_ERROR;
|
||||
if ((fletcher32_avail = H5Zfilter_avail(H5Z_FILTER_FLETCHER32)) < 0)
|
||||
T_PMD_ERROR;
|
||||
|
||||
for (i = 0; i <= MDSET_ALL_FLAGS; i++) {
|
||||
/* Skip incompatible flag combinations */
|
||||
if (((i & MDSET_FLAG_MLAYOUT) && (i & MDSET_FLAG_CHUNK)) ||
|
||||
((i & MDSET_FLAG_MLAYOUT) && !(i & MDSET_FLAG_MDSET)) ||
|
||||
((i & MDSET_FLAG_MLAYOUT) && !(i & MDSET_FLAG_COLLECTIVE)) ||
|
||||
((i & MDSET_FLAG_MLAYOUT) && (i & MDSET_FLAG_TCONV)) ||
|
||||
((i & MDSET_FLAG_FILTER) && !(i & MDSET_FLAG_CHUNK)) ||
|
||||
((i & MDSET_FLAG_FILTER) && !(i & MDSET_FLAG_COLLECTIVE)) ||
|
||||
((i & MDSET_FLAG_FILTER) && (i & MDSET_FLAG_TCONV)) ||
|
||||
(!(i & MDSET_FLAG_COLLECTIVE_OPT) && !(i & MDSET_FLAG_COLLECTIVE)))
|
||||
continue;
|
||||
|
||||
/* Print flag configuration */
|
||||
if (MAINPROCESS) {
|
||||
puts("\nConfiguration:");
|
||||
printf(" Layout: %s\n", (i & MDSET_FLAG_MLAYOUT) ? "Multi"
|
||||
: (i & MDSET_FLAG_CHUNK) ? "Chunked"
|
||||
: "Contiguous");
|
||||
printf(" Shape same: %s\n", (i & MDSET_FLAG_SHAPESAME) ? "Yes" : "No");
|
||||
printf(" I/O type: %s\n", (i & MDSET_FLAG_MDSET) ? "Multi" : "Single");
|
||||
printf(" MPI I/O type: %s\n", (i & MDSET_FLAG_COLLECTIVE) ? "Collective" : "Independent");
|
||||
if (i & MDSET_FLAG_COLLECTIVE)
|
||||
printf(" Low level MPI I/O:%s\n",
|
||||
(i & MDSET_FLAG_COLLECTIVE_OPT) ? "Collective" : "Independent");
|
||||
printf(" Type conversion: %s\n", (i & MDSET_FLAG_TCONV) ? "Yes" : "No");
|
||||
printf(" Data filter: %s\n", (i & MDSET_FLAG_MLAYOUT) ? "Mixed"
|
||||
: (i & MDSET_FLAG_FILTER) ? "Yes"
|
||||
: "No");
|
||||
} /* end if */
|
||||
|
||||
test_pmdset(10, i);
|
||||
} /* end for */
|
||||
|
||||
/* 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) */
|
||||
if (MPI_SUCCESS != MPI_Barrier(MPI_COMM_WORLD))
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Delete file */
|
||||
if (mpi_rank == 0)
|
||||
if (MPI_SUCCESS != MPI_File_delete(FILENAME, MPI_INFO_NULL))
|
||||
T_PMD_ERROR;
|
||||
|
||||
/* Gather errors from all processes */
|
||||
MPI_Allreduce(&nerrors, &ret, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
|
||||
nerrors = ret;
|
||||
|
||||
if (MAINPROCESS) {
|
||||
printf("===================================\n");
|
||||
if (nerrors)
|
||||
printf("***Parallel multi dataset tests detected %d errors***\n", nerrors);
|
||||
else
|
||||
printf("Parallel multi dataset tests finished with no errors\n");
|
||||
printf("===================================\n");
|
||||
} /* end if */
|
||||
|
||||
/* close HDF5 library */
|
||||
H5close();
|
||||
|
||||
/* MPI_Finalize must be called AFTER H5close which may use MPI calls */
|
||||
MPI_Finalize();
|
||||
|
||||
/* cannot just return (nerrors) because exit code is limited to 1 byte */
|
||||
return (nerrors != 0);
|
||||
} /* end main() */
|
||||
Reference in New Issue
Block a user