使用所有 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
的标准输入。也不能保证没有重定向的进程会失败,而不是等待读取。
到目前为止我一直在使用 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
的标准输入。也不能保证没有重定向的进程会失败,而不是等待读取。