R在HPC MPIcluster上运行foreach dopar循环

Posted

技术标签:

【中文标题】R在HPC MPIcluster上运行foreach dopar循环【英文标题】:R Running foreach dopar loop on HPC MPIcluster 【发布时间】:2016-03-11 07:01:32 【问题描述】:

我可以访问带有 MPI 分区的 HPC 集群。

我的问题是 - 无论我尝试什么 - 我的代码(在我的 PC 上运行良好)都无法在 HPC 集群上运行。代码如下所示:

图书馆(tm) 图书馆(qdap) 图书馆(雪) 图书馆(doSNOW) 库(foreach)

> cl<- makeCluster(30, type="MPI")
> registerDoSNOW(cl)
> np<-getDoParWorkers()
> np
> Base = "./Files1a/"
> files = list.files(path=Base,pattern="\\.txt");
> 
> for(i in 1:length(files))
...some definitions and variable generation...
+ text<-foreach(k = 1:10, .combine='c') %do%
+   text= if (file.exists(paste("./Files", k, "a/", files[i], sep=""))) paste(tolower(readLines(paste("./Files", k, "a/", files[i], sep=""))) , collapse=" ") else ""
+ 
+ 
+ docs <- Corpus(VectorSource(text))
+ 
+ for (k in 1:10)
+ ID[k] <- paste(files[i], k, sep="_")
+ 
+ data <- as.data.frame(docs) 
+ data[["docs"]]=ID
+ rm(docs)
+ data <- sentSplit(data, "text")
+ 
+ frequency=NULL
+ cs <- ceiling(length(POLKEY$x) / getDoParWorkers()) 
+ opt <- list(chunkSize=cs) 
+ frequency<-foreach(j = 2: length(POLKEY$x), .options.mpi=opt, .combine='cbind') %dopar% ...
+ write.csv(frequency, file =paste("./Result/output", i, ".csv", sep=""))
+ rm(data, frequency)
+ 

当我运行批处理作业时,会话在时间限制内被终止。而我在 MPI 集群初始化后收到以下消息:

Loading required namespace: Rmpi
--------------------------------------------------------------------------
PMI2 initialized but returned bad values for size and rank.
This is symptomatic of either a failure to use the
"--mpi=pmi2" flag in SLURM, or a borked PMI2 installation.
If running under SLURM, try adding "-mpi=pmi2" to your
srun command line. If that doesn't work, or if you are
not running under SLURM, try removing or renaming the
pmi2.h header file so PMI2 support will not automatically
be built, reconfigure and build OMPI, and then try again
with only PMI1 support enabled.
--------------------------------------------------------------------------
--------------------------------------------------------------------------
An MPI process has executed an operation involving a call to the
"fork()" system call to create a child process.  Open MPI is currently
operating in a condition that could result in memory corruption or
other system errors; your MPI job may hang, crash, or produce silent
data corruption.  The use of fork() (or system() or other calls that
create child processes) is strongly discouraged.  

The process that invoked fork was:

  Local host:         ...
  MPI_COMM_WORLD rank: 0

If you are *absolutely sure* that your application will successfully
and correctly survive a call to fork(), you may disable this warning
by setting the mpi_warn_on_fork MCA parameter to 0.
--------------------------------------------------------------------------
    30 slaves are spawned successfully. 0 failed.

不幸的是,循环似乎没有通过一次,因为没有返回任何输出。

为了完整起见,我的批处理文件:

#!/bin/bash -l
#SBATCH --job-name MyR
#SBATCH --output MyR-%j.out
#SBATCH --nodes=5
#SBATCH --ntasks-per-node=6
#SBATCH --mem=24gb
#SBATCH --time=00:30:00

MyRProgram="$HOME/R/hpc_test2.R"

cd $HOME/R

export R_LIBS_USER=$HOME/R/Libs2

# start R with my R program
module load R

time R --vanilla -f $MyRProgram

有没有人建议如何解决这个问题?我做错了什么?

提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

您的脚本是一个 MPI 应用程序,因此您需要通过 Slurm 适当地执行它。 Open MPI 常见问题解答有一个关于如何做到这一点的特殊部分:

https://www.open-mpi.org/faq/?category=slurm

最重要的一点是你的脚本不应该直接执行 R,而应该通过 mpirun 命令执行它,使用类似的东西:

mpirun -np 1 R --vanilla -f $MyRProgram

我的猜测是“PMI2”错误是由于没有通过 mpirun 执行 R 引起的。我不认为“fork”消息表明存在真正的问题,而且它有时会发生在我身上。我认为这是因为 R 在初始化时调用了“fork”,但这对我来说从来没有造成问题。我不知道为什么我只是偶尔收到此消息。

请注意,告诉 mpirun 只启动一个进程非常重要,因为其他进程将被派生,因此您应该使用 mpirun -np 1 选项。如果 Open MPI 是在 Slurm 支持下正确构建的,那么 Open MPI 应该知道在生成这些进程时在哪里启动它们,但是如果您不使用 -np 1,那么通过 mpirun 启动的所有 30 个进程将分别生成 30 个进程,导致一团糟。

最后,我认为您应该告诉makeCluster 只生成 29 个进程以避免运行总共 31 个 MPI 进程。根据您的网络配置,即使是超额订阅也可能导致问题。

我会按如下方式创建集群对象:

library(snow)
library(Rmpi)
cl<- makeCluster(mpi.universe.size() - 1, type="MPI")

这样更安全,更容易让您的 R 脚本和作业脚本彼此同步。

【讨论】:

感谢您的帮助!我用 srun -n 1 再次尝试了代码,并且 fork() 警告消失了。但是,现在出现了一个新问题,因为系统将节点数减少到了 1 个;输出开头的错误消息说:“srun.bin:警告:无法在 5 个节点上运行 1 个进程,将 nnodes 设置为 1”。因此,不可能分配所有资源。 @C.G.我没有建议“srun -n 1”:我建议“mpirun -n 1”。使用“srun”请求尽可能多的节点和核心,但使用“mpirun -n 1”启动 R 脚本。当您在 R 脚本中执行 makeCluster 时,将生成剩余的进程。 @C.G.我编辑了我的答案以使用 mpirun -np 选项以与 Slurm 文档保持一致,并避免与 srun 选项混淆。希望现在更清楚了。 抱歉,我没听懂。我现在改为 mpirun -np1 ...,第一条错误消息消失了。不幸的是,错误消息“一个 MPI 进程已执行涉及调用“fork()”系统的操作”再次出现。此外,我发现如果我使用 foreach%do% 而不是 %dopar%,代码可以工作。 非常感谢。问题解决了。我不得不将 makeCluster 更改为 makeMPIcluster,但您的回复得到了解决方案。

以上是关于R在HPC MPIcluster上运行foreach dopar循环的主要内容,如果未能解决你的问题,请参考以下文章

如何在 HPC(Argon)上运行 Keras 时解决“内存不足”问题?

如何指定在 R 中运行的 MPI 的核心数和节点数

4-HPC场景下Volcano批量调度能力实践

OGS HPC 集群中的 Perl 运行时错误

HPC 集群:选择 SLURM sbatch 中的 CPU 和线程数

Azure HPC Pack 部署必要条件准备