отменить регистрацию кластера doParallel

Если я запускаю 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:::foreachCleanup() в пакете bumphunter Biocondoctor:

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 хранит информацию о зарегистрированном кластере?


person Zach    schedule 02.08.2014    source источник
comment
Разве вы не должны использовать stopCluster(cl) после операции foreach()? Тогда вилки должны быть закрыты, и нет необходимости удалять объект cl.   -  person Patrick McCarthy    schedule 02.08.2014
comment
@ Патрик Маккарти Обычно это то, что вы делаете, да. Дело в том, что после закрытия форка foreach все равно ищется остановленный кластер.   -  person Zach    schedule 02.08.2014
comment
Может быть, я не понимаю вас правильно. Предполагаемое поведение состоит в том, чтобы запустить foreach после остановки кластера, или вопреки вашему желанию кластер останавливается преждевременно до завершения foreach, или что-то еще? Перечитывая, вы хотите, чтобы он запускался, но с предупреждением, в случае остановки кластера?   -  person Patrick McCarthy    schedule 03.08.2014
comment
@Patrick McCarthy Я бы хотел вернуться к работе foreach с предупреждением, а не с ошибкой после отмены регистрации кластера.   -  person Zach    schedule 04.08.2014


Ответы (2)


Единственный официальный способ «отменить регистрацию» бэкенда foreach — это зарегистрировать последовательный бэкенд:

registerDoSEQ()

Это имеет смысл для меня, потому что вы должны объявить, какой бэкенд использовать, поэтому я не видел никакого смысла в предоставлении способа «отменить объявление», какой бэкэнд использовать. Вместо этого вы заявляете, что хотите использовать последовательный бэкэнд, который используется по умолчанию.

Первоначально я рассматривал возможность включения функции «отменить регистрацию», но, поскольку я не мог убедить себя в ее полезности, я решил не включать ее, так как гораздо проще добавить функцию, чем удалить ее.

При этом я думаю, что все, что вам нужно сделать, это удалить все переменные из foreach:::.foreachGlobals, где foreach хранит все свое состояние:

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

После вызова этой функции регистрация любого параллельного бэкэнда будет отменена, а при вызове %dopar% снова будет выдано предупреждение.

person Steve Weston    schedule 04.08.2014
comment
Может быть, стоит добавить псевдоним для registerDoSeq -> unregister? - person Hong Ooi; 04.08.2014
comment
Идеально, это то, что я искал. Спасибо. - person Zach; 04.08.2014

    cl <- makeCluster(2)
    registerDoParallel(cl)
    on.exit(stopCluster(cl))

Это отлично сработало для меня.

person Smit    schedule 20.01.2016
comment
Если вы запустите stopCluster(cl), а затем попытаетесь запустить %dopar%, произойдет сбой. Сначала вам нужно запустить registerDoSEQ(). - person Zach; 20.01.2016
comment
Думаю, on.exit() позаботится об этом. - person Smit; 21.01.2016
comment
on.exit() выполняет stopClusters(cl) только после выполнения %dopar% с использованием параллельного бэкенда, зарегистрированного с помощью registerDoParallel(cl) - person Smit; 21.01.2016
comment
on.exit() в основном означает, что stopCluster никогда не вызывается во время сеанса. Мне нужен был способ остановить кластер и продолжить выполнение %dopar% кода - person Zach; 25.01.2016