如何在并行bash中运行这个简单的for循环?

如何在并行bash中运行这个简单的for循环?,r,bash,parallel-processing,slurm,R,Bash,Parallel Processing,Slurm,我尝试使用不同的参数多次运行Rscript,并使用bash脚本来执行此操作(我尝试在R中与foreach和doParallel等并行运行Rscript时出错,但这不是问题所在) 我打算用$sbatch script.sh(在hpc上)调用的脚本如下所示: #!/usr/bin/bash #SBATCH --time=48:00:00 #SBATCH --mem=10G #SBATCH --mail-type=END #SBATCH --mail-type=FAIL #SBATCH --mail

我尝试使用不同的参数多次运行Rscript,并使用bash脚本来执行此操作(我尝试在R中与foreach和doParallel等并行运行Rscript时出错,但这不是问题所在)

我打算用
$sbatch script.sh
(在hpc上)调用的脚本如下所示:

#!/usr/bin/bash

#SBATCH --time=48:00:00
#SBATCH --mem=10G
#SBATCH --mail-type=END
#SBATCH --mail-type=FAIL
#SBATCH --mail-user=my@mail.com

cd my_dir

for a in 1 2
do
for b in 1 2 3 4
do
for c in 1 2 3
do
for d in 1 2 3 4
do
for e in 5 10 15 20 30 40 50 75 100 200 300 400 500 750 1000 1250 1500 1750 2000
do
Rscript /hpc/someRscript.R $dist $rlen $trans $meta $init &
done
done
done
done
done

echo done
命令
$sbatch script.sh
导致我在大约40秒后收到一封电子邮件,告诉我它完成了。我怀疑使用&符号是这里的罪魁祸首。我认为它试图同时执行所有操作,这会使计算节点过载


有没有一种简单的方法可以将其转换为阵列作业?或者有更好的方法让我并行运行吗?

