“注销” doParallel 集群

Posted

技术标签:

【中文标题】“注销” doParallel 集群【英文标题】:"un-register" a doParallel cluster 【发布时间】: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 运行并显示警告,而不是在取消注册集群后出现错误。 【参考方案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% 代码

以上是关于“注销” doParallel 集群的主要内容,如果未能解决你的问题,请参考以下文章

R:在doParallel /降雪中制作集群挂起

插入符号训练二进制 glm 通过 doParallel 在并行集群上失败

已注册的 doParallel 集群不适用于 train/caret parRF 模型

R语言-并行计算

series和 paralle

R中doMC和doParallel的区别