在并行 foreach 循环中使用 source()

Posted

技术标签:

【中文标题】在并行 foreach 循环中使用 source()【英文标题】:Using source() within parallel foreach loops 【发布时间】: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() 调用显着减慢了计算速度,因为子进程必须通过网络获取该源文件 【参考方案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?

以上是关于在并行 foreach 循环中使用 source()的主要内容,如果未能解决你的问题,请参考以下文章

c#并行foreach循环查找索引

带有异步 lambda 的并行 foreach

Python 中的 C# Parallel.Foreach 等效项

在 R doParallel foreach 循环中运行 ovun.sample

在 R 中使用 foreach 循环读取 MATLAB .mat 文件时出现问题

在foreach循环内没有收到标准输出[重复]