Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
595 commits
Select commit Hold shift + click to select a range
4b68baa
Reapply "perf(amr): iterate ghost fills over face slabs instead of ma…
sbryngelson Jul 21, 2026
e45d94c
docs(amr): correct stale comments and complete drift-protection markers
sbryngelson Jul 22, 2026
742140b
refactor(amr): call shared own-box device kernel from the np=1 gather
sbryngelson Jul 22, 2026
6243634
fix(amr): fail-closed IGR+AMR at num_procs > 1
sbryngelson Jul 22, 2026
7936b27
examples: add 2D AMR advected-droplet case
sbryngelson Jul 22, 2026
5740882
refactor(amr): rename ref_ratio -> amr_ref_ratio
sbryngelson Jul 22, 2026
8923a71
refactor(amr): shrink m_amr public surface
sbryngelson Jul 22, 2026
b61858b
docs(amr): clarify block-index and tagging params, freshness-lint amr.md
sbryngelson Jul 22, 2026
24d4bd6
test(amr): drop redundant multi-level static golden
sbryngelson Jul 22, 2026
05e2663
test(amr): add 3D AMR restart-roundtrip coverage
sbryngelson Jul 22, 2026
35d45e0
docs(amr): tighten AMR and load-balance source comments
sbryngelson Jul 22, 2026
fa43e19
docs(amr): tighten AMR comments in touched solver files
sbryngelson Jul 22, 2026
5436431
test(amr): skip 2D_amr_droplet from the Example smoke suite
sbryngelson Jul 22, 2026
20a742c
spike(l0-blocks): L0-as-blocks feasibility, bit-identical CPU+GPU (l0…
sbryngelson Jul 23, 2026
f48fc19
spike(l0-blocks): persistent multi-rank tiling, bit-identical np=1 an…
sbryngelson Jul 23, 2026
2030012
spike(l0-blocks): P2P tile migration primitive, bit-identical across …
sbryngelson Jul 23, 2026
0443fbb
spike(l0-blocks): closed-loop rebalancer (detect->migrate->re-level),…
sbryngelson Jul 23, 2026
29757a8
spike(l0-blocks): beta - tiles own storage, L0 demoted to I/O staging…
sbryngelson Jul 23, 2026
0aabc42
spike(l0-blocks): GPU migration - device pack/unpack for migrate+scat…
sbryngelson Jul 23, 2026
2585175
spike(l0-blocks): real measured-cost feedback (GPU-synced per-tile ti…
sbryngelson Jul 23, 2026
02a3eba
spike(l0-blocks): reflective (symmetry) domain-edge BC for tiles, bit…
sbryngelson Jul 23, 2026
d8576aa
spike(l0-blocks): periodic BC for tiles at np=1 (self-wrap + cross-ti…
sbryngelson Jul 23, 2026
adfdcfb
spike(l0-blocks): periodic BC at np>1 (allreduce rank-0-only periodic…
sbryngelson Jul 23, 2026
46565e5
spike(l0-blocks): smooth rebalancer per-tile cost with an EMA across …
sbryngelson Jul 23, 2026
0351170
spike(l0-blocks): make branch precheck-clean (format pass, param docs…
sbryngelson Jul 23, 2026
884af71
proto(l0-amr-unify): L0 tiles -> level-0 base (rr=1 per-slot override…
sbryngelson Jul 23, 2026
1ebff0e
proto(l0-amr-unify) step1: split amr_max_blocks into amr_max_fine (ca…
sbryngelson Jul 23, 2026
9abd282
test(l0): forced cross-rank tile-migration golden (np=2, fixed dt) - …
sbryngelson Jul 23, 2026
83f7bf0
fix(l0): gfortran/ifx portability - s_l0_copy_coarse_to_tiles q_cons_…
sbryngelson Jul 23, 2026
22bd925
fix(l0): nest mod() under l0_rebalance_interval>0 guard - amdflang in…
sbryngelson Jul 23, 2026
c91ea0c
proto(l0-amr-unify) step2a: add f_l0_slot(k)=l0_slot_off+k helper (id…
sbryngelson Jul 24, 2026
161f77a
proto(l0-amr-unify) step2b: single shared-pool allocator; s_l0_tiles_…
sbryngelson Jul 24, 2026
0203fe5
proto(l0-amr-unify) step2c: AMR initial fine block at slot l0_slot_of…
sbryngelson Jul 24, 2026
7cc3ee3
proto(l0-amr-unify) step2d: s_tvd_rk skips level-0 (tile) slots in AM…
sbryngelson Jul 24, 2026
d586a6d
feat(l0-amr): @:PROHIBIT l0_ntile>0 with amr=T (coexist needs Increme…
sbryngelson Jul 24, 2026
fa2877a
docs(l0-amr): fix stale amr_cur=1 comments; note amr_slot_live coexis…
sbryngelson Jul 24, 2026
5fdd071
inc3(l0-amr): coexist-safe amr_decomp/finalize alloc-free (.not. amr …
sbryngelson Jul 24, 2026
abacb26
inc3(l0-amr): harden coexist scaffolding - gate amr_ref_ratio clobber…
sbryngelson Jul 24, 2026
179ed60
inc(l0-amr): level-0 tile capture guard in s_amr_capture_boundary_flu…
sbryngelson Jul 24, 2026
4983cc9
inc(l0-amr): narrow coexist guard to static single-level any-np (dyna…
sbryngelson Jul 24, 2026
366d321
inc(l0-amr): per-stage tiles->L0 scatter in coexist (fresh coarse sta…
sbryngelson Jul 24, 2026
aca4191
inc(l0-amr): re-enable L0 coarse RHS under coexist with BC+halo (L0-f…
sbryngelson Jul 24, 2026
5fc583a
inc(l0-amr): split fine/tile stage advance into RHS + RK passes (byte…
sbryngelson Jul 24, 2026
295a277
inc(l0-amr): np>1 coexist coupling — cross-rank copy-back + fix coexi…
sbryngelson Jul 24, 2026
75af093
test(l0-amr): add coexist golden regression tests NP1-G + NP2-MIG
sbryngelson Jul 25, 2026
054b435
inc(l0-amr): skip the L0 tile prefix in s_amr_reconcile_slots (audit …
sbryngelson Jul 25, 2026
d815e1c
inc(l0-amr): fill L0 tile multi-dim ghost cells (diagonal corners / e…
sbryngelson Jul 25, 2026
e123ba7
inc(l0-amr): add computed s_amr_rank_decomp + validate vs amr_decomp …
sbryngelson Jul 25, 2026
0a5d9d5
inc(l0-amr): route decomposition consumers through s_amr_rank_decomp …
sbryngelson Jul 25, 2026
5c6f52c
inc(l0-amr): delete replicated amr_decomp table + its MPI_ALLGATHERs;…
sbryngelson Jul 25, 2026
d2f149e
merge upstream master (combustion reactive-burn #1670) into l0-amr; k…
sbryngelson Jul 26, 2026
6bd7009
fix(l0-amr): guard start_idx(2/3) reads in s_amr_validate_decomp behi…
sbryngelson Jul 26, 2026
618823f
inc(l0-amr): add O(overlap) rank-inversion helpers + transitional cro…
sbryngelson Jul 26, 2026
f12da8a
inc(l0-amr): build ovl lists + reflux participants by O(overlap) inve…
sbryngelson Jul 26, 2026
2ea15ad
Merge commit 'bfdc8f5e' into spike/l0-amr-unify
sbryngelson Jul 26, 2026
451a3f3
inc(l0-amr): delete O(P) ovl scan + reflux rank-loops + cross-checks;…
sbryngelson Jul 26, 2026
1b820e4
inc(l0-amr): add O(num_procs) SFC owner cut-points + f_amr_owner + va…
sbryngelson Jul 26, 2026
1708ffc
fix(l0-amr): scope s_amr_validate_owner to level>=1 blocks (level-0 t…
sbryngelson Jul 27, 2026
f1452f3
inc(l0-amr): convert L0 rebalancer greedy->SFC weighted re-cut + reba…
sbryngelson Jul 27, 2026
559ff53
refactor(l0-amr): extract s_amr_sfc_cut shared by fine + tile owner cuts
sbryngelson Jul 27, 2026
a463c54
inc(l0-amr): SFC compute-owner + cut for L0 tiles (storage owner stay…
sbryngelson Jul 27, 2026
6a20916
inc(l0-amr): add amr_fine_cut so f_amr_owner reproduces fine + tile o…
sbryngelson Jul 27, 2026
c053cdf
inc(l0-amr): routed initial fill + compute-owner slot allocation (uni…
sbryngelson Jul 27, 2026
c3f3add
docs(amr): correct stale slot-memory and output claims, document L0 t…
sbryngelson Jul 27, 2026
26adc58
docs(amr): record the swap topology and why hoisting the restore does…
sbryngelson Jul 27, 2026
ea9440c
inc(amr): split reflux out of the per-block advance loop (batching pr…
sbryngelson Jul 27, 2026
400d0b3
docs(amr): correct the batching prerequisites - the RK pass nests swa…
sbryngelson Jul 27, 2026
4cde6bc
docs(amr): record the AMR strong-scaling baseline (the Track 3 'befor…
sbryngelson Jul 27, 2026
0e552bb
inc(amr): make the grid swap re-entrant (batching prerequisite 2 of 2)
sbryngelson Jul 27, 2026
edec1ec
docs(amr): third batching prerequisite - the IGR sigma bounce is save…
sbryngelson Jul 27, 2026
2bffefd
inc(amr): split the IGR sigma save from the seed (batching prerequisi…
sbryngelson Jul 27, 2026
9188204
docs(amr): mark batching prerequisite 3 resolved and state what remains
sbryngelson Jul 27, 2026
d24c290
docs(amr): record that hoisting the restore was measured and has no e…
sbryngelson Jul 27, 2026
46bef79
docs(amr): measure kernel launch count directly - it is the per-block…
sbryngelson Jul 27, 2026
0c0d823
amr(coexist): split the l0_ntile+amr gate into one clause per unimple…
sbryngelson Jul 27, 2026
c115d54
amr(coexist): make dynamic regrid work with L0 tiles at np=1
sbryngelson Jul 27, 2026
ab87d49
amr(restrict): unpack the cross-rank fold-back on the device, not via…
sbryngelson Jul 28, 2026
108d90e
docs(pitfalls): record that a strided GPU_UPDATE section is silently …
sbryngelson Jul 28, 2026
6aadf6f
amr(coexist): support amr_subcycle with L0 tiles
sbryngelson Jul 28, 2026
e96ca62
amr(coexist): derive the static level-2 box from the parent BLOCK, no…
sbryngelson Jul 28, 2026
6c0c622
amr(coexist): restore to the first FINE block after the multi-level b…
sbryngelson Jul 28, 2026
2e7151f
amr(perf): exchange same-rank seam ghosts in one device kernel
sbryngelson Jul 28, 2026
fc3d1e9
amr(perf): fill a fine block's ghost slabs in one kernel
sbryngelson Jul 28, 2026
00db9cb
amr(perf): fuse the multi-fluid alpha-closure ghost slabs too
sbryngelson Jul 28, 2026
404d97b
amr(perf): fuse the remaining three ghost-slab loops
sbryngelson Jul 28, 2026
1895c0e
amr: make the fine-fine seam halo level-selective
sbryngelson Jul 28, 2026
2734961
amr(subcycle): advance level>=2 siblings transposed, with an L2 seam …
sbryngelson Jul 28, 2026
3db24df
amr(subcycle): tile wide level-2 boxes instead of capping to one child
sbryngelson Jul 29, 2026
741af6f
docs(amr): record the measured multi-block baseline and launch attrib…
sbryngelson Jul 29, 2026
e93f23d
docs(amr): retract the regrid cost claim and attribute it by direct m…
sbryngelson Jul 29, 2026
3a71839
amr: add amr_max_grid_size, a rank-independent fine-block size cap
sbryngelson Jul 29, 2026
7b1e493
amr: separate solver allocation bounds from runtime bounds (idwbuff_a…
sbryngelson Jul 29, 2026
8864d7d
docs(amr): design spec for per-level distribution
sbryngelson Jul 30, 2026
b2afa83
Merge upstream/master into up/mega: adopt stage-independent common re…
sbryngelson Jul 30, 2026
8678224
amr: size the m/n/p-keyed solver scratch to the block cap (idwbuff_al…
sbryngelson Jul 30, 2026
a108dd3
amr: let amr_max_grid_size exceed half a rank subdomain
sbryngelson Jul 30, 2026
6832d29
amr: point-to-point parent<->child gather and restrict for level>=2 b…
sbryngelson Jul 30, 2026
8e2768d
docs(amr): active_box multi-rank is now a declared prohibit, not a si…
sbryngelson Jul 30, 2026
d53fac4
amr: point-to-point multi-level reflux for level>=2 blocks
sbryngelson Jul 30, 2026
26e0d08
amr: advance level>=2 blocks per level, not per parent
sbryngelson Jul 30, 2026
cfdd284
amr: give each level its own rank mapping and drop tower co-location
sbryngelson Jul 31, 2026
1f20aee
docs(amr): formalize load balancing at scale and record the step-4 me…
sbryngelson Jul 31, 2026
e36c10a
docs(amr): the step-4 A/B was run too small above np=2 - reclassify a…
sbryngelson Jul 31, 2026
fc53e09
amr: report per-level load balance (max/mean) when load_weight_wrt is on
sbryngelson Jul 31, 2026
3780f30
amr: fix the balance report and correct three stale subcycle docstrings
sbryngelson Jul 31, 2026
be94db3
amr: halve the level>=2 child slot cap once per level, not a fixed /2
sbryngelson Jul 31, 2026
8dca4b6
amr: allow multi-level subcycle with dynamic regrid at num_procs > 1
sbryngelson Jul 31, 2026
3ab65ab
docs(amr): a no-block rank count is not an idleness measurement
sbryngelson Jul 31, 2026
3384911
amr: drop the orphaned seam-halo comment from the checker
sbryngelson Jul 31, 2026
1e07eb6
amr: record the level-3 slot-cap counterfactual at the cap site
sbryngelson Jul 31, 2026
a8b1b7b
amr(bench): add hardcoded IC 299, scattered blobs for load-balance be…
sbryngelson Jul 31, 2026
cfbaceb
amr: tile the brand-new-region child to the slot cap (fixes heap corr…
sbryngelson Jul 31, 2026
d99cbd0
test(amr): cover amr_max_grid_size at multi-level np=2 (golden 00EB793A)
sbryngelson Jul 31, 2026
526f2dc
amr: assert the box/slot-cap invariant, and report box-count imbalance
sbryngelson Jul 31, 2026
c3c674c
Docs: exclude stackoverflow.com from lychee link check (403 to bots)
sbryngelson Jul 31, 2026
2051aa1
amr: make the SFC cut boundary robust to floating-point ties
sbryngelson Jul 31, 2026
c3364a5
amr: keep uninitialized tile-prefix slots out of the fine-level SFC cut
sbryngelson Aug 1, 2026
0e3418e
amr: drop the unused K_box constant
sbryngelson Aug 1, 2026
b1fc067
docs(amr): record the measured cost-model result and requeue the open…
sbryngelson Aug 1, 2026
2a3e453
docs(amr): the scaling ceiling is MFC's, not AMR's - revise the queue…
sbryngelson Aug 1, 2026
d71b9fc
Merge branch 'master' into up/mega
sbryngelson Aug 1, 2026
cfbcead
docs(amr): write down the real exascale blocker - regrid cost scales …
sbryngelson Aug 1, 2026
7636c76
docs(amr): reorganise - blocker first, retract three superseded measu…
sbryngelson Aug 1, 2026
3f75489
amr: one collective per regrid instead of one per box
sbryngelson Aug 1, 2026
83bf457
amr: O(n log n) merge sort for the SFC cut instead of insertion sort
sbryngelson Aug 1, 2026
2f8e51c
docs: record limit 2 (SFC cut sort) as fixed in the AMR scaling plan
sbryngelson Aug 1, 2026
a500b68
amr: golden coverage for amr_max_level = 3, and print fine_work in th…
sbryngelson Aug 1, 2026
27133f1
docs: AMR costs ~31x uniform per cell, and the overhead is per-block
sbryngelson Aug 1, 2026
4ffb3a3
docs: repeat the block-size sweep; time and work move in opposite dir…
sbryngelson Aug 1, 2026
7107697
docs: the packed super-grid is disproved - tiled blocks are already s…
sbryngelson Aug 1, 2026
214a682
docs: AMR box set is rank-invariant; the 2D benchmark case is not
sbryngelson Aug 1, 2026
dec226e
docs: the AMR scaling limiter is cross-rank block adjacency, not per-…
sbryngelson Aug 1, 2026
ea849f7
docs: correct the limiter - AMR overhead does not distribute, it is n…
sbryngelson Aug 1, 2026
df5a612
docs: profiling says the cost is host time and device copies, not ker…
sbryngelson Aug 1, 2026
313dcbc
docs: root cause is s_compute_rhs fixed per-invocation cost, dominate…
sbryngelson Aug 2, 2026
108268c
docs: confirm the per-call copies are sys_size-scaled descriptor traffic
sbryngelson Aug 2, 2026
d212792
docs: pin the per-call copies to metadata by volume and distribution …
sbryngelson Aug 2, 2026
bcab519
amr: hoist the loop-invariant coarse halo exchange out of the per-blo…
sbryngelson Aug 2, 2026
c1f64d8
docs: measured AMR configuration guidance - parameters are worth ~6.9x
sbryngelson Aug 2, 2026
4b784a4
docs: parameters measure 7.0x combined; per-phase imbalance is the la…
sbryngelson Aug 2, 2026
bf7f1c6
amr: raise amr_max_blocks default to 1024 and add runtime configurati…
sbryngelson Aug 3, 2026
cc6cc5d
amr: reject SFC re-cuts that worsen the load gap; record that coarse …
sbryngelson Aug 3, 2026
bca7d41
docs: the AMR per-block tax is dummy-argument mapping, and why conver…
sbryngelson Aug 3, 2026
6122cbd
docs: plan to promote the RHS working set from dummy arguments to mod…
sbryngelson Aug 3, 2026
851055f
docs: MWE results for the promotion design - correctness de-risked 5/…
sbryngelson Aug 3, 2026
ae46193
docs: retract the promotion plan - per-region map cost is irreducible…
sbryngelson Aug 3, 2026
8a7e337
docs: profiled governing law - wall time is set by GPU operation coun…
sbryngelson Aug 3, 2026
c8066bd
docs: the law is two-dimensional - work per kernel decides the regime…
sbryngelson Aug 3, 2026
b423ed9
docs: the latency-bound regime persists at 60% of GCD memory - it is …
sbryngelson Aug 3, 2026
c7cd92d
docs: how AMReX and Parthenon solve this, measured here at 12.4x, and…
sbryngelson Aug 3, 2026
905e9d7
amr: add a dense local index for live slots
sbryngelson Aug 3, 2026
d9a7c28
docs: record the step-1b scoping constraint found by attempting it
sbryngelson Aug 3, 2026
58c8fad
docs: execution plan for the flat store and batched kernels
sbryngelson Aug 3, 2026
cacc14e
amr: add the flat per-block field store and its reserve/finalize
sbryngelson Aug 3, 2026
ac69f41
docs: measured split - AMR-local kernels are a third of launches, and…
sbryngelson Aug 3, 2026
bbf8ec8
amr: migrate the subcycle ghost sources to the flat store
sbryngelson Aug 3, 2026
181e222
docs: fork 1 chosen, 2a landed, and the true scope and payoff of 2b
sbryngelson Aug 3, 2026
5909833
amr: make the flat store authoritative for q_cons, behind a copy bridge
sbryngelson Aug 4, 2026
fc7d2c2
docs: 2b landed - the store-growth hazard it created, and the polymor…
sbryngelson Aug 4, 2026
e7b52f6
amr: batch the same-rank seam exchange into one kernel over all pairs
sbryngelson Aug 4, 2026
c50cbd0
docs: concurrency disproved (0.0% overlap), fusion measured - wall is…
sbryngelson Aug 4, 2026
3c24a54
docs: production-size 3D results - cap exhausted, balance is state of…
sbryngelson Aug 4, 2026
98941d9
docs: proper 3D profile - the 9.1x AMR penalty is 1.38x arithmetic an…
sbryngelson Aug 4, 2026
d80b5a5
riemann: fuse the finalize reshape kernels, 6 regions per block-stage…
sbryngelson Aug 4, 2026
ecd83d4
docs: retract the weno+riemann fusion - at realistic size it is a net…
sbryngelson Aug 4, 2026
ee11a4d
sim: per-phase wall budget for the AMR step, gated on rank_time_wrt
sbryngelson Aug 4, 2026
e64b0bc
docs: AMReX head-to-head - kernel count is not the problem, 19.75 cop…
sbryngelson Aug 4, 2026
a3f76b4
amr: move q_cons_stor into the flat store, deleting its scalar_field …
sbryngelson Aug 4, 2026
724ef4f
riemann: delete flux_n and flux_gsrc_n, reading the flat Riemann buff…
sbryngelson Aug 5, 2026
7e014f2
riemann/amr: delete flux_src_n and size the remaining buffers to what…
sbryngelson Aug 6, 2026
107695d
amr: non-blocking sends in the per-box coarse-patch gather
sbryngelson Aug 6, 2026
b68c727
docs: AMR profiling results - rhs is 82.6% of wall, regrid is 1.9%
sbryngelson Aug 10, 2026
b5fb48b
docs: the per-launch cost is mapped ENTITIES, not launches or bytes
sbryngelson Aug 13, 2026
ab11150
simulation: map(alloc:) the private arrays in hllc and weno (-26.4% o…
sbryngelson Aug 13, 2026
9cca350
docs: AMR action plan - at matched block size the AMReX excess is 2.0…
sbryngelson Aug 15, 2026
fe4d2f2
docs: mark the break-even conclusions provisional - two cap pairs dis…
sbryngelson Aug 15, 2026
d3fe912
docs: cost model rejected - a depends on block size, break-even numbe…
sbryngelson Aug 15, 2026
78a2504
docs: measured a and b directly - cap64 is 2.32x, a depends on block …
sbryngelson Aug 15, 2026
b185c90
docs: four-cap clean measurement - a falls to the uniform arm's, b is…
sbryngelson Aug 16, 2026
251904a
docs: remove self-contradiction - the 31% disproof and 2.74x were alr…
sbryngelson Aug 16, 2026
022abc5
docs: correct the last stale 2.74x in the metric-discipline section
sbryngelson Aug 16, 2026
cfb7bf3
docs: MPI is the symptom - per-rank work skew 33.7% mirrors MPI time,…
sbryngelson Aug 16, 2026
9e18365
docs: rocprof-sys-causal cannot profile MFC - rejects .text FUNCs, ac…
sbryngelson Aug 16, 2026
ae2b172
docs: oracle load-balance ceiling is 5.1% of wall - rebalancing close…
sbryngelson Aug 16, 2026
322603d
Bracket the regrid gather, the per-block swap, and the level-2 parent…
sbryngelson Aug 19, 2026
d696b8c
Make the level-2 parent gather send non-blocking (-17 to -22% wall)
sbryngelson Aug 19, 2026
cc59ad3
docs: rewrite the AMR action plan around the G0 gate results
sbryngelson Aug 19, 2026
45e7212
Bound AMR store growth and compact it after regrid
sbryngelson Aug 20, 2026
7cd6400
Add per-rank phase reporting and finer AMR phase brackets
sbryngelson Aug 20, 2026
d519af9
Document the AMR implementation and the store investigation
sbryngelson Aug 20, 2026
2358c88
Post reflux face receives non-blocking
sbryngelson Aug 21, 2026
7366613
Instrument AMR exchange volumes and split the regrid migration phases
sbryngelson Aug 21, 2026
96e7496
Design the plan-based exchange (T1/S4) and record the T0 closure evid…
sbryngelson Aug 21, 2026
fb11b1b
Revise the plan-based exchange design from four independent audits
sbryngelson Aug 21, 2026
af5ab6e
Re-found the AMR program from the end-state architecture
sbryngelson Aug 21, 2026
3f06825
Record the full-commitment and node-scarcity decisions; add the plann…
sbryngelson Aug 21, 2026
ca360af
Push the received migration stash to device before any mid-rebuild st…
sbryngelson Aug 21, 2026
24a00ae
Land I0 of the plan-based exchange: mesh epoch, tag bases, invariants…
sbryngelson Aug 21, 2026
b08e37f
Add the suite's first np=4 golden: churn-growth blast at ppn=4
sbryngelson Aug 21, 2026
8bd2fc7
Record the verified call-site inventory and the S0 np=4 diagnosis
sbryngelson Aug 21, 2026
a00ee80
Record the S0 v2 weak-scaling table and the W8 device-memory invariant
sbryngelson Aug 21, 2026
0a38a54
Attribute W8: the store-capacity ratchet over global slot indices
sbryngelson Aug 21, 2026
9bcc986
Fix W8: per-rank device memory now tracks the live box set (S0 np=4 c…
sbryngelson Aug 21, 2026
7ca673a
Document the W8 arc: measured facts, the refuted design, and what it …
sbryngelson Aug 21, 2026
86aab06
Write the Phase 1 attack plan with the measured 2.59x split and pre-r…
sbryngelson Aug 21, 2026
c97f5f5
I1a: per-call-site exchange audit across all seven AMR p2p families p…
sbryngelson Aug 22, 2026
e89ff36
Record the M4 verdicts: hardware inert, the straggler is rank-attache…
sbryngelson Aug 22, 2026
c9a98f3
Ledger: mechanism proven, np=8 needs pooling, P1 increment redesigned…
sbryngelson Aug 22, 2026
f722d58
Close the allocator config decision: threshold=0 is the standing defa…
sbryngelson Aug 22, 2026
cc40cd3
Point the P1 redesign at the durable lifetime-audit file
sbryngelson Aug 22, 2026
f5f9933
Pool fine-block q_prim/rhs into one shared advance scratch (P1)
sbryngelson Aug 22, 2026
718d16f
Ledger + constitution: P1 gate results (np=8 first completion, W8 hol…
sbryngelson Aug 22, 2026
190647c
Gather-batching design: S0 np=8 reverses the level-1/level-2 priority…
sbryngelson Aug 22, 2026
3a6f592
Derive the rebuild gather message set up front and assert the per-box…
sbryngelson Aug 22, 2026
a7a0d63
Gather-batching step-2 design: chunked pre-posted exchange, both fami…
sbryngelson Aug 22, 2026
1056e5c
Step-2 design review: fatal same-chunk parent-pack defect found by bo…
sbryngelson Aug 22, 2026
01cc431
Chunk the rebuild gather: pre-posted recvs, plan-driven sends, one wa…
sbryngelson Aug 22, 2026
3de4724
Arm the parent send-size assert on the chunked gather path
sbryngelson Aug 22, 2026
2505d9c
Record the step-2 verdict and the expert-audit re-aim in the AMR ledgers
sbryngelson Aug 22, 2026
7d8cc4a
Add hcid 306: the AMR benchmark blob as a hardcoded IC
sbryngelson Aug 22, 2026
7b7ae5c
Add the [amr-cov] dead-word counters for the gather families
sbryngelson Aug 22, 2026
47460b3
Record the [amr-cov] verdict: clipping promoted ahead of T1
sbryngelson Aug 22, 2026
81bea2e
Close G-B: the AMReX S0 weak-scaling bar is 1.20x/1.15x per np-doubling
sbryngelson Aug 22, 2026
93e5a7d
Ring-clip design for the runtime fill gathers, adversarially reviewed…
sbryngelson Aug 22, 2026
e53db27
Close ring-clip finding F5 by evidence: boundary patches are unreachable
sbryngelson Aug 22, 2026
dc6d412
Ring-clip the runtime fill gathers to the hollow shell
sbryngelson Aug 22, 2026
bd85c79
Stage ring-clip slab metadata through a device-resident buffer
sbryngelson Aug 22, 2026
a797074
Use full-column pool slices in the clipped packs
sbryngelson Aug 22, 2026
dcb1995
Ledger: ring clip landed and bit-correct, wall regression open
sbryngelson Aug 23, 2026
43ba113
Revert the ring clip: amdflang whole-image codegen regression
sbryngelson Aug 23, 2026
873cce6
Add the regrid-cadence containment audit ([amr-cad])
sbryngelson Aug 23, 2026
58c0b61
Right-size the migration pack pools and request array (T1/I4a)
sbryngelson Aug 23, 2026
de12b8d
Split rg:move with mg:slot/pack/unpk/push brackets (I4b pricing)
sbryngelson Aug 23, 2026
180cdf1
Pre-reserve the migration wave's stash slots in one exact-target grow…
sbryngelson Aug 23, 2026
c7de5b6
Ledger: I4b priced (growth, not pack), I4b-a landed, I4b-b deferred b…
sbryngelson Aug 23, 2026
0b36c14
Cadence move validated (int=20, -41% wall); ladder 1.392x/1.993x; rea…
sbryngelson Aug 23, 2026
b554aa2
Ledger: T1 re-priced at int=20 (I2 first); I1b-gather implementation …
sbryngelson Aug 23, 2026
e531d35
Add per-xfer identity headers to the gather trio (T1/I1b-gather)
sbryngelson Aug 23, 2026
bdb00d5
Convert the level-1 stage fill to plan-based waves (T1/I2a)
sbryngelson Aug 23, 2026
cdf78c1
Convert level>=2 parent gathers to per-level F2 waves (T1/I3)
sbryngelson Aug 24, 2026
5537999
Convert the seam-halo cross-rank pairs to per-peer waves (T1/I5-F6)
sbryngelson Aug 24, 2026
37a4d9b
Convert the reflux-face and freg exchanges to single waves (T1/I5-F5)
sbryngelson Aug 24, 2026
083c782
Ledger: the post-wave measurement (np8 -17.7 pct, top rung 1.99x -> 1…
sbryngelson Aug 24, 2026
5ac7b6f
Batch the reflux apply: one kernel per face direction over all level-…
sbryngelson Aug 24, 2026
62bf3e1
Move the regrid stash chain device-side (stash copy, migration pack/u…
sbryngelson Aug 24, 2026
a1ea597
Move the prolongation kernels device-side; delete the per-box slot pu…
sbryngelson Aug 24, 2026
eeee912
Grow the flat store device-natively (no PCIe round trip)
sbryngelson Aug 25, 2026
3c3bbc5
Instrument the stage-fill wave: gw:plan/gw:pack/gw:wait sub-brackets
sbryngelson Aug 25, 2026
c738918
Fix three review findings: IB merge separation, bounded grow transien…
sbryngelson Aug 25, 2026
34296de
Re-land the stepfill ring clip on the wave plan walks (F1 wire -61 pct)
sbryngelson Aug 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .claude/rules/common-pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,37 @@ covered in `docs/documentation/contributing.md`.
`contxb`/`momxb` shorthands are gone. Index positions depend on `model_eqns` and
enabled features — changing either moves ALL indices; never hard-code one.

## AMR levels (silent-index traps)

- **A level-`l` block's fine extent is `amr_ref_ratio**l * (coarse-region width) - 1`, NOT
`amr_ref_ratio*width`.** The `amr_ref_ratio*width` form is correct only for the level-1 initial
block; nested boxes compound by `amr_ref_ratio` per level (`amr_ref_ratio**level`). Every
fine-extent computation uses `amr_ref_ratio**amr_block_level` — geometry
(`s_set_amr_fine_geometry`), the restart-reader extent check, load-weight, `fmul`.
Assuming `amr_ref_ratio*width` rejects level≥2 blocks as corrupt (the exact bug that bit the
multi-level restart reader).
- **"coarse" in the AMR coupling routines means the block's PARENT level (`l-1`), not the
base grid (level 0).** For a level-1 block the parent IS L0; for level≥2 the block folds
to/from its parent block's fine array. `s_amr_gather_coarse_patch`,
`s_interpolate_coarse_to_fine`, and the restrict/reflux path all operate in the
parent-fine frame — assuming L0 silently corrupts level≥2 coupling.
- **The fine advance SWAPS the coarse grid globals (`m/n/p`, `idwint/idwbuff`, coords,
`acoustic_source`, `ab_active`) to a fine block and restores them after — see the SWAP
CONTRACT block at the `sw_*` declarations in `m_amr.fpp`.** Any module-level variable
DERIVED from the grid that a kernel reads during the fine advance must be swapped there or
refreshed per fine call at its use site; if it is `GPU_DECLARE`'d, its DEVICE copy must be
refreshed too. A stale device copy of coarse bounds reads out of range on the fine grid
under **CCE OpenACC only** (NVHPC/CCE-omp evaluate bounds host-side) — this was the `ab_int`
regression, fixed by an unconditional `GPU_UPDATE` in `s_compute_rhs`. `amr_rvw` (cyl_coord
radius weights) is the next candidate, currently safe only via a `m_checker.fpp` gate.
A CPU-only or NVHPC-acc pass proves NOTHING here; this class is CCE-acc-specific.

## GPU

- NEVER put a `GPU_PARALLEL_LOOP` inside a Fortran `block` construct: amdflang compiles
it clean but silently DROPS the region from the device image — the first launch dies
with `HSA_STATUS_ERROR_INVALID_SYMBOL_NAME` naming an `__omp_offloading_*` symbol.
Hoist the kernel into its own module subroutine.
- WARNING: do NOT wrap `GPU_LOOP` in `GPU_PARALLEL` for spatial loops — `GPU_LOOP` emits
empty directives on Cray and AMD, causing silent serial execution. Spatial loops always
use `GPU_PARALLEL_LOOP`/`END_GPU_PARALLEL_LOOP`. Macro API:
Expand All @@ -36,6 +65,15 @@ covered in `docs/documentation/contributing.md`.
- `@:ACC_SETUP_VFs(...)`/`@:ACC_SETUP_SFs(...)` GPU pointer setup compiles only under
Cray. Around MPI: `GPU_UPDATE(host=...)` before send, `GPU_UPDATE(device=...)` after
receive.
- **Never `GPU_UPDATE` a NON-CONTIGUOUS array section.** `GPU_UPDATE(device='[q%sf(a:b,
c:d, e:f)]')` on a sub-box emits correct OpenMP, but AMD flang copies it as
`size(section)` CONTIGUOUS elements starting at the first: only the leading run lands
where it is named and the rest overwrites neighbouring cells with stale data — no error,
no warning. A leading section (`arr(1:n)`, or a fixed trailing index like
`freg(d)%lo(:,:,:,k)`) IS contiguous and safe; anything that strides is not. To move a
sub-box, pack/unpack it with a device kernel (`s_l0_pack_unpack_block`,
`s_amr_restrict_pack_device`) — that is why those exist. Measured: 10 of 60 covered
cells delivered in the AMR cross-rank restrict, mass off 1.4e-5 per regrid.

## Parameters

Expand Down
3 changes: 3 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ TKE = "TKE"
HSA = "HSA"
infp = "infp"
Sur = "Sur"
thi = "thi" # AMR clustering local: tagged-box hi index (tlo/thi)
alo = "alo" # AMR clustering local: accepted-box lo array (alo/ahi)
thr = "thr" # AMR clustering local: min-separation merge threshold
equil = "equil" # abbreviation for "equilibrium" (flamelet chemistry)
chioces = "chioces" # typo for "choices" - tests constraint key validation
reqires = "reqires" # typo for "requires" - tests dependency key validation
Expand Down
371 changes: 371 additions & 0 deletions docs/documentation/amr.md

Large diffs are not rendered by default.

1,736 changes: 1,736 additions & 0 deletions docs/documentation/amr_action_plan.md

Large diffs are not rendered by default.

2,169 changes: 2,169 additions & 0 deletions docs/documentation/amr_block_batching.md

Large diffs are not rendered by default.

252 changes: 252 additions & 0 deletions docs/documentation/amr_endstate.md

Large diffs are not rendered by default.

172 changes: 172 additions & 0 deletions docs/documentation/amr_fine_distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
@page amr_fine_distribution AMR fine-level distribution

# AMR fine-level distribution (design note)

> **Design record / implementation note.** This documents the internal design and development of AMR
> fine-block distribution across MPI ranks. For user-facing behavior and parameters, see @ref amr.

## Problem

MFC's AMR uses a **mirror decomposition**: the fine level reuses the coarse rank
decomposition, so each rank owns exactly the fine cells over its coarse subdomain's
intersection with the blocks (`s_amr_compute_isect` → `amr_rank_owns_block`). This makes
coarse↔fine coupling entirely rank-local (zero communication) but leaves fine work
**unbalanced**: if refinement concentrates in a sub-region, only the ranks owning that
region do the fine advance while the rest idle. At scale this caps AMR speedup.

## Target

Give the fine level its **own distribution**, decoupled from the coarse decomposition, so
fine blocks spread across all ranks by measured work — the AMReX per-level
`DistributionMapping` idea. MFC already enforces an invariant that makes this far simpler
than the general case: **blocks are kept ≥ `buff_size` apart** (regrid merge), so with
**whole-block-per-rank** assignment there is *no fine–fine halo at all*
(`s_mpi_sendrecv_amr_fine_halo` disappears). The only coupling that becomes communication
is coarse↔fine, block-granular.

## Coupling changes (whole-block-per-rank)

| Step | Today (mirror, local) | Decoupled |
|---|---|---|
| Ownership | intersection, multi-owner (`amr_rank_owns_block`) | single owner (`amr_block_owner(k) == proc_rank`) |
| Ghost fill / prolong (coarse→fine) | read local coarse `q_cons` | **gather** coarse patch (block + `buff_size` halo) from coarse owner(s) to block owner |
| Reflux + restriction (fine→coarse) | write local coarse cells | **scatter** corrections from block owner back to coarse owner(s) |
| Fine–fine halo | coarse Cartesian neighbors | none (blocks separated) |
| Regrid | cluster (global) → mirror | cluster → **assign** (`amr_block_owner`) → **migrate** fine state |

The gather/scatter is the only new communication surface. SFC-ordered assignment keeps a
block's coarse patch on an SFC-nearby rank, bounding the cost. Conservation exactness is
preserved because the scatter applies the *same* reflux add / restrict overwrite the
mirror model applied locally — a pure data-movement change, not a numerics change.

## Reuse

`m_load_weight` (per-cell cost field) and `m_sfc_partition` (Morton order + chains-on-chains
balanced partition) already exist as an init-time diagnostic. They become the fine-level
distributor: feed the block list + per-block fine-work weight, return `amr_block_owner(:)`.

## Phasing (each independently mergeable)

1. **Distribution map, computed but not applied** (behavior-preserving). Add
`amr_block_owner(:)` + SFC assignment + an imbalance diagnostic; mirror ownership and all
coupling unchanged. Goldens bit-identical. *(this note's first increment)*
2. **Apply the map**: switch `amr_rank_owns_block` to single-owner, add the coarse↔fine
gather/scatter, drop the fine–fine halo. Validate conservation + assignment-independence.
3. **Dynamic rebalance each regrid**; optionally drop the fixed max-size slot pool for
right-sized boxes.

Phase 2 carries the correctness risk (gather/scatter exactness) and is the checkpoint gate.

## Phase 2 implementation status (branch `amr-fine-dist-wip`)

Done and np=1 bit-identical (the gather reduces to the local read when the owner is the sole rank):

- **Gather** (`s_amr_gather_coarse_patch`): per-block coarse patch `[region_lo-nmar : region_hi+nmar]`
assembled by a sentinel-MAX allreduce into `amr_cg` (a drop-in `scalar_field`). Contribution rule
`f_amr_own_coarse` claims interior cells + physical-boundary ghosts only (never inter-rank ghosts), so
there is one authoritative contributor per cell and no coarse-ghost halo dependence. `pull_host` flag
stages device-resident coarse to host for the runtime callers.
- **Read side rerouted**: init/regrid host prolongation (`s_interpolate_coarse_to_fine`) and the runtime
device ghost-fill (`s_amr_fill_fine_ghosts`, stage + subcycle) now prolong from `amr_cg`.
- **Restriction scatter** (`s_restrict_fine_to_coarse`): owner restricts on host into the `amr_cg_wp`
scratch (sole contributor), sentinel-MAX assembles, each rank overwrites the covered coarse cells it
owns. `s_restrict_all_vars` (old local device kernel) deleted.
- **Fine–fine halo dropped**: `s_mpi_sendrecv_amr_fine_halo` calls removed (whole-block owner has no
continuation faces; blocks ≥ buff_size apart). Routine in `m_mpi_proxy` now dead — remove with the
reflux rework.

Remaining (the conservation crux — reflux is NOT yet decoupling-correct):

- **Reflux redesign.** `s_amr_reflux_face_flags` derives transverse participation `tv` from `amr_isect`,
which is owner-only in the decoupled model, so `own_lo/own_hi` (gating BOTH `creg` capture and the
reflux apply) is true only on the block owner — which does not own the outside coarse cells. Fix:
(1) recompute `tv` from the replicated block range (`amr_region_lo/hi(t)` overlap with `sidx:sidx+ext`),
so any coarse-outside-owner participates; (2) the owner captures `freg` (already correct) and BROADCASTS
it (allreduce, replacing the cart-neighbor `s_mpi_sendrecv_amr_reflux_faces`); (3) coarse-outside-owners
capture `creg` locally and apply `(freg-creg)` to their owned outside cells — verify the apply's
block-relative transverse indexing maps onto each receiver's local coarse slice. Conservation-critical.
- **QBMM pb/mv** gather/scatter for np≥2 (currently local; non-polytropic QBMM+AMR now **gated fail-closed** at np≥2 in
`m_checker` — see "Known open" for the scatter follow-up).
- np=2 conservation + assignment-independence validation once reflux lands (acceptance goldens:
BD21A5C0, 5EFB3277, 79B334C7 — they pass on `up/mega` via the mirror).

## Phase 2 status: DONE and validated (reflux + scalability)

The reflux redesign above landed (block-relative frame, participation from the replicated block range), and the
whole coupling is now **point-to-point + right-sized** — the fine level distributes with no global collective per
stage and per-rank memory that scales with the decomposition.

- **Reflux**: `s_amr_reflux_face_flags` derives `tv`/`tlo`/`thi` from the replicated block range; `creg` capture +
both applies index block-relative; the owner's `freg` is delivered to the applying coarse-outside-owners.
- **Point-to-point coupling** (replaced the correctness-first global collectives): a replicated coarse-decomposition
table `amr_decomp` (allgathered once at init) lets any rank compute which ranks hold a coarse-cell range.
- gather: owner `Irecv`s patch slices from the coarse-owners (`f_amr_rank_coarse_range`).
- restriction: owner `Isend`s each coarse-owner its covered slice (`f_amr_rank_interior`).
- reflux: owner `Isend`s `freg` only to participants (`f_amr_reflux_participates` = `own_lo/hi` parameterized by
rank via `amr_decomp`); `s_amr_p2p_reflux_faces` in `m_amr`.
Non-participants exchange nothing.
- **Right-sized memory**: fine/coord/register arrays sized to `amr_maxc_fit` (min-over-ranks local half-extent = the
max block a rank can own, enforced by the scratch-constraint abort), not the global half-domain `amr_maxc` — about
`1/num_procs` (and `1/num_procs^(d-1)` for the face registers) the memory at scale.
- **Coordinate fix**: `s_amr_swap_to_fine` extends fine ghost coords from the global boundaries `amr_g?cb` (the owner
need not hold the block's local coarse coord slice).

Validated: np=1 1D/2D/3D goldens bit-identical; np=2 conservation exact in 1D (energy 1.9e-16) and 2D with
transverse-face appliers (mass 1.4e-14), bounds-clean. `s_mpi_allreduce_array_max` remains only for the
once-at-init coordinate assembly.

## Phase 3

1. **Block-splitting / tiling** (the coverage gap) — DONE.
- **Tiling**: `s_amr_tile_box` splits any box > `amr_maxc_fit` into contiguous ≤`amr_maxc_fit` sub-blocks, wired into
the initial-block setup and the regrid pipeline (non-IB); `s_populate_amr_fine` loops over all blocks refreshing
per-block mirrors via `s_amr_select_slot`.
- **Block-to-block fine-fine halo**: the fine advance is three driver phases — **fill all** (gather + coarse
ghost-fill), **`s_amr_fine_fine_halo`** (overwrite each seam ghost with the neighbour's *stage-entry* interior,
buff_size-deep, `MPI_Sendrecv` between owners or a local copy when one rank owns both; adjacency from the
replicated `amr_region_*_all` via `f_amr_seam`), **advance all** (RHS + RK). `s_advance_amr_fine_stage` split into
`s_amr_fine_stage_fill` / `s_amr_fine_stage_advance`.
- **Reflux seam-exclusion**: `f_amr_face_is_seam` drops a sub-block face shared with another fine sub-block from
`s_amr_reflux_face_flags` `own_lo/own_hi` (fine-fine, not c/f).
- **Owner-ordering fix**: `s_amr_assign_block_owners` runs BEFORE the owner-dependent `s_set_amr_fine_geometry` in
init, regrid, AND restart — the stale default (rank-0) owner map otherwise sized multi-block owners wrong (only
surfaces once tiling makes several blocks). Restart (`s_read_amr_restart`) is a two-pass read (regions → assign →
place data) for both the parallel_io and non-parallel_io paths.
2. **Regrid cross-rank fine-state migration** — DONE (the stretched-np≥2 correctness fix). The regrid overlap-copy
preserves a covering old block's fine detail by reading `amr_slots(kk)%%q_cons_stor`, but that was local-only
(`if (.not. old_owns(kk)) cycle`). Under fine-level distribution an old block can be owned by a rank *other* than the
one now owning a covering new block, so the copy was silently skipped and the new block kept only its
coarse-prolonged values — **exact on uniform grids** (prolongation reproduces the fine field) but **~O(1e-4) wrong on
stretched grids** (prolongation is not exact). Fix: broadcast every old block's stashed fine state from its owner
into the replicated slot's `q_cons_stor` on all ranks (`num_procs>1`; no-op at np=1), copy the overlap from *every*
covering old block regardless of ownership, and take `old_ilo`/`old_ext` from the global replicated region (not the
owner-only isect). Correctness-first collective; a per-block P2P version mirroring `s_amr_gather_coarse_patch` is
future work. Validated (`-b mpirun`): 79B334C7 (1D stretched dynamic-regrid, 2 ranks) passes; F0DDE1B4 (np=1 twin),
5EFB3277 + BD21A5C0 (uniform np=2 tiled + restart), and the np=1 AMR batch all pass.

## Golden regeneration note (tiling refines more at np=1)

At np=1, tiling adds a capability the mirror never had: refining a tagged region **larger than `amr_maxc`** (half the
domain per dim). The old regrid **clamped** any box to `amr_maxc_fit` (`hi = lo + amr_maxc_fit - 1`), so a big tag was
only partially refined; block-splitting **tiles** it and refines the whole tag. Any np=1 AMR golden whose tag exceeds
`amr_maxc(dim)` therefore changes (more cells refined) and must be regenerated with the tiled binary — an *intended*
solution change, not a regression (the tiled advance is bit-identical to the mirror where footprints match, conservation
is exact, and the seam is exact). Example: **B7704247** (2D stretched-y regrid) — the mirror refined `y4:23` (20 cells,
clamped); tiling refines the full `y4:35` (`y4:19` + `y20:35`). Golden regenerated. np≥2 goldens are unaffected: the
mirror splits a block across ranks there, so its footprint already matches tiling.

## Known open

- **QBMM pb/mv** gather/scatter for np≥2 — the pb/mv side-state coarse↔fine coupling (`s_amr_prolong_pbmv` /
`s_restrict_pbmv`) and the regrid QBMM overlap-copy are still LOCAL-only (same bug class as the q_cons migration
above). Now **gated fail-closed**: `m_checker` PROHIBITs `qbmm .and. .not. polytropic .and. num_procs > 1` for `amr`,
so np≥2 non-polytropic QBMM+AMR aborts at case load instead of silently coupling to the wrong coarse side-state.
Distributing pb/mv (gather/scatter/migration, mirroring q_cons) is future work for when np≥2 QBMM+AMR is needed and
testable. Polytropic QBMM+AMR at np≥2 is unaffected (its moments ride q_cons, which is already distributed).
- **`amr_g?cb` lacks physical-boundary ghost coords** (sized `-1:m_glb`; the base grid's `x/y/z_cb` carry BC-aware ghosts
via `s_populate_grid_variables_buffers`). A near-domain-edge **whole** (untiled) block can drive the fine ghost-coord
build out of `amr_gycb` bounds — surfaced only by artificially disabling tiling; tiled blocks stay in bounds. Fix if
untiled near-edge whole blocks ever become reachable.
- Minor: the P2P routines scan all `num_procs` to find participants (integer-only, O(P) per block per stage); the regrid
migration broadcasts (correctness-first, → P2P); patch-only device transfers instead of whole-field host round-trips
(GPU only); own-only slot allocation.
Loading