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

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

keyboard - Smiles and long press feature in Android -

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