2013-08-27 29 views
1

我遇到我在嘗試寫與MPI-IO文件,用Fortran 90。如果我這樣做有問題,使用MPI_File_Set_ViewMPI-IO:MPI_File_Set_View與MPI_File_Seek

program test 
    implicit none 

    include "mpif.h" 

    integer :: myrank, nproc, fhandle, ierr 
    integer :: xpos, ypos 
    integer, parameter :: loc_x=10, loc_y=10 
    integer :: loc_dim 
    integer :: nx=2, ny=2 
    real(8), dimension(loc_x, loc_y) :: data, data_read 
    integer :: written_arr 
    integer, dimension(2) :: wa_size, wa_subsize, wa_start 
    integer :: int_size, double_size 
    integer(kind=MPI_OFFSET_KIND) :: offset 

    call MPI_Init(ierr) 
    call MPI_Comm_Rank(MPI_COMM_WORLD, myrank, ierr) 
    call MPI_Comm_Size(MPI_COMM_WORLD, nproc, ierr) 

    xpos = mod(myrank, nx) 
    ypos = mod(myrank/nx, ny) 

    data = myrank 

    loc_dim = loc_x*loc_y 

    ! Write using MPI_File_Set_View 
    wa_size = (/ nx*loc_x, ny*loc_y /) 
    wa_subsize = (/ loc_x, loc_y /) 
    wa_start = (/ xpos, ypos /)*wa_subsize 
    call MPI_Type_Create_Subarray(2, wa_size, wa_subsize, wa_start & 
     , MPI_ORDER_FORTRAN, MPI_DOUBLE_PRECISION, written_arr, ierr) 
    call MPI_Type_Commit(written_arr, ierr) 

    call MPI_Type_Size(MPI_INTEGER, int_size, ierr) 
    call MPI_Type_Size(MPI_DOUBLE_PRECISION, double_size, ierr) 

    call MPI_File_Open(MPI_COMM_WORLD, "file_set_view.dat" & 
     , MPI_MODE_WRONLY + MPI_MODE_CREATE, MPI_INFO_NULL, fhandle, ierr) 
    call MPI_File_Set_View(fhandle, 0, MPI_DOUBLE_PRECISION, written_arr & 
     , "native", MPI_INFO_NULL, ierr) 
    call MPI_File_Write_All(fhandle, data, loc_dim, MPI_DOUBLE_PRECISION & 
     , MPI_STATUS_IGNORE, ierr) 
    call MPI_File_Close(fhandle, ierr) 

    call MPI_Finalize(ierr) 

end program test 

我得到一個69Go文件,考慮到我寫的內容太大了。順便說一下,如果我增加loc_xloc_y,文件的大小不會改變。

但是,如果我用MPI_File_Seek,它的效果要好得多;合理大小的文件被創建,包含我想寫

program test 
    implicit none 

    include "mpif.h" 

    integer :: myrank, nproc, fhandle, ierr 
    integer :: xpos, ypos 
    integer, parameter :: loc_x=10, loc_y=10 
    integer :: loc_dim 
    integer :: nx=2, ny=2 
    real(8), dimension(loc_x, loc_y) :: data, data_read 
    integer :: written_arr 
    integer, dimension(2) :: wa_size, wa_subsize, wa_start 
    integer :: int_size, double_size 
    integer(kind=MPI_OFFSET_KIND) :: offset 

    call MPI_Init(ierr) 
    call MPI_Comm_Rank(MPI_COMM_WORLD, myrank, ierr) 
    call MPI_Comm_Size(MPI_COMM_WORLD, nproc, ierr) 

    xpos = mod(myrank, nx) 
    ypos = mod(myrank/nx, ny) 

    data = myrank 

    loc_dim = loc_x*loc_y 

    ! Write using MPI_File_Seek 
    call MPI_File_Open(MPI_COMM_WORLD, "file_seek.dat" & 
     , MPI_MODE_WRONLY + MPI_MODE_CREATE, MPI_INFO_NULL, fhandle, ierr) 
    offset = loc_x*loc_y*myrank 
    print*, 'myrank, offset, data: ', myrank, offset, data(1,:2) 
    call MPI_File_Seek(fhandle, offset, MPI_SEEK_SET) 
    call MPI_File_Write_All(fhandle, data, loc_dim, MPI_DOUBLE_PRECISION & 
     , MPI_STATUS_IGNORE, ierr) 
    call MPI_File_Close(fhandle, ierr) 

    call MPI_Finalize(ierr) 

end program test 

的數據在我看來,這兩種方法應該產生同樣的事情,而且,特別是,第一種方法應該創建一個這樣大文件。

我編譯我的gfortran 4.6.3和1.6.2的openmpi代碼。

任何幫助,將不勝感激!

回答

1

答案在this question里斯託·利維的回答竟是給出:

更換0MPI_FILE_SET_VIEW通話與 0_MPI_OFFSET_KIND或聲明類型 INTEGER(KIND=MPI_OFFSET_KIND)的恆定和零值,然後把它傳遞。

call MPI_File_Set_View(fhandle, 0_MPI_OFFSET_KIND, MPI_DOUBLE_PRECISION, ... 

integer(kind=MPI_OFFSET_KIND), parameter :: zero_off = 0 
... 
call MPI_File_Set_View(fhandle, zero_off, MPI_DOUBLE_PRECISION, ... 

這兩種方法都導致尺寸的輸出文件3200個字節(如預期)。