Fortran 90 で MPI-IO を使用してファイルを書き込もうとすると問題が発生します。MPI_File_Set_View
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_x
んloc_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
これら 2 つの方法は同じものを生成するように思われます。特に、最初の方法は非常に大きなファイルを作成する必要があります。
コードを gfortran 4.6.3 と OpenMPI 1.6.2 でコンパイルします。
どんな助けでも大歓迎です!