我想在HPC上使用Slurm调度程序并行化R脚本。
SLURM配置有SelectType: CR_Core_Memory
。
每个计算节点有16个核心(32个线程)。
我使用clustermq作为Slurm的接口,使用以下配置将R脚本传递给SLURM。
#!/bin/sh
#SBATCH --job-name={{ job_name }}
#SBATCH --partition=normal
#SBATCH --output={{ log_file | /dev/null }} # you can add .%a for array index
#SBATCH --error={{ log_file | /dev/null }}
#SBATCH --mem-per-cpu={{ memory | 2048 }}
#SBATCH --cpus-per-task={{ n_cpus }}
#SBATCH --array=1-{{ n_jobs }}
#SBATCH --ntasks={{ n_tasks }}
#SBATCH --nodes={{ n_nodes }}
#ulimit -v $(( 1024 * {{ memory | 4096 }} ))
R --no-save --no-restore -e 'clustermq:::worker("{{ master }}")'
在R脚本中,我使用30个内核进行“多核”并行化。我想使用来自多个节点的核来满足30 cpu的要求,即来自node1的16个核,来自node2的14个核。
我尝试使用n_tasks = 2
和cpus-per-task=16
。这样,作业将分配给两个节点。但是,只有一个节点正在进行计算(在16个核心上)。第二个节点分配给作业但不执行任何操作。
在this问题中,srun
用于通过foreach
和Slurm ID在节点之间划分并行性。我既不使用srun
也不使用foreach
。有没有办法达到我想要的SBATCH
和multicore
并行度?
(我知道我可以使用SelectType=CR_CPU_Memory
并且每个节点有32个线程可用。但是,问题是如何使用来自多个节点的核心/线程来扩展并行性)。
我的评论摘要:
答案是你无法做到这一点,因为你的任务是在一个R进程中使用一堆CPU。您要求单个R进程在比物理机器更多的CPU上并行执行任务。您无法跨多个节点拆分单个R进程。这些节点不共享内存,因此您无法组合来自不同节点的CPU,至少不能与典型的集群架构相结合。如果你有一个像DCOS这样的分布式操作系统,这是可能的。
在您的情况下,解决方案是您需要做的是在R流程之外分配您的工作。运行2个(或3个或4个)单独的R进程,每个进程在其自己的节点上,然后将每个R进程限制为您的计算机具有的最大CPU数。