Configure stopping criteria#
Every iterative solver in Ginkgo takes one or more stopping criterion
factories through with_criteria(...). When you pass more than one,
they are combined through gko::stop::Combined, which always stops the
solver as soon as any criterion is met (a logical OR). This page covers the common
combinations and the choices behind them.
The two most-used criteria#
auto solver_factory = gko::solver::Cg<ValueType>::build()
.with_criteria(
gko::stop::Iteration::build()
.with_max_iters(1000u).on(exec),
gko::stop::ResidualNorm<ValueType>::build()
.with_reduction_factor(1e-8).on(exec))
.on(exec);
stop::Iteration: hard cap on iterations. Always include one; it guards against runaway loops if convergence never triggers.stop::ResidualNorm: relative residual reduction. Stops when \(\lVert r_k \rVert \le \tau \, \lVert b \rVert\) where \(\tau\) isreduction_factor(the defaultbaselineisrhs_norm).
These two together (a max-iter cap and a relative residual target) cover most use cases.
Relative vs absolute residual#
using BaseMode = gko::stop::mode;
gko::stop::ResidualNorm<double>::build()
.with_baseline(BaseMode::initial_resnorm) // relative to ||r_0||
.with_reduction_factor(1e-8)
.on(exec);
gko::stop::ResidualNorm<double>::build()
.with_baseline(BaseMode::absolute) // absolute: ||r_k|| <= tol
.with_reduction_factor(1e-8)
.on(exec);
gko::stop::ResidualNorm<double>::build()
.with_baseline(BaseMode::rhs_norm) // default: relative to ||b||
.with_reduction_factor(1e-8)
.on(exec);
reduction_factor is the value compared against the chosen
baseline:
|
Stops when |
|---|---|
|
\(\lVert r_k \rVert \le \tau \, \lVert b \rVert\) |
|
\(\lVert r_k \rVert \le \tau \, \lVert r_0 \rVert\) |
|
\(\lVert r_k \rVert \le \tau\) |
The default rhs_norm gives a tolerance that is independent of the
initial guess. The initial_resnorm baseline is fixed once per solve
to \(\lVert b - A x_0 \rVert\), so when you chain warm-started solves
and feed each previous solution back as \(x_0\), \(\lVert r_0 \rVert\)
shrinks and the implied stopping target \(\tau \, \lVert r_0 \rVert\)
shrinks with it, sometimes well below what the solver can actually
reach in finite precision. rhs_norm keeps the baseline at
\(\lVert b \rVert\), which stays constant across the chain.
Implicit vs explicit residual#
Most Krylov solvers maintain a residual through their recurrences and
hand it to the criterion, so a residual-norm check costs one norm
computation and no extra SpMV (MINRES and Multigrid are the exceptions
described below). Some solvers also keep a squared
residual estimate as a by-product of their inner products, which
ImplicitResidualNorm reads.
gko::stop::ResidualNorm<double>::build()
.with_reduction_factor(1e-8)
.with_baseline(gko::stop::mode::rhs_norm)
.on(exec);
gko::stop::ImplicitResidualNorm<double>::build()
.with_reduction_factor(1e-8)
.on(exec);
ResidualNorm uses the norm the solver passes to the criterion, or the
2-norm of the residual vector the solver passes (one reduction). Solvers
such as CG, BiCGSTAB and CGS pass their recurrence residual; GMRES passes
its Givens-rotation estimate. The criterion computes \(r = b - A x\) with
a matrix application only as a fallback, for solvers that pass neither
(for example MINRES and Multigrid).
ImplicitResidualNorm reads the squared residual estimate from the
solver’s recurrence. For CG-type solvers it saves the global reduction
that the norm of the residual vector needs. With a preconditioner the
estimate is \(M^{-1}\)-weighted, a different measure from
\(\lVert b - A x \rVert\). Prefer ResidualNorm when the tolerance is
stated for the residual of the system, and ImplicitResidualNorm for
loose inner solves where the reduction saving matters.
Combine criteria#
with_criteria takes any number of factories. The solver stops as soon
as any of them is met:
auto solver_factory = gko::solver::Cg<double>::build()
.with_criteria(
gko::stop::Iteration::build().with_max_iters(500u).on(exec),
gko::stop::ResidualNorm<double>::build()
.with_reduction_factor(1e-10).on(exec),
gko::stop::Time::build()
.with_time_limit(std::chrono::seconds{30}).on(exec))
.on(exec);
stop::Time ends the solve after a wall-clock budget, useful for
real-time / latency-bounded applications.
Custom criteria#
When the built-ins don’t fit, subclass gko::stop::Criterion and
provide a Factory. The check method receives the current iterate
and decides whether to stop. See include/ginkgo/core/stop/criterion.hpp
for the interface.
Common pitfalls#
One
with_criteriacall overrides previous ones. Pass all criteria in a singlewith_criteria(...)invocation, not multiple.Don’t forget the iteration cap. Without one, a non-convergent problem loops forever.
Preconditioner choice changes the implicit norm.
ResidualNormmeasures the residual of the system, taken from the solver’s recurrence (or the GMRES estimate).ImplicitResidualNormreads the recurrence’s squared estimate, which with a preconditioner is \(M^{-1}\)-weighted for CG-type solvers.
See also
Stopping criteria: the conceptual reference.
Log convergence: collect per-iteration data while solving.