0

我正在尝试通过远程连接到超级计算机以使用并行包的 parLapply 使用许多内核(通过 computeCanada)来并行运行模型列表。

当我运行该行时:

 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”列表:

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

收到错误后,我检查了 str(mods),它作为“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 非常陌生,所以此时任何指导对我都非常有用!提前致谢

4

1 回答 1

0

在对代码应用并行化之前,最好检查一下你的代码是否在没有并行化的情况下运行,以获取列表中的前几个元素。这将帮助您捕获代码中的错误。

由于我没有你的数据集,我将使用青蛙数据集来准备 unmarkedFitOccu 对象:

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)

如果一切顺利,您就可以应用并行化。

于 2019-10-18T03:52:00.760 回答