簡體   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