2016-01-22 2 views
1

Какие изменения я должен сделать, чтобы иметь воспроизводимый результат здесь? Я запускаю его несколько раз, и вектор результата отличается. Спасибо за любую помощь.R: llply полностью воспроизводимые результаты в параллельном режиме

cl <- makeCluster(2) 

registerDoParallel(2) 

set.seed(123) 

results <- unlist(llply(seq_along(1:4), .fun = function(x){ 
    runif(1)} ,.parallel = T, 
    .paropts = list(.export=ls(.GlobalEnv)))) 


stopCluster(cl) 

ответ

3

Следующий пример даст воспроизводимые результаты на Linux, Mac OS X и Windows:

library(plyr) 
library(doParallel) 
cl <- makeCluster(2) 
registerDoParallel(cl) 
opts <- list(preschedule=TRUE) 
clusterSetRNGStream(cl, 123) 
r <- llply(1:20, 
      .fun = function(x) runif(10), 
      .parallel = TRUE, 
      .paropts = list(.options.snow=opts)) 

Опция preschedule=TRUE необходима для предотвращения doParallel с помощью балансировки нагрузки, которые сделали бы отображение задач для рабочих непредсказуемым.

Если вы используете Linux или Mac OS X, и вы хотите doParallel использовать mclapply, вы могли бы использовать этот подход:

if (.Platform$OS.type != "windows") { 
    registerDoParallel(2) 
    RNGkind("L'Ecuyer-CMRG") 
    set.seed(123) 
    mc.reset.stream() 
    r <- llply(1:20, 
      .fun = function(x) runif(10), 
      .parallel = TRUE) 
} 

Это работает, потому что mclapply использует prescheduling по умолчанию. Он не будет работать в Windows, потому что doParallel будет неявно создавать объект кластера, а инициализация RNG не будет иметь никакого эффекта.

Обратите внимание, что в вашем примере вы создаете объект кластера, но не регистрируете его, поэтому он не будет использоваться doParallel. Вы должны использовать registerDoParallel(cl), иначе doParallel будет либо использовать mclapply на компьютере Posix, либо неявно созданный объект кластера на компьютере под управлением Windows. Очевидно, что очень важно инициализировать работников кластера, которые будут выполнять параллельные вычисления.

+0

спасибо за подробный ответ Удивительно! Да, я пытаюсь закодировать что-то, что работает в любой ОС. Итак, ваше первое решение - это тот, который я использую. Благодаря!. Позвольте мне задать вам следующие вопросы: В чем разница между .options.multicore и .options.snow? Почему вы использовали вектор c (1,2,3,4,5,6,7) как set.seed вместо межсетевого взаимодействия. Если вместо runif (10) у вас есть пользовательская функция, внутри которой есть «set.seed (1234)». Этот set.seed следует удалить, чтобы избежать нового многопоточного конфликта, который не позволил бы воспроизводить? – donpresente

+1

@donpresente .options.multicore используется только бэкэнд «mclapply», а .options.snow используется только для «кластерного» бэкэнда. Это позволяет вам передавать конкретные параметры без потери переносимости. –

+1

@donpresente Я должен был пройти 123 в clusterSetRNGStream. Я смешался с некоторыми внутренними функциями, использующими семерку из 7 целых чисел, используемую генератором L'Ecuyer-CMRG. Я исправил эту ошибку в своем ответе. –

Смежные вопросы