Skip to content

FMG geometric-MG coarse solve uses PCREDUNDANT: coarse LU replicated on every rank — OOM at scale when the base mesh is fine #644

Description

@bknight1

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

  1. Size-aware default in multigrid_options.py (preferred):
  2. Document the workaround: publish the coarser-base + extra-refinement recipe and warn on large-coarse redundant
  3. 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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:highUrgent review required

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions