我正在测试doRedis软件包,方法是在一台机器上运行一台机器,在另一台机器上运行主机/服务器。我的主人的代码如下:
#Register ...
r <- foreach(a=1:numreps, .export(...)) %dopar% {
train <- func1(..)
best <- func2(...)
weights <- func3(...)
return ...
}
在每个函数中,都会访问一个全局变量,但不会对其进行修改。我已经在foreach循环的.export部分中导出了全局变量,但每当我运行代码时,都会发生错误,指出找不到该变量。有趣的是,代码在我的所有工作人员在一台机器上工作,但在我有一个“外部”工作人员时崩溃。有关此错误发生的任何想法,以及如何纠正错误?
谢谢!
更新:我在这里有一些代码的要点:https://gist.github.com/liangricha/fbf29094474b67333c3b
UPDATE2:我问另一个人与doRedis有关的问题:“是否可以允许每台工作机器使用其所有核心?
答案 0 :(得分:1)
这种代码过去是doParallel,doSNOW和doMPI包的问题,但是在过去一年左右它们得到了改进,以便更好地处理它。问题是变量被导出到一个特殊的“导出”环境,不到全局环境。这在各种方面都是可取的,但这意味着后端必须做更多工作,以便导出的变量在导出函数的范围内。看起来doRedis尚未更新以使用这些改进。
这是一个说明问题的简单示例:
library(doRedis)
registerDoRedis('jobs')
startLocalWorkers(3, 'jobs')
glob <- 6
f1 <- function() {
glob
}
f2 <- function() {
foreach(1:3, .export=c('f1', 'glob')) %dopar% {
f1()
}
}
f2() # fails with the error: "object 'glob' not found"
如果使用doParallel后端,则成功:
library(doParallel)
cl <- makePSOCKcluster(3)
registerDoParallel(cl)
f2() # works with doParallel
一种解决方法是在函数“f2”中定义函数“f1”:
f2 <- function() {
f1 <- function() {
glob
}
foreach(1:3, .export=c('glob')) %dopar% {
f1()
}
}
f2() # works with doParallel and doRedis
另一种解决方案是使用某种机制将变量导出到每个工作者的全局环境中。使用doParallel或doSNOW,你可以使用clusterExport函数,但我不知道如何使用doRedis。
我将向doRedis包的作者报告此问题,并建议他更新doRedis以处理doParallel等导出函数。