【问题标题】:unrelated nested foreach with an outer %dopar% and an inner %do%具有外部 %dopar% 和内部 %do% 的不相关嵌套 foreach
【发布时间】:2015-02-27 20:27:14
【问题描述】:

我使用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 一起工作,为什么首先会出现错误?

【问题讨论】:

  • 在 SO 上发布的代码中嵌入 rm(list=ls()) 语句被认为是非常不礼貌的。试图帮助您的人可能会意外清除他们的整个会话,这可能需要数小时才能重建。这就是我评论它的原因。不要再这样做了。

标签: r foreach snow rparallel


【解决方案1】:

当然,我一发布它就让它工作(对不起..我会留下它以防其他人有同样的问题)。这是一个范围问题——我知道你必须在%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)

【讨论】:

  • 您也可以使用foreach(rc=1:5, .packages="foreach") %dopar% ...。换句话说,您可以使用.packages=... 参数来识别必要的包,而无需使用require(...)
【解决方案2】:
  • 我知道这是一个过时的问题,但只是为了给那些提示 谁没有嵌套 foreach 工作。
  • 如果用 put %do% in %dopar% 并行化外循环,你会 需要将.packages = c("doSNOW") 包含在 外循环(%dopar%),否则会遇到"doSNOW not found" 错误。
  • 一般来说,人们只是并行化内循环(%dopar% in %:%),这 对于大量数据可能会很慢(等待内部循环的组合)。

【讨论】:

    猜你喜欢
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 2014-02-11
    相关资源
    最近更新 更多