HDF5 Fortran90将数据附加为hyperslabs - 只有第一列工作

时间:2013-11-30 20:21:24

标签: fortran90 hdf5

我有一个Fortran 90程序,它在每个循环结束时创建一个大的整数列。我想将此列写入HDF5文件,每个新的整数列都写在HDF5文件中作为新列。也就是说,在第一个循环结束时,写入第1列,然后在第二个循环结束时,写入第2列等,直到创建具有与循环一样多的列的2D数组。

每个整数列的长度始终相同,我知道最后需要多少列。为此,我创建了一个足够大的数据空间来容纳最终的2D数组。然后我选择一个以offset(0,0)开头的hyperslab,然后是(0,1)用于下一个循环,(0,2)用于循环之后,等等,每次都写入我的程序创建的数据。 / p> 但是,这并不是很有效。目前,使用偏移量(0,0)一切正常。但是,如果我尝试在任何其他列中写入hyperslab,我会在输出.h5文件中得到无意义的值。

我是否正确实现了hyperslab代码?

这是一个MWE,它创建一个(20,10)的数据空间,并将一个20个列的列写入.h5文件的第一列。如果voffset从(/ 0,0 /)更改为(/ 0,1 /),则不会写入'5',而是随机数将出现在.h5文件的第二列中:

program hdf5_test
use hdf5
implicit none

! HDF5 file and path names
 character(len=10), parameter :: outfilename = "OutData.h5" ! Output file name
 character(len=8), parameter :: dsetvbinnedname = "velocity"

! Declare HDF5 IDs
integer(HID_T) :: outfile_id       ! File identifier
integer(HID_T) :: dsetv_id           
integer(HID_T) :: dataspacev_id

! Dataset dimensions in the file
integer(HSIZE_T), dimension(2) :: binned_vdims = (/20,1/)  ! Chunk dimensions
integer(HSIZE_T), dimension(2) :: export_binned_vdims = (/20,10/)  ! File dimensions

! Data buffers
integer, dimension(20) :: binned_vdata  ! Chunk dimension

! Chunk parameters
integer(HSIZE_T), dimension(2) :: voffset, vchunkcount

integer :: rank = 2
integer :: error ! HDF5 error flag

! Initialize FORTRAN interface
call h5open_f(error)

! Create a new file using the default properties.
call h5fcreate_f(outfilename, H5F_ACC_TRUNC_F, outfile_id, error)

! Create the data space for the binned dataset.
call h5screate_simple_f(rank, export_binned_vdims, dataspacev_id, error)

! Create the chunked dataset.
call h5dcreate_f(outfile_id, dsetvbinnedname, H5T_NATIVE_INTEGER, dataspacev_id, dsetv_id, error)

! Select hyperslab
voffset = (/0,0/)
vchunkcount = (/20,1/)

call h5sselect_hyperslab_f(dataspacev_id, H5S_SELECT_SET_F, voffset, vchunkcount, error)

binned_vdata = 5 ! Write a column of '5's

! Write the data to the dataset.
call h5dwrite_f(dsetv_id, H5T_NATIVE_INTEGER, binned_vdata, export_binned_vdims, error, file_space_id=dataspacev_id)

! Close dataspace, dataset, and file
call h5dclose_f(dsetv_id, error)
call h5sclose_f(dataspacev_id, error)
call h5fclose_f(outfile_id, error)

call h5close_f(error)

end program hdf5_test

2 个答案:

答案 0 :(得分:0)

您尚未指定内存数据空间。使用Fortran HDF5 API时,缺少显式内存数据空间参数的默认标识符为H5S_ALL_F,这意味着内存数据空间将与提供的文件数据空间相同。

因此,当您提供偏移到文件中的数据空间时,HDF5会从内存中写入类似偏移的值,并且此内存超出了数组的范围。

使用与现在类似的h5create_simple_f调用为内存中的数据创建另一个数据空间,并将其作为mem_space_id参数提供给h5dwrite_f调用。

答案 1 :(得分:0)

正如其他人所说,我需要使用内存数据空间。由Barbara在HDF集团提供的工作代码如下。

program hdf5_test
use hdf5
implicit none

! HDF5 file and path names
 character(len=10), parameter :: outfilename = "OutData.h5" ! Output file name
 character(len=8), parameter :: dsetvbinnedname = "velocity"

! Declare HDF5 IDs
integer(HID_T) :: outfile_id       ! File identifier
integer(HID_T) :: dsetv_id            
integer(HID_T) :: dataspacev_id 
integer(HID_T) :: memspace 

! Dataset dimensions in the file
integer(HSIZE_T), dimension(2) :: binned_vdims = (/20,1/)  ! Chunk dimensions
integer(HSIZE_T), dimension(2) :: export_binned_vdims = (/20,10/)  ! File dimensions

! Data buffers
integer, dimension(20,1) :: binned_vdata  ! Chunk dimension

! Chunk parameters
integer(HSIZE_T), dimension(2) :: voffset, vchunkcount

integer :: rank = 2,i, j
integer :: error ! HDF5 error flag

! Initialize FORTRAN interface
call h5open_f(error)

! Create a new file using the default properties.
 call h5fcreate_f(outfilename, H5F_ACC_TRUNC_F, outfile_id, error)

! Create the data space for the binned dataset.
call h5screate_simple_f(rank, export_binned_vdims, dataspacev_id,  error)

! Create the chunked dataset.
call h5dcreate_f(outfile_id, dsetvbinnedname, H5T_NATIVE_INTEGER, dataspacev_id, dsetv_id, error)

! Create the memory space for the selection
call h5screate_simple_f(rank, binned_vdims, memspace,  error)

! Select hyperslab
voffset(1) = 0
vchunkcount = (/20,1/)


DO i = 1, binned_vdims(1) 
     DO j = 1, binned_vdims(2) 
         binned_vdata(i,j) = 5 
     END DO
END DO


DO i= 1, export_binned_vdims(2) 
  voffset(2) = i-1
  call h5sselect_hyperslab_f(dataspacev_id, H5S_SELECT_SET_F, voffset, vchunkcount, error)

  ! Write the data to the dataset.
  call h5dwrite_f(dsetv_id, H5T_NATIVE_INTEGER, binned_vdata, binned_vdims, error, memspace, dataspacev_id)
  call h5sclose_f(dataspacev_id, error)
  call h5dget_space_f(dsetv_id, dataspacev_id, error)
END DO

! Close dataspace, dataset, and file
call h5dclose_f(dsetv_id, error)
call h5sclose_f(memspace, error)
call h5fclose_f(outfile_id, error)

call h5close_f(error)

end program hdf5_test