1

我正在尝试使用一个简单的 bash 脚本来顺序运行一批 MPI 作业。该脚本在运行串行代码时完美运行(我使用的是 Fortran 90),但由于某种原因,当我尝试执行 MPI 代码时 bash 会跳出循环。

我已经找到了解决该问题的方法。我只是在 Perl 中编写了基本完全相同的脚本,它就像一个魅力。我真的很想了解这里的问题,因为我更喜欢 bash 的简单性,并且它在几乎所有其他情况下都非常适合我自己的脚本需求。

我尝试将 MPI 代码作为后台进程运行,并使用 wait 得到相同的结果。如果我在后台运行作业而不使用等待,bash 不会跳出循环,但它会堆叠作业直到最终崩溃。无论如何,目标是为每个参数集按顺序运行可执行文件,我只是想注意在这种情况下循环不会中断。

Bash 脚本,interp.sh:用法 --> $ ./interp.sh 输入文件

#!/bin/bash

PROG=$1
IFILE=$2

kount=0 # Counter variable for looping through input file
sys=0 # Counter variable to store how many times model has been run
while IFS="\n" read -r line
do
    kount=$(( $kount + 1 ))
    if [ $(( kount % 2 )) -eq 1 ] # if kount is even, then expect headers
    then
        unset name defs
        sys=$(( $sys + 1 ))
        name=( $line ) # parse headers
        defs=${#name[*]}
        k=$(( $defs - 1 ))

    else # if count is odd, then expect numbers
        unset vals
        vals=( $line ) # parse parameters
        for i in $( seq 0 $k )
        do
            # Define variables using header names and set their values
            printf -v "${name[i]}" "${vals[i]}"
        done

        # Print input variable values
        echo $a $b $c $d $e $nPROC
        # Run executable
        mpiexec -np $nPROC --oversubscribe --hostfile my_hostfile $PROG
    fi
done < $IFILE

输入文件,input.dat:

a   b   c   d   e   nPROC
1   2   3   4   5    2
nPROC
3
nPROC
4
nPROC
5
nPROC
6
nPROC
7
nPROC
8

示例 MPI f90 代码,main.f90:

program main
use mpi
implicit none
integer :: i, ierr, myID, nPROC
integer, parameter :: foolen = 100000

double precision, dimension(0:foolen) :: foo

call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, nPROC, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, myID, ierr)

if ( myID .eq. 0 ) then
    do i=0,foolen
        foo(i) = i
    end do
else
    do i=0,foolen
        foo(i) = i
    end do
end if
call MPI_FINALIZE(ierr)

end program

示例生成文件:

COMP=mpif90
EXT=f90
CFLAGs=-Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=all \
       -fbacktrace
MPIflags=--oversubscribe --hostfile my_hostfile

PROG=main.x
INPUT=input.dat
OUTPUT=output
OBJS=main.o

$(PROG): $(OBJS)
    $(COMP) $(CFLAGS) -o $(PROG) $(OBJS) $(LFLAGS)

main.o: main.f90
    $(COMP) -c $(CFLAGs) main.f90

%.o: %.f90
    $(COMP) -c $(CFLAGs) $<

run:
    make && make clean
    ./interp.sh $(PROG) $(INPUT)

clean:
    rm -f *.o DONE watch

我的主机文件

localhost slots=4

请注意,如果 mpiexec 行被注释掉,脚本将按预期运行。输出如下所示:

1 2 3 4 5 2
1 2 3 4 5 3
1 2 3 4 5 4
1 2 3 4 5 5
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 8

这些是应该在每个循环中传递给 MPI 代码的参数值。但是,在脚本中调用 mpiexec 时,只会读取并传递第一组参数。

如果这一切有点过分,我深表歉意,我只是想提供测试所需的一切。任何帮助解决 bash 中的问题或解释为什么会发生这种情况将不胜感激!

4

0 回答 0