MPI_FILE_WRITE_ORDERED 覆盖之前写入的数据
MPI_FILE_WRITE_ORDERED overwrites previous written data
我有以下代码
program mpi_io
use mpi
implicit none
integer :: mpierr, whoami, nproc, iout, STATUS(MPI_STATUS_SIZE),charsize
integer(kind=mpi_offset_kind):: OFFSET, fs
character(len=60) :: dd,de
character:: newline = NEW_LINE('FORTRAN')
call MPI_INIT ( mpierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, whoami, mpierr )
call MPI_COMM_SIZE ( MPI_COMM_WORLD, nproc, mpierr )
dd ='=========================' // INT2STR(whoami)//newline
de = 'special'// INT2STR(whoami)//newline
call MPI_FILE_OPEN( MPI_COMM_WORLD, 'test.dat', MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, IOUT, mpierr)
call mpi_type_size(mpi_byte, charsize , mpierr)
offset = charsize*len(TRIM(de))
if(whoami == 0)call MPI_FILE_WRITE_AT( iout,offset, TRIM(de), len(TRIM(de)), MPI_BYTE, status, mpierr)
call MPI_File_get_size(iout, fs, mpierr)
offset = fs
call MPI_FILE_SEEK(iout, fs, MPI_SEEK_SET, mpierr)
call MPI_FILE_WRITE_ordered( iout, TRIM(dd), len(TRIM(dd)), MPI_BYTE, status, mpierr)
!call MPI_FILE_WRITE_ordered( iout, dd, len(dd), MPI_CHARACTER, status, mpierr)
call mpi_file_close(iout,mpierr)
call mpi_finalize(mpierr)
contains
function INT2STR( i ) result( str )
integer, intent(in) :: i
character(:), allocatable :: str
character(RANGE(i)+2) :: tmp
write(tmp, '(I0)') i
str = TRIM(tmp)
end function
end program
我正在寻找的是仅由一个处理器写入文件,有时由所有处理器写入文件的组合。正如您在本例中看到的,我首先只想按根等级写入 de
,然后按所有处理器写入 dd
。
写吧,好像我的de
被覆盖了
如您所见,我试图通过查询文件大小来抵消它并执行 MPI_FILE_SEEK,但它似乎没有帮助
有没有人有想法。
我正在使用 IFORT v19
引用 MPI 3.1 标准,来自第 13.4.1 节,定位小节:"MPI provides three types of positioning for data access routines: explicit offsets, individual file pointers, and shared file pointers. The different positioning methods may be mixed within the same program and do not affect each other."
你的问题是你混合了所有三种不同的定位方法。 MPI_FILE_WRITE_AT 使用显式偏移量。同样,MPI_FILE_SEEK 更改单个文件指针。 MPI_FILE_WRITE_ordered 在共享文件指针给定的当前位置写入。因此,作为 "the different positioning methods may be mixed within the same program and do not affect each other",无论您向 MPI_FILE_WRITE_AT 和 MPI_FILE_SEEK 提供什么,都不会以任何方式影响 MPI_FILE_WRITE_ordered 将数据放入文件的位置。因此,在您的程序中第一次调用 MPI_FILE_WRITE_ordered 将覆盖 MPI_FILE_WRITE_AT.
写入的数据
你想要的是当你写 de 时更新共享文件指针。此外,由于它仅通过一个过程完成,因此您不需要集体例程。实现此目的的正确例程是 MPI_FILE_WRITE_SHARED。这是您的程序的一个版本,我相信它可以满足您的要求:
ijb@ianbushdesktop ~/work/stack $ cat mpiio.f90
program test_mpi_io
use mpi
implicit none
integer :: mpierr, whoami, nproc, iout, STATUS(MPI_STATUS_SIZE),charsize
character(len=60) :: dd,de
character:: newline = NEW_LINE('FORTRAN')
call MPI_INIT ( mpierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, whoami, mpierr )
call MPI_COMM_SIZE ( MPI_COMM_WORLD, nproc, mpierr )
dd ='=========================' // INT2STR(whoami)//newline
de = 'special'// INT2STR(whoami)//newline
call MPI_FILE_OPEN( MPI_COMM_WORLD, 'test.dat', MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, IOUT, mpierr)
call mpi_type_size(mpi_byte, charsize , mpierr)
if(whoami == 0)call MPI_FILE_WRITE_SHARED( iout,TRIM(de), len(TRIM(de)), MPI_BYTE, status, mpierr)
call MPI_FILE_WRITE_ordered( iout, TRIM(dd), len(TRIM(dd)), MPI_BYTE, status, mpierr)
call mpi_file_close(iout,mpierr)
call mpi_finalize(mpierr)
contains
function INT2STR( i ) result( str )
integer, intent(in) :: i
character(:), allocatable :: str
character(RANGE(i)+2) :: tmp
write(tmp, '(I0)') i
str = TRIM(tmp)
end function INT2STR
end program test_mpi_io
ijb@ianbushdesktop ~/work/stack $ mpif90 -Wall -Wextra -std=f2003 -O mpiio.f90 -o test_mpi_io
ijb@ianbushdesktop ~/work/stack $ rm test.dat
ijb@ianbushdesktop ~/work/stack $ mpirun -np 4 ./test_mpi_io
ijb@ianbushdesktop ~/work/stack $ cat test.dat
special0
=========================0
=========================1
=========================2
=========================3
ijb@ianbushdesktop ~/work/stack $ rm test.dat
ijb@ianbushdesktop ~/work/stack $ mpirun -np 8 ./test_mpi_io
ijb@ianbushdesktop ~/work/stack $ cat test.dat
special0
=========================0
=========================1
=========================2
=========================3
=========================4
=========================5
=========================6
=========================7
ijb@ianbushdesktop ~/work/stack $
另外,当我在这里时,您应该避免在 mpi 程序中调用任何以 mpi_ 开头的名称。这是因为该组合由 mpi 保留,使用它有名称冲突的风险。因此我重命名你的程序单元
我有以下代码
program mpi_io
use mpi
implicit none
integer :: mpierr, whoami, nproc, iout, STATUS(MPI_STATUS_SIZE),charsize
integer(kind=mpi_offset_kind):: OFFSET, fs
character(len=60) :: dd,de
character:: newline = NEW_LINE('FORTRAN')
call MPI_INIT ( mpierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, whoami, mpierr )
call MPI_COMM_SIZE ( MPI_COMM_WORLD, nproc, mpierr )
dd ='=========================' // INT2STR(whoami)//newline
de = 'special'// INT2STR(whoami)//newline
call MPI_FILE_OPEN( MPI_COMM_WORLD, 'test.dat', MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, IOUT, mpierr)
call mpi_type_size(mpi_byte, charsize , mpierr)
offset = charsize*len(TRIM(de))
if(whoami == 0)call MPI_FILE_WRITE_AT( iout,offset, TRIM(de), len(TRIM(de)), MPI_BYTE, status, mpierr)
call MPI_File_get_size(iout, fs, mpierr)
offset = fs
call MPI_FILE_SEEK(iout, fs, MPI_SEEK_SET, mpierr)
call MPI_FILE_WRITE_ordered( iout, TRIM(dd), len(TRIM(dd)), MPI_BYTE, status, mpierr)
!call MPI_FILE_WRITE_ordered( iout, dd, len(dd), MPI_CHARACTER, status, mpierr)
call mpi_file_close(iout,mpierr)
call mpi_finalize(mpierr)
contains
function INT2STR( i ) result( str )
integer, intent(in) :: i
character(:), allocatable :: str
character(RANGE(i)+2) :: tmp
write(tmp, '(I0)') i
str = TRIM(tmp)
end function
end program
我正在寻找的是仅由一个处理器写入文件,有时由所有处理器写入文件的组合。正如您在本例中看到的,我首先只想按根等级写入 de
,然后按所有处理器写入 dd
。
写吧,好像我的de
被覆盖了
如您所见,我试图通过查询文件大小来抵消它并执行 MPI_FILE_SEEK,但它似乎没有帮助 有没有人有想法。
我正在使用 IFORT v19
引用 MPI 3.1 标准,来自第 13.4.1 节,定位小节:"MPI provides three types of positioning for data access routines: explicit offsets, individual file pointers, and shared file pointers. The different positioning methods may be mixed within the same program and do not affect each other."
你的问题是你混合了所有三种不同的定位方法。 MPI_FILE_WRITE_AT 使用显式偏移量。同样,MPI_FILE_SEEK 更改单个文件指针。 MPI_FILE_WRITE_ordered 在共享文件指针给定的当前位置写入。因此,作为 "the different positioning methods may be mixed within the same program and do not affect each other",无论您向 MPI_FILE_WRITE_AT 和 MPI_FILE_SEEK 提供什么,都不会以任何方式影响 MPI_FILE_WRITE_ordered 将数据放入文件的位置。因此,在您的程序中第一次调用 MPI_FILE_WRITE_ordered 将覆盖 MPI_FILE_WRITE_AT.
写入的数据你想要的是当你写 de 时更新共享文件指针。此外,由于它仅通过一个过程完成,因此您不需要集体例程。实现此目的的正确例程是 MPI_FILE_WRITE_SHARED。这是您的程序的一个版本,我相信它可以满足您的要求:
ijb@ianbushdesktop ~/work/stack $ cat mpiio.f90
program test_mpi_io
use mpi
implicit none
integer :: mpierr, whoami, nproc, iout, STATUS(MPI_STATUS_SIZE),charsize
character(len=60) :: dd,de
character:: newline = NEW_LINE('FORTRAN')
call MPI_INIT ( mpierr )
call MPI_COMM_RANK ( MPI_COMM_WORLD, whoami, mpierr )
call MPI_COMM_SIZE ( MPI_COMM_WORLD, nproc, mpierr )
dd ='=========================' // INT2STR(whoami)//newline
de = 'special'// INT2STR(whoami)//newline
call MPI_FILE_OPEN( MPI_COMM_WORLD, 'test.dat', MPI_MODE_CREATE + MPI_MODE_WRONLY, MPI_INFO_NULL, IOUT, mpierr)
call mpi_type_size(mpi_byte, charsize , mpierr)
if(whoami == 0)call MPI_FILE_WRITE_SHARED( iout,TRIM(de), len(TRIM(de)), MPI_BYTE, status, mpierr)
call MPI_FILE_WRITE_ordered( iout, TRIM(dd), len(TRIM(dd)), MPI_BYTE, status, mpierr)
call mpi_file_close(iout,mpierr)
call mpi_finalize(mpierr)
contains
function INT2STR( i ) result( str )
integer, intent(in) :: i
character(:), allocatable :: str
character(RANGE(i)+2) :: tmp
write(tmp, '(I0)') i
str = TRIM(tmp)
end function INT2STR
end program test_mpi_io
ijb@ianbushdesktop ~/work/stack $ mpif90 -Wall -Wextra -std=f2003 -O mpiio.f90 -o test_mpi_io
ijb@ianbushdesktop ~/work/stack $ rm test.dat
ijb@ianbushdesktop ~/work/stack $ mpirun -np 4 ./test_mpi_io
ijb@ianbushdesktop ~/work/stack $ cat test.dat
special0
=========================0
=========================1
=========================2
=========================3
ijb@ianbushdesktop ~/work/stack $ rm test.dat
ijb@ianbushdesktop ~/work/stack $ mpirun -np 8 ./test_mpi_io
ijb@ianbushdesktop ~/work/stack $ cat test.dat
special0
=========================0
=========================1
=========================2
=========================3
=========================4
=========================5
=========================6
=========================7
ijb@ianbushdesktop ~/work/stack $
另外,当我在这里时,您应该避免在 mpi 程序中调用任何以 mpi_ 开头的名称。这是因为该组合由 mpi 保留,使用它有名称冲突的风险。因此我重命名你的程序单元