title: Fully reproducible parallel models using caret
body: <p>When I run 2 random forests in caret, I get the exact same results if I set a random seed:</p>
  
  <pre><code>library(caret)
  library(doParallel)
  
  set.seed(42)
  myControl &lt;- trainControl(method='cv', index=createFolds(iris$Species))
  
  set.seed(42)
  model1 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  set.seed(42)
  model2 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  &gt; all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
  [1] TRUE
  </code></pre>
  
  <p>However, if I register a parallel back-end to speed up the modeling, I get a different result each time I run the model:</p>
  
  <pre><code>cl &lt;- makeCluster(detectCores())
  registerDoParallel(cl)
  
  set.seed(42)
  myControl &lt;- trainControl(method='cv', index=createFolds(iris$Species))
  
  set.seed(42)
  model1 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  set.seed(42)
  model2 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  stopCluster(cl)
  
  &gt; all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
  [1] "Component 2: Mean relative difference: 0.01813729"
  [2] "Component 3: Mean relative difference: 0.02271638"
  </code></pre>
  
  <p>Is there any way to fix this issue?  One suggestion was to use the <a href="http://cran.r-project.org/web/packages/doRNG/index.html" rel="noreferrer">doRNG</a> package, but <code>train</code> uses nested loops, which currently aren't supported:</p>
  
  <pre><code>library(doRNG)
  cl &lt;- makeCluster(detectCores())
  registerDoParallel(cl)
  registerDoRNG()
  
  set.seed(42)
  myControl &lt;- trainControl(method='cv', index=createFolds(iris$Species))
  
  set.seed(42)
  &gt; model1 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  Error in list(e1 = list(args = seq(along = resampleIndex)(), argnames = "iter",  : 
    nested/conditional foreach loops are not supported yet.
  See the package's vignette for a work around.
  </code></pre>
  
  <p>UPDATE:
  I thought this problem could be solved using <code>doSNOW</code> and <code>clusterSetupRNG</code>, but I couldn't quite get there.</p>
  
  <pre><code>set.seed(42)
  library(caret)
  library(doSNOW)
  cl &lt;- makeCluster(8, type = "SOCK")
  registerDoSNOW(cl)
  
  myControl &lt;- trainControl(method='cv', index=createFolds(iris$Species))
  
  clusterSetupRNG(cl, seed=rep(12345,6))
  a &lt;- clusterCall(cl, runif, 10000)
  model1 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  clusterSetupRNG(cl, seed=rep(12345,6))
  b &lt;- clusterCall(cl, runif, 10000)
  model2 &lt;- train(Species~., iris, method='rf', trControl=myControl)
  
  all.equal(a, b)
  [1] TRUE
  all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
  [1] "Component 2: Mean relative difference: 0.01890339"
  [2] "Component 3: Mean relative difference: 0.01656751"
  
  stopCluster(cl)
  </code></pre>
  
  <p>What's special about foreach, and why doesn't it use the seeds I initiated on the cluster? objects <code>a</code> and <code>b</code> are identical, so why not <code>model1</code> and <code>model2</code>?</p>