【问题标题】:"un-register" a doParallel cluster“注销” doParallel 集群
【发布时间】:2014-09-25 16:33:46
【问题描述】:

如果我在没有注册集群的情况下运行foreach... %dopar%,foreach 会引发警告,并按顺序执行代码:

library("doParallel")
foreach(i=1:3) %dopar%
  sqrt(i)

产量:

Warning message:
executing %dopar% sequentially: no parallel backend registered 

但是,如果我在启动、注册和停止集群后运行相同的代码,它会失败:

cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
foreach(i=1:3) %dopar%
  sqrt(i)

产量:

Error in summary.connection(connection) : invalid connection

有没有registerDoParallel() 的反义词可以清理集群注册?还是在我重新启动 R 会话之前,我是否被旧集群的幽灵所困扰?

/edit:一些谷歌搜索揭示了bumphunter Biocondoctor 包中的bumphunter:::foreachCleanup() 函数:

function () 
{
    if (exists(".revoDoParCluster", where = doParallel:::.options)) {
        if (!is.null(doParallel:::.options$.revoDoParCluster)) 
            stopCluster(doParallel:::.options$.revoDoParCluster)
        remove(".revoDoParCluster", envir = doParallel:::.options)
    }
}
<environment: namespace:bumphunter>

但是,这个功能似乎并不能解决问题。

library(bumphunter)
cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
bumphunter:::foreachCleanup()
foreach(i=1:3) %dopar%
  sqrt(i)

foreach 将注册集群的信息保存在哪里?

【问题讨论】:

  • 你不应该在 foreach() 操作之后使用 stopCluster(cl) 吗?叉子应该关闭,不需要删除 cl 对象。
  • @Patrick McCarthy 通常你会这样做,是的。关键是,fork 关闭后,foreach 仍在寻找停止的集群。
  • 也许我没有正确地关注你。预期的行为是在集群停止后运行foreach,或者违背您的意愿集群在foreach 完成之前提前停止,或者其他什么?重读,您希望它运行,但在集群停止的情况下会出现警告?
  • @Patrick McCarthy 我想返回到 foreach 运行并显示警告,而不是在取消注册集群后出现错误。

标签: r parallel-processing parallel-foreach


【解决方案1】:

“注销”foreach 后端的唯一官方方法是注册顺序后端:

registerDoSEQ()

这对我来说很有意义,因为您应该声明要使用哪个后端,所以我认为提供一种“取消声明”要使用哪个后端的方法没有任何意义。相反,您声明要使用默认的顺序后端。

我最初考虑包含一个“取消注册”功能,但由于我无法说服自己它有用,所以我决定将其省略,因为添加功能比删除功能要容易得多。

话虽如此,我认为您需要做的就是从 foreach:::.foreachGlobals 中删除所有变量,这是 foreach 保留其所有状态的位置:

unregister <- function() {
  env <- foreach:::.foreachGlobals
  rm(list=ls(name=env), pos=env)
}

调用此函数后,任何并行后端将被注销,如果调用%dopar%,将再次发出警告。

【讨论】:

  • 也许为registerDoSeq 添加别名-> unregister 会是要走的路吗?
  • 完美,这就是我想要的。谢谢。
  • 这是一个很好的解决方案,因为我已经处理这个问题近两年没有找到解决方案。但是,我确实有一个问题,如果我注册了这个函数,我是在运行 foreach 循环之前单独在一行中运行“unregister”,还是将它放入甚至在循环之后?谢谢!
【解决方案2】:
    cl <- makeCluster(2)
    registerDoParallel(cl)
    on.exit(stopCluster(cl))

这对我来说很好。

【讨论】:

  • 如果你运行stopCluster(cl)然后尝试运行%dopar%,它会失败。你需要先运行registerDoSEQ()
  • 我猜 on.exit() 会处理它。
  • on.exit() 仅在使用 registerDoParallel(cl) 注册的并行后端完成 %dopar% 后才执行 stopClusters(cl)
  • on.exit() 基本上意味着stopCluster 在您的会话期间永远不会被调用。我需要一种方法来停止集群然后继续运行%dopar% 代码
猜你喜欢
  • 2015-05-03
  • 2016-02-08
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2020-12-04
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
相关资源
最近更新 更多