使用所有 MPI 进程从标准输入读取

Read from standard input with all MPI processes

到目前为止我一直在使用 OPEN(fid, FILE='IN', ...) 并且似乎所有 MPI 进程都读取同一个文件 IN 而不会相互干扰。

此外,为了允许在多个文件中选择输入文件,我只是将 IN 文件设为指向所需输入的符号 link。这意味着当我想更改输入文件时,我必须在 运行 程序 (mpirun -n $np ./program).

之前 运行 ln -sf desidered-input IN

我真的很想 运行 作为 mpirun -n $np ./program < input-file 的节目。为此,我删除了 OPEN 语句和相应的 CLOSE 语句,并将所有 READ(fid,*) 语句更改为 READ(INPUT_UNIT,*) (我正在使用 ISO_FORTRAN_ENV 模块) .

但是,在所有编辑之后,我意识到只有一个进程(总是 0,我注意到)从中读取,因为所有其他进程都会立即到达 EOF。这是一个 MWE,使用 OpenMPI 2.0.1。

! cat main.f90
program main
    use, intrinsic :: iso_fortran_env
    use mpi
    implicit none
    integer :: myid, x, ierr, stat
    x = 12
    call mpi_init(ierr)
    call mpi_comm_rank(mpi_comm_world, myid, ierr)
    read(input_unit,*, iostat=stat) x
    if (is_iostat_end(stat)) write(output_unit,*) myid, "I'm out"
    if (.not. is_iostat_end(stat)) write(output_unit,*) myid, "I'm in", myid, x
    call mpi_finalize(ierr)
end program main

可以用 mpifort -o main main.f90 编译,运行 可以用 mpirun -np 4 ./main 编译,结果是这个输出

               1 I'm out
               2 I'm out
               3 I'm out
    17 this is my input from keyboard
               0 I'm in           0          17

我知道 MPI 有适当的例程来执行并行 I/O,但我没有发现任何有关从标准输入读取的信息。

您看到的是 expected behaviour with OpenMPI。默认情况下,mpirun

directs UNIX standard input to /dev/null on all processes except the MPI_COMM_WORLD rank 0 process. The MPI_COMM_WORLD rank 0 process inherits standard input from mpirun.

选项--stdin可用于将标准输入定向到另一个进程,但不能定向到所有进程。


还可以注意到,标准输入的重定向行为在 MPI 实现中并不一致(MPI 标准未指定该概念)。例如,使用英特尔 MPI 时,mpirun-s 选项。 mpirun -np 4 -s all ./main 确实允许所有进程访问 mpirun 的标准输入。也不能保证没有重定向的进程会失败,而不是等待读取。