-
Notifications
You must be signed in to change notification settings - Fork 1
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
parabar with foreach()? #53
Comments
Hi Jonas! I took a look at the Looking at the code for the
Here is such an implementation, starting with (1): # Implementation for the `%dopar%` operator.
doParabar <- function(obj, expr, envir, data) {
# Extract the `backend` from the data argument.
backend <- data$backend
# Create an iterator object from the input object.
iterator <- iterators::iter(obj)
# Create an accumulator function for the iterator.
accumulator <- foreach::makeAccum(iterator)
# Prepare the items to be processed.
items <- as.list(iterator)
# Define the task to be evaluated for each item.
task <- function(arguments) {
# Evaluate the task for the current item.
eval(expr, envir = arguments, enclos = envir)
}
# Export any objects to the cluster.
parabar::export(backend, variables = ls(envir), environment = envir)
# Apply the task function to each item using `parabar::par_lapply`.
results <- parabar::par_lapply(backend, items, task)
# Accumulate the results.
accumulator(results, seq_along(results))
# Return the results.
return(foreach::getResult(iterator))
} Then, for (2) and (3) things are much simpler: # The user function for registering the `parabar`-compatible `%dopar%` implementation.
registerDoParabar <- function(backend) {
# Register the `%dopar%` operator implementation.
foreach::setDoPar(
# The implementation.
fun = doParabar,
# Infomration to be passed to the regiserered implementation.
data = list(backend = backend),
# Information about the implementation.
info = function(data, item) NULL
)
} Finally, you can use # Load packages.
library(parabar)
library(foreach)
library(iterators)
# Start an asynchronous `parabar` backend as usual.
backend <- parabar::start_backend(cores = 4, cluster_type = "psock", backend_type = "async")
# Register it with the `foreach` package.
registerDoParabar(backend)
# Use the `foreach` package as usual.
results <- foreach(i = 1:1000, .combine = c) %dopar% {
# Sleep a bit.
Sys.sleep(0.01)
# Compute and return.
i + 1
}
# Stop the backend.
parabar::stop_backend(backend) Note that the If you think it makes sense, we could consider placing the implementation for the I hope this helps! |
Hi Mihai, Thanks a million for this! The technical details are a bit over my head, but your code works like a charm. One question I still have would be how I can make the progress bar optional. In my earlier solution with doSNOW (which I can't use because it is superseded in R as you know) I simply put an if-statement before setTxtProgressBar(), but since I don't fully see through your solution, this is less clear to me here. Does configure_bar() allow me to switch it off? If there is no obvious way that I am missing here, it could be nice to add another option "none" next to "modern" and "basic" to this function for this purpose. Thanks again & all the best, |
Hi Jonas, Super happy to hear it works!
Not sure if this is what you mean, but you can disable the progress tracking by running: # Set the progress tracking option to `FALSE`.
set_option("progress_track", FALSE) Functions like Lines 103 to 104 in 52234ba
And the progress is tracked only if the conditions are right: Lines 115 to 116 in 52234ba
You can further control progress tracking options (e.g., the overhead) via the package options documented here, and restore things to default using the I hope this helps! |
That's it, thank you! |
Hi Mihai, One more question on this one. I used your solution which works beautifully, but it seems like it forces the use of at least two cores:
Is there a way to also use only a single core? Of course, in almost all cases at least two cores are available, but if possible we'd also like to allow for n_cores=1. Let me know in case you'd like me to open a separate issue on this. Thanks, |
Hi Jonas, Thanks for the kind words! Regarding |
Hi Mihai,
Thanks a lot for creating a package solution for this annoying problem. However, in the examples on your website I only see examples which work with parSapply() from (I guess) the parallel package.
Any chance your package also work with foreach() from the foreach package?
Best wishes,
Jonas
The text was updated successfully, but these errors were encountered: