This package addresses a common problem of running a simulation with large numbers of treatment combinations and replications on a shared computing cluster. The usual tools such as {parallel} and even {foreach} can be frustrating for a number of reasons:
This can be worked around in a variety of ways. Functions can be wrapped in try(). Simulation inputs and random seed can be stored alongside the output. Rather than returning the result to the manager process, the worker can save its results to a unique file, with the results collated at the end. {piecemeal} automates this. Here are some of its features:
The easiest way is to install it from CRAN:
install.packages("piecemeal")
To get a bug fix or to use a feature from the development version, you can install the development version of {piecemeal} from GitHub, depending on your preferred tool:
# install.packages("pak")
# pak::pak("krivit/piecemeal")
install.packages("piecemeal", repos = c('https://krivit.r-universe.dev', 'https://cloud.r-project.org'))
or
# install.packages("remotes")
remotes::install_github("krivit/piecemeal", build_vignettes = TRUE)
The current version does not need compilation, so it can be installed on systems without development tools.
This is a basic example. For a more involved example, including debuging the simulation, see the vignette (vignette("piecemeal")).
# Piecemeal is an R6 class, so we access its methods using $. Since
# the package doesn't have any other functions, a shorthand for
# initialising is provide as well:
sim <- piecemeal::init(file.path(tempdir(), "piecemeal_demo"))
# Clear the previous simulation, if present.
sim$reset()
# Set up a simulation:
sim$
# for every combination of x = 1, 2 and y = 1, 3, 9, 27,
factorial(x = 2^(0:1), y = 3^(0:3))$
# each combination replicated 3 times (with seeds 1:3),
nrep(3)$
# first load library 'rlang',
setup({library(rlang)})$
# then for each x, y, and seed, evaluate
worker(function(x, y) {
p <- x*y
u <- runif(1)
dbl(p = p, u = u) # from rlang
})$
# on a cluster with two nodes.
cluster(2)
# Go!
sim$run()
# Get a table with the results.
sim$result_df()
When running on a cluster, you may want to put the code for setting-up, the code for running, and the code for postprocessing into separate files. See inst/examples for an example.