【发布时间】:2020-07-28 04:16:42
【问题描述】:
我正在使用 foreach 循环在 R 中并行化一个任务,并使用 dorng 运算符获得可重现的结果。这是一个复杂的代码,即使我使用常规的for 循环运行相同的代码,我也无法识别出一个错误。
我的基本问题是:假设我有可重现的结果,我该如何调试 foreach 循环中的函数?以下是我目前的尝试。
在 doRNG 包的 vignette 中,它说将使用 R 数生成器“L'Ecuyer-CMRG”在每次迭代开始时生成并设置随机种子序列。随机种子的序列可以在foreach循环之前使用set.seed定义:
library(doRNG)
library(doParallel)
library(foreach)
registerDoParallel(2)
set.seed(1234)
f01 <- foreach(i = 1:100, .combine = 'c') %dorng% {
out <- 1 + i
}
r01 <- attr(f01, "rng")
set.seed(1234)
f02 <- foreach(i = 1:100, .combine = 'c') %dorng% {
out <- 1 + i
}
r02 <- attr(f02, "rng")
对象r01 和r02 包含f01 和f02 中使用的种子序列,
identical(f01, f02)
identical(r01, r02)
这样foreach 循环的结果及其种子与预期的相同!
然后,让我们考虑foreach 循环会给我一个随机错误的情况:
set.seed(1234)
f03 <- foreach(i = 1:100, .combine = 'c') %dorng% {
u <- floor(runif(1, 1, 101))
if (i == as.integer(u)){
out <- "a" + "b"
} else {
out <- 1 + i
}
}
Error in { : task 67 failed - "non-numeric argument to binary operator"
错误发生在第 67 次迭代,很容易理解错误。不幸的是,我的情况不一样。
我希望能够使用debug 并遍历我的函数以了解错误。据我所知,我不能在 R 中的 foreach 循环中使用 debug。
然后,我考虑在常规的for 循环中捕获错误,但是运行我的代码非常慢,而且显然我无法在迭代次数少的情况下观察到错误。我需要使用foreach 了解错误。
虽然我无法从f03 恢复种子序列,但我知道它们将与r01 或r02 相同。对于第 67 次迭代,我有
r01[[67]]
[1] 10407 1484283582 -741709185 513087691 132931819
[6] 1318506528 -1383054295
因此,我想将我的种子固定在 r01[[67]] 应该会给我同样的错误:
i <- 67
set.seed(r01[[67]], kind = "L'Ecuyer-CMRG")
u <- floor(runif(1, 1, 101))
if (i == as.integer(u)){
out <- "a" + "b"
} else {
out <- 1 + i
}
u
[1] 74
这不是真的。
在 doRNG vignette,第 6 页,他们有一个在前一个循环的循环中使用种子的示例:
set.seed(1234)
ex01 <- foreach(i=1:5) %dorng% { runif(3) }
ex02 <- foreach(i=1:5, .options.RNG=attr(ex01, 'rng')[[2]]) %dorng% { runif(3) }
identical(ex02[1:4], ex01[2:5])
我错过了什么?
【问题讨论】: