如何让Julia在集群启动作业时利用多节点资源?
解决Slurm集群上Julia多节点并行资源利用问题
问题根源
你当前的写法中,addprocs(Nworkers - 1)只会在提交作业的本地节点启动Worker进程,完全没有利用Slurm分配的其他节点,所以多节点请求时只有一个节点在工作。
推荐解决方案:用Slurm srun 自动分配跨节点Worker
这种方式最简洁,让Slurm直接管理Worker的节点分布,无需手动处理节点列表。
1. 修改Slurm批处理脚本
#SBATCH --partition=partition #SBATCH --nodes=2 #SBATCH --ntasks-per-node=5 # 每个节点启动5个Worker,2节点共10个,匹配你原来的Nworkers=10 #SBATCH --cpus-per-task=16 # 每个Worker分配16线程 export JULIA_NUM_THREADS=$SLURM_CPUS_PER_TASK # 用srun启动Julia,自动在所有分配节点上启动Worker进程 srun julia --optimize=3 --compile=all --threads=$JULIA_NUM_THREADS --project myScript.jl
2. 修改Julia脚本(无需手动添加Worker)
srun已经根据Slurm配置启动了所有需要的Worker,直接使用即可:
using Distributed # 可选:验证Worker数量,应该等于--ntasks-per-node * --nodes = 10 # println("Total workers: ", nworkers()) @sync for pid in workers() @spawnat pid longComputation() end # 或者用更简洁的分布式循环语法: # @sync @distributed for _ in 1:nworkers() # longComputation() # end
备选方案:手动传递节点列表给addprocs
如果需要更灵活控制Worker分布,可以手动从Slurm获取节点列表,再传递给Julia的addprocs:
1. 修改Slurm批处理脚本
#SBATCH --partition=partition #SBATCH --nodes=2 #SBATCH --cpus-per-task=16 export JULIA_NUM_THREADS=$SLURM_CPUS_PER_TASK # 获取分配的节点列表,每个节点重复5次(对应每个节点5个Worker) NODE_LIST=$(scontrol show hostnames $SLURM_JOB_NODELIST | xargs -I{} echo {} {} {} {} {}) # 将节点列表作为参数传给Julia脚本 julia --optimize=3 --compile=all --threads=$JULIA_NUM_THREADS --project myScript.jl $NODE_LIST
2. 修改Julia脚本
从命令行参数读取节点列表,添加跨节点Worker:
using Distributed # 从命令行参数获取节点列表 node_list = ARGS # 添加Worker到指定节点 addprocs(node_list) @sync for pid in workers() @spawnat pid longComputation() end
关键说明
--ntasks-per-node控制每个节点启动的Worker数量,结合--nodes可以精准控制总Worker数;--cpus-per-task必须和JULIA_NUM_THREADS对应,保证每个Worker能用到分配的所有CPU线程;- 用
srun的方式能避免手动处理节点列表的错误,是Slurm集群上并行作业的标准做法。
内容的提问来源于stack exchange,提问作者MaxiKubi
相关产品推荐
相关产品推荐

