hyunjimoon / SBC

https://hyunjimoon.github.io/SBC
Other
53 stars 4 forks source link

Verbose mode #75

Open dmi3kno opened 1 year ago

dmi3kno commented 1 year ago

I am running some expensive models, which take a while to sample. I would like to be able to see the progress (n_sims). Is there a way to add a progress bar or at least some way of seeing how many datasets have been distributed to workers?

hyunjimoon commented 1 year ago

Cmdstanpy supports progress bars e.g. below (perhaps using tqdm library), but it shows the progress within one n_sim (chains and samplings), not n_sim progress bars. Moreover, I'm not sure it's possible within R.

image

@martinmodrak, @Dashadower, @paul-buerkner and I are having a meeting for R-Python connection with inferencedata next week and I will put this on our agenda. Thanks for bringing this up!

martinmodrak commented 1 year ago

Hi, SBC uses future_lapply from the future.apply package to run the fits. It appears (I didn't test it) that future.apply integrates well with progressr to show progress - see https://github.com/HenrikBengtsson/future.apply/issues/34#issuecomment-549011124 for discussion and example.

EDIT: Sorry this is wrong - future.apply does not directly support progressr, we need to add some additional support for this manually - keeping the link to have a starting point.

mike-lawrence commented 1 year ago

furrr supports progressr. Here's what I use:

#' Run a function on each element of a list in parallel
#'
#' This function runs a protopipe on each entry in a list
#' @param .x List of inputs
#' @param .f Function to run on each element in `.x`
#' @param ... Optional arguments to .f
#' @param .furrr_options Result of a call to `furrr::furrr_options()`
#' @param .strategy A strategy to be used as input to future::plan(); default is parallel and cores set to number of physical cores
#'
#' @return A list.
#' @export
#' @examples
#' \dontrun{
# '     map_parallel(
# '         .x = my_input_list
# '         , .f = my_function
# '         , named_arg = an_argument_to_my_function
# '         , .furrr_options = furrr::furrr_options(
# '             # example options; "clean-slate" scenario
# '             stdout = F
# '             , globals = F
# '             , packages='tidyverse' 
# '             , scheduling = Inf
# '         )
# '     )
#' }
map_parallel = function(
    .x # list over which to iteratively apply f
    , .f #function to apply to each element of .x
    , ... # arguments passed to .f
    , .furrr_options = furrr::furrr_options()
    , .strategy = future::multisession(workers=parallel::detectCores()/2-1)
){
    future::plan(.strategy)
    progressr::with_progress({
        .ff <- .f
        .f <- function(.x,.ff,...,pb){
            out=.ff(.x,...)
            pb()
            return(out)
        }
        pb <- progressr::progressor(along = .x)
        y <- furrr::future_map(
            .x = .x
            , .f = .f
            , .ff = .ff
            , ...
            , pb = pb
            , .options = furrr_options
            , .progress = FALSE
        )
    })
    return(y)
}