21

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

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

A然后我在控制台中调用函数。问题是我正在调用一个函数,该函数PosdefB我来源的另一个脚本文件中定义。我不得不将:Posdef的导出参数列表放入。但是我收到以下错误:foreach.export=c("Posdef")

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

为什么 R 找不到这个定义的函数?

4

3 回答 3

16

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

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 可能无法与函数名称一起正常工作,但在下面得到了更正。]

于 2012-04-11T21:21:54.430 回答
11

简短的回答是,这是并行后端中的一个错误,例如doSNOW,doParalleldoMPI,但它已经被修复。

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

doSNOW和后端现在将关联环境从全局更改为通过“.export”导出的函数的“导出”环境,doParallel并且doMPI似乎已经解决了这些问题。

于 2013-07-26T14:19:24.993 回答
1

foreach %dopar% 问题的快速解决方法是重新安装这些软件包:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

它在我的情况下有效。

于 2017-08-21T09:08:22.833 回答