R 使用并行函数时的环境和范围
我有以下功能:R 使用并行函数时的环境和范围,r,function,parallel-processing,scope,R,Function,Parallel Processing,Scope,我有以下功能: f1<-function(x){ iih_data<-...stuff... ...more stuff... cl <- makeCluster(mc <- getOption("cl.cores", 6)) clusterExport(cl, c("iih_data")) clusterEvalQ(cl, require(lme4)) Tstar<-parCapply(cl, ystar, function(x){
f1<-function(x){
iih_data<-...stuff...
...more stuff...
cl <- makeCluster(mc <- getOption("cl.cores", 6))
clusterExport(cl, c("iih_data"))
clusterEvalQ(cl, require(lme4))
Tstar<-parCapply(cl, ystar, function(x){
ostar=glmer(x ~ GENO + RACE + (1|GROUP), family="binomial",data=iih_data,nAGQ=1)
fixef(ostar)[2]/sqrt(vcov(ostar)[2,2])
})
stopCluster(cl)
...more stuff...
}
我猜这与我试图在函数内部运行并行应用程序有关。你们能帮我解决这个问题吗?谢谢添加
envir=environment()
to clusterExport()修复了该问题。e、 g
clusterExport(cl, c("iih_data"),envir=environment())
如您所知,
clusterExport
在.GlobalEnv
中查找指定的变量,除非使用envir
参数另有指示。但在您的特定示例中,iih_数据
与您使用parcaply
执行的未命名函数一起被序列化,因此您通过clusterExport
导出给工作人员的副本实际上不会被使用。实际上,在执行parcaply
之前在f1
中定义的所有局部变量都将与未命名的辅助函数一起序列化,并发送给每个辅助函数
这种技术在向工作人员发送数据时非常有用(实际上由clusterExport
本身使用),但您必须知道自己在做什么,否则会严重影响性能,尤其是在使用clusterApply
和clusterApplyLB
时,因为它们不执行与parlappy
和parapply
相同的预调度
下面是一个简单的示例,演示了这一点:
library(parallel)
cl <- makePSOCKcluster(3)
f1 <- function() {
iih_data <- 'foo'
parLapply(cl, 1:3, function(i) iih_data)
}
f1()
但为什么它说“对象‘x’未找到”而不是“对象‘iih_数据’未找到”?这是由于R对函数参数的惰性计算。函数及其关联的环境被序列化并发送给worker,而无需计算参数“iih_data”。直到对worker执行了unnamed worker函数之后,才会对其进行计算,这时它发现在worker的全局环境中没有定义“x”
您可以通过将f1
更改为:
f1 <- function(iih_data) {
force(iih_data)
parLapply(cl, 1:3, function(i) iih_data)
}
f1哇,这是一个多么完美、彻底的答案啊!非常感谢。我知道发生了一些复杂的事情。@Benjamin我包含了关于未赋值函数参数的内容,因为这是您在上一个问题中遇到的问题,可能被错误地标记为重复。其寓意是:“当心并行执行闭包”。伙计,我希望我能为我目前遇到的问题提供一个可复制的例子。我有1000%的人相信这是事实,但我不知道如何重现它。我有一个源代码脚本,它有两个cl
library(parallel)
cl <- makePSOCKcluster(3)
f1 <- function(iih_data) {
parLapply(cl, 1:3, function(i) iih_data)
}
x <- 'foo'
f1(x)
Error in checkForRemoteErrors(val) :
3 nodes produced errors; first error: object 'x' not found
f1 <- function(iih_data) {
force(iih_data)
parLapply(cl, 1:3, function(i) iih_data)
}