20

当我使用%dopar%调用自定义函数的 foreach 循环(使用)时遇到问题。使用Linux时确实没有问题,但是使用Windows时却找不到自定义函数。这个问题很难用语言来解释,所以我写了一个小例子来展示它。假设我有三个简单函数的集合,其中FUN2(using %do%) 和FUN3(using %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)%dopar%使用Windows时的问题。我尝试clusterExport(cl, varlist=c("FUN", "a", "b"), env=environment())在调用的行之前插入该行,FUN3以确保FUN在正确的环境中找到函数和变量 a 和 b,但错误仍然存​​在。

registerDoParallel我的问题:尽管代码相同(除了语法不同),为什么 Windows 的行为与 Linux 不同?如何确保 Windows在通过 function 调用时确实找到了函数?FUNFUN3

4

2 回答 2

26

它们的行为不同,因为在 Linux 上注册了registerDoParallel一个后端,而在 Windows 上注册了一个后端。使用后端时,基本上没有数据导出问题,因此可以在 Linux 上运行。但是,如果不自动导出所需的功能和数据,您可能会遇到问题。mclapplyclusterApplyLBmclapplyclusterApplyLBforeach

您可以通过以下选项修改FUN3为导出来解决此问题:FUN.export

FUN3 <- function(a, b) {
  foreach(i=1:3, .export='FUN') %dopar% FUN(i, a, b)
}

此解决方案适用于 Linux 和 Windows,因为.exportmclapply后端忽略。

正如 Hong Ooi 所指出的,您在使用 时有一个错误clusterExport,但我不会用clusterExport它来解决问题,因为它是特定于后端的。

于 2013-06-27T17:06:10.360 回答
1

在您的clusterExport通话中,删除该env=environment()部分。你正在做的是告诉clusterExport在一个全新的环境中寻找你的对象,所以它自然不会找到它们。

于 2013-06-27T14:15:05.047 回答