我正在尝试使用一个简单的 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 中的问题或解释为什么会发生这种情况将不胜感激!