Skip to content

Implement reproducible event generation - #51

Draft
theoheimel wants to merge 38 commits into
mainfrom
feat-reproducibility
Draft

Implement reproducible event generation#51
theoheimel wants to merge 38 commits into
mainfrom
feat-reproducibility

Conversation

@theoheimel

@theoheimel theoheimel commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Features

  • Reproducible event generation and training for both VEGAS and MadNIS, on CPU and GPU, independent of number of worker threads.
  • The reproducible path is always used. By default, the seed is chosen randomly, but it is written to the events.lhe and info.json file so the run can be reproduced later.
  • Replace std::mt19937, CURAND, ROCRAND random number generators with the mixmax RNG, as it has superior sequence length properties and allows for a 64-bit seed.

Limitations

  • CPU and GPU jobs with the same seed will not give the same result
  • heterogeneous runs, i.e. CPU + GPU, are not reproducible
  • There are some setups where parts of the computation do not yield bit-identical results. In the MadNIS training discrepancies at the FP precision level can accumulate and lead to effectively non-reproducible runs. This happens for example in GPU MadNIS trainings since the accumulation of channel weights in madmatrix using atomicAdd leads to differences in the channel weight.

Benchmarks

Check if there is any degradation in performance from reproducibility
TBA

oliviermattelaer and others added 28 commits July 23, 2026 07:48
Introduce a `seed` field in the mg7 run_card that makes CPU event
generation reproducible: the same (seed, thread-pool sizes) reproduces
bit-identically and distinct seeds are statistically independent. Seed 0
(the default) keeps the previous non-deterministic behaviour.

madspace previously seeded every RNG from std::random_device with no seed
input and drew randomness from thread-local generators dispatched to the
pool in non-deterministic order, so runs were never reproducible.

Plumbing:
- run_card `[run] seed` + RunCardMG7 default; per-context seed derivation
  (splitmix64) in madevent.py and gridpack.py (--seed); Context(seed=)
  exposed through the Python bindings.
- seeded_rng()/mix_seed() helpers in util.hpp; the driver-level
  random_device sites reseeded from the context seed.

Determinism (gated on seed != 0, so the default path is unchanged):
- Per-job RNG keyed by logical job identity (channel, sequence, phase)
  via Runtime::begin/end_job_rng, so a job's randomness no longer depends
  on which worker thread runs it.
- Deterministic commit ordering: survey/generate harvest jobs in job-id
  order with unweighting folded in synchronously, making cross-section
  sums, max-weight snapshots, event order and stopping deterministic.

Validated end-to-end through the mg7 driver with a dummy matrix element:
same seed gives byte-identical events.npy at 4 and 8 threads, a different
seed differs, and seed 0 differs run-to-run. Adds a portable unit test
(madspace/tests/test_determinism.py) covering the seeding plumbing.

For output_format = lhe, bit-identical output also needs
combine_thread_pool_size = 1 (the parallel LHE combine is not yet
deterministic); compact_npy and lhe_npy are reproducible at any size.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conflict in madgraph/iolibs/template_files/mg7/gridpack.py: main added a
resolve_verbosity() helper at the same spot this branch added derive_seed();
kept both. The other overlapping files (madevent.py, run_card.toml, banner.py,
context.hpp) merged automatically.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The --seed argument was parsed but never passed to ms.Context, so reproducible
gridpack runs had no effect. Derive a per-context seed from it and update the
help text to match the run_card (reproducible at any cpu_thread_pool_size).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants