2013-03-11 147 views
2

HDF5數據存儲使用C約定,即如果我在二進制文件中存儲矩陣A(N,M,K),則存儲數據的最快變化維度將具有大小N.顯然,當我使用HDF5的Fortran包裝時,HDF5會自動轉換矩陣,以便與C一致。我有一個存儲在由fortran編寫的未格式化二進制文件中的大小數據(256 x 128 x 256) 。我試圖通過使用下面給出的程序將其轉換成h5格式。但最終的輸出結果是將存儲矩陣的維數作爲(128,256,256)。我不知道該怎麼做才能確保最終的hd5文件可以在可視化軟件(Paraview)中正確顯示。HDF5用於用fortran編寫的數據文件

PROGRAM H5_RDWT 

USE HDF5 ! This module contains all necessary modules 

IMPLICIT NONE 


CHARACTER(LEN=6), parameter :: out_file = "out.h5" ! File name 
CHARACTER(LEN=6), parameter :: in_file = "in.dat" ! File name 
CHARACTER(LEN=4), parameter :: dsetname = "vort"! Dataset name 
CHARACTER(LEN=50) :: len 

INTEGER(HID_T) :: in_file_id ! File identifier 
INTEGER(HID_T) :: out_file_id ! File identifier 
INTEGER(HID_T) :: dset_id  ! Dataset identifier 
INTEGER(HID_T) :: dspace_id ! Dataspace identifier 

INTEGER :: in_file_id = 23 

INTEGER  :: nx = 256, ny=128, nz=256 

INTEGER(HSIZE_T), DIMENSION(3) :: dims    ! Dataset dimensions 
INTEGER  :: rank = 3       ! Dataset rank 

INTEGER  :: error     ! Error flag 
INTEGER  :: i, j, k, ii, jj, kk ! Indices 

REAL, allocatable :: buff_r(:,:,:) ! buffer for reading from input file 

dims(1) = nx 
dims(2) = ny 
dims(3) = nz 
allocate(buff_r(nx,ny,nz)) 

! Read the input data. 
open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=4*nx*ny*nz) 
read (in_file_id,rec=1) buff_r 


! Initialize FORTRAN interface of HDF5. 
CALL h5open_f(error) 

! Create a new file. 
CALL h5fcreate_f (out_file, H5F_ACC_TRUNC_F, out_file_id, error) 

! Create the dataspace. 
CALL h5screate_simple_f(rank, dims, dspace_id, error) 


! Create the dataset with default properties. 
CALL h5dcreate_f(out_file_id, dsetname, H5T_NATIVE_REAL, dspace_id, & 
     dset_id, error) 

! Write the dataset. 
CALL h5dwrite_f(dset_id, H5T_NATIVE_REAL, buff_r, dims, error) 

! End access to the dataset and release resources used by it. 
CALL h5dclose_f(dset_id, error) 

! Terminate access to the data space. 
CALL h5sclose_f(dspace_id, error) 

! Close the file. 
CALL h5fclose_f(out_file_id, error) 

! Close FORTRAN interface. 
CALL h5close_f(error) 

deallocate(buff_r) 

END PROGRAM H5_RDWT 

爲了說明發生了什麼,我使用下面的腳本生成一個簡單的數據文件:

program main 

    !-------- initialize variables ------------- 
    character(8) :: fname 
    integer, parameter:: n = 32 
    real*8, dimension(n,n,2*n) :: re 
    integer i,j,k, recl 
    Inquire(iolength = recl) re 

    !------ fill in the array with sample data ---- 

    do k = 1, 2*n 
    do j = 1, n 
     do i = 1, n 
      re(i,j,k) = 1.0 
     end do 
    end do 
    end do 

    !------ write in data in a file ----------- 
    write(fname, "(A)") "data.dat" 
    open (10, file=fname, form='unformatted', access='direct', recl=recl) 
    write(10,rec=1) re 
    close(10) 

    stop 
    end program main 

我複製伊恩·布什粘貼的程序,改變x的值, ny和nz分別爲32,32和64。我希望生成的h5文件有尺寸(32,32,64)。但它是(64,32,32)。這裏是正在發生的事情在我的機器:

[[email protected]]$gfortran generate_data.f90 
[[email protected]]$./a.out 
[[email protected]]$ls -l data.dat 
-rw-r--r-- 1 pradeep staff 524288 Mar 12 14:04 data.dat 
[[email protected]]$h5fc convert_to_h5.f90 
[[email protected]]$./a.out 
[[email protected]]$ls -l out.h5 
-rw-r--r-- 1 pradeep staff 526432 Mar 12 14:05 out.h5 
[[email protected]]$h5dump -H out.h5 
HDF5 "out.h5" { 
GROUP "/" { 
    DATASET "data" { 
     DATATYPE H5T_IEEE_F64LE 
     DATASPACE SIMPLE { (64, 32, 32)/(64, 32, 32) } 
    } 
} 
} 

請與我確認,如果你看到了同樣的事情。

回答

0

長註釋真的,而不是一個答案......

你能解釋,爲什麼你不認爲這是工作?有一次,我糾正了幾個東西在你的代碼

1)in_file_id與2種不同

2)RECL直接訪問文件中聲明兩次不一定以字節爲單位 - 通過輸出列表查詢得多便攜式

我得到它,已經產生一個虛擬文件用隨機數據下面,似乎工作:

[email protected]:~/test/stack$ cat hdf5.f90 
PROGRAM H5_RDWT 

USE HDF5 ! This module contains all necessary modules 

IMPLICIT NONE 


