0

我在某种程度上本着 MPI I/O 的精神,从https://github.com/LadaF/PoisFFT/blob/master/src/testmpi.f90(在最后)对一个简单的 MPI-IO 子程序进行了现代化改造,混合单一- 和多进程输出。我的意图是在一个更重要的程序中使用这个过程。save_vtk()

我到达了这段代码,它产生了正确的输出(删除了错误检查):

这只做了一次,对性能来说是微不足道的:

if (master) then
  header =  ... !the header from the link above in a long string
end if
call MPI_Bcast(header_len, storage_size(header_len)/8, &
      MPI_BYTE, 0, glob_comm, ie)

call MPI_Type_create_subarray(3, int(ng), int(nxyz), int(off), &
   MPI_ORDER_FORTRAN, MPI_RP, filetype, ie)

call MPI_type_commit(filetype, ie)

这做了很多次:

call MPI_File_open(glob_comm,"out.vtk", &
       IOR(IOR(MPI_MODE_CREATE, MPI_MODE_WRONLY), &
       MPI_MODE_EXCL), MPI_INFO_NULL, fh, ie)

if (ie/=0) then                  !should not happen in serious computations
  call MPI_Barrier(glob_comm, ie)

  if (master) call MPI_File_delete("out.vtk",MPI_INFO_NULL, ie)

  call MPI_Barrier(glob_comm, ie)

  call MPI_File_open(glob_comm,"out.vtk", &
         IOR(MPI_MODE_CREATE, MPI_MODE_WRONLY),&
         MPI_INFO_NULL, fh, ie)
end if

call MPI_File_set_view(fh, 0_MPI_OFFSET_KIND, &
       MPI_CHARACTER, MPI_CHARACTER, "native", &
       MPI_INFO_NULL, ie)

if (master) then
   call MPI_File_write(fh, header, header_len, &
         MPI_CHARACTER, MPI_STATUS_IGNORE, ie)
end if

call MPI_Barrier(glob_comm, ie)
call MPI_File_set_view(fh, header_len, MPI_RP, &
       filetype, "native", MPI_INFO_NULL, ie)

call MPI_File_write_all(fh, buffer, nx*ny*nz, MPI_RP, &
       MPI_STATUS_IGNORE, ie)

call MPI_File_close(fh, ie)

代码首先测试文件是否已经存在,如果是,则将其删除并再次打开。完整的可测试代码位于新的 git 分支中(https://github.com/LadaF/PoisFFT/blob/new_mpi_io/src/testmpi.f90)。

我想摆脱重复的MPI_File_set_view()或至少MPI_Barrier()介于两者之间的,因此立即为标头和数组块的根进程设置视图,然后让根进程同时写入标头和数组块到视图中。

那可能吗?

4

1 回答 1

1

我会让根进程只使用带有“替换”的 fortran streamIO 来摆脱 MPI_File_delete 以及多个视图和屏障调用:

if (master) then
  open(file="out.vtk", access='stream', status='replace', newunit=out)
  write(out) header
  close(out)
endif

call MPI_Barrier(...)

call MPI_File_open(...)

call MPI_File_setview(...)

call MPI_File_write_all(...)

call MPI_File_close(...)

仍然有一个障碍,但我看不到绕过它的方法。

于 2018-04-19T16:42:28.527 回答