要让脚本正常工作,您需要

  • 可以使用变量名
    a
    b
    c
    等,也可以使用
    $dist
    $rlen
    $trans
    $meta
    $init
    ,但不能同时使用两者
  • wait
    结束脚本,否则Slurm会认为脚本已经完成
  • 因此:

    现在的一个问题是,这将创建1824个进程,并尝试同时运行它们。这将是非常低效的。因此,您应该使用
    srun
    在可用的CPU数量上“微调度”所有这些进程。请注意,您可能需要使用
    --ntasks
    显式请求一定数量的CPU

    #!/usr/bin/bash
    
    #SBATCH --time=48:00:00
    #SBATCH --mem=10G
    #SBATCH --mail-type=END
    #SBATCH --mail-type=FAIL
    #SBATCH --mail-user=my@mail.com
    #SBATCH --ntasks=<SOME NUMBER>
    
    cd my_dir
    
    for dist in 1 2
    do
    for rlen in 1 2 3 4
    do
    for trans in 1 2 3
    do
    for meta in 1 2 3 4
    do
    for init in 5 10 15 20 30 40 50 75 100 200 300 400 500 750 1000 1250 1500 1750 2000
    do
    srun -n 1 -c 1 --exclusive Rscript /hpc/someRscript.R $dist $rlen $trans $meta $init &
    done
    done
    done
    done
    done
    wait
    echo done
    
    #/usr/bin/bash
    #SBATCH--时间=48:00:00
    #SBATCH--mem=10G
    #SBATCH--邮件类型=结束
    #SBATCH--邮件类型=失败
    #SBATCH--邮件用户=my@mail.com
    #SBATCH--ntasks=
    我的目录
    12区
    做
    在1 2 3 4中的rlen
    做
    对于trans in 1 2 3
    做
    对于12 3 4中的meta
    做
    对于5 10 15 20 30 40 50 75 100 200 300 500 750 1000 1250 1500 1750 2000中的初始值
    做
    srun-n1-c1——独占Rscript/hpc/someRscript.R$dist$rlen$trans$meta$init&
    完成
    完成
    完成
    完成
    完成
    等待
    回音完成
    
    此外,如果GNUparallel可用,您可以将脚本简化为

    #!/usr/bin/bash
    
    #SBATCH --time=48:00:00
    #SBATCH --mem=10G
    #SBATCH --mail-type=END
    #SBATCH --mail-type=FAIL
    #SBATCH --mail-user=my@mail.com
    #SBATCH --ntasks=<SOME NUMBER>
    
    cd my_dir
    
    parallel -P SLURM_NTASKS srun -n 1 -c 1 --exclusive Rscript /hpc/someRscript.R ::: 1 2 ::: 1 2 3 4 ::: 1 2 3 ::: 1 2 3 4 ::: 5 10 15 20 30 40 50 75 100 200 300 400 500 750 1000 1250 1500 1750 2000
    
    echo done
    
    #/usr/bin/bash
    #SBATCH--时间=48:00:00
    #SBATCH--mem=10G
    #SBATCH--邮件类型=结束
    #SBATCH--邮件类型=失败
    #SBATCH--邮件用户=my@mail.com
    #SBATCH--ntasks=
    我的目录
    parallel-P SLURM_NTASKS srun-n1-c1——独占Rscript/hpc/someRscript.R::12::1234::1234:::5101520300507510000750125017502000
    回音完成
    
    将其转换为作业数组并非易事。一个小步骤是以最里面的循环为例(最大的循环),并在该参数上运行数组

    #!/usr/bin/bash
    
    #SBATCH --time=48:00:00
    #SBATCH --mem=10G
    #SBATCH --mail-type=END
    #SBATCH --mail-type=FAIL
    #SBATCH --mail-user=my@mail.com
    #SBATCH --ntasks=<SOME NUMBER>
    #SBATCH --array=0-18
    
    cd my_dir
    
    INIT=(5 10 15 20 30 40 50 75 100 200 300 400 500 750 1000 1250 1500 1750 2000)
    
    parallel -P SLURM_NTASKS srun -n 1 -c 1 --exclusive Rscript /hpc/someRscript.R {} ${INIT[$SLURM_ARRAY_TASK_ID]} ::: 1 2 ::: 1 2 3 4 ::: 1 2 3 ::: 1 2 3 4 
    
    echo done
    
    #/usr/bin/bash
    #SBATCH--时间=48:00:00
    #SBATCH--mem=10G
    #SBATCH--邮件类型=结束
    #SBATCH--邮件类型=失败
    #SBATCH--邮件用户=my@mail.com
    #SBATCH--ntasks=
    #SBATCH--数组=0-18
    我的目录
    初始值=(510 15 20 30 40 50 75 100 200 300 500 750 1000 1250 1500 1750 2000)
    parallel-P SLURM_NTASKS srun-n1-c1——独占Rscript/hpc/someRscript.R{}${INIT[$SLURM_ARRAY_TASK_ID]}:::12::1234:::1233::1234
    回音完成
    

    如果在Bash数组中创建所有组合,则可以在所有组合上运行该数组,并使用
    $SLURM\u array\u TASK\u ID
    对它们进行索引。

    如果希望限制并行操作(例如,基于可用资源),则可能需要查看a)
    GNU parallel
    ,b)
    xargs/-p
    ,或者c)通过手动计算在后台启动的作业数,再加上使用
    wait-n
    ,滚动您自己的代码;谷歌搜索这些项目中的任何一个都会在stackoverflow(或其姊妹网站)上找到相当多的点击率
    #!/usr/bin/bash
    
    #SBATCH --time=48:00:00
    #SBATCH --mem=10G
    #SBATCH --mail-type=END
    #SBATCH --mail-type=FAIL
    #SBATCH --mail-user=my@mail.com
    #SBATCH --ntasks=<SOME NUMBER>
    #SBATCH --array=0-18
    
    cd my_dir
    
    INIT=(5 10 15 20 30 40 50 75 100 200 300 400 500 750 1000 1250 1500 1750 2000)
    
    parallel -P SLURM_NTASKS srun -n 1 -c 1 --exclusive Rscript /hpc/someRscript.R {} ${INIT[$SLURM_ARRAY_TASK_ID]} ::: 1 2 ::: 1 2 3 4 ::: 1 2 3 ::: 1 2 3 4 
    
    echo done