10

I have the following code:

myfun <- function() {
  fun2()

  return(1+1)
}

I want fun2() is invoked and then moved to the next lines without waiting for the result. Function fun2 does not return anything and I don't care when it finishes, I just need to launch it. What is the best way to achieve it? Parallel process, multithreading, async call? Any code samples are appreciated.

Sergey Ivanov
  • 3,719
  • 7
  • 34
  • 59

2 Answers2

22

The future package (I'm the author) provides this:

library("future")
plan(multisession)

myfun <- function() {
  future(fun2())

  return(1+1)
}

Unless fun2() is function used purely for its side effects, you typically want to retrieve the value of that future expression, which you do as:

f <- future(fun2())
y <- fun3()
v <- value(f)
z <- v + y

An alternative is to use the %<-% operator, as in:

v %<-% fun2()
y <- fun3()
z <- v + y

FYI, if you use

plan(cluster, workers = c("n1", "n3", "remote.server.org"))

then the future expression is resolved on one of those machines. Using

plan(future.batchtools::batchtools_slurm)

will cause it to be resolved via a Slurm job scheduler queue.

HenrikB
  • 6,132
  • 31
  • 34
  • Would you recommend the `foreach` interface for using the future engine, or `furrr`? – jiggunjer Jul 21 '20 at 10:01
  • 1
    They're all map-reduce siblings and equally efficient when it comes to parallel processing: [foreach](https://cran.r-project.org/web/packages/foreach) w/ [doFuture](https://cran.r-project.org/web/packages/doFuture), [future.apply](https://cran.r-project.org/web/packages/future.apply), [furrr](https://cran.r-project.org/web/packages/furrr), ... You can pick the map-reduce style you like. – HenrikB Jul 21 '20 at 17:34
  • 1
    Thanks. I saw your rstudio presentation, thank you for helping us run our models faster! – jiggunjer Jul 21 '20 at 17:53
  • Thanks and I'm glad you find it useful. {future} is building on-top of prior and existing work by others, so I'm standing on giants – HenrikB Jul 21 '20 at 18:06
5

Eventually I stopped on the following solution:

Rpath <- Find(file.exists, c(commandArgs()[[1]], file.path(R.home("bin"), commandArgs()[[1]]),
                             file.path(R.home("bin"), "R"), file.path(R.home("bin"), "Rscript.exe")))
out <- system('%s --no-save --slave -e \"Your R code here\" ', wait=FALSE)

The first line searches for the path of R executable, and the second executes R code from the command-line environment not waiting for result.

Sergey Ivanov
  • 3,719
  • 7
  • 34
  • 59