Repository navigation
IB: size the ownership hand-off arrays by the neighborhood radius - #1944
Merged
sbryngelson merged 2 commits intoOct 8, 2026
Merged
Conversation
s_handoff_ib_ownership hard-coded max_nbrs = 26, but its send/receive loops visit all (2R+1)^num_dims - 1 neighbor offsets (124 for R = 2, 342 for R = 3 in 3-D), so requests, recv_neighbor_list and recv_bufs overflowed for ib_neighborhood_radius >= 2. Allocate them from the actual radius. The per-neighbor receive buffer was also sized for num_local_ibs_max (~5 MB per neighbor); a rank can hand off at most every global patch, so size it by min(num_local_ibs_max, num_gbl_ibs). Co-Authored-By: Claude <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The corrected multi-rank radius-dependent path needs an automated regression test.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Fixes moving-IB ownership hand-off buffer overruns for neighborhood radii greater than one.
Changes:
- Dynamically sizes neighbor/request arrays from radius and dimensionality.
- Reduces per-neighbor buffer capacity using the global IB count.
- Reuses the computed neighbor count during unpacking.
| File | Description |
|---|---|
src/simulation/m_ibm.fpp |
Corrects MPI hand-off array and buffer sizing. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Add "3D -> 2 MPI Ranks -> IBM Moving Sphere -> ib_neighborhood_radius=2" (2440B4AE). The ownership hand-off loops over all 124 radius-2 offsets on any multi-rank run, so two ranks exercise the radius-sized neighbor arrays. The sphere moves < 1% of a cell, so no cell crosses its surface. Golden generated with GNU 12.3, MPI, Release. On master a bounds-checked build aborts: Index '27' of array 'recv_neighbor_list' above upper bound of 26. Co-Authored-By: Claude <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1944 +/- ##
==========================================
+ Coverage 62.64% 62.98% +0.34%
==========================================
Files 86 86
Lines 22425 22426 +1
Branches 3325 3325
==========================================
+ Hits 14048 14126 +78
+ Misses 6119 6018 -101
- Partials 2258 2282 +24 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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
s_handoff_ib_ownership(src/simulation/m_ibm.fpp) overruns its neighbor arrays whenib_neighborhood_radius >= 2, which crashes multi-node runs with a moving IB in 3D.Root cause.
max_nbrs = 26is a hard-coded parameter, andrequests(2*max_nbrs),recv_neighbor_list(max_nbrs)andrecv_bufs(:, max_nbrs)are sized from it. The receive loop, though, visits all(2R+1)^num_dims - 1offsets (124 for R = 2, 342 for R = 3 in 3D) and writesrecv_neighbor_list(nbr_idx)andrequests(nreqs)for each one. The per-neighbor tags were already widened for R > 1, but the arrays were not. Separately, each receive buffer is sized fornum_local_ibs_maxpatches (about 5 MB per neighbor), so every step posts megabytes ofMPI_PACKEDreceives even when the sizes are legal.Fix.
requests,recv_neighbor_listandrecv_bufsfrommax_nbrs = (2R+1)**num_dims - 1, and reusemax_nbrsin the unpack loop.min(num_local_ibs_max, num_gbl_ibs)patches. A rank can hand off at most every global patch.Behavior is unchanged for R = 1, apart from the smaller buffers. CFD results are unchanged.
Verification
This was run in production on OLCF Frontier (CCE 19, OpenACC GPU build,
--case-optimization) with the same patch applied to3dc5b2f, which is the currentmaster:ib_neighborhood_radius = 3. The run aborted in the first steps after about 65,000cxil_map: write errorlines, then failed with:MPI_Irecv(buf=..., count=5120004, MPI_PACKED, src=31, tag=216, ...) failed ... OFI tagged recv failed (Invalid argument).The out-of-bounds writes happen on any multi-rank run with R >= 2, because
recv_neighbor_list(nbr_idx)is written for every offset, includingMPI_PROC_NULLones. With few ranks, though, they usually corrupt memory silently instead of crashing. The production crash needed many real neighbors (64 ranks across 8 nodes).Regression test (added):
3D -> 2 MPI Ranks -> IBM Moving Sphere -> ib_neighborhood_radius=2(2440B4AE),ppn = 2. It is the existing2 MPI Ranks -> IBM Spheresetup (30x30x50 cells), with the sphere given a prescribed velocity (moving_ibm = 1,vel(1) = 0.01) so the hand-off runs every step, andib_neighborhood_radius = 2. The sphere moves less than 1% of a cell in 50 steps, so no cell crosses its surface and the golden is not sensitive to roundoff. The golden was generated on a Frontier CPU compute node with GNU 12.3 (gcc-native/12.3) + Cray MPICH, MPI, Release, matching the existing2 MPI Ranksgoldens. Results:-fcheck=all)master(m_ibm.fppat3dc5b2f)-fcheck=all)At line 1782 of m_ibm.fpp: Index '27' of dimension 1 of array 'recv_neighbor_list' above upper bound of 26masterSo, to be explicit: this test guards the fix only in bounds-checked builds. The CI
reldebugGNU lanes compile with-fcheck=bounds,pointer, which would catch a regression. In Release builds it is coverage of the R > 1 multi-rank hand-off path. The existing testsAFBACA70(2-rank IB sphere),CE232828(3D 2 ranks) andD7E7DE04(moving IB, pitch ramp) still pass.simulationalso builds with CCE 19 on CPU. Precheck passes apart from twotest_thermochemcases that fail on the Frontier login node because they compile with the system/usr/bin/gfortran(addressed by #1943).Contribution Policy
We do not accept pull requests generated primarily by AI without genuine understanding or real-world usage context.
All contributions are expected to demonstrate:
If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.
Acknowledgement
This PR was prepared with the assistance of an AI tool (Claude Code). The bug was found, and the fix exercised, in multi-node production runs on Frontier.
PR template credit: junegunn