我在使用snow
和R
的群集计算机上运行蒙特卡罗模拟。一切顺利,直到R
达到stopCluster
的线,R
冻结,最后超过了墙上时间。我没有看到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/R
。我发送到服务器的pbs
脚本如下。
#!/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)
答案 0 :(得分:1)
昨天我得知答案:OpenMPI的版本是关键。
如果你使用OpenMPI 1.6.5并且不是从并行包中调用stopCluster()而是从snow调用一个,那么解决带有stopCluster的freezup。明白我的意思了吗?用
替换stopCluster()snow::stopCluster()
而且,为了更好的衡量,我们明确地调用
Rmpi::mpi.quit()
最后。
只要我记得,在使用MPI时,stopCluster中并没有挂起,但是snow :: stopCluster确实解决了这个问题,直到我们用OpenMPI&gt; = 2重建R包。如果针对OpenMPI进行编译&GT; 2,然后挂起stopCluster,无论你使用哪个stopCluster。
看来OpenMPI 1.6.5是完全正确的。
如果您使用Openmpi&gt; 1.6.5但是&lt; 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矩阵线程弹出并且作业将永远存在,而不是失败,不计算。这让我想起了。