37

如果我在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 将注册集群的信息保存在哪里?

4

2 回答 2

58

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

registerDoSEQ()

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

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

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

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

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

于 2014-08-04T00:01:28.893 回答
4
    cl <- makeCluster(2)
    registerDoParallel(cl)
    on.exit(stopCluster(cl))

这对我来说很好。

于 2016-01-20T04:23:38.420 回答