函数调用内使用 foreach + doMC 的并行 RNG

问题描述 投票:0回答:1

我想编写一个函数,在函数内自动执行

foreach
/
%dopar%
语法。具体来说,我想生成一个对
NREP
EXPR
评估列表。在我的四核机器上,以下调用

library(doMC)
library(foreach)

parReplicate <- function(NREP, EXPR, ncores=NULL, ...){
    if (is.null(ncores)) {
        doMC::registerDoMC()
    } else {
        doMC::registerDoMC(ncores)
    }
    foreach(ii=1:NREP,...) %dopar% {
        eval(substitute(EXPR))
    }
}

parReplicate(10, rnorm(1))

返回相同的四个值,回收到长度 10。另一方面,

foreach(ii=1:10) %dopar% {
    eval(substitute(rnorm(1)))
}

按预期返回 10 个不同的值。为什么会发生这种情况以及如何解决它?

r random parallel-foreach domc
1个回答
0
投票

我有一个 2 核系统,我得到 2 个“回收”值。如果您有 4 核系统,您将获得相同的 4 个值“回收”。

要修复此问题,如果指定“ncores = 10”,您将获得 10 个唯一值,例如

#install.packages("doMC")
library(doMC)
#> Loading required package: foreach
#> Loading required package: iterators
#> Loading required package: parallel
library(foreach)

parReplicate <- function(NREP, EXPR, ncores=NULL, ...){
  if (is.null(ncores)) {
    doMC::registerDoMC()
  } else {
    doMC::registerDoMC(ncores)
  }
  foreach(ii=1:NREP,...) %dopar% {
    EXPR
  }
}
parReplicate(10, rnorm(1))
#> [[1]]
#> [1] -0.009443308
#> 
#> [[2]]
#> [1] -0.4582835
#> 
#> [[3]]
#> [1] -0.009443308
#> 
#> [[4]]
#> [1] -0.4582835
#> 
#> [[5]]
#> [1] -0.009443308
#> 
#> [[6]]
#> [1] -0.4582835
#> 
#> [[7]]
#> [1] -0.009443308
#> 
#> [[8]]
#> [1] -0.4582835
#> 
#> [[9]]
#> [1] -0.009443308
#> 
#> [[10]]
#> [1] -0.4582835

parReplicate <- function(NREP, EXPR, ncores=10, ...){
  if (is.null(ncores)) {
    doMC::registerDoMC()
  } else {
    doMC::registerDoMC(ncores)
  }
  foreach(ii=1:NREP,...) %dopar% {
    EXPR
  }
}
parReplicate(10, rnorm(1))
#> [[1]]
#> [1] 0.8427892
#> 
#> [[2]]
#> [1] 0.0575821
#> 
#> [[3]]
#> [1] -0.9282243
#> 
#> [[4]]
#> [1] 0.5650128
#> 
#> [[5]]
#> [1] -0.4067625
#> 
#> [[6]]
#> [1] -0.01367014
#> 
#> [[7]]
#> [1] -1.7156
#> 
#> [[8]]
#> [1] -0.2796529
#> 
#> [[9]]
#> [1] 0.3309782
#> 
#> [[10]]
#> [1] -0.2163732

创建于 2024-09-11,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.