Skip to content

Implement reproducible event generation#51

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

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

Conversation

@theoheimel

Copy link
Copy Markdown
Contributor

Building on #48, implement reproducible event generation.

Design goals:

  • full reproducibility in VEGAS mode
  • full reproducibility of generation in regular and gridpack mode
  • might implement reproducible MadNIS trainings later
  • independent of worker thread count
  • should work on CPU and GPU as well as multi-GPU setups
  • keep performance penalty as low as possible, including for inclusive runs with very different computational cost between channels

Tasks:

  • implement main features
  • performance tests and validation on CPU and GPU setups
  • remove unreproducible code path once everything is validated and the performance penalty is sufficiently low

oliviermattelaer and others added 18 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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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.

2 participants