我在R的循环中的parLapply
中运行了parallel
,但是我收到了错误:
library(doSNOW)
library(foreach)
cl<-makeCluster(4) #change the 2 to your number of CPU cores
registerDoSNOW(cl)
foreach(1:2) %dopar% {
clusterExport(cl, "parLapply")
parLapply(cl, 1:2,function(exponent)2^exponent)
}
启动此代码时,出现以下错误:
> Error in { : task 1 failed - "object 'c1' not found"
有人能帮我解释原因吗?可以在循环中使用parLapply
中的parallel
吗?
非常感谢!
答案 0 :(得分:4)
无法导出群集对象,因为它们无法安全地序列化并发送给工作者,因为它们包含socketConnection对象。相反,您应该在每个worker上创建它们作为worker初始化的一部分。群集创建可能需要很长时间,因此无论foreach循环中的迭代次数如何,每个工作者只创建一个群集对象非常重要。
这是一个使用clusterEvalQ
函数初始化和清理worker的示例,以便您可以在foreach循环中执行parLapply
:
library(doSNOW)
# Start cluster on master and register it for use with doSNOW
cl <- makeCluster(4)
registerDoSNOW(cl)
# Start cluster on workers
clusterEvalQ(cl, {
library(parallel)
cl <- makeCluster(2)
})
# Execute nested parallel loop
r <-
foreach(1:2, .noexport='cl', .packages='parallel') %dopar% {
parLapply(cl, 1:2, function(exponent)2^exponent)
}
# Stop clusters on workers
clusterEvalQ(cl, {
stopCluster(cl)
})
# Stop cluster on master
stopCluster(cl)
答案 1 :(得分:0)
替换包列表并使用以下更新的命令。它对我有用。另外,您需要在工作节点中定义单独的集群 cl 。或者您可以尝试在cl上使用clusterCall函数来创建再次创建集群的子进程。
library(doParallel)
cl<-makeCluster(2,outfile = "")
registerDoParallel(cl)
foreach(1:2, .export = c('cl','parLapply') , .packages = 'doParallel' ) %dopar% {
cl2<-makeCluster(2,outfile = "")
registerDoParallel(cl2)
parLapply(cl2, 1:2,function(exponent)2^exponent)
stopCluster(cl2)
}
stopCluster(cl)
在我看来,嵌套并行内部只会增加进程的开销。避免这种嵌套可能会更好。