gko::LinOpFactory#
Abstract base for factories that produce a LinOp from a
system matrix. The canonical workflow is
auto factory = SomeSolver::build()
.with_criteria(...)
.on(exec); // returns a unique_ptr<LinOpFactory>
auto solver = factory->generate(system_matrix); // returns a unique_ptr<LinOp>
solver->apply(b, x);
with_* setters configure the factory parameters; .on(exec) ties
the factory to an executor and produces the LinOpFactory; finally
generate(matrix) binds the factory to a concrete system and returns
the operator. Solver / preconditioner / factorisation classes all
expose this pattern through CRTP mixins (EnableLinOpFactory,
EnableDefaultLinOpFactory).
-
class LinOpFactory #
Inherits from
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
In Ginkgo, every linear solver is viewed as a mapping. For example, given an s.p.d linear system \(Ax = b\), the solution \(x = A^{-1}b\) can be computed using the CG method. This algorithm can be represented in terms of linear operators and mappings between them as follows:
A Cg::Factory is a higher order mapping which, given an input operator \(A\), returns a new linear operator \(A^{-1}\)
stored in “CG
format”
Storing the operator \(A^{-1}\) in “CG format” means that the data structure used to store the operator is just a simple pointer to the original matrix \(A\). The application \(x = A^{-1}b\) of such an operator can then be implemented by solving the linear system \(Ax = b\) using the CG method. This is achieved in code by having a special class for each of those “formats” (e.g. the “Cg” class defines such a format for the CG solver).
Another example of a LinOpFactory is a preconditioner. A preconditioner for a linear operator \(A\) is a linear operator \(M^{-1}\), which approximates \(A^{-1}\). In addition, it is stored in a way such that both the data of \(M^{-1}\) is cheap to compute from \(A\), and the operation \(x = M^{-1}b\) can be computed quickly. These operators are useful to accelerate the convergence of Krylov solvers. Thus, a preconditioner also fits into the LinOpFactory framework:
The factory maps a linear operator \(A\) into a preconditioner \(M^{-1}\) which is stored in suitable format (e.g. as a product of two factors in case of ILU preconditioners).
The resulting linear operator implements the application operation \(x = M^{-1}b\) depending on the format the preconditioner is stored in (e.g. as two triangular solves in case of ILU)
#
Example: using CG in Ginkgo#
// Suppose A is a matrix, b a rhs vector, and x an initial guess // Create a CG which runs for at most 1000 iterations, and stops after // reducing the residual norm by 6 orders of magnitude auto cg_factory = solver::Cg<>::build() .with_max_iters(1000) .with_rel_residual_goal(1e-6) .on(cuda); // create a linear operator which represents the solver auto cg = cg_factory->generate(A); // solve the system cg->apply(b, x);