我在R中并行运行随机森林
library(doMC)
registerDoMC()
x <- matrix(runif(500), 100)
y <- gl(2, 50)
Run Code Online (Sandbox Code Playgroud)
并行执行(耗时73秒)
rf <- foreach(ntree=rep(25000, 6), .combine=combine, .packages='randomForest') %dopar%
randomForest(x, y, ntree=ntree)
Run Code Online (Sandbox Code Playgroud)
顺序执行(耗时82秒)
rf <- foreach(ntree=rep(25000, 6), .combine=combine) %do%
randomForest(x, y, ntree=ntree)
Run Code Online (Sandbox Code Playgroud)
在并行执行中,树生成非常快,如3-7秒,但其余时间用于组合结果(组合选项).因此,它唯一值得运行并行执行的是树的数量真的很高.有什么方法可以调整"组合"选项,以避免在我不需要的每个节点上的任何计算,并使其更快
PS.以上只是数据的一个例子.实际上,对于大约100个观察,我有大约10万个特征.
我试图在几个核心上运行代码(我尝试了两个snow
和parallel
包).我有
cl <- makeCluster(2)
y <- 1:10
sapply(1:5, function(x) x + y) # Works
parSapply(cl, 1:5, function(x) x + y)
Run Code Online (Sandbox Code Playgroud)
最后一行返回错误:
Error in checkForRemoteErrors(val) :
2 nodes produced errors; first error: object 'y' not found
Run Code Online (Sandbox Code Playgroud)
显然parSapply
没有y
在全球环境中找到.有办法解决这个问题吗?谢谢.
我正在尝试使用foreach在R中进行多核计算.
A <-function(....) {
foreach(i=1:10) %dopar% {
B()
}
}
Run Code Online (Sandbox Code Playgroud)
然后我A
在控制台中调用函数.问题是我调用一个函数Posdef
内B
只在其它脚本文件我源中定义.我不得不把Posdef
输出参数列表放在foreach
:.export=c("Posdef")
.但是我收到以下错误:
Error in { : task 3 failed - "could not find function "Posdef""
Run Code Online (Sandbox Code Playgroud)
为什么不能找到这个定义的函数?
我有一个foreach的问题,我无法搞清楚.以下代码在我尝试过的两台Windows计算机上失败,但在三台Linux计算机上运行成功,所有这些都运行相同版本的R和doParallel:
library("doParallel")
registerDoParallel(cl=2,cores=2)
f <- function(){return(10)}
g <- function(){
r = foreach(x = 1:4) %dopar% {
return(x + f())
}
return(r)
}
g()
Run Code Online (Sandbox Code Playgroud)
在这两台Windows计算机上,返回以下错误:
Error in { : task 1 failed - "could not find function "f""
Run Code Online (Sandbox Code Playgroud)
但是,这在Linux计算机上运行得很好,并且使用%do%而不是%dopar%也可以正常工作,并且适用于常规for循环.
同样是变量,如设置真正的i <- 10
和更换return(x + f())
用return(x + i)
对于具有相同问题的其他人,有两种解决方法:
1)使用.export显式导入所需的函数和变量:
r = foreach(x=1:4, .export="f") %dopar%
Run Code Online (Sandbox Code Playgroud)
2)导入所有全局对象:
r = foreach(x=1:4, .export=ls(.GlobalEnv)) %dopar%
Run Code Online (Sandbox Code Playgroud)
这些变通方法的问题在于,对于一个积极开发的大型软件包来说,它们并不是最稳定的.无论如何,foreach应该表现得像.
是什么导致了这个以及是否有修复的想法?
该功能的计算机版本信息:
R version 3.2.2 (2015-08-14)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS release 6.5 (Final)
other …
Run Code Online (Sandbox Code Playgroud) 我试图使用该try()
函数来处理我的并行化for循环中发生的错误:
results <- foreach (i = 1:2, .errorhandling = 'remove') %dopar% {
res <- try(myfun(i), TRUE)
}
Run Code Online (Sandbox Code Playgroud)
同
myfun <- function(i){
if (i==1) return(rnorm(1))
else stop('error')
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息
Error in checkForRemoteErrors(val) :
one node produced an error: Error in myfun(i) : error
Run Code Online (Sandbox Code Playgroud)
如何让foreach"循环"忽略错误消息(或者至少更优雅地处理它)?
我经常最终得到几个嵌套foreach
循环,有时候在编写一般函数时(例如对于一个包),没有明显的并行化级别.有没有办法完成下面的模型描述?
foreach(i = 1:I) %if(I < J) `do` else `dopar`% {
foreach(j = 1:J) %if(I >= J) `do` else `dopar`% {
# Do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
此外,有没有办法检测并行后端是否已注册,以便我可以避免收到不必要的警告消息?在CRAN提交之前检查包并且不打扰在单核计算机上运行R的用户时,这将非常有用.
foreach(i=1:I) %if(is.parallel.backend.registered()) `dopar` else `do`% {
# Do stuff
}
Run Code Online (Sandbox Code Playgroud)
谢谢你的时间.
编辑:非常感谢您对核心和工作人员的所有反馈,并且你是对的,处理上述示例的最佳方法是重新考虑整个设置.我更喜欢下面这个triu
想法,但它基本上是相同的.它当然也可以tapply
像Joris建议的那样平行完成.
ij <- expand.grid(i=1:I, j=1:J)
foreach(i=ij$I, j=ij$J) %dopar% {
myFuction(i, j)
}
Run Code Online (Sandbox Code Playgroud)
然而,在我试图简化引起这个线程的情况时,我遗漏了一些关键的细节.想象一下,我有两个功能analyse
,并batch.analyse
和最好的水平,在并行依据的值可能是不同的n.replicates
和n.time.points
.
analyse <- function(x, y, n.replicates=1000){
foreach(r = 1:n.replicates) %do% {
# Do stuff with …
Run Code Online (Sandbox Code Playgroud) 我有一个Windows HPC Server在后端运行一些节点.我想使用后端的多个节点运行Parallel R. 我认为Parallel R可能在Windows上使用SNOW,但对它不太确定.我的问题是,我是否还需要在后端节点上安装R?假设我想使用两个节点,每个节点32个核心:
cl <- makeCluster(c(rep("COMP01",32),rep("COMP02",32)),type="SOCK")
Run Code Online (Sandbox Code Playgroud)
现在,它只是挂起.
我还需要做什么?后端节点是否需要运行某种sshd以便能够相互通信?
我在使用并行处理将值附加到数据框时遇到问题.
我有一个函数会做一些计算并返回一个数据帧,包括这些计算是一个随机抽样.
所以我做的是:
randomizex <- function(testdf)
{
foreach(ind=1:1000)%dopar%
{
testdf$X = sample(testdf$X,nrow(testdf), replace=FALSE)
fit = lm(X ~ Y, testdf)
newdf <- rbind(newdf, data.frame(pc=ind, err=sum(residuals(fit)^2) ))
}
return(newdf)
}
resdf = randomizex(mydf)
Run Code Online (Sandbox Code Playgroud)
当我查看结果时resdf
,它是空的
如果我更换%dopar%
与%do%
结果被正确地计算,但它太慢了..
反正有没有提高这一点?
在使用doMC和foreach在其核心之间分配进程时,我在计算机中遇到了一种奇怪的行为.有人知道为什么使用单核我比使用2核更好的性能?正如您所看到的,处理相同的代码而不注册任何核心(据称只使用1个核心)会产生更多的时间效率处理.虽然%do%似乎比%dopar%表现更好,但注册2个核心中的2个核心会产生更多时间.
require(foreach)
require(doMC)
# 1-core
> system.time(m <- foreach(i=1:100) %dopar%
+ matrix(rnorm(1000*1000), ncol=5000) )
user system elapsed
9.285 1.895 11.083
> system.time(m <- foreach(i=1:100) %do%
+ matrix(rnorm(1000*1000), ncol=5000) )
user system elapsed
9.139 1.879 10.979
# 2-core
> registerDoMC(cores=2)
> system.time(m <- foreach(i=1:100) %dopar%
+ matrix(rnorm(1000*1000), ncol=5000) )
user system elapsed
3.322 3.737 132.027
> system.time(m <- foreach(i=1:100) %do%
+ matrix(rnorm(1000*1000), ncol=5000) )
user system elapsed
9.744 2.054 11.740
Run Code Online (Sandbox Code Playgroud)
在少数试验中使用4个核心会产生截然不同的结果:
> registerDoMC(cores=4)
> system.time(m <- foreach(i=1:100) %dopar%
{ matrix(rnorm(1000*1000), ncol=5000) …
Run Code Online (Sandbox Code Playgroud) 我编写了一些代码,使用foreach
哪些进程并组合了大量的CSV文件.我在32核机器上运行它,使用%dopar%
和注册32个核心doMC
.我已经设置.inorder=FALSE
,.multicombine=TRUE
,verbose=TRUE
,和有一个自定义组合函数.
我注意到如果我在一个足够大的文件集上运行它,看起来R会在第一次调用.combine之前尝试处理每个文件.我的证据是,在监测我的服务器HTOP,我最初看到的所有核心刷爆,然后对剩余作业,同时它在〜100批次的联合收割机只使用一个或两个核心(.maxcombine
的默认值),如详细的控制台输出中所示.真正有用的是我给foreach的工作越多,看到"First call to combine"所需的时间就越长!
这对我来说似乎是违反直觉的; 我天真地期望foreach处理.maxcombine
文件,合并它们,然后继续下一批,将它们与最后一次调用的输出结合起来.combine
.我认为,对于.combine
它的大多数用途都无关紧要,因为输出的大小与输入大小的总和大致相同; 但是我的组合功能减小了一些尺寸.我的工作足够大,以至于我不可能同时在RAM中保存所有4200多个单独的foreach作业输出,所以我依靠我的节省空间.combine
和单独的批处理来看我.
我是对的.在我的所有foreach
工作单独完成之前,组合不会被调用吗?如果是这样,为什么会这样,我如何优化(除了使每个作业的输出更小)或改变这种行为?