Skip to content

fix(sparse): zero-init UMFPACK solution vectors (non-deterministic Phi garbage)#176

Open
marjohma wants to merge 2 commits into
mainfrom
fix/sparse-uninit-solution
Open

fix(sparse): zero-init UMFPACK solution vectors (non-deterministic Phi garbage)#176
marjohma wants to merge 2 commits into
mainfrom
fix/sparse-uninit-solution

Conversation

@marjohma

Copy link
Copy Markdown
Member

Problem

KIM's Phi_m.dat (and Phi_MA, Phi_m_i/e) intermittently contained uninitialized-memory garbage (e.g. 2.6e+243, 9.6e-315) in a few inner-boundary cells of the localised electrostatic solve — on ~1 in 6 runs. Re-running the same binary on the same inputs gave clean zeros, i.e. non-deterministic.

Root cause

In the SuiteSparse solve routines of QL-Balance/src/base/sparse_mod.f90, the solution vectors (xx/xz for complex, x for real) are ALLOCATEd but never initialized:

ALLOCATE( xx(nrow) )        ! uninitialized
ALLOCATE( xz(nrow) )
...
CALL umf4zsol(sys, xx, xz, bx, bz, numeric, control, info)
b = DCMPLX(xx, xz)          ! copies ALL of xx/xz into the solution

For a field-free localised Poisson solve, the matrix has decoupled/empty rows; umf4zsol leaves those solution entries unwritten, so b = DCMPLX(xx,xz) copies uninitialized heap into the output -> EBdat%Phi -> Phi_m.dat.

Pre-existing latent bug — the solve code is byte-identical across the recent fortnum migration; that migration only perturbed heap/allocation layout, which is why the garbage began surfacing (the archived pre-fortnum output happened to get clean zeros).

Fix

Zero-initialize the solution vectors after allocation in all four SuiteSparse routines (sparse_solve_suitesparse_b1, sparse_solve_suitesparseComplex_b1, and their _b2_loop variants). Decoupled DOFs now come out as 0 — the correct field-free value.

Also delete KIM/src/math/sparse_mod.f90, a stale divergent copy that is no longer compiled (KIM links the shared QL-Balance sparse target; the file is absent from CMakeSources.in). It nearly masked this fix.

Verification

  • Compiled in: sparse_mod.f90.o -> libsparse.a -> KIM.x relinked (build log).
  • 6/6 clean runs on the AUG 33353/2900 m7 electrostatic case (150/150 grid): no garbage in any Phi field; Phi_MA_ideal matches the archived pre-fortnum reference to <3e-8.
  • Correct by construction: explicitly-zeroed memory cannot read as garbage; decoupled DOFs UMFPACK does not write stay 0.

marjohma added 2 commits July 10, 2026 13:01
…d reads

The SuiteSparse complex/real solve routines (sparse_solve_suitesparse*)
ALLOCATE the solution vectors xx/xz (or x) but never initialize them.
umf4zsol does not write solution entries for decoupled/empty matrix rows
(e.g. field-free DOFs in a localised Poisson solve), so those cells were
copied straight into b (=DCMPLX(xx,xz)) carrying uninitialized heap.

Symptom: KIM Phi_m.dat showed non-deterministic garbage (e.g. 2.6e+243)
in a few inner-boundary cells on ~1/6 of runs; re-running the same binary
gave clean zeros. Pre-existing latent bug, surfaced by the fortnum
migration perturbing heap/alloc layout (the solve code itself is unchanged).

Zero-initializing xx/xz/x makes decoupled DOFs come out as 0 (the correct
field-free value). Confirmed: 6/6 clean runs on the 33353_2900 m7 ES case,
Phi_MA_ideal still matching the reference to <3e-8.

Note: KIM/src/math/sparse_mod.f90 is a stale unused copy of this file (KIM
links the shared QL-Balance 'sparse' target); it should be deleted.
KIM/src/math/sparse_mod.f90 was a divergent copy no longer compiled:
KIM links the shared 'sparse' target built from QL-Balance/src/base/
sparse_mod.f90 (KIM/src/CMakeLists.txt), and it is absent from
CMakeSources.in. Keeping it invites editing the wrong file (it nearly
masked the sparse-solver fix). Remove it.
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.

1 participant