繁体   English   中英

修复用于不同数量内核的并行仿真运行的种子

[英]Fixing the seed for parallel simulation runs with different number of cores

我想并行进行模拟研究以加快速度,并且还要考虑可重复性。 特别是,我希望获得与在顺序模拟运行开始时使用set.seed相同的结果。 这是我尝试设置它的示例(我在这里故意使用.inorder=T ):

library(doSNOW)
library(rlecuyer)

nr.cores = 4
nr.simulations = 10 
sample.size = 100000

seed = 12345

cl = makeCluster(nr.cores)
registerDoSNOW(cl)
clusterExport(cl=cl, list=c('sample.size'), envir=environment())
clusterSetupRNGstream(cl,rep(seed,6))

result = foreach(i=1:nr.simulations, .combine = 'c', .inorder=T)%dopar%{
  tmp = rnorm(sample.size)
  tmp[sample.size]
}

stopCluster(cl)

print(paste0('nr.cores = ',nr.cores,'; seed = ',seed,'; time =',Sys.time()))
print(result)

多次运行此示例后,我有两个问题:

  1. 核心数会影响生成的序列,例如,对于nr.cores=14只有第一个值重合,对于nr.cores=48 ,前四个值是重合。 有没有办法让它独立于nr.cores 从概念上讲,我想我可以创建一个大小为nr.simulations * sample.size的RNG流,将其拆分为nr.simulations片段,并将它们始终以相同的顺序分配给节点。 更简单的是,我可以修复(不同)种子的nr.simulations值,然后将它们以固定顺序再次传递给节点。 可以使用某种节点映射来完成此操作,节点可以使用这些映射来从表中读取其适当的种子值。 有办法吗?

  2. 当我多次运行脚本时,即使我不更改任何参数(我只是一次又一次地获取文件),也会发生(并非总是但不时地)对结果序列进行重新排序的情况。 它只是看起来像一个错误给我的任何.inorderclusterSetupRNGstream失败。 还是我错过了什么?

     [1] "nr.cores = 4; seed = 12345; time =2017-09-08 19:00:24" [1] 1.327091137 -1.800244293 -1.163391460 0.005980001 0.957521136 1.641354433 -1.219033091 [8] -0.238129356 -0.225193384 1.457018576 [1] "nr.cores = 4; seed = 12345; time =2017-09-08 19:00:28" [1] 1.327091137 -1.800244293 -1.163391460 0.005980001 -0.238129356 0.957521136 1.641354433 [8] -1.219033091 0.870269174 -0.225193384 

第一问 :以下内容似乎对我有用

library(parallel)
library(doParallel)
cl <- makeCluster(5)
registerDoParallel(cl)
seedlist <- c(100, 200, 300, 400, 500)
clusterExport(cl, 'seedlist')
foreach(I=1:5) %dopar% {set.seed(seedlist[I]); runif(1)}

[[1]]
[1] 0.3077661

[[2]]
[1] 0.5337724

[[3]]
[1] 0.9152467

[[4]]
[1] 0.1499731

[[5]]
[1] 0.8336


set.seed(100)
runif(1)
[1] 0.3077661

第二问 :好像是个错误,但也许其他人有更好的线索

因此,为了证明我的观点, .inorder参数只是说您需要按顺序排列结果,而不是按顺序计算结果,您可以这样做

cl = makeCluster(nr.cores)
registerDoSNOW(cl)
replicate(10, {
  foreach(ic = 1:8, .combine = 'c', .inorder = TRUE) %dopar% {
    Sys.sleep(runif(1))
    Sys.getpid()
  } 
})
stopCluster(cl)

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 9252 9252 9252 9252 9252 9252 9252 9252 9252  9252
[2,] 9259 9259 9259 9259 9259 9259 9259 9259 9259  9259
[3,] 9266 9266 9266 9266 9266 9266 9266 9266 9266  9266
[4,] 9273 9273 9273 9273 9273 9273 9273 9273 9273  9273
[5,] 9273 9252 9259 9266 9273 9266 9252 9252 9266  9252
[6,] 9266 9266 9273 9273 9273 9259 9266 9259 9273  9266
[7,] 9266 9259 9252 9259 9259 9273 9273 9252 9259  9266
[8,] 9252 9252 9259 9266 9252 9252 9266 9252 9273  9259

哼,不确定它是否真的证明了我的意思。 它仅显示集群在开始时按顺序进行计算,然后完成的第一个继续进行计算。


如@Roland所建议,您可以使用软件包doRNG来执行所需的操作。 让我们验证一下:

library(doRNG)
cl = makeCluster(nr.cores)
registerDoSNOW(cl)
replicate(14, {
  set.seed(12345)
  sample.size = 100000
  foreach(ic = 1:8, .combine = 'c', .inorder = TRUE) %dorng% {
    Sys.sleep(runif(1))
    tmp = rnorm(sample.size)
    tmp[sample.size]
  } 
})
stopCluster(cl)

            [,1]        [,2]        [,3]        [,4]        [,5]        [,6]        [,7]
[1,]  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264
[2,] -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339
[3,] -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636
[4,] -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416
[5,] -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022
[6,]  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835
[7,]  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101
[8,] -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750
            [,8]        [,9]       [,10]       [,11]       [,12]       [,13]       [,14]
[1,]  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264  0.42281264
[2,] -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339 -1.67678339
[3,] -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636 -0.49011636
[4,] -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416 -0.87165416
[5,] -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022 -1.02636022
[6,]  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835  0.56549835
[7,]  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101  0.03998101
[8,] -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750 -0.38754750

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM