【问题标题】:How to export objects to parallel clusters within a function in R如何将对象导出到 R 函数中的并行集群
【发布时间】:2014-03-30 03:22:45
【问题描述】:

我正在编写一个函数来组合和组织数据,然后使用 base R 中的并行函数并行运行 MCMC 链。我的函数如下。

dm100zip <- function(y, n.burn = 1, n.it = 3000, n.thin = 1) {
  y <- array(c(as.matrix(y[,2:9]), as.matrix(y[ ,10:17])), c(length(y$Plot), 8, 2))
  nplots <- nrow(y)
  ncap1 <- apply(y[,1:8, 1],1,sum)
  ncap2 <- apply(y[,1:8, 2],1,sum)
  ncap <- as.matrix(cbind(ncap1, ncap2))
  ymax1 <- apply(y[,1:8, 1],1,sum)
  ymax2 <- apply(y[,1:8, 2],1,sum)

  # Bundle data for JAGS/BUGS
  jdata100 <- list(y=y, nplots=nplots, ncap=ncap)

  # Set initial values for Gibbs sampler
  inits100 <- function(){
    list(p0=runif(1, 1.1, 2),
      p.precip=runif(1, 0, 0.1),
      p.day = runif(1, -.5, 0.1))
  }

  # Set parameters of interest to monitor and save
  params100 <- c("N", "p0")

  # Run JAGS in parallel for improved speed
  CL <- makeCluster(3) # set number of clusters = to number of desired chains
  clusterExport(cl=CL, list("jdata100", "params100", "inits100", "ymax1", "ymax2", "n.burn", "jag", "n.thin")) # make data available to jags in diff cores
  clusterSetRNGStream(cl = CL, iseed = 5312)

  out <- clusterEvalQ(CL, {
    library(rjags)
    load.module('glm')
    jm <- jags.model("dm100zip.txt", jdata100, inits100, n.adapt = n.burn, n.chains = 1)
    fm <- coda.samples(jm, params100, n.iter = n.it, thin = n.thin)
    return(as.mcmc(fm))

  })

  out.list <- mcmc.list(out) # group output from each core into one list
  stopCluster(CL)

  return(out.list)
}

当我运行该函数时,我收到一个错误,即未找到用于 clusterExport 函数的 n.burn、n.it 和 n.thin。例如,

dm100zip.list.nain <- dm100zip(NAIN, n.burn = 1, n.it = 3000, n.thin = 1) # returns error

如果我在运行函数之前为它们中的每一个设置了值,那么它会使用这些值并且运行良好。例如,

n.burn = 1
n.it = 1000
n.thin = 1
dm100zip.list.nain <- dm100zip(NAIN, n.burn = 1, n.it = 3000, n.thin = 1) 

这运行良好,但使用 n.it = 1000 而不是 3000

有人可以帮助解释为什么ClusterExport 函数使用全局环境中的对象,而不是ClusterExport 在其中运行的函数分配的值吗?有没有办法解决这个问题?

【问题讨论】:

    标签: r function parallel-processing


    【解决方案1】:

    默认情况下,clusterExport 在全局环境中查找“varlist”指定的变量。在您的情况下,它应该查看 dm100zip 函数的本地环境。为此,您可以使用 clusterExport "envir" 参数:

    clusterExport(cl=CL, list("jdata100", "params100", "inits100", "ymax1",
                              "ymax2", "n.burn", "jag", "n.thin"),
                  envir=environment())
    

    请注意,“varlist”中定义在全局环境中的变量也会被找到,但在 dm100zip 中定义的值将优先。

    【讨论】:

      【解决方案2】:

      由于 R 中的函数参数是通过惰性求值处理的,因此您需要确保函数的执行环境中确实存在任何默认参数。事实上,R 核心作者为此目的包含了 force 函数,它只是 function(x) x 并强制将参数从承诺转换为评估表达式。尝试进行以下修改:

      dm100zip <- function(y, n.burn = 1, n.it = 3000, n.thin = 1) {
        force(n.burn); force(n.it); force(n.thin)
        # The rest of your code as above...
      }
      

      有关这些问题的更详细说明,请咨询Lazy Evaluation section of Hadley's treatment of functions

      【讨论】:

      • 感谢您的信息。我不知道力功能。不幸的是,我仍然遇到同样的错误: > dm100zip.list.nain
      • 不必强制评估通过 clusterExport 导出的变量。您可能必须强制在用户提供的工作函数的序列化环境中隐式发送到工作进程的变量,但这是 parLapply 和 clusterApplyLB 等函数的问题,而不是 clusterEvalQ。
      猜你喜欢
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 2021-12-22
      相关资源
      最近更新 更多