Fortran MPI代码中的标准输出

ast*_*rog 5 fortran mpi

我有一个并行的fortran代码,我只希望rank = 0进程能够写入stdout,但我不想乱丢代码:

if(rank==0) write(*,*) ...
Run Code Online (Sandbox Code Playgroud)

所以我想知道做以下事情是不是一个好主意,或者是否有更好的方法?

program test

  use mpi

  implicit none

  integer :: ierr
  integer :: nproc
  integer :: rank

  integer :: stdout

  call mpi_init(ierr)
  call mpi_comm_rank(mpi_comm_world, rank, ierr)
  call mpi_comm_size(mpi_comm_world, nproc, ierr)

  select case(rank)
  case(0)
     stdout = 6
  case default
     stdout = 7
     open(unit=stdout, file='/dev/null')
  end select

  write(stdout,*) "Hello from rank=", rank

  call mpi_finalize(ierr)

end program test
Run Code Online (Sandbox Code Playgroud)

这给出了:

$ mpirun -n 10 ./a.out
Hello from rank=           0
Run Code Online (Sandbox Code Playgroud)

谢谢你的建议!

ste*_*ert 12

您的解决方案有两个缺点:

  1. 这个"聪明"的解决方案实际上掩盖了代码,因为它存在:stdout不再是stdout.如果有人读取代码,他/她会认为所有进程都写入stdout,而实际上并非如此.
  2. 如果您希望所有进程在某个时刻写入stdout,那么您会做什么?添加更多技巧?

如果你真的想坚持这个技巧,请不要使用"stdout"作为单元号的变量,但是例如"master"或任何表明你实际上没有写入stdout的东西.此外,您应该知道该数字6并不总是标准输出.Fortran 2003允许您检查stdout的单元号,因此如果可以,您应该使用它.

我的建议是坚持这些if(rank==0)陈述.它们清楚地表明代码中发生了什么.如果使用大量类似的i/o语句,则可以编写子程序,仅用于写入0级或所有进程.这些可以具有指示预期用途的有意义的名称.