使用 foreach 循环(使用 %dopar%
)调用自定义函数时,我遇到了问题。在 Linux 上工作时没有问题,但在 Windows 上使用时无法找到自定义函数。很难用语言解释这个问题,所以我编写了一个小例子来展示它。假设我有三个简单函数的集合,其中 FUN2
(使用 %do%
)和 FUN3
(使用 %dopar%
)调用第一个函数(FUN
):
FUN <- function(x,y,z) { x + y + z }
FUN2 <- function(a, b) {
foreach(i=1:3) %do% FUN(i, a, b)
}
FUN3 <- function(a, b) {
foreach(i=1:3) %dopar% FUN(i, a, b)
}
这些函数存储在一个名为foreach_testfunctions.R
的脚本中。在另一个脚本(foreach.test
)中,我使用library(doParallel)
调用这些函数并尝试使用它们。首先在Linux中进行,一切正常:
source("foreach_testfunctions.R")
a <- 2
b <- 3
library(doParallel)
registerDoParallel()
foreach(i=1:3) %do% FUN(i, a, b) ## works fine
FUN2(a, b) ## works fine
foreach(i=1:3) %dopar% FUN(i, a, b) ## works fine
FUN3(a, b) ## works fine
然后我在Windows上执行:
source("foreach_testfunctions.R")
a <- 2
b <- 3
library(doParallel)
cl <- makeCluster(3)
registerDoParallel(cl)
foreach(i=1:3) %do% FUN(i, a, b) ## works fine
FUN2(a, b) ## works fine
foreach(i=1:3) %dopar% FUN(i, a, b) ## works fine
FUN3(a, b) ## does not work
Error in FUN(i, a, b) : task 1 failed - "Could not find function "FUN""
结论: (1) 使用
%do%
没有问题。(2) 在 Windows 上使用 %dopar%
存在问题。我尝试在调用 FUN3
的行之前插入一行 clusterExport(cl, varlist=c("FUN", "a", "b"), env=environment())
,以确保函数 FUN
和变量 a 和 b 在正确的环境中找到,但错误仍然存在。我的问题是:为什么 Windows 的行为与 Linux 不同,尽管代码相同(除了不同的
registerDoParallel
语法)? 如何确保Windows在通过函数FUN3
调用函数FUN
时能够找到它?
FUN
之前没有被引用过(即在工作环境中不存在),那怎么办?是否可以通过导出相应的R文件(例如,.export="path/to/FUN.R"
)在foreach
内部使其可用?换句话说,.export
是否也适用于文件而不仅仅是R对象? - Antoine.txt
文件,调用一个以该文件为输入的可执行文件,并读取.exe
的输出(另一个.txt
文件)。我想知道是否可以使用.export
将.exe
文件复制到每个工作进程的临时工作目录中。 - Antoine.export
参数指定一个或多个变量的名称。此外,我通常会使用特定于后端的方法来初始化工作进程,例如在使用 doParallel 时使用clusterExport
或clusterEvalQ
。 - Steve Weston