【问题标题】:MPI_FILE_WRITE_ORDERED overwrites previous written dataMPI_FILE_WRITE_ORDERED 覆盖之前写入的数据
【发布时间】:2019-12-14 23:24:42
【问题描述】:

我有以下代码

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

【问题讨论】:

    标签: fortran mpi intel-fortran mpi-io


    【解决方案1】:

    引用 MPI 3.1 标准,来自 13.4.1 节的定位小节:“MPI 为数据访问例程提供三种定位类型:显式偏移、单个文件指针和共享文件指针。不同的定位方法可能是混在同一个程序中,互不影响。”

    您的问题是您混合了所有三种不同的定位方法。 MPI_FILE_WRITE_AT 使用显式偏移量。同样, MPI_FILE_SEEK 更改单个文件指针。 MPI_FILE_WRITE_ordered 在共享文件指针给定的当前位置写入。因此,由于“不同的定位方法可以在同一个程序中混合并且不会相互影响”,所以无论您提供给 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 保留的,使用它可能会发生名称冲突。因此我重命名了你的程序单元

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 2020-03-24
      • 2012-07-06
      • 2014-02-05
      相关资源
      最近更新 更多