Why Random-Number Management Matters
A simulation of a group sequential design may involve thousands of trial paths, each with data generated at several planned looks. Parallel computing can reduce elapsed time, but it also creates a practical question: will the same simulation tasks generate the same paths when they run on different workers, in a different order, or in a later extension? The answer depends on how the random-number generator is initialized and how its output is allocated.
A seed is not a record of a simulation’s results, nor is it a guarantee that every software environment will reproduce them. It initializes a deterministic pseudorandom-number generator. Once initialized, the generator produces a sequence determined by its algorithm and state. Parallel code must divide that sequence into streams in a way that avoids overlap and does not make a task’s results depend on scheduling.
The earlier material on designing simulation studies and building a scenario matrix supplies the tasks to be run. Here, the focus is how to give those tasks reliable random-number streams and preserve their provenance.
Assign Streams to Tasks, Not Workers
A simulation task should have a stable identity, such as a combination of scenario identifier and replication identifier. Assigning a stream to that task makes its random inputs independent of which processor happens to execute it. By contrast, if each worker gets one stream and processes whichever task arrives next, a change in scheduling can give a replication a different part of the random sequence.
A suitable generator may provide a documented method for creating independent streams or substreams from a master seed. Some systems use a seed-sequence or spawning mechanism; counter-based generators can derive outputs from stable task identifiers and counters. Use a method designed and documented for parallel use. Merely choosing different integer seeds for different workers does not, by itself, establish that the resulting sequences are independent or non-overlapping.
For simulations where each replication generates a complete trial path, a useful unit of allocation is the replication. The stream then supplies all random quantities needed for that trial, including observations at successive looks. The simulation applies its stopping rule to that path. It should not restart the generator at each look: doing so can break the intended relationship among successive data increments or accidentally repeat random inputs.
Justification: Why Stable Task Streams Give Schedule-Invariant Results
Let task \(i\) have fixed inputs \(c_i\), such as its scenario settings, and stream \(R_i\). Suppose the task’s output is computed as \(Y_i=F(c_i,R_i)\), where \(F\) is deterministic once the inputs and random-number stream are fixed. If the task-to-stream mapping is unchanged, then changing the order in which tasks execute does not change \(c_i\), \(R_i\), or \(F(c_i,R_i)\). Therefore it does not change \(Y_i\).
This argument concerns task-level reproducibility. It does not mean that any two software environments will produce bit-for-bit identical output. A changed generator, distribution-sampling algorithm, code version, or floating-point operation can alter results even when the initial seed is the same. Nor does the argument prove that a particular stream-allocation method has good statistical properties; that depends on the generator and its documented design.
A reliable implementation therefore separates two responsibilities: use a generator method intended to provide distinct streams, and make the assignment of those streams to task identifiers deterministic and recorded. Save results under their task identifiers rather than relying on the order in which workers finish.
Specify scenario and replication identifiers, and decide whether a task is one complete trial path or another clearly defined unit of simulation.
Record the master seed and generator method, then allocate a distinct stream or substream to each task using a documented parallel-safe procedure.
Generate the task’s random inputs, apply the design and stopping rules, and store the output with its task identifier and stream assignment.
Repeat selected tasks and test changes in scheduling. Save the software and configuration details needed to interpret or reproduce the results.
Worked Example: Assigning Replications Across Four Workers
Suppose a hypothetical design evaluation has 12,000 replications for one scenario. Four workers are available. The implementation creates 12,000 stable task identifiers, \(1,\ldots,12{,}000\), and allocates one stream to each replication from a documented stream-spawning procedure initialized with master seed 731204.
For a simple initial partition, worker 1 may receive replications 1–3,000, worker 2 replications 3,001–6,000, worker 3 replications 6,001–9,000, and worker 4 replications 9,001–12,000. Each replication’s stream is selected by its replication identifier, not by the worker’s own random-number sequence. If worker 2 becomes slower and replications finish out of order, replication 4,217 still uses the stream assigned to 4,217.
Now suppose the same 12,000 tasks are run using six workers. The scheduler may assign different replications to each worker, but the mapping from replication identifier to stream remains unchanged. Under the same code, generator implementation, and other relevant settings, each replication receives the same random inputs as before. The arithmetic for the initial allocation is \(12{,}000/4=3{,}000\) replications per worker; this is a workload partition, not the definition of a stream.
The master seed and the number of workers are not enough to describe this run. The record should also identify the generator and stream-allocation method, the task identifiers, the simulation code version, and any relevant software versions. If the program instead assigns one stream to each worker and takes the next random values for each arriving replication, changing from four workers to six can change the paths attached to replication identifiers.
Preserving a Sequential Trial Path
In a group sequential simulation, a replication represents one evolving trial, not a set of unrelated snapshots. The random inputs used at the first look and later looks must be generated according to the model for that trial. Allocate the replication’s stream once, then advance its state as the path is generated. If the simulated trial stops early, unused later draws need not be consumed; they must not be reassigned in a way that changes another replication’s stream.
This matters especially when code is reorganized. For example, a program that first simulates all first-look data and then all second-look data can be valid only if its stream and data-generation scheme preserve each trial’s intended path. It is not enough that every look uses random numbers. The relationship of the generated data across looks must match the model being simulated.
Worked Example: Keeping One Path Together Across Looks
Consider a hypothetical replication with three planned looks. Its task identifier is scenario A, replication 42. Under the chosen generator, that task receives one stream. For illustration, suppose its stream supplies three successive standardized increments of 0.40, −0.10, and 0.70. These values are hypothetical, not outputs claimed for a particular software generator.
The simulation uses the first increment to generate the first-look data, then the next increment when extending the same trial to the second look, and then the third when extending it to the third look. If the stopping rule stops the trial after look 2, the third increment is not used for that trial. The path through look 2 is still generated from the same task stream in every run.
A faulty alternative is to initialize a fresh generator with the same seed at every look. That would make the first random draw at each look repeat, rather than continue the task’s sequence. Another faulty alternative is to give each look to a separate worker and let worker-specific streams determine the data. That can change the path when worker assignment changes. The correction is to define the trial path and its stream at the replication level, then implement the look-by-look data generation consistently with the assumed model.
Recording Seeds, States, and Run Metadata
A master seed is a compact starting point, but by itself it may not be sufficient for a robust audit or restart. Record enough information to answer both what random-number procedure was used? and which stream generated this task? For long runs, checkpoints can additionally save generator states and completed task identifiers, so unfinished work can resume without silently reassigning streams.
| Record | Why it matters |
|---|---|
| Master seed and generator name | Identifies the initialization and the basic pseudorandom-number procedure. |
| Stream-allocation method and task-to-stream mapping | Shows how parallel tasks received their random inputs. |
| Scenario and replication identifiers | Connects each result to its simulation task, even when execution order varies. |
| Code, package, and software versions | Helps identify changes in generator implementation, distribution routines, or simulation logic. |
| Configuration, completion status, and checkpoint state when used | Supports audit, restart, and comparison of the intended run with the completed run. |
For an extendable run, keep the existing task-to-stream mapping fixed and assign new, non-overlapping streams to new task identifiers through the same documented allocation scheme. Do not change the old mapping simply because the requested replication count increased. If the allocation method depends on a predeclared number of tasks, decide and document how that total is handled before starting; otherwise changing it later could alter assignments. The exact behavior is generator-specific, so consult and record the generator’s rules rather than assuming that a master seed automatically creates a stable mapping.
Worked Example: Extending a Run Without Reassigning Existing Tasks
A hypothetical analysis initially completes 8,000 replications per scenario. The planned extension adds 2,000, for a total of 10,000. The task identifiers are scenario-specific pairs, such as (B, 1) through (B, 10,000), and the stream-allocation procedure deterministically assigns a stream to each pair.
To extend the run, retain the original records for identifiers 1 through 8,000 and allocate streams for identifiers 8,001 through 10,000 under the same documented scheme. The count of new replications is \(10{,}000-8{,}000=2{,}000\). A reproducibility check reruns selected old identifiers and confirms that their random inputs and outputs match the saved run under the same computing environment.
If the allocation procedure instead assigns a block of streams based on the total planned number of tasks, verify that raising the total from 8,000 to 10,000 does not change the old assignments. If it does, the original mapping must be preserved explicitly or the run must be treated as a new configuration. Merely using the same master seed does not establish that old task streams remain unchanged.
Diagnostics, Comparisons, and Failure Modes
The main alternative to task-level stream allocation is worker-level seeding. It can be simple, but it ties random inputs to worker count and task scheduling unless the implementation carefully preserves a stable assignment. It is therefore a poor default when results must be reproducible after changing parallel settings. Serial execution can be easier to reason about, but it may be slower; a parallel-safe stream scheme aims to retain reproducibility without requiring a fixed execution order.
Useful checks focus on invariance and traceability. Run a small set of task identifiers twice and compare their random inputs or outputs. Run the same tasks with a different worker count or task order and check that each identifier still matches. Restart from a checkpoint and verify that completed tasks are not repeated under new identifiers or assigned different streams. Inspect records for duplicated task-to-stream assignments and missing task identifiers.
Identical results from two tasks are not, by themselves, proof of a stream collision: discrete outcomes can match by chance. Conversely, different results are not necessarily a defect if the generator, software version, configuration, or stream mapping changed. The diagnostic target is the reproducibility claim actually being made, with those conditions held fixed.
- Worker-specific seeds are mistaken for guaranteed independent streams. Different seed values alone do not establish the required separation; use a documented parallel stream mechanism.
- Results are stored in completion order. Parallel completion order can vary; save and compare by stable scenario and replication identifiers.
- A new seed is assigned whenever a task restarts. A retry can then silently become a different replication; preserve the task’s stream assignment when reproducing or resuming it.
- One seed is reset at each interim look. This can repeat draws or disrupt the intended path; advance the replication’s stream as the trial evolves.
- Only the master seed is archived. Without generator, allocation, code, and version details, the record may not support exact reproduction.
Reproducibility has limits. A fixed seed does not make a simulation scientifically valid, prove that streams are statistically independent, or eliminate Monte Carlo variability. Nor does it guarantee identical results across different generator implementations or software versions. Stream design, simulation assumptions, and the interpretation of simulation results remain separate responsibilities.
Check Your Understanding
Answer each question using the distinction between task identity, worker assignment, and stream allocation.
- A program assigns one seed to each worker, and each worker processes whichever replication is next in a queue. Why might replication 120 differ when the worker count changes?
- In a group sequential simulation, should each interim look usually reinitialize the replication’s generator from the same seed? Explain.
- A run has 5,000 replications and is extended to 7,000. What must be preserved or checked so the old replications remain reproducible?
- Name at least four pieces of information, besides the master seed, that strengthen the audit record.
- Two replications have identical binary stopping outcomes. Does that establish that they used the same stream? Why or why not?
Solutions. (1) The worker count can change which worker processes replication 120; worker-specific streams then give it different random inputs. Allocate streams by stable replication identifier instead. (2) No. The same seed at each look can repeat initial draws or fail to continue the trial path. Allocate one stream to the replication and advance it consistently across looks. (3) Preserve the old task-to-stream mapping, allocate new streams for identifiers 5,001–7,000 using the documented procedure, and rerun selected old identifiers to verify reproducibility under the same environment. (4) Examples include generator name, stream-allocation method, task-to-stream mapping, scenario and replication identifiers, code and package versions, configuration, and checkpoint state. (5) No. Identical binary outcomes can occur by chance even with distinct streams; inspect the recorded allocation and test the reproducibility claim directly.