我正在尝试使用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""
为什么无法找到这个定义的函数?
答案 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)
简短的回答是,这是doSNOW
,doParallel
和doMPI
等并行后端的错误,但此后已修复。
稍微长一点的答案是foreach
使用特殊的“导出”环境而不是全局环境向工作人员输出函数。这通常会导致在全局环境中创建的函数出现问题,因为“导出”环境不在其范围内,即使它们现在已在同一“导出”环境中定义。因此,他们看不到“导出”环境中定义的任何其他函数或变量,例如您的情况中的“Posdef”。
doSNOW
,doParallel
和doMPI
后端现在将通过“.export”导出的功能的关联环境从全局更改为“导出”环境,并且似乎已解决这些问题。
答案 2 :(得分:1)
快速修复foreach%dopar%的问题是重新安装这些软件包:
install.packages("doSNOW")
install.packages("doParallel")
install.packages("doMPI")
它适用于我的情况。