-
Notifications
You must be signed in to change notification settings - Fork 86
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
Suggestion: future::with_plan() and/or future::local_plan() #263
Comments
As you've might have noticed (and for "new comers"), I'm really hesitant suggesting that developers could/should set plan locally in their code. I really want to avoid design patterns such as: foo <- function(..., cores = 1) {
oplan <- plan("list")
on.exit(plan(oplan)) # <= super important!
plan(multiprocess, workers = cores)
...
} that may appear out of habit and will just lock the users into a specific parallel backend although some users may have way more powerful alternatives at hand, e.g. 1,000's of cores on a compute cluster. Having said this, I do understand that there are use cases where you need to temporarily use another future backend than what is already set (by the user) with withPlan <- function(expr, ..., envir = parent.frame()) {
expr <- substitute(expr)
oplan <- plan("list")
on.exit(plan(oplan))
plan(...)
eval(expr, envir = envir)
} is handy. I prefer to hold back on adding such a function to the future package because of the above concerns. On the other hand, the advantage of providing such a function would be lowered risk for code/packages messing with the user's Long-term thoughts: Related to our discussion in Issue #181, it would be better if the developer needs could be handled by only specifying what type of resources they need, e.g. "give me a local parallel backend - I don't care exactly which". Now, such a framework will not be in place anytime soon (it's only being processed on idle speed far back somewhere in my head). EDIT 2019-06-26: Previous version claimed that |
That makes sense, and I respect your decision to separate the choice of backend from the hard-coded workflow. Because of ropensci/drake#598 (comment), my original point in this thread might actually become moot. For the original motivating use case of #181, we might actually be able to stick with a single user-defined |
On further reflection, this feels like something I could implement in |
Note that the |
I think that it still suits the use case I was picturing. |
UPDATE 2019-06-26: There was a mistake in my example code of comment #263 (comment). I've updated it accordingly. Please see the 'EDIT' note at the very end. |
... and, before you guys rush and update your code, I'll see if I can change the default value of |
…o change the default value of plan() [#263]
FYI, in the next release, it'll be slightly easier to undo the future plan, e.g. my_fcn <- function(...) {
oplan <- plan("multicore")
on.exit(plan(oplan))
...
} vs my_fcn <- function(...) {
oplan <- plan("list")
on.exit(plan(oplan))
plan("multicore")
...
} In other words, when setting a new set of strategies, plan(list(A = multicore, B = batchtools_local))
# temporary use sequential processing
oplan <- plan(sequential)
y <- future.apply::future_lapply(1:10, FUN = identical)
# undo strategy stack
plan(oplan) Previously, the above code would effectively do: plan(oplan[[1]]) that is, |
I overlooked your proposal of |
Sounds like a great safeguard. Will it be optional like in |
I am picturing something similar to the
with_*()
andlocal_*()
functions fromwithr
. Example use case: ropensci/drake#561. When adrake
user selects a distributed parallel backend, the imported functions and files are still processed locally. (If we are just hashing an input data file, it does not make sense to send the job to a compute node on a cluster.) Indrake
, it might be nice to write something like this:Or alternatively:
where
The text was updated successfully, but these errors were encountered: