HDF5 Fortran90将数据作为hyperslabs附加

编程入门 行业动态 更新时间:2024-10-10 21:23:56
HDF5 Fortran90将数据作为hyperslabs附加 - 只有第一列工作(HDF5 Fortran90 append data as hyperslabs - only first column working)

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

每个整数列的长度始终相同,我知道最后需要多少列。 为此,我创建了一个足够大的数据空间来容纳最终的2D数组。 然后我选择一个以offset(0,0)开头的hyperslab,然后是(0,1)用于下一个循环,(0,2)用于循环之后,等等,每次都写入我的程序创建的数据。

然而,这并不是很有效。 目前,使用偏移量(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

I have a Fortran 90 program that creates a large column of integers at the end of each loop. I would like to write this column into an HDF5 file with each new integer column being written as a new column in the HDF5 file. That is, at the end of the first loop, write column 1, then at the end of the second loop, write column 2, etc, until a 2D array with as many columns as there were loops is created.

Each of these integer columns will always be the same length and I know how many columns will be needed in the end. To do this, I create a dataspace large enough to hold the final 2D array. Then I select a hyperslab beginning with offset (0,0), then (0,1) for the next loop, (0,2) for the loop after that, etc., each time writing the data that my program creates.

This isn't quite working, however. Currently, with the offset (0,0) everything works. However, if I try to write to a hyperslab in any other column, I get nonsense values in my output .h5 file.

Am I implementing the hyperslab code correctly?

Here is a MWE which creates a dataspace of (20,10) and writes a column of twenty '5's into the first column of the .h5 file. If voffset is changed from (/0,0/) to (/0,1/), the '5's are not written and instead random numbers will appear in the second column of the .h5 file:

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

最满意答案

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

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

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

As suggested by others, I needed to use a memory dataspace. Working code, provided by Barbara at the HDF Group, is below.

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

更多推荐

本文发布于:2023-07-18 07:17:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1156690.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据   hyperslabs

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!