R在HPC MPIcluster上运行foreach dopar循环

时间:2015-12-06 17:51:54

标签: r foreach parallel-processing mpi hpc

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

我的问题是 - 无论我尝试什么 - 我的代码(在我的电脑上工作正常)都不能在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 个答案:

答案 0 :(得分:3)

您的脚本是MPI应用程序,因此您需要通过Slurm正确执行它。 Open MPI FAQ有一个关于如何做到这一点的特殊部分:

  

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脚本和作业脚本彼此同步。