“注销” 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 集群的主要内容,如果未能解决你的问题,请参考以下文章
插入符号训练二进制 glm 通过 doParallel 在并行集群上失败