doParallel():将值缓存到预定义的环境中[Windows]

时间:2018-06-28 18:22:03

标签: r windows foreach scoping doparallel

我想更多地了解“ doParallel”软件包。我正在玩环境。我想在.someEnv<-new.env(parent = emptyenv())之外创建一个foreach() %dopar%{…}全局环境

我知道foreach()需要使用foreach().export= “”将所有包,函数,值和数据导入到.packages=””函数中。

我的问题是,是否有一种方法可以将Global环境导入foreach(),并在该环境中进行读写,并将其用作缓存计算的方法? (请不要对使用.Rdata,.RDS,.feather等的缓存计算发表评论)

这是一个示例:

require(doParallel)
library(doSNOW)
getDoParWorkers()
getDoParName()
cl<-makeCluster(4, type = "SOCK")
registerDoSNOW(cl)
getDoParWorkers()
getDoParName()

#define environment
.someEnv<-new.env(parent =  emptyenv())
.someEnv$var<-1:10
.someEnv$squared<-matrix(nrow=10)

#define Function for "foreach"
do.something<-function(x)
{
  .someEnv$squared[x]<-.someEnv$var[x] *.someEnv$var[x]   
   return(.someEnv$squared[x])
}

foreach(i=1:10) %dopar% do.something(i)
stopCluster(cl)

错误消息:

Error in do.something(i) : 
  task 1 failed - "Objekt '.someEnv' nicht gefunden"

1 个答案:

答案 0 :(得分:0)

首先,doSNOWdoParallel是两个不同的程序包,它们为foreach提供后端。 您当然可以同时测试 只是不要感到困惑。 以下适用于任何一种, 但是您的问题与parallel软件包的使用关系更紧密 (包含在R中)。

您的方法行不通,因为即使您将环境放在每个并行工作者中, 它们将是独立修改的副本:

foreach(i = 1L:2L) %dopar% {
    .someEnv$hello <- "world"
    .someEnv$hello
}
[[1]]
[1] "world"

[[2]]
[1] "world"

print(.someEnv$hello)
NULL

但是,您可以使用bigmemory软件包:

library(doParallel)
library(bigmemory)

cl <- makeCluster(4L)
registerDoParallel(cl)

var <- 1L:10L

squared <- big.matrix(nrow = 10L, ncol = 1L, type = "integer")
# show by coercing to normal matrix
squared[,]
[1] NA NA NA NA NA NA NA NA NA NA

squared_desc <- describe(squared)
# assign it to each worker's global environment
clusterExport(cl, c("squared_desc"))

foreach(i = 1L:10L,
        .noexport = c("squared_desc"),
        .packages = "bigmemory") %dopar%
        {
          squared <- attach.big.matrix(squared_desc)
          squared[i] <- var[i] * var[i]
          NULL
        }

stopCluster(cl); registerDoSEQ()

squared[,]
[1]   1   4   9  16  25  36  49  64  81 100

请注意,bigmemory中的矩阵是严格内部输入的, 因此,如果您将它们定义为整数, 您应该为他们分配整数值, 通过在数字的末尾附加L在R中明确指定 否则,您会收到有关垂降的警告。

此外,您无需强迫整个big.matrix来使用它, 但是几乎每次访问它的元素时,您都会将一些数据复制到常规R矩阵/向量中。

编辑:最后,我认为bigmemory没有提供任何同步机制来防止出现竞争情况。