我正试图在SLURM集群(4x树莓派3(上运行一个简单的并行程序,但没有成功。我一直在读有关它的文章,但我就是无法让它发挥作用。问题如下:
我有一个名为remove_duplicates_in_scraped_data.py的Python程序。这个程序在一个节点上执行(节点=1xraspberry-pi(,程序内部有一个多处理循环部分,看起来像:
pool = multiprocessing.Pool()
input_iter= product(FeaturesArray_1, FeaturesArray_2, repeat=1)
results = pool.starmap(refact_featureMatch, input_iter)
其想法是,当它到达程序的这一部分时,它应该分发计算,迭代器中的每个元素一个线程,并在最后组合结果。因此,程序remove_duplicates_in_scraped_data.py运行一次(而不是多次(,在池计算过程中会产生不同的线程。
在一台机器上(不使用SLURM(,它运行得很好,对于树莓派的特殊情况,它生成4个线程,进行计算,保存在结果中,并将程序作为一个线程继续。
我想利用SLURM集群的所有16个线程,但我似乎无法使其发挥作用。我相信集群的配置是正确的,因为它可以在集群的所有16个线程中使用SLURM运行所有的多处理示例(例如计算pi的位数(。
现在,看看带有sinfo -N -l
的SLURM配置,我们有:
NODELIST NODES PARTITION STATE CPUS S:C:T MEMORY TMP_DISK WEIGHT AVAIL_FE REASON
node01 1 picluster* idle 4 4:1:1 1 0 1 (null) none
node02 1 picluster* idle 4 4:1:1 1 0 1 (null) none
node03 1 picluster* idle 4 4:1:1 1 0 1 (null) none
node04 1 picluster* idle 4 4:1:1 1 0 1 (null) none
每个集群报告4个套接字、1个Core和1个Thread,就SLURM而言,报告4个CPU。
我希望利用所有的16个CPU,如果我运行我的程序作为:
srun -N 4 -n 16 python3 remove_duplicates_in_scraped_data.py
它只会在每个节点中运行主程序的4个副本,从而产生16个线程。但这不是我想要的。我想要该程序的一个实例,然后它在集群中生成16个线程。至少我们知道使用srun-N-n16集群是可行的。
因此,我尝试更改程序如下:
#!/usr/bin/python3
#SBATCH -p picluster
#SBATCH --nodes=4
#SBATCH --ntasks=16
#SBATCH --cpus-per-task=1
#SBATCH --ntasks-per-node=4
#SBATCH --ntasks-per-socket=1
#SBATCH --sockets-per-node=4
sys.path.append(os.getcwd())
...
...
...
pool = multiprocessing.Pool()
input_iter= product(FeaturesArray_1, FeaturesArray_2, repeat=1)
results = pool.starmap(refact_featureMatch, input_iter)
...
...
并使用执行
sbatch remove_duplicates_in_scraped_data.py
slurm作业创建成功,我看到集群上的所有节点都已分配
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
picluster* up infinite 4 alloc node[01-04]
该程序开始在node01上作为单个线程运行,但当它到达并行部分时,它只在node01中生成4个线程,而在所有其他节点上没有生成任何线程。
我尝试了不同的设置组合,甚至尝试通过脚本运行它
#!/bin/bash
#SBATCH -p picluster
#SBATCH --nodes=4
#SBATCH --ntasks=16
#SBATCH --cpus-per-task=1
#SBATCH --ntasks-per-node=4
#SBATCH --ntasks-per-socket=1
#SBATCH --ntasks-per-core=1
#SBATCH --sockets-per-node=4
python3 remove_duplicates_in_scraped_data.py
但我就是无法让它在其他节点上生成。
你能帮帮我吗?有可能做到这一点吗?即在集群的不同节点上使用python的多处理池?如果没有,我还有什么其他选择?集群还配置了dask。这样能更好地工作吗?
请帮帮我,因为我真的陷入了困境。
感谢
Pythons多处理包仅限于共享内存并行化。它产生了新的进程,所有进程都可以访问单个机器的主内存。
您不能简单地将这样的软件扩展到多个节点上。由于不同的机器没有可以访问的共享内存。
要同时在多个节点上运行程序,您应该了解MPI(消息传递接口(。还有一个python包。
根据您的任务,也可能适合运行程序4次(因此每个节点一个作业(,并让它处理数据的子集。这通常是一种更简单的方法,但并不总是可行的。
因此,我使用SLURM集群运行DASK,Python脚本发誓可以很好地并行化。这需要最少的代码更改。因此,上面的多处理池代码被更改为:
cluster = SLURMCluster( header_skip=['--mem'],
queue='picluster',
cores=4,
memory='1GB'
)
cluster.scale(cores=16) #the number of nodes to request
dask_client = Client(cluster)
lazy_results=[]
for pair in input_iter:
res = dask_client.submit(refact_featureMatch, pair[0], pair[1])
lazy_results.append(res)
results = dask_client.gather(lazy_results)
当然,通过DASK可能还有更好的方法。我愿意接受建议:(