为什么tempdir()在fork集群的每个核心上都给出相同的结果?

时间:2018-06-06 09:54:24

标签: r random parallel-processing fork

我想并行运行几个自举样本。计算涉及为每个样本创建临时目录。我使用包futureplan(multisession),它会在我的linux机器上自动创建一个fork集群来并行运行样本。

我的问题是tempdir()并不会为每个样本返回不同的结果,即使每个核心set.seed(.)不同也是如此。

MCVE(这不适用于Windows,因为Windows无法fork()):

clu <- parallel::makeForkCluster(4)
unlist(parallel::clusterApply(clu, 1:4, 
  function(x){ set.seed(x); tempdir() }))
## [1] "/tmp/Rtmp0uaUin" "/tmp/Rtmp0uaUin" "/tmp/Rtmp0uaUin" "/tmp/Rtmp0uaUin"

如果我重新启动R,我会得到不同的结果,但每个会话的返回值都相等。

另一方面,其他随机函数可以正常工作,至少如果我包含set.seed(x)

unlist(parallel::clusterApply(clu, x = 1:4, 
  function(x){ set.seed(x); rnorm(1) }))
##[1] -0.6264538 -0.8969145 -0.9619334  0.2167549

unlist(parallel::clusterApply(clu, x = 1:4, 
  function(x){ rnorm(1) }))
## [1] -1.100044 -1.100044 -1.100044 -1.100044

为什么tempdir()的行为与其他随机函数不同,我该怎么办呢?

1 个答案:

答案 0 :(得分:3)

引自?tempdir

  

[...]每个会话临时目录在解释器启动之前创建。

因此,初始R进程修复并创建tempdir(),分叉进程继承该进程。一种可能的解决方案是基于tempfile()创建新的临时目录:

unlist(parallel::mclapply(1:4, function(x){ tempfile(pattern = "dir") }))
#> [1] "/tmp/Rtmpl1ynxV/dir42bb40fa8f75" "/tmp/Rtmpl1ynxV/dir42bc40fa8f75"
#> [3] "/tmp/Rtmpl1ynxV/dir42bb2c930883" "/tmp/Rtmpl1ynxV/dir42bc2c930883"

请注意,我使用的是mclapply,因为它默认处理RNG的播种。