2011-07-14 39 views
18

称为调用,其包括功能的foreach%dopar%从的Optim构造导致错误:的R - 与内部功能的foreach%dopar%问题通过的Optim

> 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:革命分析企业4.3

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

请始终在您的问题中包含确切的错误信息。 –

回答

2

[编辑]

pf功能,你的 “静态表” x必须分发到所有工作节点。您必须阅读并行库的文档,了解它的工作原理。

它似乎是在通过优化运行时发现的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) 
} 
+0

如何确保被调用的函数和表分配给工作节点? – mjaniec

+1

'pf'存在于内置的'stats'包中,并且是F分配的分配函数。 – James

+0

我更新了答案,因为它似乎是我所怀疑的 - 调用错误的“pf”函数。 – Tommy

18

我遇到了同样的问题所涉及的问题在于环境未包含在子线程中。你的错误

Error in { : task 1 failed - "could not find function "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

我一直很想知道为什么'.export = ls()'不是默认值。在大多数情况下,这似乎是一个好主意,从这个主题的帖子数量来看......任何想法? – Ruben

+1

@Ruben - 实际上它是有意义的,因为在处理大型数据集时并行化是最相关的 –

+1

但是,然后您会在每个节点中单独加载大块数据,对吧?那么我不会在全局会话中加载整个df。一些东西会自动加载(例如,您正在迭代的矢量)。而且,使用ls并不像我刚才所预期的那样工作。我可靠地得到我预测会发生的唯一解决方案是在循环内部定义。效率低下,但有时很难看。 – Ruben

0

为用foreach%dopar%的问题快速修复是重新安装这些程序包:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

正如在StackOverflow的各个线程所提到的,这些都是负责R.错误并行这在旧版本中存在的这些包现在被删除。它在我的情况下工作。我应该提到,即使你没有在你的项目/软件包中使用这些软件包,这很可能会有所帮助。