@@ -36,6 +36,35 @@ covered in `docs/documentation/contributing.md`.
3636- ` @:ACC_SETUP_VFs(...) ` /` @:ACC_SETUP_SFs(...) ` GPU pointer setup compiles only under
3737 Cray. Around MPI: ` GPU_UPDATE(host=...) ` before send, ` GPU_UPDATE(device=...) ` after
3838 receive.
39+ - An array whose bound is a device global (` dimension(num_fluids) ` , ` dimension(num_species) ` ) may be
40+ passed to a device routine ** from a parallel-loop body, but not from inside another
41+ ` GPU_ROUTINE(parallelism='[seq]') ` ** . CCE OpenACC rejects the second form with
42+ ` ftn-7066 ... Global in accelerator routine without declare -- num_fluids ` , and reports it at
43+ whatever line it gave up on: remove one trigger and the message * walks forward* to the next call,
44+ so the reported line is not the cause. Only the plain lanes fail - under ` --case-optimization `
45+ those bounds are ` parameter ` s, so a green Case Opt lane beside a failing plain one is the
46+ signature. Every accepted call site in the tree already obeys this (` m_cbc ` , ` m_ibm ` ,
47+ ` m_bubbles_EL ` , ` s_compute_cell_state ` ): form such a call in the loop body and pass scalars
48+ deeper. Neither ` cray_inline ` nor a ` num_fluids_max ` bound nor dropping optional dummies helps -
49+ all three were measured.
50+ - nvfortran 23.11/24.1 segfault (` fort2 TERMINATED by signal 11 ` ) on a caller that passes a
51+ ` parameter ` array from ` m_thermochem ` (e.g. ` molecular_weights ` ) into a declare-target routine.
52+ Read such arrays directly in the kernel, or pass a plain local computed from them.
53+ - The ` USING_AMD ` fypp guards (86 sites, ` #:set ` in ` src/common/include/shared_parallel_macros.fpp ` ) are
54+ load-bearing, not a stale workaround - do not "modernize" them away. They swap a device-global array
55+ bound for a literal: ` dimension(3) ` for ` num_dims ` /` num_fluids ` when case optimization is off (64
56+ sites), and ` dimension(20) ` for ` sys_size ` in ` m_compute_cbc ` (21 sites, with a matching
57+ ` @:PROHIBIT ` in ` m_start_up ` capping ` sys_size <= 20 ` under AMD+CBC). Setting ` USING_AMD = False `
58+ and rebuilding amdflang ` --gpu mp ` without case optimization compiles CLEAN - 728 s, zero
59+ diagnostics - and then NaNs at step 50 in CBC, riemann ` wave_speeds=2 ` , IBM, surface tension,
60+ QBMM/viscous and MHD HLLD, while both Lagrange bubble cases * complete* with out-of-tolerance
61+ answers. Measured 2026-08-29 on MI210. A compile-only check returns green, so any future attempt to
62+ drop these must run the tests, not just build.
63+ - The same "call it from the loop body" rule covers ` m_thermochem ` : calling ` get_species_* ` from
64+ inside a ` GPU_ROUTINE ` rather than from the kernel gave CCE OpenMP a runtime
65+ ` Memory access fault by GPU node-N ... Reason: Unknown ` on the first step (exit 134), while every
66+ other backend ran. Evaluate them at the call site and pass the arrays in. Note this one only shows
67+ at runtime, and only on a case that reaches the path - the build is clean.
3968
4069## Parameters
4170
@@ -105,6 +134,27 @@ covered in `docs/documentation/contributing.md`.
105134- Tests are generated programmatically in ` toolchain/mfc/test/cases.py ` (parameter
106135 modifications on ` BASE_CFG ` via the ` CaseGeneratorStack ` push/pop pattern); test UUID =
107136 CRC32 of the trace string; ` ./mfc.sh test -l ` lists all.
137+ - ` --only ` matches whole trace * elements* , not substrings, and ` _filter_only `
138+ (` toolchain/mfc/test/test.py ` ) ** ANDs labels while ORing UUIDs** . So ` --only bubbles ` matches
139+ nothing (the element is ` Bubbles ` ), and ` --only low_Mach=1 low_Mach=2 ` asks for cases carrying
140+ both and also matches nothing. It then exits ** 143** , which reads like an external kill rather
141+ than an empty filter. Pass UUIDs whenever you want the union of several groups.
142+ - Sibling ` define_case_d ` calls off the same stack level are never * combined* . Two switches that
143+ only matter together (` avg_state=1 ` needs ` wave_speeds=2 ` to be read at all) therefore get zero
144+ effective coverage unless something pushes one and defines the other beneath it. Check
145+ reachability before trusting that a flag is tested.
146+ - ` --no-build ` silently runs whatever binary is on disk for a configuration it did not build.
147+ Chemistry has its own config (` gpu-mp-chem-* ` ) that a plain ` ./mfc.sh build ` never produces, so
148+ a ` --no-build ` run reports failures from stale binaries and hides real compile breaks. Run
149+ chemistry-touching sets without it.
150+ - Pick the newest binary by the * binary's* mtime (` ls -t build/install/*/bin/simulation ` ), not the
151+ install directory's - a stale config's directory can be newer than a fresh build's.
152+ - The pre-commit hook lives in the main repo's ` .git/hooks/ ` and git exports ` GIT_DIR ` there
153+ during a commit, so from a worktree the toolchain lint enumerates the * other* checkout and
154+ fails. Reproduce with ` GIT_DIR=<main>/.git ./mfc.sh precheck ` . Run precheck by hand and commit
155+ with ` --no-verify ` .
156+ - ` /tmp ` is node-local: scratch does not survive a compute-node change, and its absence is
157+ silence, not an error. Keep patches and resource baselines on a shared filesystem.
108158- Golden files are tolerance-compared. Regenerate only the affected tests
109159 (` ./mfc.sh test --generate --only <tests> ` ) — an unexplained golden-file diff is a bug
110160 report, not noise to be regenerated away.
0 commit comments