Fix Mgxs::get_xs CHI_DELAYED indexing the wrong tensor when gout is null - #4067
Open
dallonby wants to merge 1 commit into
Open
Fix Mgxs::get_xs CHI_DELAYED indexing the wrong tensor when gout is null#4067dallonby wants to merge 1 commit into
dallonby wants to merge 1 commit into
Conversation
The gout == nullptr branches of the CHI_DELAYED case summed delayed_nu_fission instead of chi_delayed: - delayed_nu_fission is rank 3, [angle][delayed group][incoming group] (xsdata.cpp), but was indexed with four indices. tensor::Tensor's operator() performs no rank check, so the four-index read walks past the stride vector and reads out of bounds. - With dg == nullptr, the inner loop bound used delayed_nu_fission.shape(3), which is 0 for a rank-3 tensor, so the branch silently returned 0. Both branches are meant to return chi_delayed summed over outgoing groups; they now read chi_delayed with its actual shape [angle][delayed group][incoming group][outgoing group]. The chi_delayed dimension comment in xsdata.h documented the layout as [angle][in][out][delayed group] and is corrected to match the allocation in xsdata.cpp. No current caller reaches the fixed branches: the only external CHI_DELAYED caller (random_ray/flat_source_domain.cpp) always passes a non-null gout, so this produces no behavior change today — but any new caller would have hit silent out-of-bounds reads or a silent zero. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dallonby
added a commit
to dallonby/openmc
that referenced
this pull request
Aug 21, 2026
CHI_DELAYED -> PR openmc-dev#4067; discrete-line lin-lin sampling (with the ENDF/B-VIII.0 photon-table census) -> issue openmc-dev#4068 + PR openmc-dev#4069; MG density_mult tally asymmetry -> issue openmc-dev#4070. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Found while porting the OpenMC transport engine to Apple Silicon GPUs (Metal) — dallonby/openmc-metal — where flattening the MG data model for the device meant auditing these tensor layouts against the code that reads them.
The
gout == nullptrbranches of theCHI_DELAYEDcase inMgxs::get_xs(src/mgxs.cpp) sumdelayed_nu_fissionwhere they should sumchi_delayed:delayed_nu_fissionis rank 3 with shape[angle][delayed group][incoming group](src/xsdata.cpp), but was indexed with four indices,(a, *dg, gin, g).tensor::Tensor::operator()performs no rank check, so the four-index read walks past the stride vector and reads out of bounds.dg == nullptrbranch, the inner loop bound wasdelayed_nu_fission.shape(3), which returns 0 for a rank-3 tensor — so that branch silently returned 0 rather than a spectrum sum.Both branches are meant to return
chi_delayedsummed over outgoing groups (mirroring the structure of theCHI_PROMPTcase); they now readchi_delayedwith its actual shape[angle][delayed group][incoming group][outgoing group]and loop overchi_delayed.shape(1)/shape(3).Also fixed: the dimension comment for
chi_delayedin include/openmc/xsdata.h documented the layout as[angle][in group][out group][delayed group], which does not match the allocation in src/xsdata.cpp ({n_ang, n_dg, n_g, n_g}). The comment now matches the code.Reachability / impact: no current caller reaches the fixed branches — the only external
CHI_DELAYED/CHI_PROMPTcaller (src/random_ray/flat_source_domain.cpp) always passes a non-nullgout, and the direct-indexgout != nullptrpath (which is correct) is untouched. So this changes no existing results; it removes silent out-of-bounds reads / silent zeros waiting for the first caller that asks for a group-summed delayed spectrum.A possible follow-up hardening (not included here to keep this minimal): a debug-mode rank assertion in
tensor::Tensor::operator(), which would have turned this into a loud failure. Happy to add a unit test exercisingget_xs(CHI_DELAYED, gin, nullptr, ...)if that's preferred.Checklist
xsdata.hlayout comment)🤖 Generated with Claude Code