R - 由foreach调用的foreach%dopar%问题

时间:2011-07-14 07:39:32

标签: r parallel-processing

从optim调用包含foreach%dopar%构造的函数会导致错误:

> workers <- startWorkers(6) # 6 cores
> 
> registerDoSMP(workers)
> 
> t0 <- Sys.time() 
>
> optim(w,maxProb2,control=list(fnscale=-1))
> 
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)"
> 
> Sys.time()-t0
>
> Time difference of 2.032 secs
> 
> stopWorkers(workers)

被调用函数看起来像这样:

> maxProb2 <- function(wp) {
>   
>   r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],wp,isPrebuilt=TRUE) }
>   
>   cat("w=",wp,"max=",sum(r),"\n")
>   
>   sum(r)
>   
> }

pf是一些其他函数,x是预先计算元素的静态表。

同样调用要优化的函数只会导致同样的错误:

> workers <- startWorkers(6) # 6 cores
>
> Warning message:
> In startWorkers(6) : there is an existing doSMP session using doSMP1
>
> registerDoSMP(workers)
>
> maxProb2(w)
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)"
>
> stopWorkers(workers)

奇怪的是,相同的代码在一次直接调用时工作正常(optim会多次调用相同的函数):

> workers <- startWorkers(6) # 6 - ilosc rdzeni
> 
> Warning message:
> In startWorkers(6) : there is an existing doSMP session using doSMP1
>
> registerDoSMP(workers)
> 
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],w,isPrebuilt=TRUE) } 
>   
> sum(r)
> [1] 187.1781
> 
> stopWorkers(workers)

当使用%do%而不是%dopar%时,被调用函数(maxProb2)工作正常。

如何正确调用包含foreach%dopar%构造的函数?

更新2011-07-17:

我已将pf函数重命名为probf,但问题仍然存在。

probf函数在脚本中定义,而不是在某些外部包中定义。

两个注意事项:操作系统:Windows 7,IDE:Revolution Analytics Enterprise 4.3

> workers <- startWorkers(workerCount = 3)
>
> registerDoSMP(workers)
>
> maxProb2(w)
>
Error in { : task 1 failed - "could not find function "probf""

3 个答案:

答案 0 :(得分:21)

我遇到了同样的问题,问题是环境没有包含在子线程中。你的错误

  

{:任务1失败 - “无法找到功能”simple_fn“”

出错

可以通过这个非常简单的例子再现:

simple_fn <- function(x)
    x+1

test_par <- function(){
    library("parallel")
    no_cores <- detectCores()
    library("foreach")
    cl<-makeCluster(no_cores)
    library("doSNOW")
    registerDoSNOW(cl)
    out <- foreach(i=1:10) %dopar% {
        simple_fn(i)
    }

    stopCluster(cl)
    return(out)
}

test_par()

现在您需要将foreach(i=1:10)更改为foreach(i=1:10, .export=c("simple_fn"))。如果您想要导出完整的全球环境,那么只需编写.export=ls(envir=globalenv())即可获得更好或更差的信息。

答案 1 :(得分:2)

[[编辑]]

您的pf函数和“静态表”x必须分发给所有工作节点。您必须阅读并行库的文档,了解其工作原理。

似乎是当通过optim运行时,它找到的pf函数是另一个(可能是stats::pf,它没有isPrebuilt参数)。

您可以尝试重命名pf功能(例如mypf)吗?

mypf <- pf # renaming the function

maxProb2 <- function(wp) {
  r <- foreach (i=s0:s1, .combine=c) %dopar% { mypf(i,x[i,5],wp,isPrebuilt=TRUE) }
  cat("w=",wp,"max=",sum(r),"\n")
  sum(r)
}

或者,如果您的pf函数是包含命名空间的包(例如mypackage)的一部分,则可以像这样引用它:mypackage::pf

maxProb2 <- function(wp) {
  r <- foreach (i=s0:s1, .combine=c) %dopar% { mypackage::pf(i,x[i,5],wp,isPrebuilt=TRUE) }
  cat("w=",wp,"max=",sum(r),"\n")
  sum(r)
}

答案 2 :(得分:0)

快速修复foreach%dopar%的问题是重新安装这些软件包:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

如StackOverflow中的各种线程所述,它们负责R中的并行性。现在删除了旧版本的这些软件包中存在的Bug。它适用于我的情况。我应该提一下,即使你没有在你的项目/包中使用这些包,它也很有帮助。