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

4

目前我一直在使用OPEN(fid, FILE='IN', ...), 看起来所有的MPI进程都可以无干扰地读取相同的文件IN.

此外,为了让输入文件可以从多个文件中选择,我只需将IN文件做成指向所需输入文件的符号链接。这意味着当我想要更改输入文件时,我必须在运行程序之前运行ln -sf desired-input INmpirun -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的标准输入(有时是可控的)。 - francescalus
Open MPI v2.0.1 - Enlico
不建议使用带有重定向的 mpirun,只有在没有其他选择时才应该使用(例如,如果输入文件仅在调用 mpirun 的节点上可用)。原因是它涉及到次优的带外流量。这种用例也经过轻微测试,并报告了一些错误。此外,请注意 Open MPI 2.0.x 系列已不再受支持,您应该升级到 3.0.x 或至少 2.1.x 系列。 - Gilles Gouaillardet
1个回答

4
你正在看到与OpenMPI的预期行为相同。默认情况下,mpirun将UNIX标准输入重定向到除MPI_COMM_WORLD等级0进程外的所有进程上的/dev/null。MPI_COMM_WORLD等级0进程从mpirun继承标准输入。
选项--stdin可用于将标准输入重定向到另一个进程,但不能全部重定向。
可以注意到,标准输入重定向的行为在MPI实现中并不一致(该概念未由MPI标准指定)。例如,在使用Intel MPI时,有一个“-s”选项可用于“mpirun”。使用“mpirun -np 4 -s all ./main”将允许所有进程访问“mpirun”的标准输入。没有保证没有进行重定向的进程会失败而不是等待读取。

一旦确认这是预期行为,处理它的方法就会变得清晰明了。如果需要,可以留言让我进一步解释。 - francescalus
OpenMPI的令人满意的答案和令人失望的限制,因为我认为它与Unix哲学背道而驰。好吧,如果您能扩展您的答案,那就不错了:您如何将进程0的标准输入分发给所有其他进程?是否有比基于stdin确定或读取的每个变量都进行MPI_BCAST更好的方法?此时,我正在尝试在0读取行时向每个人广播这些行,以便每个进程都可以独立解析它们。 - Enlico
广播输入行将是我的第一推荐。不可否认,这可能很快变得无聊。另一个选择:填充然后广播“参数”类型。 - francescalus
你的意思是定义一个派生类型来收集所有基于输入文件应该被设置的东西吗? - Enlico
1
是的。这样的派生类型也将对填充结果数据集中的元数据以及可能的检查点/恢复非常有用。 - francescalus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接