我正在使用foreach
包中的%dopar%
在本地并行运行任务,使用doSNOW
包来创建集群(目前在Windows机器上运行)。我以前做过很多次,它工作正常,直到我在其中使用%do%
(即非并行)放置一个不相关的foreach
循环。然后R给了我错误(带有回溯):
Error in { : task 1 failed - "could not find function "%do%"" 3 stop(simpleError(msg, call = expr)) 2 e$fun(obj, substitute(ex), parent.frame(), e$data) 1 foreach(rc = 1:5) %dopar% {
aRandomCounter = -1
if (1 > 0) {
for (batchi in 1:20) { ...
以下是在我的计算机上复制问题的一些代码:
require(foreach)
require(doSNOW)
cl<-makeCluster(5)
registerDoSNOW(cl)
for(stepi in 1:10) # normal outer for
{
foreach(rc=1:5) %dopar% # the time consuming stuff in parallel (not looking to actually retrieve any data)
{
aRandomCounter = -1
if(1 > 0)
{
for(batchi in 1:20)
{
anObjectIwantToCreate <- foreach( qrc = 1:100, .combine=c ) %do%
{
return(runif(1)) # I know this is not efficient, it is a placeholder to reproduce the issue
}
aRandomCounter = aRandomCounter + sum(anObjectIwantToCreate > 0.5)
}
}
return(aRandomCounter)
}
}
stopCluster(cl)
用简单的for
或(l/s)apply
代替内部foreach
是一种解决方案。但是有没有办法使它与内部foreach
一起工作,为什么首先会出现错误?
当然,我一发布它就让它工作(对不起......如果其他人有同样的问题,我会离开它)。这是一个范围问题 - 我知道您必须在%dopar%
内加载任何外部包,但我没有意识到这包括foreach
包本身。这是解决方案:
require(foreach)
require(doSNOW)
cl<-makeCluster(5)
registerDoSNOW(cl)
for(stepi in 1:10) # normal outer for
{
foreach(rc=1:5) %dopar% # the time consuming stuff in parallel (not looking to actually retrieve any data)
{
require(foreach) ### the solution
aRandomCounter = -1
if(1 > 0)
{
for(batchi in 1:20)
{
anObjectIwantToCreate <- foreach( qrc = 1:100, .combine=c ) %do%
{
return(runif(1))
}
aRandomCounter = aRandomCounter + sum(anObjectIwantToCreate > 0.5)
}
}
return(aRandomCounter)
}
}
stopCluster(cl)
- 我知道这是一个过时的问题,但只是为了给那些人一个提示谁不被嵌套为工作。
- 如果并行化外循环与放置
%do% in %dopar%
,您将需要将.packages = c("doSNOW")
纳入外部循环 (%dopar%),否则会遇到"doSNOW not found"
错误。 - 通常,人们只是并行化内部循环(%:%中的%dopar%,这对于大量数据(等待内部循环的组合)可能会很慢。