1

我正在通过在一台机器上运行工作者和在另一台机器上运行主/服务器来测试 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相关的问题:“是否有可能允许每台工作机器利用其所有核心?

@Steve Weston 回应:“每个核心启动一个 redis 工作者通常会充分利用机器。”

4

1 回答 1

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"

If the doParallel backend is used, it succeeds:

library(doParallel)
cl <- makePSOCKcluster(3)
registerDoParallel(cl)

f2()  # works with doParallel

One workaround is to define the function "f1" inside function "f2":

f2 <- function() {
  f1 <- function() {
    glob
  }
  foreach(1:3, .export=c('glob')) %dopar% {
    f1()
  }
}

f2()  # works with doParallel and doRedis

Another solution is to use some mechanism to export the variables to the global environment of each of the workers. With doParallel or doSNOW, you could do that with the clusterExport function, but I'm not sure how to do that with doRedis.

I'll report this issue to the author of the doRedis package and suggest that he update doRedis to handle exported functions like doParallel.

于 2014-04-08T21:36:52.980 回答