【问题标题】:Read from standard input with all MPI processes使用所有 MPI 进程从标准输入读取
【发布时间】:2018-08-07 13:41:02
【问题描述】:

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

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

我真的很希望能够以mpirun -n $np ./program < input-file 的身份运行该程序。为此,我删除了OPEN 语句和相应的CLOSE 语句,并将所有READ(fid,*) 语句更改为READ(INPUT_UNIT,*)(我正在使用ISO_FORTRAN_ENV 模块)。

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

$ 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,但我没有发现任何关于从标准输入读取的信息。

【问题讨论】:

  • 您使用哪种 MPI 实现?单个进程只获得mpirun 的标准输入(有时是可控的)是很常见的。
  • 打开 MPI v2.0.1
  • 不鼓励将mpirun 与重定向一起使用,并且仅应在没有其他选择时使用(例如,如果输入文件仅在调用mpirun 的节点上可用)。原因是它涉及次优的带外流量。此用例也经过了轻微测试,并且报告了一些错误。另外,请注意 Open MPI 2.0.x 系列不再受支持,您应该升级到 3.0.x 或至少 2.1.x 系列。

标签: io fortran mpi stdin


【解决方案1】:

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

在除 MPI_COMM_WORLD rank 0 进程之外的所有进程上将 UNIX 标准输入定向到 /dev/null。 MPI_COMM_WORLD rank 0 进程从 mpirun 继承标准输入。

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


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

【讨论】:

  • 一旦断定这是预期的行为,使用它的方法就很清楚了。不过,如果您希望我扩展,请发表评论。
  • OpenMPI 令人满意的答案和令人失望的限制,因为我认为它与 Unix 哲学方向相反。好吧,如果您可以扩展您的答案,那也不错:您将如何将进程 0 的标准输入分配给所有其他进程?有没有比MPI_BCASTing 0 基于标准输入或从标准输入读取的每个变量更好的东西?在这一刻,我正在尝试向所有人广播0 读取的行,以便每个进程都可以独立解析它们。
  • 广播输入行将是我的第一个建议。诚然,这可能很快就会变得无聊。另一种选择:填充然后广播“参数”类型。
  • 你的意思是定义一个派生类型来收集所有应该根据输入文件设置的东西吗?
  • 是的。这种派生类型也可用于在结果数据集中填充元数据,并可能用于检查点/恢复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
相关资源
最近更新 更多