【问题标题】:How to pass parameters from input file to fortran 77 mpirun during run time?如何在运行时将参数从输入文件传递到 fortran 77 mpirun?
【发布时间】:2013-10-09 13:26:25
【问题描述】:

我是 MPI 和 Fortran 77 新手。我有一个 fortran 77 代码FKRPRO.f,我想使用 OpenMPI 对其进行并行化。该代码需要大量参数,这些参数在运行时从单独的文件中输入。编译运行是这样的

gfortran -o FKRPRO FKRPRO.f
./FKRPRO < Modelfile.txt

代码中的等效行(不是我的代码)是

      PARAMETER(LIN=5)
      INTEGER ERROR
      LOGICAL PRNTA
      PRNTA=.FALSE.
      READ(LIN,'(L3)') PRNTA
      READ(LIN,21) M1,M2
   21 FORMAT(11I5)

等等。有人可以向我解释READ(LIN,'(L3)') PRNTA 的含义。输入文件Modelfile.txt中的输入是这样的

.F.                                                                             
    0   64  
and so on..   

我将必要的 MPI 语句放入代码中。

      INCLUDE 'MPIF.H'
...
      CALL MPI_INIT(ERROR)
      CALL MPI_COMM_SIZE(MPI_COMM_WORLD,NPROCS,ERROR)
      CALL MPI_COMM_RANK(MPI_COMM_WORLD,PRANK,ERROR)
...
      CALL MPI_TYPE_FREE(NEWMATRIX,ERROR)
      CALL MPI_FINALIZE(ERROR)

所有进程都无法读取输入文件。我已经编译并运行了这样的代码

mpif77 -o bc3 FKRPROG5.f
mpirun -np 4 bc3 < Modelfile.txt 

这不起作用。我收到以下错误。只有第一个进程或 rank 0 可以读取文件。

At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
At line 50 of file FKRPROG5.f (unit = 5, file = 'stdin')
Fortran runtime error: End of file
mpirun has exited due to process rank 3 with PID 866 on
node Avinash-rMBP.local exiting improperly. There are two reasons this could occur:

1. this process did not call "init" before exiting, but others in
the job did. This can cause a job to hang indefinitely while it waits
for all processes to call "init". By rule, if one process calls "init",
then ALL processes must call "init" prior to termination.

2. this process called "init", but exited without calling "finalize".
By rule, all processes that call "init" MUST call "finalize" prior to
exiting or it will be considered an "abnormal termination"

This may have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).

第 50 行是 READ(LIN,'(L3)') PRNTA。有人请指出我哪里出错了 :( 那么,如何让所有进程从此输入文件

【问题讨论】:

    标签: fortran openmpi fortran77


    【解决方案1】:

    声明

    READ(LIN,'(L3)') PRNTA
    

    使程序从连接到 ID 为 LIN 的通道的单元中读取一个 3 字符序列,该序列表示一个逻辑值并将读取的值分配给变量 PRNTA。从您向我们展示的片段中,程序将读取.F. 并将PRNTA 设置为.false.

    LIN 设置为常数值 5,通常表示stdin。这种使用5 来表示stdin 不是法律上 标准,它更像是事实上 标准。

    将参数文件读入 MPI 程序的直接方法是确保只有一个进程读取文件,然后将值发送给需要它们的其他进程。

    您似乎编写了一个程序,其中所有进程都尝试读取相同的输入文件,但在运行时,您用来传递 Modelfile.txt 的重定向仅适用于一个进程(可能是与排名 0)。其他进程根本没有得到输入文件并抱怨,然后导致程序崩溃。您显示的错误消息是典型的 Fortran 程序,它在尝试读取时根本找不到输入文件。

    更好地编写代码:

    call mpi_init ...
    ...
    if (myrank==0) then
        open(...) inputfile
        read(...) parameters
        close(...)
    end if
    ...
    call mpi_bcast(parameters from 0 to all)
    ...
    

    一般来说,不要期望 MPI 进程的运行时环境与顺序程序的运行时环境完全相同。我认为您看到的证据表明您的运行时仅将输入定向到程序运行时创建的第一个进程。由于mpirun 不是标准化的(尽管mpiexec 是标准化的),我认为您不能依赖这种运行时行为对于所有MPI 实现都是相同的。为了可移植性和兼容性,最好在程序中显式处理 I/O,而不是使用重定向等 o/s 功能。

    您可以编写代码,让每个进程读取相同的文件,而不是让进程 0 读取参数并将它们分发给其他进程。如果您确实以这种方式编写代码,请注意确保进程不会争夺对 I/O 通道的访问权限;让多个进程尝试(几乎)同时读取单个输入通道是减慢速度的可靠方法。

    【讨论】:

    • @HighPermonaceMark:亲爱的马克!只是出于好奇,你的经验是什么?并发阅读真的会减慢事情的完成速度吗?总是如此还是仅适用于大文件?它依赖于文件系统吗?我知道许多代码(包括我们的),所有线程同时读取(诚然只有几 kB 小)输入文件,而且它似乎不是任何类型的瓶颈。 (另一方面,错误地同时写入同一个文件会产生巨大的影响)。
    • @BálintAradi:将这些陈述与您的相匹配:广泛,包括具有 0000 个处理器和并行 i/o 的机器。通过少量进程并发访问小文件,可能不会导致足够的减速而烦恼。测试和测量,不要相信我的话。是的,依赖于操作系统和文件系统,依赖于硬件。 YMMV,或者更准确地说,您的体验确实有所不同。 (并不惊讶)。最后,此答案中提供的建议针对的是新手 OP,您在 SO 上的足迹表明您已经足够成熟,可以自己解决大部分问题。
    • 谢谢!对不起我上面的表述,我意识到它读起来可能有点冒犯,这绝对不是故意的。我没有质疑你的经历。相反,我在这方面寻求建议,因为我们正处于并行化项目的开始阶段,我想避免因缺乏经验而做出糟糕的设计决策。不幸的是,我无法像您那样使用大型机器,因此我的测试可能性相当有限。
    • @BálintAradi:我丝毫没有被冒犯,我读了你的评论(我认为)你的意思。如果您开始进行广泛的代码并行化,那么我建议您在自己的系统上研究 i/o 并量化我所涉及的各种影响。通常我们在进程 0 上对小文件(例如作业参数)使用串行 i/o,然后使用 MPI_BCAST。对于大文件,有时是并行 i/o,有时让进程顺序读取它们自己的块。有时我们只是让进程争夺一个驱动头并接受后果。
    • @BálintAradi:MPI 为具有数据视图、流访问等的并行 I/O 提供了非常广泛的 API。 ROMIO 是大多数通用 MPI 库(如 MPICH、Open MPI 等)使用的 MPI I/O 实现,它知道如何显式处理某些文件系统,以实现最大的和可移植性 性能。即使在访问小文件时,MPI I/O 也可能比 Fortran 或 C 运行时库函数更快。
    猜你喜欢
    • 2016-12-15
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-07-06
    • 2011-05-30
    • 2016-07-10
    相关资源
    最近更新 更多