Repository navigation
Segfault in symbfact_dist with ParSymbFact=YES and Fact=SamePattern #230
Description
Unsure of this, needs checking by someone with expertise.
Note: This issue text was generated by an LLM (Claude Code), working with a FEniCS developer, and checked against the 9.3.0 sources and the reproducer below.
In SuperLU_DIST 9.3.0, refactoring with Fact=SamePattern while ParSymbFact=YES (with ColPerm=PARMETIS) segfaults in symbfact_dist.
Likely cause
In SRC/double/pdgssvx.c (v9.3.0):
sizesandfstVtxSepare initialised toNULL(line 582).- They are only filled in by the ordering step:
get_perm_c_parmetis(line 1056), insideif ( permc_spec != MY_PERMC && Fact == DOFACT )(line 1044). - With
Fact=SamePattern,perm_cis reused and the ordering is skipped. The symbolic factorisation still runs, becauseFact != SamePattern_SameRowPerm. WithparSymbFact == YES,symbfact_dist(line 1160) then receivessizes == NULLandfstVtxSep == NULL.
The same structure appears in the single and complex drivers.
Reproducer
The setup is SuperLU_DIST 9.3.0 with ParMETIS support (here Scotch 7.0.17's ParMETIS/METIS compatibility layers) on macOS arm64 with Open MPI 5.0. A 3D 7-point Laplacian (1,728 unknowns) is distributed by rows (SLU_NR_loc), and the options are the defaults except ColPerm=PARMETIS and ParSymbFact=YES. The sequence is:
Fact=DOFACT, thenpdgssvx;- change the matrix values, keeping the sparsity pattern;
dDestroy_LU, thenFact=SamePattern, thenpdgssvx. This segfaults insymbfact_dist.
Results:
| Sequence | ParSymbFact=NO | ParSymbFact=YES | |---|---|---| | DOFACT → SamePattern → FACTORED | correct, on 1, 2 and 4 processes | segfault in symbfact_dist, on 1, 2 and 4 processes | | DOFACT → DOFACT → FACTORED | correct | correct | | DOFACT → SamePattern_SameRowPerm → FACTORED | correct | correct |
In the DOFACT refactorisation, dDestroy_LU and dSolveFinalize were called first.
Possible fixes
The separator tree is local to pdgssvx. get_perm_c_parmetis allocates sizes and fstVtxSep, and they are freed after the symbolic factorisation (line 1185 on master). Only perm_c survives in ScalePermstruct, and the documentation (around line 401) says perm_c is an input when Fact = SamePattern. A later SamePattern call therefore has perm_c but no tree. Some options, in increasing order of effort:
- Use a trivial separator tree.
ColPerm = MY_PERMCandNATURALalready have this problem, and theif ( permc_spec == NATURAL || permc_spec == MY_PERMC )block (lines 1019–1037 onmaster) handles it by putting allmrows in the top separator. Taking the same branch forpermc_spec == PARMETIS && Fact == SamePatternwould keep theperm_creuse contract. The cost is that aSamePatternrefactorisation loses most of the parallelism of the symbolic factorisation. - Recompute the ordering for
SamePattern. This is simple, but it changesperm_c, which breaks the documented contract and invalidates a solve setup (SOLVEstruct) built from the oldperm_c. - Keep the separator tree between calls, for example in
ScalePermstructnext toperm_c.SamePatternwould then keep the full parallel symbolic factorisation with no extra ParMETIS call. It changes a public struct, though.
If none of these suits, document the restriction and return an error from pdgssvx instead of crashing.
The same NATURAL/MY_PERMC block appears in p[sdz]gssvx.c, psgssvx_d2.c, p[sdz]gssvx3d.c and psgssvx3d_d2.c. I have only reproduced the crash with pdgssvx.
Downstream, DOLFINx refactors with DOFACT when SamePattern is requested under ParSymbFact=YES (FEniCS/dolfinx#4665). Related: #229.
Activity
Fix segfault in symbfact_dist for ColPerm=PARMETIS + Fact=SamePattern…