【问题标题】:R - problem with foreach %dopar% inside function called by optimR - optim调用的foreach %dopar%内部函数的问题
【发布时间】:2017-08-21 16:53:26
【问题描述】:

从 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)

奇怪的是,相同的代码在直接调用一次时运行良好(优化多次调用相同的函数):

> 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""

【问题讨论】:

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

标签: r parallel-processing


【解决方案1】:

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

{ 中的错误:任务 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()),无论好坏,您都会拥有它。

【讨论】:

  • 我一直想知道为什么.export=ls() 不是默认值。从关于该主题的帖子数量来看,在大多数情况下似乎是个好主意......有什么想法吗?
  • @Ruben - 实际上这是有意义的,因为在处理大型数据集时并行化是最相关的
  • 但是你会在每个节点中单独加载数据块,对吧?那时我不会在全局会话中加载整个 df 。有些东西会自动加载(例如,您正在迭代的向量)。此外,使用 ls 并没有像我刚才预期的那样工作。我可靠地得到我预测发生的唯一解决方案是在循环内部定义。效率低下,但有时很丑陋。
  • @Ruben multidplyr 有一个示例如何加载子数据集:github.com/hadley/multidplyr/blob/master/vignettes/… 我经常将完整的数据集加载到工作人员中,因为我在每个模型中测试了不同数量的样条结需要整个数据集。这仍然很有效,因为我经常在内存中有一些我不想到处发送的 munging 数据集......
【解决方案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)
}

【讨论】:

  • 我应该如何确保被调用的函数和表被分发到工作节点?
  • pf存在于内置的stats包中,是F分布的分布函数。
  • 我更新了答案,因为这似乎是我所怀疑的 - 调用了错误的 pf 函数。
  • 我已将 pf 函数重命名为 probf 但问题仍然存在。 probf 函数是在脚本中定义的,而不是在某些外部包中。两个注意事项:操作系统:Windows 7,IDE:Revolution Analytics Enterprise 4.3 > workers registerDoSMP(workers) > maxProb2(w) > Error in { : task 1 failed - "could not find function "probf ""
【解决方案3】:

foreach %dopar% 问题的快速解决方法是重新安装这些软件包:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

正如 StackOverflow 的各种线程中所提到的,这些线程负责 R 中的并行性。这些包的旧版本中存在的错误现在已被删除。它在我的情况下有效。我应该提一下,即使您没有在项目/包中使用这些包,它也很可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-02
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多