在foreach循环中找不到函数

时间:2011-01-22 00:23:12

标签: r foreach parallel-processing multicore scoping

我正在尝试使用foreach在R中进行多核计算。

A <-function(....) {
    foreach(i=1:10) %dopar% {
    B()
    }
}

然后我在控制台中调用函数A。问题是我在Posdef内调用了一个函数B,该函数在我提供的另一个脚本文件中定义。我必须将Posdef放在foreach.export=c("Posdef")的导出参数列表中。但是我收到以下错误:

Error in { : task 3 failed - "could not find function "Posdef""

为什么无法找到这个定义的函数?

3 个答案:

答案 0 :(得分:13)

所以我可以为好奇重现这个:

require(doSNOW)
registerDoSNOW(makeCluster(5, type="SOCK"))
getDoParWorkers()
getDoParName()
getDoParVersion()

fib <- function(n) {
  if (n <= 1) { return(1) }
  return(fib(n-1) + fib(n-2))
}

my.matrix <- matrix(runif(2500, 10, 50), nrow=50)

calcLotsaFibs <- function() {
  result <- foreach(row.num=1:nrow(my.matrix), .export=c("fib", "my.matrix")) %dopar% {
    return(Vectorize(fib)(my.matrix[row.num,]))
  }
  return(result)
}

lotsa.fibs <- calcLotsaFibs()

我已经能够通过将该函数放在另一个文件中并将该文件加载到foreach的主体中来解决这个问题。您显然也可以将函数定义移动到foreach本身的主体中。

[编辑 - 我之前曾建议.export可能无法正常使用函数名称,但在下面进行了更正。]

答案 1 :(得分:10)

简短的回答是,这是doSNOWdoParalleldoMPI等并行后端的错误,但此后已修复。

稍微长一点的答案是foreach使用特殊的“导出”环境而不是全局环境向工作人员输出函数。这通常会导致在全局环境中创建的函数出现问题,因为“导出”环境不在其范围内,即使它们现在已在同一“导出”环境中定义。因此,他们看不到“导出”环境中定义的任何其他函数或变量,例如您的情况中的“Posdef”。

doSNOWdoParalleldoMPI后端现在将通过“.export”导出的功能的关联环境从全局更改为“导出”环境,并且似乎已解决这些问题。

答案 2 :(得分:1)

快速修复foreach%dopar%的问题是重新安装这些软件包:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

它适用于我的情况。