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)
}