Skip to content

Commit

Permalink
allowing parallel model runs
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroliman committed Oct 11, 2023
1 parent 9c2950a commit b18066f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
4 changes: 2 additions & 2 deletions R/R6Experiment.R
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ R6Experiment <- R6::R6Class(
}
},

run = function(n_cores = 3, parallel = T, cluster_eval_script) {
R6Experiment_run(self = self, n_cores = n_cores, parallel = parallel, cluster_eval_script = cluster_eval_script)
run = function(n_cores = 3, parallel = F, cluster_eval_script, model_from_cluster_eval = T) {
R6Experiment_run(self = self, n_cores = n_cores, parallel = parallel, cluster_eval_script = cluster_eval_script, model_from_cluster_eval = model_from_cluster_eval)
}
),

Expand Down
36 changes: 22 additions & 14 deletions R/R6Experiment_run.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,26 @@
#' @param n_cores number of cores to use
#' @param parallel whether to evaluate run in parallel
#' @param cluster_eval_script path to script that instantiates necessary functions. this will often mean sourcing functions external to the package and loading dependencies for the model. needed if parallel = T
#'
#' @param model_from_cluster_eval T if model is instantiated in the cluter eval scripts, F otherwise. Use T if using models that need compilation (like odin) and F otherwise.
#' @return results data.frame from all simulations in parallel
#'
#' @import parallel
#' @import doSNOW
#' @import foreach
#' @import progress
R6Experiment_run <- function(self, n_cores, parallel, cluster_eval_script) {
R6Experiment_run <- function(self, n_cores, parallel, cluster_eval_script, model_from_cluster_eval) {

# TODO: Continue here.
# browser()

# If we are running the experiment in parallel, we need to instantiate the models explicitly within each "node".
# if the model is self-contained, that should be enough.
if (parallel) {
# PNL note: Decide whether to use snow:: or parallel:: makeCluster

browser()

cl <- parallel::makeCluster()

# Make cluster and evaluate the cluster eval script.
cl <- snow::makeCluster(n_cores)
doSNOW::registerDoSNOW(cl)
#snow::clusterExport(cl, "cluster_eval_script")
#snow::clusterEvalQ(cl, source(cluster_eval_script))
snow::clusterEvalQ(cl, source("./R/scripts/cluster_eval.R"))
snow::clusterExport(cl, "cluster_eval_script", envir = environment())
snow::clusterEvalQ(cl, source(cluster_eval_script))

}

# progress bar ------------------------------------------------------------
Expand All @@ -68,8 +64,19 @@ R6Experiment_run <- function(self, n_cores, parallel, cluster_eval_script) {
# foreach loop ------------------------------------------------------------
results <- foreach(i = 1:nrow(self$policy_design), .combine = rbind, .options.snow = opts) %dopar% {

# Assign model inputs:
model <- self$models[[self$policy_design$model.id[i]]]
if(!model_from_cluster_eval) {

model <- self$models[[self$policy_design$model.id[i]]]

} else {

stopifnot("cluster_experiment object not defined. Create an R6Experiment object called cluster_experiment in your cluster_eval_script file, containing the models used in this analysis." = exists("cluster_experiment"))

stopifnot("cluster_experiment object is not an R6Experiment. Make sure to use R6Experiment to create the cluster_experiment object." = is.R6Experiment(cluster_experiment))

model <- cluster_experiment$models[[self$policy_design$model.id[i]]]

}

id_cols <- c("grid.id", "lhs.id", "params_design.id", "param.id", "model.id", "all.params.id", "policy.exp.id")

Expand All @@ -94,3 +101,4 @@ R6Experiment_run <- function(self, n_cores, parallel, cluster_eval_script) {

return(results)
}

4 changes: 2 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ knitr::opts_chunk$set(
[![R-CMD-check](https://github.com/RANDCorporation/R6Sim/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/RANDCorporation/R6Sim/actions/workflows/R-CMD-check.yaml)
<!-- badges: end -->

`R6Sim` provides an `R6` base class for simulation modeling for those who appreciate the structure of encapsulated object-oriented programming provided by `R6`. This package allows one to create a model that inherits `R6Sim`, and specify experimental designs that potentially use multiple models using the `R6Experiment` class.
`R6Sim` provides an `R6` base class for simulation modeling analyses using the structure of encapsulated object-oriented programming provided by `R6`. This package allows one to create models that inherit `R6Sim`, and specify models and experimental designs that can use multiple models using the `R6Experiment` class.

We use `R6Sim` across multiple projects, and the purpose of releasing it publicly is to facilitate reproducibility and enhance the quality, agility and reliability of code used in simulation-based policy research projects.
We use `R6Sim` across multiple projects, and the purpose of releasing it publicly is to facilitate reproducibility and enhance the quality, agility and reliability of code used in simulation-based research projects.

## Installation

Expand Down

0 comments on commit b18066f

Please sign in to comment.