0

我是 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。有人请指出我哪里出错了 :( 那么,我怎样才能让所有进程从此输入文件 < Modelfile.txt 中读取??谢谢。

4

1 回答 1

5

该声明

READ(LIN,'(L3)') PRNTA

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

LIN设置为常数值 5,这通常意味着stdin. 使用5to 表示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 通道的访问权限;让多个进程尝试(几乎)同时读取单个输入通道是减慢速度的可靠方法。

于 2013-10-03T09:13:11.157 回答