在并行 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()的主要内容,如果未能解决你的问题,请参考以下文章
Python 中的 C# Parallel.Foreach 等效项
在 R doParallel foreach 循环中运行 ovun.sample