【问题标题】:Why does tempdir() give the same result on every core of a fork cluster?为什么 tempdir() 在 fork 集群的每个核心上都给出相同的结果?
【发布时间】:2018-11-15 23:08:00
【问题描述】:

我想并行运行几个引导样本。计算涉及为每个样本创建一个临时目录。我使用包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() 的行为与其他随机函数不同,我该怎么办?

【问题讨论】:

标签: r random parallel-processing fork


【解决方案1】:

引用?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 的播种。

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2021-02-12
    • 2015-07-20
    • 2018-05-02
    • 2023-02-10
    • 2012-06-22
    • 2020-12-09
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多