Skip to contents

The general parallel simulation algorithm from the book, with the worker passed as a function instead of read from a file named sim_worker.R: choose a master seed, give each process an independent PCG64 stream, divide the replications evenly, run the worker on every process, and return the combined results.

Usage

sim_template(
  worker,
  seed,
  n,
  n_reps,
  n_cores,
  ...,
  packages = NULL,
  type = "PSOCK",
  cl = NULL
)

Arguments

worker

A worker function worker(n, set_up, ...).

seed

Master seed.

n

Sample size for each replication.

n_reps

Total number of replications.

n_cores

Number of worker processes.

...

Model parameters passed on to worker.

packages

Character vector of packages to attach on each process in addition to dqrng, for workers that call functions without a pkg:: prefix.

type

Cluster type passed to parallel::makeCluster(). The default "PSOCK" works everywhere. "FORK" is available on macOS and Linux.

cl

An existing cluster from parallel::makeCluster(). When supplied, it is used as is and not stopped; n_cores must equal its size.

Value

A list of length n_cores holding each process's result, in process order. Use bind_results() to combine them.

Details

A worker is a function worker(n, set_up, ...). n is the per-replication sample size, set_up is one element of make_set_up() (the process's n_reps, seed, and stream), and ... carries any model parameters given to sim_template(). The worker must seed its generator from set_up, for example with set_worker_rng(), and must be self-contained: it runs in a fresh process that has not seen your workspace. See pi_worker(), iqr_worker(), and regression_worker() for the book's examples.

Results are reproducible for a fixed seed and a fixed n_cores. Changing the number of processes changes how the replications are divided and therefore which stream produces which draw.

Examples

out <- sim_template(pi_worker, 1234, 100, 1000, 2)
mean(bind_results(out))
#> [1] 3.14924

# the Cauchy scale example, with the scale parameter passed through `...`
out <- sim_template(iqr_worker, 1234, 100, 20, 2, 5)
lapply(out, round, 3)
#> [[1]]
#>  [1] 4.451 4.383 4.709 5.576 4.471 5.015 7.168 4.148 6.032 4.565
#> 
#> [[2]]
#>  [1] 4.175 6.718 7.271 4.296 7.065 4.411 4.575 4.773 4.411 5.356
#>