CHARACTER(LEN=6), parameter :: out_file = "out.h5" ! File name 
CHARACTER(LEN=6), parameter :: in_file = "in.dat" ! File name 
CHARACTER(LEN=4), parameter :: dsetname = "vort"! Dataset name 
CHARACTER(LEN=50) :: len 

!!$ INTEGER(HID_T) :: in_file_id ! File identifier 
INTEGER(HID_T) :: out_file_id ! File identifier 
INTEGER(HID_T) :: dset_id  ! Dataset identifier 
INTEGER(HID_T) :: dspace_id ! Dataspace identifier 

INTEGER(HID_T) :: in_file_id = 23 

INTEGER  :: nx = 256, ny=128, nz=256 

INTEGER(HSIZE_T), DIMENSION(3) :: dims    ! Dataset dimensions 
INTEGER  :: rank = 3       ! Dataset rank 

Integer :: recl 

INTEGER  :: error     ! Error flag 
INTEGER  :: i, j, k, ii, jj, kk ! Indices 

REAL, allocatable :: buff_r(:,:,:) ! buffer for reading from input file 

dims(1) = nx 
dims(2) = ny 
dims(3) = nz 
allocate(buff_r(nx,ny,nz)) 

Inquire(iolength = recl) buff_r 

! Read the input data. 
open (in_file_id,FILE=in_file,form='unformatted',access='direct',recl=recl) 
read (in_file_id,rec=1) buff_r 


! Initialize FORTRAN interface of HDF5. 
CALL h5open_f(error) 

! Create a new file. 
CALL h5fcreate_f (out_file, H5F_ACC_TRUNC_F, out_file_id, error) 

! Create the dataspace. 
CALL h5screate_simple_f(rank, dims, dspace_id, error) 


! Create the dataset with default properties. 
CALL h5dcreate_f(out_file_id, dsetname, H5T_NATIVE_REAL, dspace_id, & 
     dset_id, error) 

! Write the dataset. 
CALL h5dwrite_f(dset_id, H5T_NATIVE_REAL, buff_r, dims, error) 

! End access to the dataset and release resources used by it. 
CALL h5dclose_f(dset_id, error) 

! Terminate access to the data space. 
CALL h5sclose_f(dspace_id, error) 

! Close the file. 
CALL h5fclose_f(out_file_id, error) 

! Close FORTRAN interface. 
CALL h5close_f(error) 

deallocate(buff_r) 

END PROGRAM H5_RDWT 
[email protected]:~/test/stack$ h5fc hdf5.f90 
[email protected]:~/test/stack$ ./a.out 
[email protected]:~/test/stack$ ls -l out.h5 
-rw-rw-r-- 1 ian ian 33556576 Mar 11 10:29 out.h5 
[email protected]:~/test/stack$ ncdump out.h5 | head 
netcdf out { 
dimensions: 
    phony_dim_0 = 256 ; 
    phony_dim_1 = 128 ; 
variables: 
    float vort(phony_dim_0, phony_dim_1, phony_dim_0) ; 
data: 

vort = 
    0.9975595, 0.5668247, 0.9659153, 0.7479277, 0.3673909, 0.4806369, 
[email protected]:~/test/stack$ 

那麼,爲什麼你覺得有什麼問題嗎?

+0

感謝您指出的錯誤。感謝recl評論。該程序正常工作。但它給了我一個轉置矩陣。例如,如果使用fortran我寫一個大小爲(256,128,256)的3D數組,當我檢查輸出文件的數組維數時,它是(128,256,256)。要檢查輸出H5文件的尺寸,我用「h5dump -H out.h5」 – jhaprade 2013-03-11 11:37:27

+0

這是從我一個人的HDF5支持組聯繫了迴應:http://www.hdfgroup.org/HDF5/doc/ UG/UG_frame12Dataspaces.html,部分:7.3.2.5。 C與Fortran數據空間。但我不知道如何正確地實現它讀取fortran二進制文件並重寫它在h5格式 – jhaprade 2013-03-11 11:41:23

+0

好的,我完全困惑。我輸出的h5dump -H out.h5給出了DATASPACE SIMPLE {(256,128,256)/(256,128,256)},類似於我的「答案」中的ncdump報告。我看不出你是怎麼得到的(128,256,256)! – 2013-03-11 12:02:02

4

我也遇到了使用Fortran應用程序查看HDF5文件的麻煩。基本問題是Fortran和C以不同的方式存儲多維數組(Fortran是列主要的,C是行主要的),並且由於Fortran HDF5庫是C HDF5庫的接口,因此Fortran封裝器在傳遞數據之前轉換維度到C代碼中。同樣,當Fortran應用程序讀取HDF5文件時,Fortran包裝器會再次轉換尺寸。

因此,如果您使用Fortran應用程序進行所有寫作和閱讀,則不應該注意到任何差異。如果使用Fortran應用程序編寫文件,然後使用C應用程序(例如h5dump)讀取該文件,則尺寸將出現換位。這不是一個錯誤,它只是它的工作原理。

如果要正確顯示數據,請使用Fortran應用程序讀取數據或使用C應用程序並首先轉置數據。 (或者你可以在寫入數據之前轉置數據。)

如前所述,在第7.3.2節中對此進行了相當好的解釋。5文檔:http://www.hdfgroup.org/HDF5/doc/UG/UG_frame12Dataspaces.html

0

爲了安全原因,我建議你拆開矩陣轉換成向量形式,並將它們存儲在HDF5文件1D數據集。然後,在閱讀時以相同的方式組裝它們。使用H5SSELECT_HYPERSLAB_F寫入/讀取矩陣的切片。

+1

Fortran的HDF5庫綁定完全能夠處理多維數據集,您的建議部分刪除了使用HDF5的興趣。我建議不要關注它。 – 2017-10-24 08:46:07