Problem
When using FMG with the default redundant coarse solver (pc_type=redundant + pc_factor_mat_solver_type=lu), the coarse-grid LU factorization is replicated on every MPI rank. For models with large base meshes (e.g., 10 km cells, 800x230 km domain), the coarsest level still has ~14k velocity DOFs, causing:
- ~300 MB/rank replicated memory from the coarse LU factorization (fill ratio 5.16× on 14k DOFs)
- Total ~9 GB equivalent replicated across 30 ranks
- OOM kills at 900 MB/rank cap on Setonix/Pawsey
Root Cause
The multigrid_options.py default geometric_mg_bundle() sets mg_coarse_pc_type=redundant (see multigrid_options.py:262). This is documented as "(small) coarse system" but fails when base mesh resolution is high.
Related: PR #213 (_use_iterative_solver) already avoids MUMPS in parallel for the same reason, using redundant+svd instead — but svd is infeasible at this scale (dense 14k×14k).
Solution Found
Using a finer base mesh with more refinement levels keeps the finest grid identical while shrinking the coarsest level:
# Original (OOM)
-uw_csize_km 10 -uw_refinement 2 # 14k coarse DOFs → ~300 MB/rank replicated
# Fixed (fits in 900 MB/rank cap)
-uw_csize_km 20 -uw_refinement 3 # ~1.9k coarse DOFs → divided / minimal replication
| Config |
Coarsest vDOFs |
Linear solve time (serial) |
Peak RSS/rank (np=30) |
csize10 ref2 |
14,195 |
~100 s |
683 MB ❌ OOM at 900 MB cap |
csize20 ref3 |
~1,900 |
111 s (+11%) |
416 MB ✅ |
- Finest grid essentially unchanged (233k vs 227k velocity DOFs)
- Trade-off: +11 % linear-solve time buys −39 % per-rank peak RSS
- Causal check: shrinking only the coarsest level removed 261 MB/rank, matching the redundant gather + LU-fill arithmetic (~45 MB gathered copy + 232 MB factor ≈ 280 MB)
Proposed Fix Options
- Size-aware default in
multigrid_options.py (preferred):
- Document the workaround: publish the
coarser-base + extra-refinement recipe and warn on large-coarse redundant
- Expose the threshold as a solver option for user control
Related
Verification
Setonix (Pawsey), production-geometry model, np=30, per-rank RSS sampled every 2 s:
- Control (
csize10 ref2): post-solve 683 MB/rank uniform across all 30 ranks (spread 13 MB) → step killed at the 900 MB/task cgroup cap
- Treatment (
csize20 ref3): post-solve 398–427 MB/rank (median 416), window max 576 MB, clean completion
- Convergence identical between arms (same SNES iteration sequence)
Problem
When using FMG with the default
redundantcoarse solver (pc_type=redundant+pc_factor_mat_solver_type=lu), the coarse-grid LU factorization is replicated on every MPI rank. For models with large base meshes (e.g., 10 km cells, 800x230 km domain), the coarsest level still has ~14k velocity DOFs, causing:Root Cause
The
multigrid_options.pydefaultgeometric_mg_bundle()setsmg_coarse_pc_type=redundant(seemultigrid_options.py:262). This is documented as "(small) coarse system" but fails when base mesh resolution is high.Related: PR #213 (
_use_iterative_solver) already avoids MUMPS in parallel for the same reason, usingredundant+svdinstead — butsvdis infeasible at this scale (dense 14k×14k).Solution Found
Using a finer base mesh with more refinement levels keeps the finest grid identical while shrinking the coarsest level:
csize10 ref2csize20 ref3Proposed Fix Options
multigrid_options.py(preferred):mesh.dm_hierarchyredundant+luonly below a threshold (≈3–5k coarse DOFs)gamg, orasm) — note distributed MUMPS must stay excluded per PR Parallel adaptive seam-spike fix: mover heap corruption + locator hardening + remesh field-transfer redesign (Phase 1 + 2) #213's finding that MUMPS-in-parallel corrupts in this buildcoarser-base + extra-refinementrecipe and warn on large-coarseredundantRelated
docs/developer/design/parallel-repeated-solve-corruption.md: MUMPS-in-parallel heap corruption in this build (why mumps-based coarse solves are excluded here)Verification
Setonix (Pawsey), production-geometry model, np=30, per-rank RSS sampled every 2 s:
csize10 ref2): post-solve 683 MB/rank uniform across all 30 ranks (spread 13 MB) → step killed at the 900 MB/task cgroup capcsize20 ref3): post-solve 398–427 MB/rank (median 416), window max 576 MB, clean completion