Проблемы при параллельном запуске моделей на суперкомпьютере - 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)
А если все пойдет хорошо, можно применить распараллеливание.