在循环R中并行使用parLapply

时间:2017-06-01 21:36:48

标签: r parallel-processing

我在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吗?

非常感谢!

2 个答案:

答案 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)

在我看来,嵌套并行内部只会增加进程的开销。避免这种嵌套可能会更好。