запуск нескольких параллельных процессов параллельно - PullRequest
0 голосов
/ 03 декабря 2018

Я запускаю байесовские статистические модели с каждой цепочкой на отдельном узле обработки, используя пакет runjags в R. Я хочу разместить сразу несколько моделей, вложив вызовы run.jags в параллельный цикл с использованием пакета foreach.Однако это часто приводит к сообщениям об ошибках, вероятно потому, что цикл foreach не «знает», что в цикле я вызываю другие параллельные процессы, и поэтому ядра, вероятно, имеют двойное распределение (или что-то в этом роде).Вот пример сообщения об ошибке:

Ошибка в {: сбой задачи 2 - «При попытке запустить модель JAGS обнаружена следующая ошибка:
Ошибка в socketConnection (« localhost », порт)= порт, сервер = ИСТИНА, блокировка = ИСТИНА,: не удается открыть соединение(который у меня есть на моем ноутбуке). Я хотел бы найти решение, которое позволило бы мне запускать несколько параллельных моделей 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)
}

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Здесь необходимо рассмотреть две вещи: как вложить параллельные циклы foreach() в целом, и как решить эту конкретную проблему.

Решение для размещения параллельных циклов foreach() исходит от @Carlos Santillan'sответ ниже, и это основано на виньетке, которую можно найти здесь .Допустим, у нас есть один внутренний цикл, вложенный во внешний цикл, аналогично описанной выше проблеме, однако вместо параллельного вызова 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(), я изменил настройку method в run.jags на method=parallel вместо method=rjparallel.run.jags() имеет несколько различных параллельных реализаций, и эта конкретная, похоже, работает на основе моего анализа синхронизации.Надеемся, что в будущем будет более точный ответ на вопрос , почему это работает.Я просто знаю, что это работает.

0 голосов
/ 03 декабря 2018

Я не могу запустить ваш образец, но следующая виньетка должна вам помочь.

Вы можете попробовать использовать оператор вложенности 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)
}
...