0

I'm trying to run a simulation in R where I make a whole bunch of phylogenetic trees. The tree simulation is a bit of a problem because its run time is highly variable, sometimes 0.005 seconds and sometimes minutes. I want to avoid the slow trees so I'm trying to use evalWithTimeout to skip them. So far I'm having problems because I can't make it kill slow tasks without also killing the loop. My problem is similar to this question but the solution to that question hasn't helped me.

library(TreeSim)
library(R.utils)
for (i in 1:100){
  tryCatch(
    expr = {
      evalWithTimeout(sim.rateshift.taxa(10,1,c(0.5,2),c(0.5,0),
                                         c(1,1),c(0,0.5),complete=F),
      timeout=0.005)
    }, 
    TimeoutException = function(ex) cat("Timeout. Skipping.\n")
  )
  print(i)
}

This is what I have so far. I would like to it continue printing "i" regardless of whether the simulation goes over the time limit, but currently it gives me "reached CPU time limit" errors and stops.

Greg Owens
  • 15
  • 1
  • 4

2 Answers2

0

Try this:

library(TreeSim)
library(R.utils)
for (i in 1:100){
  tryCatch(
    expr = {
      evalWithTimeout(sim.rateshift.taxa(10,1,c(0.5,2),c(0.5,0),
                                         c(1,1),c(0,0.5),complete=F), timeout=0.005)
    }, error = function(ex) cat("Timeout. Skipping.\n"))
  print(i)
}

As @AhmedMasud mentions in the comment, the function is throwing a different error. So using error = ... catches any other issue as well.

thc
  • 9,527
  • 1
  • 24
  • 39
  • actually not quite, TimeoutException is the exception caught by tryCatch. See https://www.rdocumentation.org/packages/R.utils/versions/2.5.0/topics/withTimeout for actual examples – Ahmed Masud Sep 13 '17 at 17:20
  • 1
    Thanks, but using `error` works in Rstudio whereas the original code does not. I'm not sure what the reason is, but the code in the answer fixes his issue, so please kindly reconsider your down vote. – thc Sep 13 '17 at 17:34
  • the reason it works is because sim.rateshift.taxa is throwing some other error. – Ahmed Masud Sep 13 '17 at 17:37
0

Using https://www.rdocumentation.org/packages/R.utils/versions/2.5.0/topics/withTimeout as a source. Here's a test unit that works as expected.

foo = function() {
    print("Tic");
    x <- ceiling(runif(1) * 100)+1;
    for (kk in 1:x) {
        print(kk);
        Sys.sleep(runif(1));
    }
    print("Tac");
}

bar = function() { 
  for (i in 1:100) { 
    tryCatch({
      res <- withTimeout({
        foo();
     }, timeout=1.08);
    }, TimeoutException=function(ex) {
        cat("Timeout. Skipping.\n");
       }); 
    print(i); 
   } 
}

So the question is, is there an error that is thrown by interrupting by sim.rateshift.taxa that is not being caught, use error as thc mentions in order to catch that but use the TimeoutException to skip over proper timeouts

There is also a problem with setting too low a time limit:

https://github.com/mhahsler/arules/issues/22

You may want to simply use setTimeLimit yourself and ensure that transient is set to TRUE that way you have finer control.

Here's an example taken from http://blog.revolutionanalytics.com/2014/10/r-in-production-controlling-runtime.html

system.time(Sys.sleep(5))

##user system elapsed 
## 0.000 0.000 5.005

system.time(local({
  setTimeLimit(elapsed = 1, transient = TRUE)
  Sys.sleep(5)
}))

## Error in Sys.sleep(5): reached elapsed time limit

## Timing stopped at: 0 0 5.006
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
  • This works perfectly in the example. When I substitute "sim.rateshift.taxa(10,1,c(0.5,2),c(0.5,0),c(1,1),c(0,0.5),complete=F)" in foo(), it works most of the time, but is dependent on the timout limit. Setting the limit too low results in the function breaking with the error "reached CPU time limit". I would have thought it would just skip foo more often with a lower limit. – Greg Owens Sep 13 '17 at 18:46
  • The problem you're experiencing is also related to R.utils implementation. I have updated the answer – Ahmed Masud Sep 13 '17 at 19:08