From 9de7a25a180e6a2e7a5a5f83840230ecd637c299 Mon Sep 17 00:00:00 2001 From: Mark Adams <524115-markadams4@users.noreply.gitlab.com> Date: Fri, 15 May 2026 09:28:27 -0400 Subject: [PATCH] Fix Chebyshev solver: zero x in solve_init when xIsZero=true When Chebyshev is used as a smoother inside AMG with an outer Krylov solver (e.g. PCG), solve_init() is called with xIsZero=true at the start of each outer iteration. However, the x buffer may contain stale data from the previous outer iteration. solve_iteration() then computes: x += gamma * p which accumulates onto the stale x, causing the smoother to diverge and the outer solver to fail. The fix explicitly zeros x when xIsZero=true, matching the contract implied by the flag name and the behavior expected by callers. --- src/solvers/cheb_solver.cu | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/solvers/cheb_solver.cu b/src/solvers/cheb_solver.cu index 95070b0b..9d1fabc8 100644 --- a/src/solvers/cheb_solver.cu +++ b/src/solvers/cheb_solver.cu @@ -282,6 +282,15 @@ Chebyshev_Solver::solve_init( VVector &b, VVector &x, bool xIsZero ) int offset, size; A.getOffsetAndSizeForView(A.getViewExterior(), &offset, &size); + // Ensure x is actually zero when xIsZero is claimed. + // Callers (e.g. PCG) pass xIsZero=true but may not have zeroed the buffer. + // Without this, solve_iteration's "x += gamma*p" accumulates onto stale data + // from the previous outer iteration, causing divergence. + if (xIsZero) + { + fill(x, types::util::get_zero()); + } + // Run one iteration of preconditioner with zero initial guess if (no_preconditioner) {