使用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%
出现问题。我尝试在调用clusterExport(cl, varlist=c("FUN", "a", "b"), env=environment())
的行之前插入FUN3
行,以确保在正确的环境中找到函数FUN
以及变量a和b,但错误仍然存在。我的问题:尽管代码相同(除了不同的
registerDoParallel
语法),为什么Windows在行为上与Linux不同?通过函数FUN
调用时,如何确保Windows确实找到函数FUN3
?
最佳答案
它们的行为有所不同,因为registerDoParallel
在Linux上注册了mclapply
后端,而在Windows上注册了clusterApplyLB
后端。使用mclapply
后端时,基本上没有数据导出问题,因此可以在Linux上使用。但是使用clusterApplyLB
,如果foreach
不能自动导出所需的功能和数据,则可能会遇到问题。
您可以通过使用FUN3
选项将FUN
修改为导出.export
来解决此问题:
FUN3 <- function(a, b) {
foreach(i=1:3, .export='FUN') %dopar% FUN(i, a, b)
}
该解决方案在Linux和Windows上均适用,因为
.export
被后端忽略。正如Hong Ooi指出的那样,您在使用
mclapply
时遇到了错误,但是我不会使用clusterExport
来解决问题,因为它是特定于后端的。
关于r - R:foreach循环如何找到应调用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17345271/