Проблемы при параллельном запуске моделей на суперкомпьютере - do.call не распознает мой список моделей в parLapply/clusterApply

Я пытаюсь запустить список моделей параллельно, удаленно подключаясь к суперкомпьютеру, чтобы использовать много ядер (через computeCanada), используя parLapply параллельного пакета.

Когда я запускаю линию:

 modsout<-parLapply(cl=cl, X=mods, fun=run_um)

Я получаю следующую ошибку:

 models3out<-parLapply(cl=cl, X=mods, fun=run_um)
 Error in do.call(c, clusterApply(cl = cl, x = splitList(X, nchunks), fun 
 = lapply,  : 
 second argument must be a list
 Calls: parLapply -> do.call
 Execution halted

Я создал свой список модов, выполнив, например, следующее:

mods<-list(mod1, mod2, mod3, mod4)

После получения ошибки я проверил str (моды), и она была возвращена как "список из 4", поэтому я действительно не понимаю, почему она не распознается в моей строке parLapply.

Вот выдержка из моего кода:

nodeslist = unlist(strsplit(Sys.getenv("NODESLIST"), split=" "))
cl<-makeCluster(nodeslist, type="PSOCK") #make cluster

#load all the data xxx

#create model list
mods<- list(b0<-list(formula='~1~1', data=bear3),
           b1<-list(formula='~trail+elev+precip+temp+hum+cat+tree+month+topo~1', data=bear3),
           b2<-list(formula='~trail~1', data=bear3),
           b3<-list(formula='~elev~1', data=bear3))

run_um<-function(x) {unmarked::occu(as.formula(x[[1]]),x[[2]])} #define the function

clusterExport(cl=cl, varlist=c("bear3", "run_um") #send data to cores

clusterEvalQ(cl=cl, library(unmarked))#load package on all cores

modsout<-parLapply(cl=cl, X=mods, fun=run_um)

Моя полная работа состоит из>2000 моделей, и каждая модель требует не менее 20 минут для запуска, плюс мне необходимо выполнить тесты на соответствие требованиям, поэтому я пытаюсь использовать HPC. Я все еще относительно новичок в R и чрезвычайно новичок в HPC, поэтому любые рекомендации были бы чрезвычайно полезны для меня в это время! заранее спасибо

0 ответов

Прежде чем применять распараллеливание к вашему коду, всегда рекомендуется проверить, работает ли ваш код без распараллеливания для первых пар элементов в вашем списке. Это поможет вам обнаружить ошибки в вашем коде.

Поскольку у меня нет вашего набора данных, я буду использовать лягушки набора данных, чтобы подготовить немаркированный объект FitOccu:

library(unmarked)

# Create some unmarkedFitOccu object
data(frogs)
pferUMF <- unmarkedFrameOccu(pfer.bin)
siteCovs(pferUMF) <- data.frame(sitevar1 = rnorm(numSites(pferUMF)))
obsCovs(pferUMF) <- data.frame(obsvar1 = rnorm(numSites(pferUMF) * obsNum(pferUMF)))

Второй шаг - подготовить список (в вашем случае моды). Когда вы создаете именованный список, вы должны использовать "="знак (не"<-"как в коде):

# Create a list
mods <- list(b1 = list(formula='~obsvar1~1', data=pferUMF),
             b2 = list(formula='~sitevar1~1', data=pferUMF))

Затем мы можем определить функцию:

run_um<-function(x) {unmarked::occu(as.formula(x[[1]]),data=x[[2]])  }

Затем убедитесь, что вы проверили, работает ли он для пары элементов в вашем списке:

# Check if the function works on a single list item
run_um(mods[[2]])
# Call:
#   unmarked::occu(formula = as.formula(x[[1]]), data = x[[2]])
# 
# Occupancy:
#   Estimate   SE     z P(>|z|)
# 8.81 29.7 0.297   0.767
# 
# Detection:
#   Estimate    SE       z  P(>|z|)
# (Intercept)   -1.916 0.164 -11.721 9.93e-32
# sitevar1      -0.139 0.178  -0.781 4.35e-01
# 
# AIC: 262.7176 

Затем вы можете сначала попробовать обычную функцию lapply для первых нескольких элементов:

lapply(mods,FUN=run_um)

А если все пойдет хорошо, можно применить распараллеливание.

Другие вопросы по тегам