There's no particular problem with having a foreach loop inside of a foreach loop. Here's an example of a doMC loop inside a doSNOW loop:
library(doSNOW)
hosts <- c('host-1', 'host-2')
cl <- makeSOCKcluster(hosts)
registerDoSNOW(cl)
r <- foreach(i=1:4, .packages='doMC') %dopar% {
registerDoMC(2)
foreach(j=1:8, .combine='c') %dopar% {
i * j
}
}
stopCluster(cl)
It seems natural to me to use doMC for the inner loop, but you can do it anyway you want. You could also use doSNOW for both loops, but then you would need to create and stop the snow cluster inside the outer foreach loop.
Here's an example of using doMC inside a doMC loop:
library(doMC)
registerDoMC(2)
r <- foreach(i=1:2, .packages='doMC') %dopar% {
ppid <- Sys.getpid()
registerDoMC(2)
foreach(j=1:2) %dopar% {
c(ppid, Sys.getpid())
}
}
The results demonstrate that a total of six processes are forked by the doMC package, although only four execute the body of the inner loop:
> r
[[1]]
[[1]][[1]]
[1] 14946 14949
[[1]][[2]]
[1] 14946 14951
[[2]]
[[2]][[1]]
[1] 14947 14948
[[2]][[2]]
[1] 14947 14950
Of course, you need to be careful not to start too many processes on a single node. I found this kind of nesting a bit awkward, which led to the development of the nesting operator.