2017-04-06 46 views
1

我有一個奇怪的例子,其中使用帶串行和並行後端的foreach在第一次調用時給出不同的結果,但後來在兩個結果匹配時都給出了不同的結果。我用RNG,使結果重現性好,同樣seed帶串行和並行後端的foreach給出不同的結果

下面是一個示例函數來解釋場景:

func <- function(ncores = NULL, seed = 1234){ 
    if (!is.null(ncores)){ # this block registers for parallel backend 
    cl <- makeCluster(ncores) 
    registerDoParallel(cl) 
    registerDoRNG(seed, once = TRUE) 
    on.exit(stopCluster(cl)) 
    } else {    # this block registers for serial computation 
    registerDoSEQ() 
    registerDoRNG(seed, once = TRUE) 
    } 
    w = foreach(i = 1:10, .combine = 'c') %dorng% { 
    mean(sample(1:100, 50, replace = TRUE)) 
    } 
    attr(w, "rng") <- NULL 
    return(w) 
} 

# first time running below 2 lines 
# case 1 : serial 
w1 <- func(ncores = NULL) 
# Case 2 : parallel 
w2 <- func(ncores= 5) 
identical(w1, w2) 

# second time running below 2 lines 
# case 1: serial 
w3 <- func(ncores = NULL) 
# case 2: parallel 
w4 <- func(ncores= 5) 

identical(w1, w2) 
# [1] FALSE 
identical(w3, w4) 
# [1] TRUE 

我失去的東西,而登記順序的過程?

回答

1

的解決方案是使用下面的表達式:

w = foreach(i = 1:10, .combine = 'c', .options.RNG=seed) %dorng% { 
    mean(sample(1:100, 50, replace = TRUE))} 

您可以在小品文here找到一個解釋。

所以你的函數如下所示:

func <- function(ncores = NULL, seed = 1234){ 
    if (!is.null(ncores)){ # this block registers for parallel backend 
    cl <- makeCluster(ncores) 
    registerDoParallel(cl) 
    on.exit(stopCluster(cl)) 
    } else {    # this block registers for serial computation 
    registerDoSEQ() 
    } 
    w = foreach(i = 1:10, .combine = 'c', .options.RNG=seed) %dorng% { 
    mean(sample(1:100, 50, replace = TRUE)) 
    } 
    attr(w, "rng") <- NULL 
    return(w) 
} 
+0

我已通過了小插曲前..但沒有發現這種現象的原因。 Bdw您的解決方案解決了問題+1。你知道爲什麼'registerDoRNG()'有這個問題嗎? –

相關問題