繁体   English   中英

在并行R中运行多个并行进程

[英]running multiple parallel processes in parallel R

我使用R中的runjags包在单独的处理节点上运行每个链的贝叶斯统计模型。我想一次通过使用foreach包在并行循环中嵌套run.jags调用来一次拟合多个模型。 但是,这通常会导致错误消息,这很可能是因为foreach循环不“知道”该循环内我正在调用其他并行进程,因此内核可能被双重分配了(或其他方式)。 这是示例错误消息:

{:任务2中的错误失败-“尝试运行JAGS模型时遇到以下错误:
socketConnection(“ localhost”中的错误,端口=端口,服务器= TRUE,阻止= TRUE ,:无法打开连接

这是一些示例代码,用于生成数据并适合两个模型,每个模型需要2个内核(总共需要4个内核,我在笔记本电脑上拥有)。 我很想找到一个解决方案,使我可以并行运行多个并行JAGS模型。 实际上,我一次运行5-10个模型,每个模型需要3个内核。

library(foreach)
library(runjags)

#generate a random variable, mean of 25, sd = 5.----
y.list <- list()
for(i in 1:2){
  y.list[[i]] <- rnorm(100, 25, sd = 5)
}

#Specify a JAGS model to fit an intercept.----
jags.model = "
model{
  for(i in 1:N){
    y.hat[i] <- intercept
    y[i] ~ dnorm(y.hat[i], tau)
  }

  #specify priors.
  intercept ~ dnorm(0,1E-3)
  tau <- pow(sigma, -2)
  sigma ~ dunif(0, 100)
}
"

n.cores <- 4
registerDoParallel(n.cores)

#Fit models in parallel, with chains running in parallel.----
#two processes that each require two cores (4 cores are registered and all that is required.)
output <- list()
output <- 
foreach(i = 1:length(y.list)) %dopar% {
    #specify data object.
    jd <- list(y=y.list[[i]], N = length(y.list[[i]]))
    #fit model.
    jags.out <- run.jags(jags.model,
                         data=jd,
                         n.chains=2,
                         monitor=c('intercept','tau'),
                         method='rjparallel')
    #return output
    return(jags.out)
}

我无法运行您的示例,但是以下小插图应该可以帮助您。

您可能想尝试使用foreach嵌套运算符%:%

https://cran.r-project.org/web/packages/foreach/vignettes/nested.pdf

foreach(i = 1:length(y.list)) %:% {
    #specify data object.
    jd <- list(y=y.list[[i]], N = length(y.list[[i]]))
    #fit model.
    jags.out <- run.jags(jags.model,
                         data=jd,
                         n.chains=2,
                         monitor=c('intercept','tau'),
                         method='rjparallel')
    #return output
    return(jags.out)
}

这里有两件事要考虑-一般如何嵌套并行的foreach()循环,以及如何解决此特定问题。

嵌套并行foreach()循环的解决方案来自@Carlos Santillan的以下答案,该解决方案基于可在此处找到的小插图。 可以说我们有一个内部循环嵌套在一个外部循环中,类似于上面的问题,但是除了并行调用run.jags ,还有一个并行的foreach()调用:

outer_list <- list()
#begin outer loop:
outer_list <-
foreach(i = 1:length(some_index)) %:% {
    #grab something to feed next foreach loop.
    to_inner <- grab_data[[i]]

    #Do something in a nested foreach loop.
    inner_list <- list()
    #begin inner loop:
    inner_list <-
    foreach(k = 1:some_index) %dopar% {
      #do some other function.
      out_inner <- some_function(to_inner)
      return(out_inner)
      }
   out_outer <- some_function(out_inner)
   return(out_outer)
}

关键是在外部循环中使用%:%运算符,在内部循环中使用%dopar%运算符。

但是,这不是上面的run.jags()嵌套并行问题,因为它不是嵌套的foreach()循环。 为了解决这个特殊的嵌套run.jags()问题,我将run.jags中的method设置更改为method=parallel而不是method=rjparallel run.jags()具有多个不同的并行实现,并且根据我的时序分析,这一特定实现似乎可以正常工作。 希望在将来, 为什么会有更好的答案。 我只知道它确实有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM