You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Ledger 160: the descriptor tax -- BLOCK-local work arrays take 42 of HLLC's 47 descriptor copies per launch out; wall -69 ms/step (t -5.2), MFC excess 0.615 -> 0.530 s/step node-matched (1.60x -> 1.53x); the device-routine form withdrawn as a device-side loss
Copy file name to clipboardExpand all lines: docs/documentation/amr_action_plan.md
+78Lines changed: 78 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8903,3 +8903,81 @@ emitted, or make the batched advance indifferent to shape -- and both are on the
8903
8903
**Transport, for the record.** The first A/B (418147) died of UCX ROCm signal-pool exhaustion under a 16-block migration; the
8904
8904
default pool is 1024 and its control on k004-001 already logged 353 of the error, where four earlier controls on k004-002/004
8905
8905
logged none -- per-node. `UCX_ROCM_COPY_SIGPOOL_MAX_ELEMS=32768` on both arms: 0 errors on every arm of 418161.
8906
+
8907
+
## 2026-09-14 (160) — THE DESCRIPTOR TAX: amdflang charges ~31 us per launch for every `private` array; declaring the work arrays in a BLOCK removes it. Wall -69 ms/step (-6.0 %, t = -5.2), launches unchanged; the kernel-as-device-routine form is a device-side loss and was withdrawn
8908
+
8909
+
**Mechanism** (GOAL v13; `amr-bench/notes/rhs_trace_418457.md`). Every OpenMP target launch on amdflang (TheRock AFAR 23.2)
8910
+
pays a host-side floor of ~85 us plus one descriptor materialisation per mapped entity; the batched RHS call was ~350 such
8911
+
copies (LIBOMPTARGET_INFO accounting on A5DAD70D, 8 ranks): HLLC 46.9 copies per launch on 137 kernel arguments, WENO5
8912
+
25.9, cons-to-prim 16.1. The standalone probe `amr-bench/nowait_probe/descr.f90` priced the entities: module allocatables
8913
+
~2 copies each (the floor), assumed-shape dummies +30 us, **`private` fixed-size arrays +31 us each**, a local of a
8914
+
called device routine 0, and -- variant B -- **an array declared in a `block` inside the loop body 0** (83.0 us per launch
8915
+
against the module-only floor 82.2; the six-private-array variant 265.6).
8916
+
8917
+
**What landed** (`up/mega` `205ec78f` + `4315bc8a`, on top of the withdrawn device-routine commits `25663cde`..`1c7e1dfe` and their three repairs). The work arrays of the
8918
+
WENO5 kernel (`m_weno.fpp`: dvd/poly/alpha/omega/beta/delta), the HLLC 5-equation kernel (`m_riemann_solver_hllc.fpp`:
8919
+
vel/alpha/alpha_rho/alpha_lim/Ys/Xs/Gamma_i/Cp_i/h_i/R_species/Re, plus the hypoelastic tau_e/U/F set) and the cons-to-prim
8920
+
kernel (`m_variables_conversion.fpp`: alpha_K/alpha_rho_K/Re_K/nRtmp/rhoYks/B) are declared in a `block` inside the loop
8921
+
body instead of at routine scope under `private=`; the loop bodies are otherwise the original statements. Copies per launch:
8922
+
**HLLC 46.9 -> 5.0, cons-to-prim 16.1 -> 4.2, WENO5 13.9** (its remainder is five module allocatables and the two output
8923
+
dummies), launches unchanged. Gates at every commit: goldens byte-identical with FMA contraction pinned
8924
+
(`-ffp-contract=off`, `amr-bench/bytecmp.sh` against `8afa1156`) on the 8 dynamic-regrid tests + A5DAD70D, 2,130,902
8925
+
values; amdflang gpu-omp 9/9; all three targets build. `docs/documentation/gpuParallelization.md` documents the idiom.
8926
+
8927
+
**The dead end, so nobody walks it again.** The first form moved each kernel body into a `GPU_ROUTINE` called per cell
8928
+
(the goal's A.1 mechanism), which took the host copies out just the same (HLLC 4.0) -- and made the device slower:
8929
+
rhstrace 418669/418732/418529a, untouched kernels flat within 1.5 %, HLLC **+34..47 % per launch**, WENO5 +6..42 %, whether
8930
+
the call was inlined (`!dir$ forceinline`, verified in device IR), took explicit-shape dummies, or returned through private
8931
+
scalars. The device ELF metadata says why: the inlined body inherits the `declare target` routine's register budget
8932
+
(WENO5 x/y/z 130/134/170 -> 118 VGPRs, 148 vs 102 `s_waitcnt`), which nothing in Fortran can lift. A second trap on the
8933
+
way: a `declare target` routine reads the never-updated device copy of a host-only module scalar (`wave_speeds`,
8934
+
dflt_int) where the kernel had taken the host value as an implicit firstprivate -- CPU goldens byte-identical, 9/9 NaN on
8935
+
the GPU. And the block's position is load-bearing: with WENO5's block inside the seq `do i` loop the kernel ran +30..50 %
8936
+
(418529b); wrapping the i-loop it is at base (418529c: 3555/3732/3800 vs 3624/3732/4258 us).
8937
+
8938
+
**A/B** (session allocation 418529 on k004-006, `amr-bench/dt_ab.sbatch`, pinned case-optimized `8afa1156` (control, the
8939
+
parent line) vs `4315bc8a`, arms differ by binary only, 3 reps rotated, differenced 240-40, `HZ VERDICT: CLEAN`, all six
8940
+
240-step arms stalldet CLEAN, 0 UCX pool errors). Pre-registered in `amr-bench/notes/prereg_descriptor_tax.md`:
0 commit comments