我想并行运行几个自举样本。计算涉及为每个样本创建临时目录。我使用包future
和plan(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()
的行为与其他随机函数不同,我该怎么办呢?
答案 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的播种。