Skip to content

custom_mg at np 32 and 52: the nested interpolation fails on preallocation, the FMG build falls back and the ranks deadlock #902

Open

Description

@lmoresi

Measured on kaiju (ZG95 annulus campaign with box faults) on 2026-10-23/24 and recorded in uw3-campaigns HUB.md, before #890 merged. Together with the coarse SVD (filed alongside), this is why the fault campaigns cannot run past np 16. To re-check on development.

What happens

  • At np 32 and 52: building the custom-P FMG fails with a PETSc "new nonzero" error in DMCreateInterpolation. The nested interpolation between custom_mg levels (DMPlexComputeInterpolatorNested) fails on preallocation, and the barycentric transfer fails before it. The FMG build then falls back to the default preconditioner, and the ranks deadlock: no step finished in 1.6 h.
  • At np 104: an IndexError in custom_mg._colocate_level on ranks holding no cells of the 124-cell coarsest level, then a hang. The empty-rank work (bugfix/custom-mg-empty-rank, merged with The add-on partitioned once, custom multigrid on empty ranks, and the rotated solve's switch and record #890) addressed this part.
  • The empty-rank fix did not unblock np 32/52 (kaiju jobs 2097/2098, identical failure counts), so the preallocation failure is a separate defect.
  • np 8 and 16 work.

Notes

Done when

The custom FMG builds and solves kaiju's annulus fault case at np 32 and 52 with the same answer as np 16, and a parallel test pins a nested custom-MG build at a rank count where the coarsest level leaves ranks empty.

Underworld development team with AI support from Claude Code

Activity

  1. lmoresi commented on Oct 31, 2026

    @lmoresi
    MemberAuthor

    Mechanism

    DMCreateInterpolation between two DMs on one plex goes to PETSc's DMPlexComputeInterpolatorNested (plexfem.c).

    • Its preallocation loop runs only on a rank with local rows or columns. Its fill loop runs on every rank that holds cells.
    • A shared point belongs to the highest rank that holds it. A low rank whose cells sit inside higher ranks' regions therefore owns nothing, and it skips the preallocation.
    • It still sends its cells' entries to their owners. An entry that only its cells generate was never preallocated: the owner raises "New nonzero ... caused a malloc" in MatAssemblyEnd, and the other ranks wait in the assembly's collective.
    • P1 to P1 escapes, because the neighbours' cells cover every vertex pair. P2 fails.

    Custom-P multigrid reads each level's node coordinates through Mesh._get_coords_for_basis, which builds this matrix. On kaiju, the 124-cell coarsest level at np 32 and 52 left a rank owning nothing.

    On the laptop, natural partitions did not reproduce it: an annulus, plain and faulted, at np 8, and the 124-cell annulus at np 32 oversubscribed. A shell partition at np 2 reproduces it every time, with rank 0 given one interior cell of a 4 x 4 grid.

    The guard came in with PETSc b4ec2976 ("Plex: Fix interpolator for empty mesh", v3.24.0). By source, it is still there in v3.25.6, v3.26.0 and main. A petsc4py reproducer and the report text are ready for upstream.

    Notch draft 02 (the 3-D notch at np 16) is the same defect.

    Fix, on bugfix/custom-mg-many-ranks (57d8778, no PR yet)

    • The interpolation. UW3 now builds this matrix with its own copy of the nested interpolator, for the same-plex finite-element case (UW_DMCreateInterpolationWithinPlex in petsc_compat.h). The preallocation and fill loops run over the same cells.
      • It is used by _get_coords_for_basis, project_to_degree and boundary_flux._trace_interior_coords.
      • It also builds a mesh's coordinate space. createCoordinateSpace projected degree >= 2 coordinates through PETSc's own interpolator, so Mesh(degree=2) failed during setup on such a rank. The space is now installed without projection, and the coordinates are copied or interpolated through the copy. Periodic coordinates keep PETSc's projection.
      • Wherever PETSc's version assembles, the copy gives the same matrix: max |A - B| = 0 and the same nonzeros. That was checked on triangles, quads, tets, hexes, a degree-2 annulus and a spherical shell, for continuous and discontinuous degree 1 to 3, at np 1 and 4.
    • The deadlock (custom_mg.build_transfers: a rank-local exception decides a collective retry #886). build_transfers caught a builder failure on the rank where it happened and retried there alone, so the ranks met different collectives.
      • The barycentric builder's verdict is now agreed across ranks as soon as it returns.
      • The checks on allreduced sizes, in custom_mg and in fault_mg's provenance transfer, raise CollectiveBuildError on every rank.
      • In parallel, only that error is retried or degraded.
      • The fault split's replay down the tail agrees on any exception, not only its own refusal types, and every verdict runs on a communicator of its own, so it cannot pair with a collective another rank is still inside.
      • A PETSc error raised inside the interpolation's own assembly cannot be made collective after the fact. The fix for that path is that the error no longer occurs.
    • Tests.
      • test_1107 uses two shell partitions: rank 0 on an interior cell (no vertex or edge owned) and on a boundary cell (only its wall edge owned). It covers node coordinates at degree 1 to 3, projection between degrees, a degree-2 mesh, and a custom-P FMG solve whose coarse level is the interior partition. With PETSc's route put back, one test at a time at np 2, these fail: interior P2 coordinates, the projection, the degree-2 mesh and the FMG case (inside CustomMGHierarchy.build, "New nonzero at (88,32)"); and boundary P1 coordinates and the projection. P1 reaches the bug when a rank's cell has a wall edge.
      • test_1108 covers a builder failing on one rank, and a check failing on every rank. Both hang on development.

    Still open here

    Underworld development team with AI support from Claude Code

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 working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions