I am using foreach to parallelize my code. However, I found the result to be different whether I add print statement at the end of the loop or not.
Here is with the print statement a the end (I get the result I want):
library(foreach)
grid <- expand.grid(
lambda=c(1,2),
mtry=c(1),
nodsize=c(1)
)
n.cores <- parallel::detectCores() - 1
#https://stackoverflow.com/a/16718078/1979665
my.cluster <- parallel::makeCluster(n.cores, outfile = "")
doParallel::registerDoParallel(cl = my.cluster)
params.all <- foreach (i = 1:nrow(grid), .combine = "rbind") %dopar% {
params <- grid[i,]
params$rmse <- "foo"
print(params)
}
parallel::stopCluster(cl = my.cluster)
params.all
Result is:
lambda mtry nodsize rmse
1 1 1 1 foo
2 2 1 1 foo
Here is without the print statement at the end:
library(foreach)
grid <- expand.grid(
lambda=c(1,2),
mtry=c(1),
nodsize=c(1)
)
n.cores <- parallel::detectCores() - 1
#https://stackoverflow.com/a/16718078/1979665
my.cluster <- parallel::makeCluster(n.cores, outfile = "")
doParallel::registerDoParallel(cl = my.cluster)
params.all <- foreach (i = 1:nrow(grid), .combine = "rbind") %dopar% {
params <- grid[i,]
params$rmse <- "foo"
# print(params) LINE COMMENTED
}
parallel::stopCluster(cl = my.cluster)
params.all
The result is now:
[,1]
result.1 "foo"
result.2 "foo"
Isn't it weird or is it normal?
This is expected behaviour, and has nothing to do with parallel processing or
dopar. The key is to ask yourself "what is each iteration ofdoparactually outputting?"To answer this, you need to realise that
printinvisibly returns the object it is printing:Whereas assignation with
<-silently returns the assigned value:In your first version, with
printuncommented, eachdopariteration is outputtingparamsbecause the last call in thedoparloop isprint(params).When you comment out the line
print(params), the last line of each iteration isparams$rmse <- "foo", so your iteration is not actually outputtingparams. It is returning the output of the assignationparams$rmse <- "foo", which is just the string"foo". Therefore, you just get a single string"foo"for each iteration ofdopar.We can see this is standard behaviour using only base R:
Versus
The solution is to ensure that you specifically return the object at the end of the
doparloop. You can just make the last lineparamsrather thanprint(params).In other words, your question could be rewritten as "
foreachgives the expected output only if I return the correct object from the loop"