SLURM和python,分配了节点,但是代码只在一个节点上运行
SLURM and python, nodes are allocated, but the code only runs on one node
我有一个 4*64 CPU 集群。我安装了 SLURM,它似乎在工作,就好像我调用 sbatch
我得到了正确的分配和 queue。但是,如果我使用超过 64 个内核(因此基本上超过 1 个节点),它会完美地分配正确数量的节点,但如果我 ssh
进入分配的节点,我只能看到其中一个节点的实际工作。其余的只是坐在那里无所事事。
我的代码很复杂,它使用了multiprocessing
。我打电话给大约 300 名工人的游泳池,所以我想这应该不是问题。
我想要实现的是在大约 200 个内核上调用 sbatch myscript.py
,SLURM 应该在这 200 个内核上分配我的 运行,不仅分配正确数量的节点,而且实际上只使用一个。
我的 python 脚本的 header 如下所示:
#!/usr/bin/python3
#SBATCH --output=SLURM_%j.log
#SBATCH --partition=part
#SBATCH -n 200
我用 sbatch myscript.py
调用脚本。
我认为你的 sbatch 脚本不应该在 python 脚本中。相反,它应该是一个普通的 bash 脚本,包括 #SBATCH
选项,后跟 运行 和 srun
作业的实际脚本。像下面这样:
#!/usr/bin/bash
#SBATCH --output=SLURM_%j.log
#SBATCH --partition=part
#SBATCH -n 200
srun python3 myscript.py
我建议用一个简单的 python 脚本来测试这个:
import multiprocessing as mp
def main():
print("cpus =", mp.cpu_count())
if __name__ == "__main__":
main()
不幸的是,multiprocessing
不允许在多个节点上工作。来自 documentation:
the multiprocessing module allows the programmer to fully leverage
multiple processors on a given machine
通常与 Slurm 一起使用的一个选项是使用 MPI (with the MPI4PY 包)但 MPI 被认为是 'the assembly language of parallel programming',您将需要可扩展地修改您的代码。
另一种选择是查看 Parallel Processing packages for one that suits your needs and requires minimal changes to your code. See also this other question 以获得更多见解。
最后一点:将 #SBATCH
指令放入 Python 脚本并使用 Python shebang 是完全可以的。但是由于 Slurm 执行脚本的副本而不是脚本本身,因此您必须添加一行
sys.path.append(os.getcwd())
在脚本的开头(但在 #SBATCH
行之后)以确保 Python 找到位于您的目录中的任何模块。
我试图通过在以下 bash 脚本中使用 s运行 来绕过使用不同的 python 库。 s运行 应该 运行 在你分配给你的每个节点上。基本思想是它确定它 运行 所在的节点并分配一个节点 id 0, 1, ... , nnodes-1。然后它将该信息连同线程 ID 一起传递给 python 程序。在程序中,我将这两个数字组合在一起,为每个节点上的每个 cpu 创建一个不同的 id。此代码假定每个节点上有 16 个核心,并且将使用 10 个节点。
#!/bin/bash
nnames=(`scontrol show hostnames`)
nnodes=${#nnames[@]}
nIDs=`seq 0 $(($nnodes-1))`
nID=0
for i in $nIDs
do
hname=`hostname`
if [ "${nnames[$i]}" == "$hname" ]
then nID=$i
fi
done
tIDs=`seq 0 15`
for tID in $tIDs
do
python testDataFitting2.py $nID $tID 160 &
done
wait
我有一个 4*64 CPU 集群。我安装了 SLURM,它似乎在工作,就好像我调用 sbatch
我得到了正确的分配和 queue。但是,如果我使用超过 64 个内核(因此基本上超过 1 个节点),它会完美地分配正确数量的节点,但如果我 ssh
进入分配的节点,我只能看到其中一个节点的实际工作。其余的只是坐在那里无所事事。
我的代码很复杂,它使用了multiprocessing
。我打电话给大约 300 名工人的游泳池,所以我想这应该不是问题。
我想要实现的是在大约 200 个内核上调用 sbatch myscript.py
,SLURM 应该在这 200 个内核上分配我的 运行,不仅分配正确数量的节点,而且实际上只使用一个。
我的 python 脚本的 header 如下所示:
#!/usr/bin/python3
#SBATCH --output=SLURM_%j.log
#SBATCH --partition=part
#SBATCH -n 200
我用 sbatch myscript.py
调用脚本。
我认为你的 sbatch 脚本不应该在 python 脚本中。相反,它应该是一个普通的 bash 脚本,包括 #SBATCH
选项,后跟 运行 和 srun
作业的实际脚本。像下面这样:
#!/usr/bin/bash
#SBATCH --output=SLURM_%j.log
#SBATCH --partition=part
#SBATCH -n 200
srun python3 myscript.py
我建议用一个简单的 python 脚本来测试这个:
import multiprocessing as mp
def main():
print("cpus =", mp.cpu_count())
if __name__ == "__main__":
main()
不幸的是,multiprocessing
不允许在多个节点上工作。来自 documentation:
the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine
通常与 Slurm 一起使用的一个选项是使用 MPI (with the MPI4PY 包)但 MPI 被认为是 'the assembly language of parallel programming',您将需要可扩展地修改您的代码。
另一种选择是查看 Parallel Processing packages for one that suits your needs and requires minimal changes to your code. See also this other question 以获得更多见解。
最后一点:将 #SBATCH
指令放入 Python 脚本并使用 Python shebang 是完全可以的。但是由于 Slurm 执行脚本的副本而不是脚本本身,因此您必须添加一行
sys.path.append(os.getcwd())
在脚本的开头(但在 #SBATCH
行之后)以确保 Python 找到位于您的目录中的任何模块。
我试图通过在以下 bash 脚本中使用 s运行 来绕过使用不同的 python 库。 s运行 应该 运行 在你分配给你的每个节点上。基本思想是它确定它 运行 所在的节点并分配一个节点 id 0, 1, ... , nnodes-1。然后它将该信息连同线程 ID 一起传递给 python 程序。在程序中,我将这两个数字组合在一起,为每个节点上的每个 cpu 创建一个不同的 id。此代码假定每个节点上有 16 个核心,并且将使用 10 个节点。
#!/bin/bash
nnames=(`scontrol show hostnames`)
nnodes=${#nnames[@]}
nIDs=`seq 0 $(($nnodes-1))`
nID=0
for i in $nIDs
do
hname=`hostname`
if [ "${nnames[$i]}" == "$hname" ]
then nID=$i
fi
done
tIDs=`seq 0 15`
for tID in $tIDs
do
python testDataFitting2.py $nID $tID 160 &
done
wait