Skip to content

MadSpin: -O2 for productions with >= 4 decaying particles - #238

Merged
oliviermattelaer merged 1 commit into
mainfrom
claude/gallant-franklin-15ce44
Oct 8, 2026
Merged

oliviermattelaer merged 1 commit into
mainfrom
claude/gallant-franklin-15ce44

Conversation

@oliviermattelaer

Copy link
Copy Markdown
Contributor

Summary

MadSpin compiles its standalone matrix-element trees through misc.compile, which never sets GLOBAL_FLAG, so they were always built at -O0 (MG5aMC does the same). This PR builds them at -O2, but only when a production process has at least 4 particles that MadSpin decays, because that is the only case where it pays off in a full MadSpin run.

  • MadSpin/decay.py
    • MS_GLOBAL_FLAG = '-O2', MS_GLOBAL_FLAG_MIN_DECAYS = 4.
    • set_global_flag(tree) writes GLOBAL_FLAG into the tree's Source/make_opts, which every makefile of the tree includes (DHELAS, MODEL, the P directories, MadSpin/src/makefile_*). output standalone has already built Source/DHELAS and Source/MODEL at -O0 and make does not track flags, so when the flag changes those objects and libraries are removed and rebuilt.
    • decay_all_events.nb_decaying_in_production() counts the decayed final-state particles of the production processes. Decays inside a chain (the W of t > w+ b, w+ > ...) do not count. It reads all_ME (madspin_v1) or the production entries of all_me (onshell/density modes).
    • use_global_flag() is called by both build paths: compile_fortran and decay_all_events_onshell.compile.
  • madgraph/interface/common_run_interface.py: update_make_opts_full now returns whether it changed the file. No existing caller uses the return value.

Why the threshold

Full MadSpin runs on the rows of the MG7 paper's tab_madspin_walltimes.

row decaying particles -O0 [s] -O2 [s] speed-up
WH 1 23.6 25.1 0.94
t t~ 2 27.5 29.0 0.95
t t~ (decay chain) 2 30.6 32.6 0.94
ZZ 2 28.3 30.5 0.93
t t~ Z 3 33.2 35.7 0.93
t t~ Z (decay chain) 3 37.8 39.0 0.97
t t~ t t~ 4 41.2 38.5 1.07
t t~ t t~ (decay chain) 4 48.2 45.8 1.05
W+W-W+W- 4 103.6 82.6 1.25
  • Fixed cost: -O2 adds about 2 s of compilation to every run.
  • Run-time gain: the max-weight scan and decay loop only get faster when the matrix elements dominate them. W+W-W+W-: scan 30 → 20 s, loop 52 → 34 s. On the simple rows the scan and loop are dominated by Python and do not change.
  • Fortran alone: the effect is larger. For g g > t t~ g g, GET_DENSITY goes from 476 µs per call at -O0 to 174 µs at -O2.

Validation

  • tests/test_manager.py -p tests/unit_tests/madspin '.*': Ran 634 tests, OK. 6 are new:
    • TestSetGlobalFlag: the flag is written, stale objects are removed, and nothing is removed once the flag is already set.
    • TestGlobalFlagGate: the decay count from both data layouts, and the flag applied only from 4 decays on.
  • Real density-mode MadSpin runs, both decaying 10000 events:
    • p p > t t~ (2 decays): make_opts keeps no GLOBAL_FLAG.
    • p p > t t~ t t~ (4 decays): built with GLOBAL_FLAG=-O2.
  • Object check: in an (ungated) -O2 run, the objects MadSpin built (aloha_functions.o, P1_gg_ttx/matrix.o) are byte-identical to a manual -O2 compile and differ from -O0.
  • Not bit-identical to before for these productions: -O2 against -O0 changes the density matrix only at rounding level, ≤5.4e-15 relative.

Notes

  • I did not run a madspin_v1 case with 4 or more decays end to end; it takes hours. That path goes through the same helper, which the unit tests cover.
  • A colour-sum rewrite of the standalone GET_ALL_INTER was also measured in this work and dropped. It speeds up the Fortran colour part by 2-10x, but makes no difference on these MadSpin rows because their colour matrices are small.

MadSpin compiled its standalone trees with an empty GLOBAL_FLAG, i.e. -O0:
misc.compile never sets it. set_global_flag() writes GLOBAL_FLAG into the
tree's Source/make_opts, which every makefile of the tree includes, and,
since `output standalone` has already built Source/DHELAS and Source/MODEL
at -O0 and make does not track flags, cleans those so they are rebuilt.

-O2 is only used when a production process has at least
MS_GLOBAL_FLAG_MIN_DECAYS (4) particles to decay: it costs ~2 s of
compilation per run and only pays off when the matrix elements dominate.
Measured on the MG7 paper's MadSpin timing setup (10^4 events, nb_core 6,
sequential unweighting, mg7 backend): t t~ t t~ x1.05-1.07 and W+W-W+W-
x1.25, but WH, t t~, ZZ and t t~ Z 3-7% slower.

update_make_opts_full now returns whether it changed the file.
@oliviermattelaer
oliviermattelaer merged commit bbd248f into main Oct 8, 2026
175 checks passed
@oliviermattelaer
oliviermattelaer deleted the claude/gallant-franklin-15ce44 branch October 8, 2026 17:58
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.

1 participant