Bash SLURM:尴尬的并行程序中尴尬的并行程序

Bash SLURM:尴尬的并行程序中尴尬的并行程序,bash,matlab,slurm,Bash,Matlab,Slurm,我有一个用Matlab编写的复杂模型。该模型不是由我们编写的,最好将其视为一个“黑匣子”,即为了从内部解决相关问题,需要重写整个模型,这将花费数年时间 如果我有一个“令人尴尬的并行”问题,我可以使用一个数组提交同一模拟的X个变体,选项是#SBATCH--array=1-X。然而,集群通常对最大数组大小有一个(令人沮丧的小)限制 在使用PBS/TORQUE集群时,我通过强制Matlab在单个线程上运行,请求多个CPU,然后在后台运行Matlab的多个实例来解决这个问题。提交脚本示例如下: #!/b

我有一个用Matlab编写的复杂模型。该模型不是由我们编写的,最好将其视为一个“黑匣子”,即为了从内部解决相关问题,需要重写整个模型,这将花费数年时间

如果我有一个“令人尴尬的并行”问题,我可以使用一个数组提交同一模拟的X个变体,选项是
#SBATCH--array=1-X
。然而,集群通常对最大数组大小有一个(令人沮丧的小)限制

在使用PBS/TORQUE集群时,我通过强制Matlab在单个线程上运行,请求多个CPU,然后在后台运行Matlab的多个实例来解决这个问题。提交脚本示例如下:

#!/bin/bash
<OTHER PBS COMMANDS>
#PBS -l nodes=1:ppn=5,walltime=30:00:00
#PBS -t 1-600

<GATHER DYNAMIC ARGUMENTS FOR MATLAB FUNCTION CALLS BASED ON ARRAY NUMBER>

# define Matlab options
options="-nodesktop -noFigureWindows -nosplash -singleCompThread"

for sub_job in {1..5}
do
    <GATHER DYNAMIC ARGUMENTS FOR MATLAB FUNCTION CALLS BASED ON LOOP NUMBER (i.e. sub_job)>
    matlab ${options} -r "run_model(${arg1}, ${arg2}, ..., ${argN}); exit" &
done
wait
<TIDY UP AND FINISH COMMANDS>
#/bin/bash
#PBS-l节点=1:ppn=5,墙时间=30:00:00
#PBS-t 1-600
#定义Matlab选项
options=“-nodesktop-noFigureWindows-nosplash-singleCompThread”
对于{1..5}中的sub_作业
做
matlab${options}-r“运行_模型(${arg1},${arg2},${argN});退出”&
完成
等待
有人能帮我在SLURM集群上做同样的事情吗

  • par
    函数不会在Matlab中并行循环运行我的模型
  • PBS/TORQUE的语言非常直观,但SLURM的语言让我感到困惑。假设一个结构类似的提交脚本作为我的PBS示例,下面是我认为某些命令将产生的结果。
    • --每个任务的ncpus=5对我来说似乎是最明显的一个。我是将srun放在循环中matlab命令的前面,还是让它保持在PBS脚本循环中
    • --ntasks=5我想我会请求5个CPU,但将以串行方式运行,除非程序专门请求它们(即MPI或Python多线程等)。在这种情况下,我需要将srun放在Matlab命令前面吗

我不是阵列作业方面的专家,但我可以在内部循环方面帮助您

我总是在一个有多个CPU可用的作业中并行运行多个串行进程。它是一个简单的
perl
脚本,因此“安装”并不困难,其语法非常简单。它基本上是并行运行一些(嵌套的)循环。该循环的每次迭代都包含一个(长)过程,就像您的Matlab命令一样。与您的解决方案不同,它不会一次提交所有这些进程,但它只会同时运行
N
进程(其中
N
是您可用的CPU数量)。一个循环完成后,将提交下一个循环,依此类推,直到整个循环完成。并非所有进程都需要相同的时间,一个CPU被释放后,另一个进程就开始了,这是非常好的

然后,您要做的是启动600个作业(我在下面替换3个,以显示完整的行为),每个作业有5个CPU。要做到这一点,您可以执行以下操作(其中我没有包括实际运行的
matlab
,但可以包括这些内容):

使用以下命令提交此作业:

$ sbatch job.slurm
向队列提交3个作业。例如:

$ squeue | grep tdegeus
         3395882_1     debug  example  tdegeus  R       0:01      1 c07
         3395882_2     debug  example  tdegeus  R       0:01      1 c07
         3395882_3     debug  example  tdegeus  R       0:01      1 c07
每个作业有5个CPU。
parallel
命令可以利用这些特性并行运行内部循环。同样,此内部循环的范围可能(远)大于5,
parallel
负责此作业中5个可用CPU之间的平衡

让我们检查一下输出:

$ cat job.slurm.out

matlab array=2,subjob=1
matlab array=2,subjob=2
matlab array=2,subjob=3
matlab array=2,subjob=4
matlab array=2,subjob=5
matlab array=1,subjob=1
matlab array=3,subjob=1
matlab array=1,subjob=2
matlab array=1,subjob=3
matlab array=1,subjob=4
matlab array=3,subjob=2
matlab array=3,subjob=3
matlab array=1,subjob=5
matlab array=3,subjob=4
matlab array=3,subjob=5
您现在可以清楚地看到3乘以5的进程同时运行(因为它们的输出是混合的)

在这种情况下,无需使用
srun
。SLURM将创造3个工作岗位。在每个作业中,所有事情都发生在各个计算节点上(即,就像您在自己的系统上运行一样)


安装GNU并行-选项1 要将GNU parallel“安装”到您的主文件夹中,例如在
~/opt

  • 如果目录尚不存在,则将其设置为
    ~/opt

    mkdir $HOME/opt
    
  • “安装”GNU并行:

    tar jxvf parallel-latest.tar.bz2
    cd parallel-XXXXXXXX
    ./configure --prefix=$HOME/opt
    make
    make install
    
  • ~/opt
    添加到您的路径:

    export PATH=$HOME/opt/bin:$PATH
    
    (要使其永久化,请将该行添加到
    ~/.bashrc


  • 安装GNU并行-选项2 使用
    conda

  • (可选)创建新环境

    conda create --name myenv
    
  • 加载现有环境:

    conda activate myenv
    
  • 安装GNU并行:

    conda install -c conda-forge parallel 
    

  • 请注意,该命令仅在加载环境时可用。

    虽然Tom建议使用GNU并行,但我将尝试回答提出的问题

    如果您想使用相同的参数运行5个
    matlab
    命令实例(例如,如果它们通过MPI进行通信),那么您需要请求
    --ncpus per task=1
    --ntasks=5
    ,并且您应该在
    matlab
    行前面加上
    srun
    并去掉循环

    在您的情况下,由于对
    matlab
    的5个调用都是独立的,因此您希望请求
    --ncpus per task=5
    --ntasks=1
    。这将确保您为每个作业分配5个CPU内核,以便按照您的意愿进行处理。如果您愿意,您可以在
    matlab
    行前面加上
    srun
    ,但如果您只运行一个任务,则不会有什么不同


    当然,这只有在5次matlab运行的时间相同时才有效,因为如果其中一次运行的时间更长,那么其他4个CPU核心将处于空闲状态,等待第五次运行完成。

    您可以使用python和子流程来完成,在我下面描述的内容中,您只需设置节点和任务的数量,也就是说,不需要阵列,不需要将阵列的大小与模拟的数量相匹配,等等。。。它将只执行python代码,直到完成为止,节点越多,执行速度越快。 而且,由于所有的东西都是用python准备的(比bash更容易),所以决定变量也更容易

    它确实假设Matlab脚本
    conda install -c conda-forge parallel