R:foreach循环如何找到应该调用的函数?

时间:2013-06-27 14:00:04

标签: r foreach parallel-processing mpi

当我使用调用自定义函数的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

2 个答案:

答案 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在一个全新的环境中寻找你的对象,所以很自然地找不到它们。