将嵌套的bash脚本减少为单个文件/ mpirun命令

时间:2014-06-23 23:13:06

标签: bash shell mpi pbs

我经常使用类似下面简化的2个脚本的东西,用PBS / MPI在集群中分发令人尴尬的并行工作。我想知道命令是否可以合并到一个文件中以便清晰和减少混乱。我更感兴趣的是理解bash / mpirun的局限性,而不是寻找解决原始问题的替代方法,例如PBS数组。

PBS脚本:

#PBS -l nodes=2:ppn=2
#PBS -q debug
#PBS -V

mpirun -n $PBS_NP $PBS_O_WORKDIR/worker_script.sh

worker_script.sh

#!/bin/bash
NDATA=25
DATA_ARRAY=()
for ((DATA=${OMPI_COMM_WORLD_RANK};DATA<${NDATA};DATA=${DATA}+${PBS_NP}))
do
    DATA_ARRAY+=(${DATA})
done
echo ${OMPI_COMM_WORLD_RANK} processing ${DATA_ARRAY[@]}

Running提供所需的输出:

0 processing 0 4 8 12 16 20 24
1 processing 1 5 9 13 17 21
3 processing 3 7 11 15 19 23
2 processing 2 6 10 14 18 22

----------------------------------------------------------------
Jobs exit status code is 0

有没有办法用mpirun命令内联写入worker_script.sh的内容?除了单独的文件之外,是否存在由父进行shell扩展的方法?

3 个答案:

答案 0 :(得分:2)

任何看起来像

的东西
#!/bin/bash
stuff
here

(除了带有此处文档的脚本)可以等效地在单个逻辑行上表示为

bash -c 'stuff; here'

甚至更可读

bash -c 'stuff
    here'

(在这种情况下,您甚至可以嵌入此处的文档。)

如果您的脚本包含单引号,那么显然必须以某种方式解决。

将脚本放在单引号内可以保护它免受通配符扩展,变量替换等的影响。

只是因为你的意思并不代表你应该这样做。

答案 1 :(得分:2)

感谢您的回答,他们引发了有趣的研究。到目前为止,我个人首选的解决方案是对triee的bash -c提示进行扩展,将worker命令包装在导出的函数中:

#!/bin/bash
#PBS -l nodes=2:ppn=2
#PBS -q debug
#PBS -V

# function
worker_function(){
NDATA=25
DATA_ARRAY=()
for ((DATA=${OMPI_COMM_WORLD_RANK};DATA<${NDATA};DATA=${DATA}+${PBS_NP}))
do
    DATA_ARRAY+=(${DATA})
done
echo ${OMPI_COMM_WORLD_RANK} processing ${DATA_ARRAY[@]}
}

# main
export -f worker_function
mpirun -n $PBS_NP bash -c 'worker_function'

这遵循典型的程序结构,并与vim的语法突出显示一起使用。

答案 2 :(得分:0)

唔不......通常不会。 man mpirun“mpirun”是一个shell脚本,它试图隐藏用户启动各种设备作业的差异。典型用法:

mpirun -np <number of processes> <program name and arguments>

mpirun将程序名称(或者在您的情况下为脚本名称$ PBS_O_WORKDIR / worker_script.sh)作为参数,因此通常它需要调用不同的文件。但是,mpirun有许多关于批处理模式操作的机器特定选项,在bash中,可以允许在PBS脚本中使用heredoc来提供mpirun所需的信息。