Skip to content

MCPL_input: consolidate with MCPL_input_once (MPI slicing + repeat_count) - #2780

Merged
willend merged 6 commits into
mccode-dev:mainfrom
willend:main
Oct 13, 2026
Merged

willend merged 6 commits into
mccode-dev:mainfrom
willend:main

Conversation

@willend

@willend willend commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Free-form text area

Please describe what your PR is adding in terms of features or bugfixes:

MCPL_input: consolidate with MCPL_input_once (MPI slicing + repeat_count)

MCPL_input and MCPL_input_once are merged into one implementation in MCPL_input. MCPL_input_once moves to obsolete/ as DEFINE COMPONENT MCPL_input_once INHERIT MCPL_input, so existing instruments keep working.

What MCPL_input does now

  • MPI: the file is split between processes as MCPL_input_once did it. Each process reads, or preloads, only its own slice, so every event is used once per repetition across the whole run.
  • repeat_count: kept from the old MCPL_input. Each process replays its slice repeat_count times. Every pass after the first is smeared with v_smear / pos_smear / dir_smear. The new always_smear=1 smears the first pass too.
  • Weights: scaled by (#events on the process) / (#rays on the process), which is 1/repeat_count without MPI. This also corrects for uneven slices when the event count doesn't divide by the number of processes.
  • ncount: set to #events × repeat_count, independent of the number of MPI processes.

Behaviour changes

  • With MPI, the run is no longer bigger. The old MCPL_input gave every process the whole file, smeared on all but the master, so --mpi=N meant N× the rays. Now it's 1×.
  • Empty input is an error. An empty file, or an energy window that keeps no events, stops the run.
  • repeat_count>1 with all *_smear=0: still reset to 1, but without the 10 s sleep.
  • verbose: now defaults to 0, and prints the first 10 particles read.
  • Cleanup moved to FINALLY. The file is closed and memory freed there instead of in SAVE, which can run mid-simulation when a signal arrives.
  • MCPL_input_once (now in obsolete/): keeps all its parameters and gains repeat_count (default 1). Its parameter order now follows MCPL_input; instruments that set parameters by name are unaffected.

McXtrace

MCPL_input gets the same implementation adapted to photons (E_smear, keV, k, E-field). This fixes two bugs in the old McXtrace version:

  • Without preload, |k| was computed as sqrt(E·E2K) instead of E·E2K, so energies were wrong.
  • With preload, positions were divided by 100 twice.

Other changes

  • ESS_butterfly_MCPL_test uses MCPL_input with repeat_count=repeat instead of the commented-out alternative.
  • The Test_MCPL_input_once description is updated.

Manuals

  • misc/MCPL_input.tex (McStas and McXtrace) regenerated with mcdoc --tex.
  • The MCPL_input_once snippet moves from misc/ to obsolete/, regenerated. A new obsolete/MCPL_input_once_static.tex points to MCPL_input's parameters, since mcdoc does not list inherited ones.
  • obsolete.tex lists and includes MCPL_input_once.
  • misc.tex: the MCPL section gets a short paragraph on MPI slicing and repeat_count.
  • misc/MCPL_output.tex (McStas and McXtrace) regenerated: the weight_mode default is shown as 1, following dacc4b87c.

Testing

Built from source on Linux with OpenMPI, comparing the old and new components on the same input. "Old" means the previous MCPL_input.

  • repeat_count=1, serial, preload 0 and 1: new, old, new-once and old-once give identical results (m1 I=2.27516e11, N=1000).
  • repeat_count=1 with MPI:
    • --mpi=2: identical to the serial run. The old MCPL_input emitted 2000 rays.
    • --mpi=3: 999 rays, I=2.27488e11. The old MCPL_input_once gave 2.27252e11, losing intensity on the uneven slice.
  • repeat_count=3, serial and MPI 2/3: the total intensity on an all-accepting time monitor is preserved.
  • ESS_BEER_MCPL (repeat_count=50), 10 seeds: new 150.7 ± 0.9, old 150.5 ± 0.5.
  • McXtrace round trip (Source_flat → MCPL_output → MCPL_input): the new component reproduces the source's mean energy of 9.9917 keV serial and with MPI 2/3, preload 0 and 1. The old one without preload put nothing on the energy monitor.
  • mctest, --comp MCPL_input and --comp MCPL_input_once: no wrong values.
  • Manual snippets: the committed .tex files are byte-identical to mcdoc --tex output from the current components.

Not tested

  • OpenACC/GPU. That path always preloads and picks events by _uid, as MCPL_input_once already did.
  • The mcstas-antlr code generator. Whole-component INHERIT is already used by Diaphragm.
  • Running ESS_butterfly_MCPL_test, whose input file is downloaded at build time ([CI/repo]: Use GitHub LFS / cache to make MCPL-input for ESS instrument available #2628). It does generate and compile.
  • Building the manual PDF; the .tex changes are not compiled.

Notes

  • The %Example reference values look stale. Test_MCPL_input and Test_MCPL_input_once reach 94% of reference, and ESS_BEER_MCPL 110%, with both the old and new components.

Declaration of use of AI-tools

  • Please add a checkmark here if you used AI-tools during the work for this contribution
  • Furter, please describe how / where and for what the tools were used:

^ 🤖 Generated with Claude Code


Development OS / boundary conditions

Please describe what OS you developed and tested your additions on, and if any special dependencies are required:


PR Checklist for contributing to McStas/McXtrace

For a coherent and useful contribution to McStas/McXtrace, please fill in relevant parts of the checklist:

  • My contribution includes patches to an existing component file

    • I have used the mcdoc utility and rendered a reasonable documentation page for the component (please attach as screenshot in comments!)
    • I have ensured that basic use of the component is OK (e.g. an instrument using it compiles?)
    • I have used the mctest utility to test one or more instruments making use of the component (please attach mcviewtest report as screenshot in comments)
    • I have used the mccode-clangformat tool to apply the standard McCode component indentation scheme
    • I have used the mcrun --c-lint "linter" and followed advice to remove most / all warnings that are raised
  • My contribution contains something else

    • Explanation is added in free form text above or below the checklist

Peter Willendrup and others added 4 commits October 10, 2026 19:51
…unt)

MCPL_input now splits the MCPL file between MPI processes the way
MCPL_input_once did (each process reads/preloads only its own slice),
and keeps repeat_count from MCPL_input: each slice is replayed
repeat_count times, with smearing on all passes after the first (or on
all passes with always_smear=1) and weights scaled by
#events / #rays on that process (= 1/repeat_count without MPI). This
also compensates the uneven slices when the event count does not
divide by the number of MPI processes.

ncount is set to (#events) x repeat_count, independent of the number
of MPI processes (before, MCPL_input gave every process the whole file).
Other changes: verbose prints the first 10 particles read, an empty file
or energy window is an error, repeat_count>1 without smearing is reset
to 1 without the 10 s sleep, and the file is closed / memory freed in
FINALLY rather than SAVE (which can run mid-simulation on a signal).

MCPL_input_once is now "DEFINE COMPONENT MCPL_input_once INHERIT
MCPL_input", keeping its name and all its parameters (it gains
repeat_count, default 1).

McXtrace gets the same implementation adapted to photons (E_smear,
keV, k and E-field). This also fixes two bugs in the old McXtrace
MCPL_input: k was computed as sqrt(E*E2K) instead of E*E2K when not
preloading, and preloaded positions were divided by 100 twice.

ESS_butterfly_MCPL_test now uses MCPL_input with repeat_count=repeat.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeSKcxUdgbJSVRpyB1vgdq
- Regenerate misc/MCPL_input.tex (McStas and McXtrace) with mcdoc --tex
- Move the MCPL_input_once snippet to obsolete/, regenerated
- Add obsolete/MCPL_input_once_static.tex: mcdoc does not list inherited
  parameters, so point to MCPL_input's
- obsolete.tex: list and include MCPL_input_once
- misc.tex: describe MPI slicing and repeat_count in the MCPL section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeSKcxUdgbJSVRpyB1vgdq
Regenerated with mcdoc --tex after dacc4b8 changed the default from -1 to 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QeSKcxUdgbJSVRpyB1vgdq
@willend

willend commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

@g5t and @tkittel I thought this was a good idea, one-stop shop for everything.

Take your time reviewing, I am meant to be on vacation 😅

@g5t

g5t commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

I like the idea, but could imagine the behavior change

  • With MPI, the run is no longer bigger. The old MCPL_input gave every process the whole file, smeared on all but the master, so --mpi=N meant N× the rays. Now it's 1×.

might catch someone out. If you think this is likely to be a problem, maybe there is a straight-forward way to enable the old-behavior by default for MCPL_input.comp and not for a mostly-INHERIT'ed MCPI_input_once.comp?

Something like

DEFINE COMPONENT MCPL_input
SETTING PARAMETERS (..., int replicate_across_processes=1)
...

and

DEFINE COMPONENT MCPL_input_once INHERIT MCPL_input
SETTING PARAMETERS (int replicate_across_processes=0)

@willend

willend commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

No, I think we should have just one component.

Nothing prevents to run with repeat_count=what_you_want.

A suitable heading will of course go in the release notes.

@willend

willend commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

But then again you are right that this effectively is still just one component thanks to INHERIT.

Will give it another thought, even though I kind of like the idea that the default behavior is single pass.

@willend

willend commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

@g5t I put my LLM to work on your suggestion, yet the analysis is that

Since the generator concatenates parent and child parameters, a child can’t re-default a parent parameter—so MCPL_input_once uses a lazy workaround by prepending repeat_count=1; replicate=0; to the inherited INITIALIZE. Now I’ll check the manual commit to undo the obsolete move.

Which means that the body of the MCPL_input_once comp looks like this:

DEFINE COMPONENT MCPL_input_once INHERIT MCPL_input

INITIALIZE
%{
  repeat_count = 1;
  replicate_across_processes = 0;
%}
INHERIT MCPL_input

END

What do you think?

@willend

willend commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Oh and another argument for always "splitting" the mcpl-file across cores is that KDSource.comp has that behaviour also... @g5t @tkittel what do you think.

Split the replayed stream of (#particles in file) x repeat_count rays into
one contiguous chunk per MPI process, as KDSource does. Each process now
seeks once and then reads forward, rewinding to the start of the file when
it wraps. Before, every replay pass did an mcpl_seek back to the slice
start, which for .mcpl.gz means decompressing up to that point on every
pass and every process. Preload loads only the part of the file the
process's chunk covers. Weights are p / repeat_count.

New parameter replicate_across_processes (default 0). With 1 and MPI,
repeat_count is rounded up to a multiple of the number of processes, so
that each process runs through the whole file, as MCPL_input did before
Oct 2026.

MCPL_input_once stays in obsolete/ as an INHERIT of MCPL_input. Its
INITIALIZE puts repeat_count=1 and replicate_across_processes=0 in front of
the inherited code, so each event is always used exactly once.

Behaviour changes:
- ncount is always (#particles in file) x repeat_count. Particles that are
  not neutrons (photons for McXtrace), or are outside [Emin, Emax], are
  ABSORBed. Before, with preload only the kept events were counted.
- An energy window that keeps no events no longer stops the run. The
  closing "used X of Y" message reports it.

The same changes go into McXtrace MCPL_input. Manual snippets are
regenerated with mcdoc/mxdoc --tex. misc.tex, obsolete.tex,
MCPL_input_once_static.tex and the Test_MCPL_input_once description are
updated.

Tested on macOS arm64 with OpenMPI: serial and --mpi=2/3, repeat_count 1
and 3, preload 0 and 1, replicate 0 and 1, MCPL_input and MCPL_input_once.
Total intensity is preserved and ray counts are as expected. McXtrace
round trip: intensity is preserved and the mean energy is about 10 keV.
mcstas and mcstas-antlr both generate the MCPL_input_once override. Not
tested: GPU/OpenACC, Linux, Windows, manual PDF build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@willend willend closed this Oct 13, 2026
@willend willend reopened this Oct 13, 2026
@willend

willend commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Oops managed to hit close - now reopened...

@g5t and @tkittel I went for the original intent - and standardisation amongst KDSource and MCPL_input(_once) default behaviour: Split the file.

There is however a flag to load the whole file as legacy MCPL_input did, added in the form @g5t suggested.

@tkittel

tkittel commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Sounds good to me, since the current state has way too many components for mcpl i/o. But @g5t does have a valid concern, I am just not really sure how to prevent it.

One way would be to have a period with a flag defaulting first to the old, then the new behaviour (like what we did for the stat:sum migration). But of course, that is up to @willend .

@willend

willend commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Change of behaviour with:

  • Reasonable documentation
  • Faster default-run through an MCPL file
  • A flag to use the old behaviour if one prefers
  • Standard across multiple mcpl-input-like-comps

merge.

@willend
willend merged commit fa0acff into mccode-dev:main Oct 13, 2026
30 checks passed
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