Skip to content

Commit d7627b2

Browse files
committed
Harden PPCG generalized eigensolver fallback
1 parent e305e77 commit d7627b2

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

source/source_hsolver/ppcg/diago_ppcg_lapack.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ struct HermitianLapack
4848
{
4949
std::vector<Scalar> eigvec(n * n, Scalar(0));
5050
container::kernels::lapack_hegvd<Scalar, Device>()(n, n, a, b, w, eigvec.data());
51+
for (int j = 0; j < n; ++j)
52+
{
53+
if (!std::isfinite(w[j]))
54+
throw std::runtime_error("PPCG: hegvd returned non-finite eigenvalue.");
55+
56+
Real nrm2 = 0;
57+
for (int i = 0; i < n; ++i)
58+
nrm2 += static_cast<Real>(std::norm(eigvec[i + j * n]));
59+
if (nrm2 <= static_cast<Real>(1e-30))
60+
throw std::runtime_error("PPCG: hegvd returned a zero eigenvector.");
61+
}
5162
std::copy(eigvec.begin(), eigvec.end(), a);
5263
}
5364

source/source_hsolver/ppcg/diago_ppcg_subspace.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,12 @@ void DiagoPPCG<T, Device>::solve_small_generalized(
168168
// All attempts failed — set eigenvectors to identity (no update).
169169
std::fill(subspace.k.begin(), subspace.k.end(), T(0));
170170
for (int i = 0; i < dim; ++i)
171+
{
171172
subspace.k[i + i * dim] = T(1);
172-
std::fill(subspace.eval.begin(), subspace.eval.end(), static_cast<Real>(0));
173+
subspace.eval[i] = static_cast<Real>(std::real(k0[i + i * dim]))
174+
/ std::max(static_cast<Real>(std::real(m0[i + i * dim])),
175+
static_cast<Real>(1e-30));
176+
}
173177
}
174178

175179
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)