0

我在集群计算机中运行蒙特卡罗模拟snowR. 一切顺利,直到R达到stopClusterR冻结并最终超过了墙时间。我没有看到 的问题stopCluster

以下是我的R脚本的简化版本。

simu <- function(rep_worker, n_used) {
  theta_simu <- c()
  for (i in 1 : rep_worker) {
    theta_simu[i] <- mean(rnorm(n_used))
  }
  theta_simu
}
library(Rmpi)
library(snow)
np <- mpi.universe.size() - 1
cl <- makeCluster(np, type = "MPI")
## go go go
n_used <- 1e4
rep_worker_list <- rep(1, np) # each worker do one `simu`
theta_cluster <- clusterApply(cl, rep_worker_list, simu, n_used)
theta_cluster
stopCluster(cl)
mpi.exit()

上面的脚本保存test_stack.R在目录下monte-carlo/Rpbs我发送到服务器的脚本如下。

#!/bin/bash

#PBS -N test
#PBS -l walltime=00:30:00
#PBS -l nodes=3:ppn=8
#PBS -l pvmem=8gb

module load R/3.3.1
module load openmpi/gcc/2.0.0
cd monte-carlo/R

# For snow jobs, use 'mpiexec -n 1'
mpiexec -n 1 R CMD BATCH test_stack.R

Rout下面列出了文件的一部分。它停在stopCluster()

> simu <- function(rep_worker, n_used) {
+   theta_simu <- c()
+   for (i in 1 : rep_worker) {
+     theta_simu[i] <- mean(rnorm(n_used))
+   }
+   theta_simu
+ }
> library(Rmpi)
> library(snow)
> np <- mpi.universe.size() - 1
> cl <- makeCluster(np, type = "MPI")
    23 slaves are spawned successfully. 0 failed.
> ## go go go
> n_used <- 1e4
> rep_worker_list <- rep(1, np) # each worker do one `simu`
> theta_cluster <- clusterApply(cl, rep_worker_list, simu, n_used)
> theta_cluster
[[1]]
[1] 5.54539e-05

[[2]]
[1] 0.0009270881

... (I deleted the rest to save space)

> stopCluster(cl)
4

1 回答 1

2

昨天得知答案:OpenMPI的版本是关键。

如果您使用 OpenMPI 1.6.5,而不是从并行包中调用 stopCluster(),则可以解决使用 stopCluster 的冻结问题,而是从雪中调用它。明白我的意思了吗?将 stopCluster() 替换为

snow::stopCluster()

而且,为了更好的衡量,我们明确地调用

Rmpi::mpi.quit()

在最后。

据我记事起,在使用 MPI 时,stopCluster 从并行中一直挂起,但是 snow::stopCluster 确实解决了这个问题,直到我们使用 OpenMPI >= 2 重建 R 包。如果您针对 OpenMPI > 2 进行编译,那么无论您使用哪个 stopCluster,都会发生 stopCluster 挂起。

看来 OpenMPI 1.6.5 是完全正确的。

如果您使用 Openmpi > 1.6.5 但 < 2,则不会发生挂起,但有一条关于分叉的有趣警告消息:

> library(Rmpi)
> library(parallel)
> sessionInfo()
----------------------------------------------------------------------
A 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 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:          [[44893,1],0] (PID 35793)

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.
---------------------------------------------------------------------- 

几年前,我们遇到了这个问题,因为有人在 R 函数中使用了 GOTO BLAS,触发了一些 OpenMP 矩阵线程突然打开,作业将永远存在,不会失败,不会计算。这让我想起了这一点。

于 2017-06-01T21:51:55.863 回答