如何使用 sfInit 和 makeCluster 类型“MPI”/R 中的消息传递/集群上的并行化

Posted

技术标签:

【中文标题】如何使用 sfInit 和 makeCluster 类型“MPI”/R 中的消息传递/集群上的并行化【英文标题】:How to use sfInit and makeCluster type "MPI" / message passing in R / parallelization on cluster 【发布时间】:2019-01-18 16:16:55 【问题描述】:

我正在尝试调整 this R script for a speed test 以在集群上工作。

当使用sfInitmakecluster 类型为"SOCK" 的函数时,脚本在集群上成功运行,但没有任何速度提升 - 与我的计算机不同:当我将detectcores() 更改为@987654330 @,脚本的运行速度比 4 核慢很多。

不过,我很确定我需要将类型更改为"MPI",以使节点能够以内存方式相互通信。

但是:如果我这样做了,脚本就会停止并出现以下错误代码:

Loading required package: Rmpi
Error: package or namespace load failed for ‘Rmpi’:
 .onLoad failed in loadNamespace() for 'Rmpi', details:
  call: dyn.load(file, DLLpath = DLLpath, ...)
  error: unable to load shared object '/cluster/sfw/R/3.5.1-gcc73-base/lib64/R/library/Rmpi/libs/Rmpi.so':
  libmpi.so.20: cannot open shared object file: No such file or directory
Failed to load required library: Rmpi for parallel mode MPI
Fallback to sequential execution
snowfall 1.84-6.1 initialized: sequential execution, one CPU.

我认为“小菜一碟,很简单”并添加了以下几行:

install.packages('Rmpi', repos = "http://cran.us.r-project.org",
dependencies = TRUE, lib = '/personalpath') install.packages('doMPI',
repos = "http://cran.us.r-project.org", dependencies = TRUE, lib = '/personalpath') library(topicmodels, lib.loc = '/personalpath')
library(Rmpi, lib.loc = '/personalpath')

这会导致安装成功,但是:

Error in library(Rmpi, lib.loc = "/personalpath") :
there is no package called ‘Rmpi’

1.如何安装这些软件包?

2。我真的需要安装它们还是这是完全错误的方法?

非常感谢任何帮助!我知道这里有几个问题(参见this、this 和this)。但我不熟悉 Linux 中的调用,更重要的是我对该集群没有任何权限。所以我需要在 R 中想出一个解决方案...

所以..这是我的代码:

sfInit(parallel=TRUE, cpus=detectCores(), type="MPI")

cl <- makeCluster(detectCores(), type = "MPI")
registerDoSNOW(cl) 

sfExport('dtm_stripped', 'control_LDA_Gibbs')
sfLibrary(topicmodels)

clusterEvalQ(cl, library(topicmodels))
clusterExport(cl, c("dtm_stripped", "control_LDA_Gibbs"))

BASE <- system.time(best.model.BASE <<- lapply(seq, function(d)LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d)))
PLYR_S <- system.time(best.model.PLYR_S <<- llply(seq, function(d)LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d), .progress = "text"))

wrapper <- function (d) topicmodels:::LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d)
PARLAP <- system.time(best.model.PARLAP <<- parLapply(cl, seq, wrapper))
DOPAR <- system.time(best.model.DOPAR <<- foreach(i = seq, .export = c("dtm_stripped", "control_LDA_Gibbs"), .packages = "topicmodels", .verbose = TRUE) %dopar% (LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', k=i)))
SFLAPP <- system.time(best.model.SFLAPP <<- sfLapply(seq, function(d)topicmodels:::LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d))) 
SFCLU <- system.time(best.model.SFCLU <<- sfClusterApplyLB(seq, function(d)topicmodels:::LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d))) 
PLYRP <- system.time(best.model.PLYRP <<- llply(seq, function(d)topicmodels:::LDA(dtm_stripped, control = control_LDA_Gibbs, method ='Gibbs', d), .parallel = TRUE))

results_speedtest <- rbind(BASE, PLYR_S, PARLAP, DOPAR, SFLAPP, SFCLU, PLYRP)
print(results_speedtest)

【问题讨论】:

首先,Rmpi 包的安装相当复杂,需要对 MPI 和在 Linux 上从源代码构建工具有一定的了解,参见。 fisher.stats.uwo.ca/faculty/yu/Rmpi/install.htm 其次,使用 MPI 集群而不是 PSOCK 集群将不会自动加快速度 - 代码需要优化以使用特定的 MPI 按顺序排列看到很大的不同。 【参考方案1】:

在 R 中还有其他并行化方法。正如第二页所解释的,也许此链接会帮助了解这些集群类型(如 socket、mpi 和 fork)的作用: https://stat.ethz.ch/R-manual/R-devel/library/parallel/doc/parallel.pdf

否则我也可以推荐查看包foreach,因为语法更像是一个常规的for循环。请注意,某些并行化包并非适用于所有操作系统。

【讨论】:

以上是关于如何使用 sfInit 和 makeCluster 类型“MPI”/R 中的消息传递/集群上的并行化的主要内容,如果未能解决你的问题,请参考以下文章

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

如果我已经在做 registerDoParallel(cl) 我还需要 makeCluster

在 AWS 中使用雪(和降雪)在 R 中进行并行处理

如何估计随机森林算法的内存使用量?

如何使用 devtools 在另一个包中使用并行包?

如何将许多变量和函数从全局环境导出到 foreach 循环?