@@ -74,6 +74,35 @@ covered in `docs/documentation/contributing.md`.
7474 sub-box, pack/unpack it with a device kernel (` s_l0_pack_unpack_block ` ,
7575 ` s_amr_restrict_pack_device ` ) — that is why those exist. Measured: 10 of 60 covered
7676 cells delivered in the AMR cross-rank restrict, mass off 1.4e-5 per regrid.
77+ - An array whose bound is a device global (` dimension(num_fluids) ` , ` dimension(num_species) ` ) may be
78+ passed to a device routine ** from a parallel-loop body, but not from inside another
79+ ` GPU_ROUTINE(parallelism='[seq]') ` ** . CCE OpenACC rejects the second form with
80+ ` ftn-7066 ... Global in accelerator routine without declare -- num_fluids ` , and reports it at
81+ whatever line it gave up on: remove one trigger and the message * walks forward* to the next call,
82+ so the reported line is not the cause. Only the plain lanes fail - under ` --case-optimization `
83+ those bounds are ` parameter ` s, so a green Case Opt lane beside a failing plain one is the
84+ signature. Every accepted call site in the tree already obeys this (` m_cbc ` , ` m_ibm ` ,
85+ ` m_bubbles_EL ` , ` s_compute_cell_state ` ): form such a call in the loop body and pass scalars
86+ deeper. Neither ` cray_inline ` nor a ` num_fluids_max ` bound nor dropping optional dummies helps -
87+ all three were measured.
88+ - nvfortran 23.11/24.1 segfault (` fort2 TERMINATED by signal 11 ` ) on a caller that passes a
89+ ` parameter ` array from ` m_thermochem ` (e.g. ` molecular_weights ` ) into a declare-target routine.
90+ Read such arrays directly in the kernel, or pass a plain local computed from them.
91+ - The ` USING_AMD ` fypp guards (86 sites, ` #:set ` in ` src/common/include/shared_parallel_macros.fpp ` ) are
92+ load-bearing, not a stale workaround - do not "modernize" them away. They swap a device-global array
93+ bound for a literal: ` dimension(3) ` for ` num_dims ` /` num_fluids ` when case optimization is off (64
94+ sites), and ` dimension(20) ` for ` sys_size ` in ` m_compute_cbc ` (21 sites, with a matching
95+ ` @:PROHIBIT ` in ` m_start_up ` capping ` sys_size <= 20 ` under AMD+CBC). Setting ` USING_AMD = False `
96+ and rebuilding amdflang ` --gpu mp ` without case optimization compiles CLEAN - 728 s, zero
97+ diagnostics - and then NaNs at step 50 in CBC, riemann ` wave_speeds=2 ` , IBM, surface tension,
98+ QBMM/viscous and MHD HLLD, while both Lagrange bubble cases * complete* with out-of-tolerance
99+ answers. Measured 2026-08-29 on MI210. A compile-only check returns green, so any future attempt to
100+ drop these must run the tests, not just build.
101+ - The same "call it from the loop body" rule covers ` m_thermochem ` : calling ` get_species_* ` from
102+ inside a ` GPU_ROUTINE ` rather than from the kernel gave CCE OpenMP a runtime
103+ ` Memory access fault by GPU node-N ... Reason: Unknown ` on the first step (exit 134), while every
104+ other backend ran. Evaluate them at the call site and pass the arrays in. Note this one only shows
105+ at runtime, and only on a case that reaches the path - the build is clean.
77106
78107## Parameters
79108
@@ -143,6 +172,27 @@ covered in `docs/documentation/contributing.md`.
143172- Tests are generated programmatically in ` toolchain/mfc/test/cases.py ` (parameter
144173 modifications on ` BASE_CFG ` via the ` CaseGeneratorStack ` push/pop pattern); test UUID =
145174 CRC32 of the trace string; ` ./mfc.sh test -l ` lists all.
175+ - ` --only ` matches whole trace * elements* , not substrings, and ` _filter_only `
176+ (` toolchain/mfc/test/test.py ` ) ** ANDs labels while ORing UUIDs** . So ` --only bubbles ` matches
177+ nothing (the element is ` Bubbles ` ), and ` --only low_Mach=1 low_Mach=2 ` asks for cases carrying
178+ both and also matches nothing. It then exits ** 143** , which reads like an external kill rather
179+ than an empty filter. Pass UUIDs whenever you want the union of several groups.
180+ - Sibling ` define_case_d ` calls off the same stack level are never * combined* . Two switches that
181+ only matter together (` avg_state=1 ` needs ` wave_speeds=2 ` to be read at all) therefore get zero
182+ effective coverage unless something pushes one and defines the other beneath it. Check
183+ reachability before trusting that a flag is tested.
184+ - ` --no-build ` silently runs whatever binary is on disk for a configuration it did not build.
185+ Chemistry has its own config (` gpu-mp-chem-* ` ) that a plain ` ./mfc.sh build ` never produces, so
186+ a ` --no-build ` run reports failures from stale binaries and hides real compile breaks. Run
187+ chemistry-touching sets without it.
188+ - Pick the newest binary by the * binary's* mtime (` ls -t build/install/*/bin/simulation ` ), not the
189+ install directory's - a stale config's directory can be newer than a fresh build's.
190+ - The pre-commit hook lives in the main repo's ` .git/hooks/ ` and git exports ` GIT_DIR ` there
191+ during a commit, so from a worktree the toolchain lint enumerates the * other* checkout and
192+ fails. Reproduce with ` GIT_DIR=<main>/.git ./mfc.sh precheck ` . Run precheck by hand and commit
193+ with ` --no-verify ` .
194+ - ` /tmp ` is node-local: scratch does not survive a compute-node change, and its absence is
195+ silence, not an error. Keep patches and resource baselines on a shared filesystem.
146196- Golden files are tolerance-compared. Regenerate only the affected tests
147197 (` ./mfc.sh test --generate --only <tests> ` ) — an unexplained golden-file diff is a bug
148198 report, not noise to be regenerated away.
0 commit comments