fortran - MPI-IO: MPI_File_Set_View vs. MPI_File_Seek
(1)
La respuesta fue dada realmente en la respuesta de Hristo Iliev a esta pregunta :
Reemplace el
0
en la llamadaMPI_FILE_SET_VIEW
con0_MPI_OFFSET_KIND
o declare una constante de tipoINTEGER(KIND=MPI_OFFSET_KIND)
y un valor de cero y luego páselo.
call MPI_File_Set_View(fhandle, 0_MPI_OFFSET_KIND, MPI_DOUBLE_PRECISION, ...
o
integer(kind=MPI_OFFSET_KIND), parameter :: zero_off = 0 ... call MPI_File_Set_View(fhandle, zero_off, MPI_DOUBLE_PRECISION, ...
Ambos métodos conducen a un archivo de salida de 3200 bytes de tamaño (como se esperaba).
Me encuentro con un problema cuando intento escribir un archivo con MPI-IO, en Fortran 90. Si hago lo siguiente, uso 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
Obtengo un archivo 69Go, que es demasiado grande teniendo en cuenta lo que estoy escribiendo en él. Por cierto, el tamaño del archivo no cambia si aumento loc_x
y loc_y
.
Sin embargo, si uso MPI_File_Seek
, funciona mucho mejor; se crea un archivo de un tamaño razonable que contiene los datos que deseo escribir
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
Me parece que estos dos métodos deberían producir lo mismo y, en particular, que el primer método debería crear un archivo tan grande.
Recopilo mi código con gfortran 4.6.3 y OpenMPI 1.6.2.
¡Cualquier ayuda sería apreciada!