clusterExport,环境和变量范围

时间:2013-11-25 23:44:51

标签: r parallel-processing

我写了一个函数,我在其中定义变量和加载对象。这是一个简化版本:

fn1 <- function(x) {
  load("data.RData") # a vector named "data"
  source("myFunctions.R")
  library(raster)
  library(rgdal)

  a <- 1
  b <- 2
  r1 <- raster(ncol = 10, nrow = 10)
  r1 <- init(r1, fun = runif)
  r2 <- r1 * 100
  names(r1) <- "raster1"
  names(r2) <- "raster2"
  m <- stack(r1, r2) # basically, a list of two rasters in which it is possible to access a raster by its name, like this: m[["raster1"]]

  c <- fn2(m)
}

函数“fn2”可以在“myFunctions.R”中找到并定义为:

fn2 <- function(x) {
  fn3 <- function(y) {
   x[[y]] * 100 * data
  }

  cl <- makeSOCKcluster(8)   
  clusterExport(cl, list("x"), envir = environment()) 
  clusterExport(cl, list("a", "b", "data")) 
  clusterEvalQ(cl, c(library(raster), library(rgdal), rasterOptions(maxmemory = a, chunksize = b))) 
  f <- parLapply(cl, names(x), fn3)  
  stopCluster(cl)
}

现在,当我运行fn1时,我收到如下错误:

Error in get(name, envir = envir) : object 'a' not found

根据我的理解?clusterExport,envir的默认值是.GlobalEnv,所以我假设fn2可以访问“a”和“b”。但是,似乎并非如此。如何访问“a”和“b”所属的环境?

到目前为止,我找到的唯一解决方案是将“a”和“b”作为参数传递给fn2。有没有办法在fn2中使用这两个变量而不将它们作为参数传递?

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:5)

您在调用clusterExport(cl, list("a", "b", "data"))时收到错误,因为clusterExport正在尝试查找.GlobalEnv中的变量,但fn1未将其设置为.GlobalEnv但是在它自己的本地环境中。

另一种方法是将fn1的本地环境传递给fn2,并将该环境指定为clusterExport。对fn2的调用将是:

c <- fn2(m, environment())

如果fn2的参数为function(x, env),则对clusterExport的调用将为:

clusterExport(cl, list("a", "b", "data"), envir = env)

由于环境是通过引用传递的,因此执行此操作应该没有性能问题。