r - Is there any way to break out of a foreach loop? -


i using r package foreach() %dopar% long (~days) calculations in parallel. ability stop entire set of calculations in event 1 of them produces error. however, have not found way achieve this, , documentation , various forums have found no indication possible. in particular, break() not work , stop() stops current calculation, not whole foreach loop.

note cannot use simple loop, because want parallelize using dorng package.

here simplified, reproducible version of attempting (shown here in serial %do%, have same problem when using dorng , %dopar%). note in reality want run of elements of loop (here 10) in parallel.

library(foreach) myfunc <- function() {   x <- foreach(k = 1:10, .combine="cbind", .errorhandling="stop") %do% {     cat("element ", k, "\n")     sys.sleep(0.5) # show stop not cause exit foreach     if(is.element(k, 2:6)) {       cat("should stop\n")       stop("has stopped")     }     k   }   return(x) } x <- myfunc() # stop() halts processing of k=2:6, not stop foreach loop itself. # x not returned. execution produces error message # error in { : task 2 failed - "has stopped" 

what achieve entire foreach loop can exited upon condition (here, when stop() encountered).

i have found no way achieve foreach. seems need way send message other processes make them stop too.

if not possible foreach, know of alternatives? have tried achieve parallel::mclapply, not work either.

> sessioninfo() r version 3.0.0 (2013-04-03) platform: x86_64-apple-darwin10.8.0 (64-bit)  locale: [1] c/utf-8/c/c/c/c  attached base packages: [1] stats     graphics  grdevices utils     datasets  methods base  other attached packages: [1] foreach_1.4.0  loaded via namespace (and not attached): [1] codetools_0.2-8 compiler_3.0.0  iterators_1.0.6 

it sounds want impatient version of "stop" error handling. implement writing custom combine function, , arranging foreach call each result returned. need to:

  • use backend supports calling combine on-the-fly, dompi or doredis
  • don't enable .multicombine
  • set .inorder false
  • set .init (like null)

here's example that:

library(foreach) parfun <- function(errval, n) {   abortable <- function(errfun) {     comb <- function(x, y) {       if (inherits(y, 'error')) {         warning('this leave parallel backend in inconsistent state')         errfun(y)       }       c(x, y)     }     foreach(i=seq_len(n), .errorhandling='pass', .export='errval',             .combine='comb', .inorder=false, .init=null) %dopar% {       if (i == errval)         stop('testing abort')       sys.sleep(10)           }   }   callcc(abortable) } 

note set error handling "pass" foreach call combine function error object. callcc function used return foreach loop regardless of error handling used within foreach , backend. in case, callcc call abortable function, passing function object used force callcc return. calling function combine function can escape foreach loop when detect error object, , have callcc return object. see ?callcc more information.

you can use parfun without parallel backend registered , verify foreach loop "breaks" executes task throws error, take awhile since tasks executed sequentially. example, takes 20 seconds execute if no backend registered:

print(system.time(parfun(3, 4))) 

when executing parfun in parallel, need more break out of foreach loop: need stop workers, otherwise continue compute assigned tasks. dompi, workers can stopped using mpi.abort:

library(dompi) cl <- startmpicluster() registerdompi(cl) r <- parfun(getdoparworkers(), getdoparworkers()) if (inherits(r, 'error')) {   cat(sprintf('caught error: %s\n', conditionmessage(r)))   mpi.abort(cl$comm) } 

note cluster object can't used after loop aborts, because things weren't cleaned up, why normal "stop" error handling doesn't work way.


Comments

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -