在Fortran中读取HDF5数据集子集的问题

时间:2015-10-24 21:53:00

标签: fortran fortran90 hdf5 intel-fortran

我有一个非常大的HDF5文件,并希望使用FORTRAN读取它的一小部分。到目前为止我的尝试都失败了,我对文档感到困惑。 你可以给FORTRAN新手(但合理的C / python编码器)的任何指针都将非常感激。

特别是我很难理解数据空间和内存空间是什么,在我的代码中,根据我阅读的文档,它们似乎没有按照我的预期进行操作。这可能是我自己的白痴!

这就是我的尝试:

integer, allocatable                    :: tmpdata(:,:) ! Array to contain data subset
integer(HID_T)                          :: fid          ! HDF5 File ID
integer(HID_T)                          :: did          ! Dataset ID
integer                                 :: error        ! Error variable
integer(HSIZE_T), dimension(1:2)        :: count        ! Number of px to read (x,y)
integer(HSIZE_T), dimension(1:2)        :: offset       ! Starting point for read (x,y)
integer(HID_T)                          :: dataspace        ! Dataspace
integer(HID_T)                          :: memspace     ! Memoryspace

offset=(/58000,22000/)          ! Set offset in 2d dataset
count=(/1200,1200/)             ! Set # pixels to read (1200x1200 slab)
allocate(tmpdata(1200,1200))        ! Allocate space to store this slab

call h5open_f(error)
call h5fopen_f ("myfile.h5", H5F_ACC_RDWR_F, fid, error)        ! Open HDF5 file

call h5dopen_f(fid, "mydataset", did, error)        ! Open dataset
call h5dget_space_f(did, dataspace, error)          ! Retrieve dataspace 


call h5screate_simple_f(2, count, memspace, error)      !Create memspace, rank=2,size=1200x1200 
call h5sselect_hyperslab_f(dataspace, H5S_SELECT_SET_F, offset, count, error)       ! Select slab in the data 
call h5dread_f(did, H5T_NATIVE_INTEGER, tmpdata, dimsm, error,memspace,dataspace)       ! Read the data from the HDF5 file into the tmpdata array

! Close everything
-snip-

直到h5dread_f调用,一切正常。然后我得到一个段错误。如果我将tmpdata设置为等于HDF5文件中实际数据集的大小,那么它可以工作,但这不是一个好的解决方案,因为对于某些文件,数据集太大而无法存储在内存中。 有任何想法吗?希望我只是做一些愚蠢的事情。如果重要的是我在Ubuntu 14.04上使用ifort和HDF5-1.8.15 Patch 1进行编译

1 个答案:

答案 0 :(得分:2)

根据您对变量dimsm的描述和省略,我猜测您将该变量设置为您正在阅读的变量的完整维度。这些维度应该是您设置的hyperslab的维度,这也是您在tmpdata中保存读取结果的变量的维度。您可以使用您用于在读取调用中创建hyperslab count的相同数组。

变化:

call h5dread_f(did, H5T_NATIVE_INTEGER, tmpdata, dimsm, error,memspace,dataspace)       

call h5dread_f(did, H5T_NATIVE_INTEGER, tmpdata, count, error,memspace,dataspace)    

你的阅读应该有效。

正在发生的事情(如果我的假设是正确的)是dimsm包含完整数据集维度的值(或两个维度中任何大于1200的值),因此读取数据的调用尝试读取数据在数据空间的边界之外(在给定的偏移处设置为1200x1200视图)并且如果不是段错误,那么它将尝试将大于1200x1200的读取放入1200x1200变量{{1} }。