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
ordoredis
- don't enable
.multicombine
- set
.inorder
false
- set
.init
(likenull
)
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
Post a Comment