【问题标题】:Using source() within parallel foreach loops在并行 foreach 循环中使用 source()
【发布时间】:2015-04-16 16:19:40
【问题描述】:

这是一个玩具示例来说明我的问题。

library(foreach)
library(doMC)
registerDoMC(cores=2)

foreach(i = 1:2) %dopar%{
  i + 2
}
[[1]]
[1] 3

[[2]]
[1] 4

到目前为止一切都很好......

但是,如果代码 i + 2 保存在文件 addition.R 中,并且我使用 source() 调用该文件,那么

> foreach(i = 1:2) %dopar%{
+   source("addition.R")
+ }
Error in { : task 1 failed - "object 'i' not found"

【问题讨论】:

  • 试试这个source("addtition.R",local=T) 来评估调用它的环境中的源
  • 我发现 %dopar% 块中的 source() 调用显着减慢了计算速度,因为子进程必须通过网络获取该源文件

标签: r foreach


【解决方案1】:

我无法完全复制你的玩具,但我遇到了一个类似的问题,我能够通过以下方式解决:

source(file, local = TRUE)

应该在本地环境中解析源,即识别i。

【讨论】:

    【解决方案2】:

    NiceE 的评论和 Sosel 的回答已经解决了这个问题;当调用source(file) 时,它默认为source(file, local = FALSE),这意味着源文件中的代码正在全局环境(“用户的工作空间”)中评估,并且有,参见。 ?source。请注意,全局环境中没有变量i。解决方案是确保文件来源于调用它的环境,即使用source(file, local = TRUE)

    解决方案:

    library("foreach")
    
    y <- foreach(i = 1:2) %dopar% {
      i + 2
    }
    str(y)
    
    doMC::registerDoMC(cores = 2L)
    y <- foreach(i = 1:2) %dopar% {
      source("addition.R", local = TRUE)
    }
    str(y)
    

    for() 循环的相同问题示例:

    source() 是在全局环境中进行评估的,这与 i 所在的调用环境不同,也可以使用常规 for 循环来说明,方法是在全局环境之外的另一个环境中运行 for 循环,例如在函数内部或通过:

    local({
      for(i in 1:2) {
        source("addition.R")
      }
    })
    

    给出:

    Error in eval(ei, envir) : object 'i' not found
    

    现在,上面的foreach(i = 1:2) %dopar% { source("addition.R") }registerDoSEQ() 一起工作的原因当且仅当 从全局环境调用,然后在调用环境中评估 foreach 迭代,即全局环境,也就是source() 使用的环境。但是,如果有人使用了local(foreach(i = 1:2) %dopar% { ... }),这也会与上面的local(for(i in 1:2) { ... }) 调用类似地失败。

    总结:没有什么神奇的事情发生,但是理解它有点乏味。

    【讨论】:

      【解决方案3】:

      我最终通过将 source("addition.R") 转换为函数并将变量传递给它来解决问题。我不知道为什么,但是基于source(file, local = TRUE) 的建议解决方案不起作用。

      【讨论】:

      • source("addition.R", local = TRUE) 对你不起作用对我来说没有意义。你能用我从你的 OP 中采用的可重现的例子来复制错误吗?还是您指的是更复杂的 R 脚本?如果是后者,可能有数百万个原因。另外,什么设置/sessionInfo()
      • 我说的是确切提到的脚本和确切的错误。
      • 这真的很奇怪。您是否也在该 local({ for(i in 1:12) ... }) 示例中遇到错误?如果是这样,那将排除 foreach 等。重要的是,您收到错误后的sessionInfo() 是什么?我怀疑您的设置中有某些东西导致了这种差异。在终端或 GUI(例如 RStudio)中运行 R?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多