我的默认答案过去常常是“那就别这样做”(使用foreach),因为snow包可以(可靠地!)为您完成此操作。
但正如@Spacedman所指出的,Renaud的新doRNG是你要寻找的,如果你想留在doFoo
/foreach系列中。
然而,真正的关键是一个clusterApply-style调用来设置所有节点上的种子。以协调跨流进行。哦,我提到了吗?Tierney、Rossini、Li和Sevcikova的snow已经为您完成了这个任务近十年?
编辑:虽然你没有问过snow,但为了完整起见,这里有一个命令行的例子:
edd@max:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\
clusterSetupRNG(cl);\
print(do.call("rbind", clusterApply(cl, 1:4, \
function(x) { stats::rnorm(1) } )))'
Loading required package: utils
Loading required package: utils
Loading required package: rlecuyer
[,1]
[1,] -1.1406340
[2,] 0.7049582
[3,] -0.4981589
[4,] 0.4821092
edd@max:~$ r -lsnow -e'cl <- makeSOCKcluster(c("localhost","localhost"));\
clusterSetupRNG(cl);\
print(do.call("rbind", clusterApply(cl, 1:4, \
function(x) { stats::rnorm(1) } )))'
Loading required package: utils
Loading required package: utils
Loading required package: rlecuyer
[,1]
[1,] -1.1406340
[2,] 0.7049582
[3,] -0.4981589
[4,] 0.4821092
edd@max:~$
编辑: 为了完整起见,这里结合了你的示例以及doRNG文档中的内容。
> library(foreach)
R> library(doMC)
Loading required package: multicore
Attaching package: ‘multicore’
The following object(s) are masked from ‘package:parallel’:
mclapply, mcparallel, pvec
R> registerDoMC(2)
R> library(doRNG)
R> set.seed(123)
R> a <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
R> set.seed(123)
R> b <- foreach(i=1:2,.combine=cbind) %dopar% {rnorm(5)}
R> identical(a,b)
[1] FALSE
R>
R> seed <- doRNGseed()
R> a <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> b <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> doRNGseed(seed)
R> a1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> b1 <- foreach(i=1:2,combine=cbind) %dorng% { rnorm(5) }
R> identical(a,a1) && identical(b,b1)
[1] TRUE
R>
foreach
,因为它可以从非并行代码无痛过渡到并行代码。但我知道我错过了一些东西。 - mpiktas