lint: refuse an array element passed to a device routine that runs a seq loop - #1816
Conversation
…seq loop (Cray OpenACC miscompiles the pair)
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Pull request overview
Adds a new source-lint rule (with tests + contributor guidance) to prevent reintroducing a known Cray OpenACC miscompile pattern: passing array elements into device routines that contain (or inline) acc loop seq-equivalent loops.
Changes:
- Implement
check_device_routine_element_argsinlint_source.pyand wire it into the lint runner. - Add unit tests covering flagged vs allowed call sites and propagation through device-routine call chains.
- Document the rule/workaround in
docs/documentation/contributing.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| toolchain/mfc/lint_source.py | Adds new linter logic to detect/flag element actual-args into “tainted” device routines and integrates it into main(). |
| toolchain/mfc/test_lint_source.py | Adds unit tests exercising the new lint rule across host/device/kernels and call-chain propagation. |
| docs/documentation/contributing.md | Documents the new constraint and links it to the relevant issue + linter enforcement. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…gates to its callers
…l sites by routine name, scope calls to the innermost procedure
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1816 +/- ##
=======================================
Coverage 62.26% 62.26%
=======================================
Files 84 84
Lines 21558 21558
Branches 3188 3188
=======================================
Hits 13423 13423
Misses 5937 5937
Partials 2198 2198 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Closes #1815
Enforces the workaround for #1815 so it cannot be reintroduced.
CCE OpenACC (19.0.0 through 21.0.2,
-O2) miscompiles one pairing: a device routine that contains anacc loopat any level (seqincluded; the conformingloop vectorinroutine vectorfails the same way), called with an array element as an actual argument. The element is read as garbage and never written back; either ingredient alone is fine, and CCE OpenMP offload of the same shape is correct. The pairing is what #1811 hit when it added Newton and RK4 loops to helpers that kernels called withq_prim_vf%vf(i)%sf(j,k,l)andblkmod1(k,l,q).check_device_routine_element_argsinlint_source.py: collect theGPU_ROUTINEs that contain aGPU_LOOP, close that set over device routines that call them (CCE inlines the chain, so the loop counts wherever it ends up), then flag any call to one of them, inside aGPU_PARALLEL_LOOPbody or another device routine, whose argument is exactly an element reference such asa(i)orq(i)%sf(j,k,l). Expressions (a(i)/max(b(i), eps)), intrinsic andf_*calls, array sections (w(:,q)), whole arrays and host call sites pass. Contained procedures scope correctly.Validation: master is clean; #1811 before its fix (
c167a0aa) gets 38 findings in exactly the seven files that were changed by hand (m_rhs,m_hypoelastic,m_riemann_solver_hypo_hlld,m_acoustic_src,m_ibm,m_pressure_relaxation,m_variables_conversion); #1811 after its fix (1ee119b9) is clean. Four unit tests: flagged element in and out, flagged through a caller, host call site not flagged, scalars/expressions/loop-free routines not flagged.One paragraph in
contributing.md; the mechanism itself is documented in.claude/rules/common-pitfalls.mdon #1811 and reproduced standalone in sbryngelson/compiler-bugscce/acc-routine-element-by-reference.