Skip to content

Default SuperLU_DIST to PARMETIS ordering and expose ParSymbFact - #4665

Merged
jhale merged 5 commits into
mainfrom
jhale/superlu-parmetis-default
Oct 19, 2026
Merged

jhale merged 5 commits into
mainfrom
jhale/superlu-parmetis-default

Conversation

@jhale

@jhale jhale commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

When SuperLU_DIST has ParMETIS support (HAVE_PARMETIS, which is set for both real ParMETIS and Scotch's emulation), this PR makes ColPerm=PARMETIS the default in place of METIS_AT_PLUS_A. Builds without ParMETIS keep SuperLU_DIST's own default (MMD_AT_PLUS_A). It also exposes ParSymbFact through set_option, off by default.

Deadlock with the default ordering

With ColPerm=METIS_AT_PLUS_A, every rank computes the column ordering of the gathered global matrix independently (get_perm_c_dist in pdgssvx), with no broadcast, so all ranks must get the same permutation. The wheels (#4652) build SuperLU_DIST against Scotch's METIS/ParMETIS emulation. Its METIS_NodeND returns different permutations on different ranks for identical input. I checked this by interposing it in a 2-rank solve: the ranks had the same input hash and got different outputs. Resetting Scotch's RNG and running single-threaded didn't make the orderings consistent. The ranks then reach mismatched collectives and the factorisation deadlocks. The existing tests use 5×5 meshes, which happen to order consistently, so CI didn't catch this.

PARMETIS is a single collective call, so the ranks agree by construction. It's also faster on larger 3D problems. Solve times on the wheels, 4 ranks, Poisson on a unit cube:

| Problem | DOFs | MMD_AT_PLUS_A | PARMETIS | |---|---|---|---| | P1 | 69k | 3.6 s | 1.6 s | | P1 | 185k | 22.1 s | 6.6 s | | P2 | 118k | 10.0 s | 3.7 s |

On 2D problems MMD is about 1.5× faster: 0.69 s against 1.03 s at 263k DOFs. Sequential METIS couldn't be benchmarked on the wheels because it hangs.

Reported upstream as xiaoyeli/superlu_dist#229. Follow-up once it's fixed: #4666.

Parallel symbolic factorisation (opt-in)

Serial symbolic factorisation builds the gathered global matrix and the global L/U structure on every rank, so its memory per rank grows with the problem size whatever the rank count. ParSymbFact=YES distributes both. With RowPerm=NOROWPERM it also removes the remaining global gather (pdgssvx.c:789). On a 3D 7-point Laplacian, using a C driver linked against the wheel's SuperLU_DIST, it saved ~110 MB per rank at 373k unknowns on 8 ranks (1249 MB against 1139 MB). The cost in time ranged from 10% faster to 14% slower.

It isn't the default, because it can hang. In dist_symbLU, a process with nothing to send passes an uninitialised snd_luind to MPI_Alltoallv. With ParSymbFact on a non-power-of-two process count, the processes outside the symbolic factorisation have nothing to send. When the garbage equals MPI_IN_PLACE, the collective mismatches, and the job hangs or aborts with MPI_ERR_TRUNCATE. An earlier version of this PR made ParSymbFact=YES the default. It then hung on 3 ranks in both int64 CI legs, and passed on 2 and 4. Backtraces showed rank 2 in Open MPI's in-place Alltoallv and ranks 0 and 1 in the pairwise one. The bug is in 9.2.1, 9.3.0 and master, and the one-line fix is xiaoyeli/superlu_dist#231. #4666 tracks making ParSymbFact the default once a fixed release is the minimum.

For users who opt in:

  • It needs ColPerm=PARMETIS. Setting ColPerm to another ordering through set_option turns ParSymbFact off. An explicit inconsistent combination makes solve throw before entering SuperLU_DIST.
  • Fact=SamePattern crashes with it. SamePattern skips the ordering step, but parallel symbolic factorisation needs the separator tree from that step. SuperLU_DIST 9.3.0 segfaults in symbfact_dist, so under ParSymbFact set_A(A, "SamePattern") refactors with DOFACT, and solve rejects Fact=SamePattern set through set_option. Reported as Segfault in symbfact_dist with ParSymbFact=YES and Fact=SamePattern xiaoyeli/superlu_dist#230.
  • A DOFACT refactorisation needs a fresh solve structure. DOFACT in set_A now also calls *SolveFinalize, because a new ordering invalidates the cached solve communication pattern. This also fixes the existing set_A(A, "DOFACT") path, which until now left that structure stale, whatever the ParSymbFact setting.

Using the C driver with ParSymbFact on and off, MC64 on and off, and 1–4 ranks, these refactorisation sequences give correct solutions for the latest matrix: DOFACT → DOFACT → FACTORED, SamePattern_SameRowPerm → FACTORED and DOFACT → SamePattern_SameRowPerm → FACTORED.

Tests

  • A Poisson solve on a 32×32 P2 mesh, run with the default options, with RowPerm=NOROWPERM and with ColPerm=MMD_AT_PLUS_A. On the current wheels the default case hangs on 2 ranks. With ColPerm=PARMETIS set, the whole SuperLU_DIST test file passes on 2, 3 and 4 ranks.
  • A check that ParSymbFact without PARMETIS is rejected.

The tests don't turn ParSymbFact on, because CI runs them on 3 ranks.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2

jhale and others added 2 commits October 19, 2026 08:14
With METIS_AT_PLUS_A every rank orders the global matrix itself and
SuperLU_DIST assumes the orderings agree. Scotch's METIS emulation, used
by the wheels, returns different orderings on different ranks for the
same graph, so parallel factorisations deadlock. PARMETIS ordering is a
single collective call and is also faster on larger 3D problems.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2
ParSymbFact runs the symbolic factorisation in parallel. With RowPerm
NOROWPERM it also avoids gathering the global matrix on every process.
It needs PARMETIS ordering, so solve rejects other orderings before
entering SuperLU_DIST.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2
@jhale jhale changed the title Default SuperLU_DIST to PARMETIS column ordering Default SuperLU_DIST to PARMETIS ordering and expose ParSymbFact Oct 19, 2026
Serial symbolic factorisation replicates the global matrix and L/U
structure on every rank, which limits memory scalability. Turn on
parallel symbolic factorisation wherever PARMETIS ordering is the
default.

ParSymbFact needs the ordering step, so setting ColPerm to another
ordering turns it off. SamePattern skips the ordering and crashes in
symbfact_dist, so set_A treats SamePattern as DOFACT under ParSymbFact.
A DOFACT refactorisation in set_A now also releases the solve
communication structure, which a new ordering invalidates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2
@jhale jhale changed the title Default SuperLU_DIST to PARMETIS ordering and expose ParSymbFact Default SuperLU_DIST to PARMETIS ordering and parallel symbolic factorisation Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2
An uninitialised send buffer in SuperLU_DIST's dist_symbLU makes
ParSymbFact hang on non-power-of-two rank counts, which the int64 CI
legs hit on 3 ranks. Fixed upstream in xiaoyeli/superlu_dist#231.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JudYk8UecTQyirGsLsHUN2
@jhale jhale changed the title Default SuperLU_DIST to PARMETIS ordering and parallel symbolic factorisation Default SuperLU_DIST to PARMETIS ordering and expose ParSymbFact Oct 19, 2026
@jhale
jhale added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 55a17c4 Oct 19, 2026
22 checks passed
@jhale
jhale deleted the jhale/superlu-parmetis-default branch October 19, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revisit SuperLU_DIST workarounds once superlu_dist#229, #230 and #231 are resolved

1 participant