简体   繁体   English

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

[英]running multiple parallel processes in parallel R

I run Bayesian statistical models with each chain on a separate processing node using the runjags package in R. I want to fit multiple models at onceby nesting run.jags calls in a parallel loop using the foreach package. 我使用R中的runjags包在单独的处理节点上运行每个链的贝叶斯统计模型。我想一次通过使用foreach包在并行循环中嵌套run.jags调用来一次拟合多个模型。 However, this often results in error messages, likely because the foreach loop doesn't "know" that within the loop I am calling other parallel processes, and so cores are probably double-allocated (or something). 但是,这通常会导致错误消息,这很可能是因为foreach循环不“知道”该循环内我正在调用其他并行进程,因此内核可能被双重分配了(或其他方式)。 Here is an example error message: 这是示例错误消息:

Error in { : task 2 failed - "The following error was encountered while attempting to run the JAGS model: {:任务2中的错误失败-“尝试运行JAGS模型时遇到以下错误:
Error in socketConnection("localhost", port = port, server = TRUE, blocking = TRUE, : cannot open the connection socketConnection(“ localhost”中的错误,端口=端口,服务器= TRUE,阻止= TRUE ,:无法打开连接

Here is some example code to generate data and fit two models, that request 2 cores each (requiring a total of 4 cores, which I have on my laptop). 这是一些示例代码,用于生成数据并适合两个模型,每个模型需要2个内核(总共需要4个内核,我在笔记本电脑上拥有)。 I would love to find a solution that would allow me to run multiple parallel JAGS models, in parallel. 我很想找到一个解决方案,使我可以并行运行多个并行JAGS模型。 In reality I am running 5-10 models at a time which each require 3 cores, on a cluster. 实际上,我一次运行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)
}

I am unable to run your sample, but the following vignette should help you out. 我无法运行您的示例,但是以下小插图应该可以帮助您。

You may want to try to use the foreach nesting operator %:% 您可能想尝试使用foreach嵌套运算符%:%

https://cran.r-project.org/web/packages/foreach/vignettes/nested.pdf 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)
}

There are two things to consider here- how to nest parallel foreach() loops in general, and how to solve this particular issue. 这里有两件事要考虑-一般如何嵌套并行的foreach()循环,以及如何解决此特定问题。

The solution to nesting parallel foreach() loops comes from @Carlos Santillan's answer below, and is a based on a vignette that can be found here . 嵌套并行foreach()循环的解决方案来自@Carlos Santillan的以下答案,该解决方案基于可在此处找到的小插图。 Lets say we have one inner loop nested within an outer loop, similar to the problem above, however instead of the parallel call to run.jags we have a parallel foreach() call: 可以说我们有一个内部循环嵌套在一个外部循环中,类似于上面的问题,但是除了并行调用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)
}

The key is using the %:% operator in the outer loop, and the %dopar% operator in the inner loop. 关键是在外部循环中使用%:%运算符,在内部循环中使用%dopar%运算符。

This will not solve the above run.jags() nested parallel problem however, since it is not a nested foreach() loop. 但是,这不是上面的run.jags()嵌套并行问题,因为它不是嵌套的foreach()循环。 To solve this particular nested run.jags() problem I changed the method setting in run.jags to method=parallel instead of method=rjparallel . 为了解决这个特殊的嵌套run.jags()问题,我将run.jags中的method设置更改为method=parallel而不是method=rjparallel run.jags() has multiple different parallel implementations and this particular one seems to work based on my timing analyses. run.jags()具有多个不同的并行实现,并且根据我的时序分析,这一特定实现似乎可以正常工作。 Hopefully in the future there will be a more definitive answer as to why this works. 希望在将来, 为什么会有更好的答案。 I just know that it does work. 我只知道它确实有效。

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

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