当我使用调用自定义函数的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,但错误仍然存在。< / p>
我的问题:为什么Windows的行为与Linux不同,尽管代码相同(除了不同的registerDoParallel
语法)?当通过函数FUN
调用时,如何确保Windows 找到函数FUN3
?
答案 0 :(得分:24)
它们的行为不同,因为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
后端会忽略mclapply
。
正如Hong Ooi所指出的,您使用clusterExport
时出错,但我不会使用clusterExport
来解决问题,因为它是特定于后端的。
答案 1 :(得分:1)
在clusterExport
来电中,删除env=environment()
部分。你正在做的是告诉clusterExport
在一个全新的环境中寻找你的对象,所以很自然地找不到它们。