我正在尝试使用笔记本电脑上的并行处理在R中运行NetLogo模拟(使用RNetLogo软件包)。我试图用3(即0,25和50)不同的“最小分离”值来评估“女性的t喂养”。对于每个“最小间隔”值,我想复制模拟10次。我可以使用lapply
正确运行所有内容,但我遇到parLapply
时遇到问题。我刚刚开始使用“并行”包,所以我确信它是语法中的东西。
#Set up clusters for parallel
processors <- detectCores()
cl <- makeCluster(processors)
#Simulation
sim3 <- function(min_sep) {
NLCommand("set minimum-separation ", min_sep, "setup")
ret <- NLDoReport(720, "go", "[t-feeding] of females", as.data.frame=TRUE)
tot <- sum(ret[,1])
return(tot)
}
#Replicate simulations 10 times using lapply and create boxplots. This one works.
rep.sim3 <- function(min_sep, rep) {
return(
lapply(min_sep, function(min_sep) {
replicate(rep, sim3(min_sep))
})
)
}
d <- seq(0,50,25)
res <- rep.sim3(d,10)
boxplot(res,names=d, xlab="Minimum Separation", ylab="Time spent feeding")
#Replicate simulations 10 times using parLapply. This one does not work.
rep.sim3 <- function(min_sep, rep) {
return(
parLapply(cl, min_sep, function(min_sep) {
replicate(rep, sim3(min_sep))
})
)
}
d <- seq(0,50,25)
res <- rep.sim3(d,10)
# Error in checkForRemoteErrors(val) : 3 nodes produced errors; first error: could not find function "sim3"
#Replicate simulations 10 times using parLapply. This one does work but creates a list of the wrong length and therefore the boxplot cannot be plotted correctly.
rep.sim3 <- function(min_sep, rep) {
return(
parLapply(cl, replicate(rep, d), sim3))
}
d <- seq(0,50,25)
res <- rep.sim3(d,10)
理想情况下,我想让第一个parLapply
工作。或者,我想我可以从res
修改parLapply
,以便列表的长度为max_sep
而不是30.但是,我似乎无法做到这一点。任何帮助将不胜感激!
提前致谢。
答案 0 :(得分:3)
您需要在执行rep.sim3
之前初始化集群工作者。该错误消息表明您的工作人员无法执行sim3
功能,因为您尚未将其导出。另外,我注意到你还没有在工作人员上加载RNetlogo
包。
初始化工作人员的最简单方法是使用clusterEvalQ
和clusterExport
函数:
clusterEvalQ(cl, library(RNetLogo))
clusterExport(cl, 'sim3')
请注意,您不应在rep.sim3
函数中执行此操作,因为这样做效率低且不必要。在创建群集对象后立即执行一次,并且已定义sim3
。
这种初始化是必要的,因为通过makeCluster
启动的工作人员对您的变量或函数或R会话的任何其他内容一无所知。并且parLapply
不会分析您传递给它的函数,而不仅仅是lapply
。区别在于lapply
在本地R会话中执行,其中定义了sim3
并加载了RNetLogo
包。 parLapply
在远程R会话中执行指定的函数,该函数尚未通过执行R脚本进行初始化。