You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Slurm集群并行运行R代码时仅单个节点工作的问题求助

问题原因

你当前的R代码中,makeCluster(80)默认会在提交作业的单个节点上创建80个本地进程,但该节点仅配备40核,因此实际只能利用这40核,且所有进程不会分发到Slurm分配的第二个节点。这是因为parallel::makeCluster默认使用FORK类型(仅支持本地节点),且未指定远程节点列表。

解决方案

要实现跨2个节点利用80核,需要让R明确知道Slurm分配的所有节点,并基于这些节点创建跨节点的PSOCK集群(支持远程节点通信)。

步骤1:调整Slurm作业脚本(可选但更清晰)

明确指定每个节点的任务数,避免歧义:

#!/bin/bash
#SBATCH --job-name Cores.R
#SBATCH --partition warshel-cpu
#SBATCH --nodes=2
#SBATCH --ntasks-per-node=40  # 每个节点分配40核
#SBATCH --time 1-00:00:00
#SBATCH --output /path/to/your/output.log
#SBATCH --error /path/to/your/error.log
cd /path/to/your/workdir
R --vanilla --slave < Cores.R

步骤2:修改R代码,创建跨节点集群

通过Slurm环境变量获取分配的节点列表,基于这些节点创建PSOCK集群:

rm(list = ls())

library(parallel)

fun <- function(x){
  return(x + 1)
}

# 获取Slurm分配的所有节点主机名
nodes <- system("scontrol show hostnames $SLURM_NODELIST", intern = TRUE)
# 每个节点启动40个worker(匹配节点核数)
spec <- rep(nodes, each = 40)
# 创建跨节点PSOCK集群(依赖节点间SSH免密,Slurm集群通常已配置)
cl <- makeCluster(spec, type = "PSOCK")

ptm <- proc.time()
system.time({
  res <- parLapply(cl, 1:50000000, fun)
})
print(proc.time() - ptm)

stopCluster(cl)

替代方案:使用future包(更简洁的现代并行方式)

future包对集群环境的适配性更好,代码更简洁:

rm(list = ls())

library(future)
library(future.apply)

fun <- function(x){
  return(x + 1)
}

# 获取节点列表并配置集群计划
nodes <- system("scontrol show hostnames $SLURM_NODELIST", intern = TRUE)
spec <- rep(nodes, each = 40)
plan(cluster, workers = spec)

ptm <- proc.time()
res <- future_lapply(1:50000000, fun)
print(proc.time() - ptm)
关键说明
  • PSOCK类型集群通过SSH在远程节点启动worker,Slurm集群通常已配置节点间免密SSH,无需额外操作。
  • 避免使用FORK类型(makeCluster(80, type="FORK")),该类型仅能在本地节点创建进程,无法跨节点。

内容的提问来源于stack exchange,提问作者qwq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:48:19