我想更多地了解“ 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"
答案 0 :(得分:0)
首先,doSNOW
和doParallel
是两个不同的程序包,它们为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
没有提供任何同步机制来防止出现竞争情况。