Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change forkTimeout() to use callr. #3

Open
krivit opened this issue Mar 27, 2019 · 2 comments
Open

Change forkTimeout() to use callr. #3

krivit opened this issue Mar 27, 2019 · 2 comments

Comments

@krivit
Copy link
Member

krivit commented Mar 27, 2019

forkTimeout() uses parallel::mcparallel() to impose a hard time limit on a function call. Unfortunately, this mechanism is not available on Windows. In all evidence, the callr package does not have this limitation. It may be worthwhile to switch forkTimeout() to use it instead, assuming it does not impose too much of a speed penalty (and even if it does, use it on Windows only).

Background

From statnet/ergm-private#230, certain inputs can reliably hang ergm::is.inCH() via lpSolve::lp(), sending it into an infinite loop (or something indistinguishable from one):

library(lpSolve)
load(unz("lp_input.zip","lp_input.RData"))
lp(objective.in = c(-q, q),
             const.mat = rbind( c(q, -q), cbind(L, -L)),
             const.dir = "<=",
             const.rhs = c(1, rep(0, NROW(L)))
             )

Commits c2210ba and statnet/ergm@c417215 mostly neutralise this problem on Unix-alikes forkTimeout() to terminate the call if it takes too long and rerun with invariantly perturbed input, which seems to always fix the problem.

@krivit
Copy link
Member Author

krivit commented Mar 27, 2019

Benchmarks suggest that callr is much slower:

f <- function() 2+2
microbenchmark(callr=r(f), mcp={j<-mcparallel(f()); mccollect(j)[[1]]})
Unit: milliseconds
  expr        min         lq     mean   median         uq       max neval cld
 callr 145.128327 154.612408 165.7934 162.1669 176.778607 220.87554   100   b
   mcp   4.037625   5.281864   6.0387   5.7238   6.357726  10.86342   100  a 

@krivit
Copy link
Member Author

krivit commented Apr 4, 2019

On, the other hand, not restarting the R session every time is not as bad:

library(callr)
library(microbenchmark)
library(parallel)
f <- function() 2+2
rs <- r_session$new()
microbenchmark(r=r(f), rs={rs$call(f); rs$poll_process(-1); rs$read()$result}, mcp={j<-mcparallel(f()); mccollect(j)[[1]]})
Unit: milliseconds
 expr        min         lq       mean     median         uq        max neval cld
    r 145.869876 153.497698 161.952199 158.633111 168.728134 222.200421   100   c
   rs  17.170834  21.156948  24.776113  24.541950  28.002778  35.160594   100  b 
  mcp   1.980955   2.721543   2.998776   2.998492   3.285335   4.583885   100 a  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant