Run a simulation¶
The general parallel simulation template, with the worker as the first argument, and the two pieces of it that are useful on their own: dividing the replications and building the per-process generators.
simstreams.template ¶
The general parallel simulation template.
The book's sim_template.py reads its worker with from sim_worker import
worker. Here the worker is the first argument, and the two pieces of the
template that are useful on their own, dividing the replications and building
the per-process generators, are separate functions.
split_reps ¶
split_reps(n_reps, n_cores)
Divide n_reps replications evenly across n_cores processes.
Every process gets the same base share, and the remainder is handed out one replication at a time starting with the first process. This is the load-balancing step of the general parallel simulation algorithm.
Returns a list of n_cores integers that sums to n_reps.
Source code in src/simstreams/template.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | |
make_generators ¶
make_generators(seed, n_cores)
Create one independent PCG64 generator per process.
SeedSequence(seed).spawn(n_cores) gives each process its own child
seed, so the master seed fixes every process's stream and the streams
do not overlap.
Returns a list of n_cores numpy.random.Generator objects.
Source code in src/simstreams/template.py
41 42 43 44 45 46 47 48 49 50 51 52 | |
make_set_up ¶
make_set_up(seed, n, n_reps, n_cores, *args)
Build the argument tuple handed to each process.
Element i is (rg, n, reps[i], args): the process's generator, the
per-replication sample size, its share of the replications, and the model
parameters as a tuple. A worker is called as worker(*set_up[i]).
Source code in src/simstreams/template.py
55 56 57 58 59 60 61 62 63 64 | |
sim_template ¶
sim_template(
worker, seed, n, n_reps, n_cores, *args, pool=None
)
Run a simulation experiment in parallel.
The general parallel simulation algorithm from the book: 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.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
worker
|
callable
|
|
required |
seed
|
int
|
Master seed. |
required |
n
|
int
|
Sample size for each replication. |
required |
n_reps
|
int
|
Total number of replications. |
required |
n_cores
|
int
|
Number of worker processes. |
required |
*args
|
Model parameters passed on to the worker. |
()
|
|
pool
|
Pool
|
An existing pool to reuse. When omitted, a pool of |
None
|
Returns:
| Type | Description |
|---|---|
list
|
One element per process, in process order: whatever the worker returned for its replications. |
Notes
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.
On macOS and Windows, child processes are spawned, so the calling script
needs an if __name__ == "__main__": guard.
Source code in src/simstreams/template.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | |
sim_template_serial ¶
sim_template_serial(worker, seed, n, n_reps, *args)
Run a simulation experiment in the current process.
The serial counterpart of sim_template: the same seed layout as a
one-process run, executed without a pool. Useful for debugging a worker
before running it in parallel, and for the one-core baseline of a timing
experiment. The result equals
sim_template(worker, seed, n, n_reps, 1, *args)[0].
Source code in src/simstreams/template.py
127 128 129 130 131 132 133 134 135 136 137 138 139 140 | |