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

如何在HPC集群3个节点各用20核并行运行R代码?

多节点HPC上R并行计算的核数利用问题解决

1. HPC节点详情

当前可用3个节点,每个节点的硬件参数如下(scontrol show node输出):

scontrol show node

   Arch=x86_64 CoresPerSocket=10
   CPUAlloc=20 CPUTot=20 CPULoad=22.67
   AvailableFeatures=(null)
   ActiveFeatures=(null)
   Gres=(null)
   .
   .
   RealMemory=91000 AllocMem=0 FreeMem=77291 Sockets=2 Boards=1
   State=ALLOCATED ThreadsPerCore=1 TmpDisk=0 Weight=1 Owner=N/A MCS_label=N/A
   Partitions=cpu_normal_q
   BootTime=2023-10-20T12:56:13 SlurmdStartTime=2023-10-20T12:57:43
   CfgTRES=cpu=20,mem=91000M,billing=20
   AllocTRES=cpu=20
   CapWatts=n/a
   CurrentWatts=0 AveWatts=0
   ExtSensorsJoules=n/s ExtSensorsWatts=0 ExtSensorsTemp=n/s

每个节点总计20核,目标是3个节点共使用60核运行并行任务。

2. 原并行计算代码

使用doParallel实现矩阵运算并行迭代的R代码:

library(doParallel)
library(Matrix)

# 原代码用detectCores()仅能获取当前节点核数,无法跨节点
num_cores <- detectCores()

# 初始化并行后端
cl <- makeCluster(num_cores)

# 注册集群
registerDoParallel(cl)

# 获取当前使用核数
cores_utilized <- getDoParWorkers()

# 矩阵乘与求逆函数
matrix_mult_inv <- function() {
  mat <- matrix(rnorm(10000), nrow = 100)
  result <- mat %*% mat
  inv_result <- solve(result)
  return(inv_result)
}

start_time <- Sys.time()

# 300次并行迭代,结果写入文件
result <- foreach(i = 1:300, .combine = cbind) %dopar% {
  write.table(matrix_mult_inv(), paste("iteration_", i, ".txt", sep = ""))
}

end_time <- Sys.time()

print(paste("Number of cores being utilized:", cores_utilized))
print(paste("Time taken:", end_time - start_time))

stopCluster(cl)

3. 遇到的问题

尝试用以下代码指定节点和核数时,实际仅利用了3核,无法达到60核的目标:

cl <- makeCluster(num_nodes, type = "SOCK", explicit = TRUE,
                  outfile = "", nodes = c(#3 specific node names input here#),
                  cpus = cores_per_node)

4. 解决方案

4.1 正确创建跨节点并行集群

问题出在makeCluster的参数使用上:当需要跨节点分配指定核数时,需明确指定每个节点要启动的worker数量(即核数),而非仅指定节点数量。

修改集群初始化代码如下:

library(doParallel)
library(Matrix)

# 替换为实际的3个节点名称
node_names <- c("node01", "node02", "node03")

# 每个节点分配20个worker,生成包含60个元素的节点列表(每个节点名重复20次)
spec <- unlist(lapply(node_names, function(node) rep(node, 20)))

# 创建跨节点SOCK集群,outfile=""用于捕获worker输出
cl <- makeCluster(spec, type = "SOCK", outfile = "")

# 注册集群
registerDoParallel(cl)

# 验证核数,此时应返回60
cores_utilized <- getDoParWorkers()

# 后续函数定义、迭代逻辑与原代码一致
matrix_mult_inv <- function() {
  mat <- matrix(rnorm(10000), nrow = 100)
  result <- mat %*% mat
  inv_result <- solve(result)
  return(inv_result)
}

start_time <- Sys.time()

# 注意:原代码中.combine=cbind无实际意义(write.table返回NULL),可改为.combine=list或省略
result <- foreach(i = 1:300) %dopar% {
  write.table(matrix_mult_inv(), paste("iteration_", i, ".txt", sep = ""))
}

end_time <- Sys.time()

print(paste("Number of cores being utilized:", cores_utilized))
print(paste("Time taken:", end_time - start_time))

stopCluster(cl)

4.2 关键注意事项

  • 包依赖:确保所有目标节点上都已安装doParallel和Matrix包,否则worker会报错。
  • SSH无密码访问:HPC集群通常已配置节点间免密SSH,但如果未配置,需提前完成密钥对设置,确保主节点能无密码登录其他节点。
  • 资源分配:确认3个节点的20核均未被其他任务占用(可通过squeue或scontrol show node再次核对CPUAlloc状态)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:05:12