I am parallelizing a task in R using foreach loop with reproducible results using the dorng operator. It is a complex code, and I have an error that I have not been able to identify even though I have run the same code with a regular for loop.
My fundamental question is: how do I debug a function within of a foreach loop assuming that I have reproducible results? Below is my current tentative.
In the vignette of the doRNG package, it says that a sequence of random seeds will be generated and set at the beginning of each iteration using the R number generator "L’Ecuyer-CMRG". The sequence of random seeds can be defined using set.seed before the foreach loop:
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")
The objects r01 and r02 contain the sequence of seeds used in f01 and f02,
identical(f01, f02)
identical(r01, r02)
such that the results from the foreach loop and their seeds are identical as expected!
Then, let's consider the case when the foreach loop will give me a random error:
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"
The error occurs at iteration 67 and it is very easy to understand the error. Unfortunately, it is not the same in my case.
I would like to be able to use debug and walk through my function to understand the error. From the best of my knowlegde, I cannot use debug inside a foreach loop in R.
Then, I thought about capturing the error in a regular for loop, but running my code is very slow and, apparently, I cannot observe the error with a low number of iterations. I need to understand the error using foreach.
Although I can't recover the sequence of seeds from f03, I know that they will be identical to r01 or r02. For iteration 67, I have
r01[[67]]
[1] 10407 1484283582 -741709185 513087691 132931819
[6] 1318506528 -1383054295
Therefore, I guess that fixing my seed at r01[[67]] should give me the same error:
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
which is not true.
In the doRNG vignette, page 6, they have an example of using a seed in a loop from a previous loop:
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])
What am I missing?