Bash SLURM:尴尬的并行程序中尴尬的并行程序
我有一个用Matlab编写的复杂模型。该模型不是由我们编写的,最好将其视为一个“黑匣子”,即为了从内部解决相关问题,需要重写整个模型,这将花费数年时间 如果我有一个“令人尴尬的并行”问题,我可以使用一个数组提交同一模拟的X个变体,选项是Bash SLURM:尴尬的并行程序中尴尬的并行程序,bash,matlab,slurm,Bash,Matlab,Slurm,我有一个用Matlab编写的复杂模型。该模型不是由我们编写的,最好将其视为一个“黑匣子”,即为了从内部解决相关问题,需要重写整个模型,这将花费数年时间 如果我有一个“令人尴尬的并行”问题,我可以使用一个数组提交同一模拟的X个变体,选项是#SBATCH--array=1-X。然而,集群通常对最大数组大小有一个(令人沮丧的小)限制 在使用PBS/TORQUE集群时,我通过强制Matlab在单个线程上运行,请求多个CPU,然后在后台运行Matlab的多个实例来解决这个问题。提交脚本示例如下: #!/b
#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集群上做同样的事情吗
函数不会在Matlab中并行循环运行我的模型par
- PBS/TORQUE的语言非常直观,但SLURM的语言让我感到困惑。假设一个结构类似的提交脚本作为我的PBS示例,下面是我认为某些命令将产生的结果。
- --每个任务的ncpus=5对我来说似乎是最明显的一个。我是将srun放在循环中matlab命令的前面,还是让它保持在PBS脚本循环中
- --ntasks=5我想我会请求5个CPU,但将以串行方式运行,除非程序专门请求它们(即MPI或Python多线程等)。在这种情况下,我需要将srun放在Matlab命令前面吗
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
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
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