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
{{ message }}
Repository navigation
custom_mg at np 32 and 52: the nested interpolation fails on preallocation, the FMG build falls back and the ranks deadlock #902
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.
The design note on feature/coarse-solve-nullspace suggests a gathered coarse communicator would address both this and the serial SVD.
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
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 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
Kaiju's np 32 and 52 run of the faulted annulus, compared against np 16. This is the "Done when" above.
Activity
Interpolate within one mesh cell by cell, not through PETSc's matrix (#…
Interpolate within one mesh through UW3's copy of PETSc's nested inte…
Mark the summed discontinuous-to-continuous projection in project_to_…
test_1107: custom-P FMG over a coarse level where a rank owns nothing (…
#902: the mesh's coordinate space is built through UW3's interpolator…
Text that still named PETSc's createInterpolation where UW3's copy no…
#901: test that a rotated solve sets its coarse level up once
#902: the coordinate space keeps PETSc's route only for isoperiodic m…
lmoresi commentedon Oct 31, 2026
Mechanism
DMCreateInterpolationbetween two DMs on one plex goes to PETSc'sDMPlexComputeInterpolatorNested(plexfem.c).MatAssemblyEnd, and the other ranks wait in the assembly's collective.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)UW_DMCreateInterpolationWithinPlexinpetsc_compat.h). The preallocation and fill loops run over the same cells._get_coords_for_basis,project_to_degreeandboundary_flux._trace_interior_coords.createCoordinateSpaceprojected degree >= 2 coordinates through PETSc's own interpolator, soMesh(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.build_transferscaught a builder failure on the rank where it happened and retried there alone, so the ranks met different collectives.CollectiveBuildErroron every rank.test_1107uses 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 (insideCustomMGHierarchy.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_1108covers 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