33#ifndef GKO_PUBLIC_CORE_PRECONDITIONER_ILU_HPP_
34#define GKO_PUBLIC_CORE_PRECONDITIONER_ILU_HPP_
41#include <ginkgo/core/base/abstract_factory.hpp>
42#include <ginkgo/core/base/composition.hpp>
43#include <ginkgo/core/base/exception.hpp>
44#include <ginkgo/core/base/exception_helpers.hpp>
45#include <ginkgo/core/base/lin_op.hpp>
46#include <ginkgo/core/base/precision_dispatch.hpp>
47#include <ginkgo/core/base/std_extensions.hpp>
48#include <ginkgo/core/factorization/par_ilu.hpp>
49#include <ginkgo/core/matrix/dense.hpp>
50#include <ginkgo/core/solver/solver_traits.hpp>
51#include <ginkgo/core/solver/triangular.hpp>
52#include <ginkgo/core/stop/combined.hpp>
53#include <ginkgo/core/stop/iteration.hpp>
54#include <ginkgo/core/stop/residual_norm.hpp>
58namespace preconditioner {
110template <
typename LSolverType = solver::LowerTrs<>,
111 typename USolverType = solver::UpperTrs<>,
bool ReverseApply = false,
112 typename IndexType =
int32>
114 Ilu<LSolverType, USolverType, ReverseApply, IndexType>>,
121 std::is_same<
typename LSolverType::value_type,
122 typename USolverType::value_type>::value,
123 "Both the L- and the U-solver must use the same `value_type`!");
124 using value_type =
typename LSolverType::value_type;
127 static constexpr bool performs_reverse_apply =
ReverseApply;
128 using index_type = IndexType;
130 Ilu<
typename USolverType::transposed_type,
131 typename LSolverType::transposed_type,
ReverseApply, IndexType>;
140 std::shared_ptr<const typename l_solver_type::Factory>
146 std::shared_ptr<const typename u_solver_type::Factory>
154 GKO_DEPRECATED(
"use with_l_solver instead")
159 return with_l_solver(std::move(solver));
162 parameters_type& with_l_solver(
166 this->l_solver_generator = std::move(solver);
167 this->deferred_factories[
"l_solver"] = [](
const auto& exec,
169 if (!
params.l_solver_generator.is_empty()) {
171 params.l_solver_generator.on(exec);
177 GKO_DEPRECATED(
"use with_u_solver instead")
178 parameters_type& with_u_solver_factory(
179 deferred_factory_parameter<
const typename u_solver_type::Factory>
182 return with_u_solver(std::move(solver));
185 parameters_type& with_u_solver(
186 deferred_factory_parameter<const typename u_solver_type::Factory>
189 this->u_solver_generator = std::move(solver);
190 this->deferred_factories[
"u_solver"] = [](
const auto& exec,
192 if (!
params.u_solver_generator.is_empty()) {
194 params.u_solver_generator.on(exec);
200 GKO_DEPRECATED(
"use with_factorization instead")
201 parameters_type& with_factorization_factory(
202 deferred_factory_parameter<
const LinOpFactory> factorization)
204 return with_factorization(std::move(factorization));
207 parameters_type& with_factorization(
210 this->factorization_generator = std::move(factorization);
211 this->deferred_factories[
"factorization"] = [](
const auto& exec,
213 if (!
params.factorization_generator.is_empty()) {
214 params.factorization_factory =
215 params.factorization_generator.on(exec);
222 deferred_factory_parameter<const typename l_solver_type::Factory>
225 deferred_factory_parameter<const typename u_solver_type::Factory>
291 if (&
other !=
this) {
294 l_solver_ =
other.l_solver_;
295 u_solver_ =
other.u_solver_;
296 parameters_ =
other.parameters_;
297 if (
other.get_executor() != exec) {
313 if (&
other !=
this) {
316 l_solver_ = std::move(
other.l_solver_);
317 u_solver_ = std::move(
other.u_solver_);
319 if (
other.get_executor() != exec) {
341 void apply_impl(
const LinOp* b,
LinOp* x)
const override
348 l_solver_->apply(
dense_b, cache_.intermediate);
349 if (u_solver_->apply_uses_initial_guess()) {
350 dense_x->copy_from(cache_.intermediate);
352 u_solver_->apply(cache_.intermediate,
dense_x);
354 u_solver_->apply(
dense_b, cache_.intermediate);
355 if (l_solver_->apply_uses_initial_guess()) {
356 dense_x->copy_from(cache_.intermediate);
358 l_solver_->apply(cache_.intermediate,
dense_x);
364 void apply_impl(
const LinOp* alpha,
const LinOp* b,
const LinOp* beta,
365 LinOp* x)
const override
371 l_solver_->apply(
dense_b, cache_.intermediate);
375 u_solver_->apply(
dense_b, cache_.intermediate);
383 explicit Ilu(std::shared_ptr<const Executor> exec)
384 : EnableLinOp<
Ilu>(std::
move(exec))
387 explicit Ilu(
const Factory* factory, std::shared_ptr<const LinOp>
lin_op)
389 parameters_{
factory->get_parameters()}
392 std::dynamic_pointer_cast<const Composition<value_type>>(
lin_op);
393 std::shared_ptr<const LinOp>
l_factor;
394 std::shared_ptr<const LinOp>
u_factor;
398 auto exec =
lin_op->get_executor();
401 factorization::ParIlu<value_type, index_type>::build().on(
404 auto fact = std::shared_ptr<const LinOp>(
408 std::dynamic_pointer_cast<const Composition<value_type>>(
fact);
410 GKO_NOT_SUPPORTED(
comp);
413 if (
comp->get_operators().size() == 2) {
417 GKO_NOT_SUPPORTED(
comp);
443 void set_cache_to(
const LinOp* b)
const
445 if (cache_.intermediate ==
nullptr) {
446 cache_.intermediate =
447 matrix::Dense<value_type>::create(this->
get_executor());
450 cache_.intermediate->copy_from(b);
461 template <
typename SolverType>
462 static std::enable_if_t<solver::has_with_criteria<SolverType>::value,
463 std::unique_ptr<SolverType>>
464 generate_default_solver(
const std::shared_ptr<const Executor>& exec,
465 const std::shared_ptr<const LinOp>&
mtx)
469 static_cast<unsigned int>(
mtx->get_size()[0])};
471 return SolverType::build()
483 template <
typename SolverType>
484 static std::enable_if_t<!solver::has_with_criteria<SolverType>::value,
485 std::unique_ptr<SolverType>>
486 generate_default_solver(
const std::shared_ptr<const Executor>& exec,
487 const std::shared_ptr<const LinOp>&
mtx)
489 return SolverType::build().on(exec)->generate(
mtx);
493 std::shared_ptr<const l_solver_type> l_solver_{};
494 std::shared_ptr<const u_solver_type> u_solver_{};
505 mutable struct cache_struct {
506 cache_struct() =
default;
507 ~cache_struct() =
default;
508 cache_struct(
const cache_struct&) {}
509 cache_struct(cache_struct&&) {}
510 cache_struct& operator=(
const cache_struct&) {
return *
this; }
511 cache_struct& operator=(cache_struct&&) {
return *
this; }
512 std::unique_ptr<LinOp> intermediate{};
The EnableLinOp mixin can be used to provide sensible default implementations of the majority of the ...
Definition lin_op.hpp:908
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:691
Definition lin_op.hpp:146
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition polymorphic_object.hpp:263
Linear operators which support transposition should implement the Transposable interface.
Definition lin_op.hpp:462
Represents a factory parameter of factory type that can either initialized by a pre-existing factory ...
Definition abstract_factory.hpp:337
The enable_parameters_type mixin is used to create a base implementation of the factory parameters st...
Definition abstract_factory.hpp:239
The Incomplete LU (ILU) preconditioner solves the equation for a given lower triangular matrix L,...
Definition ilu.hpp:115
Ilu(Ilu &&other)
Move-constructs an ILU preconditioner.
Definition ilu.hpp:338
Ilu & operator=(Ilu &&other)
Move-assigns an ILU preconditioner.
Definition ilu.hpp:311
std::shared_ptr< const l_solver_type > get_l_solver() const
Returns the solver which is used for the provided L matrix.
Definition ilu.hpp:239
std::unique_ptr< LinOp > conj_transpose() const override
Returns a LinOp representing the conjugate transpose of the Transposable object.
Definition ilu.hpp:269
Ilu(const Ilu &other)
Copy-constructs an ILU preconditioner.
Definition ilu.hpp:331
std::shared_ptr< const u_solver_type > get_u_solver() const
Returns the solver which is used for the provided U matrix.
Definition ilu.hpp:249
std::unique_ptr< LinOp > transpose() const override
Returns a LinOp representing the transpose of the Transposable object.
Definition ilu.hpp:254
Ilu & operator=(const Ilu &other)
Copy-assigns an ILU preconditioner.
Definition ilu.hpp:289
The ResidualNorm class is a stopping criterion which stops the iteration process when the actual resi...
Definition residual_norm.hpp:138
#define GKO_ENABLE_BUILD_METHOD(_factory_name)
Defines a build method for the factory, simplifying its construction by removing the repetitive typin...
Definition abstract_factory.hpp:422
#define GKO_ENABLE_LIN_OP_FACTORY(_lin_op, _parameters_name, _factory_name)
This macro will generate a default implementation of a LinOpFactory for the LinOp subclass it is defi...
Definition lin_op.hpp:1046
@ factory
LinOpFactory events.
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
typename detail::remove_complex_s< T >::type remove_complex
Obtain the type which removed the complex of complex/scalar type or the template parameter of class b...
Definition math.hpp:354
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:203
batch_dim< 2, DimensionType > transpose(const batch_dim< 2, DimensionType > &input)
Returns a batch_dim object with its dimensions swapped for batched operators.
Definition batch_dim.hpp:148
detail::shared_type< OwningPointer > share(OwningPointer &&p)
Marks the object pointed to by p as shared.
Definition utils_helper.hpp:254
std::shared_ptr< const LinOpFactory > factorization_factory
Factory for the factorization.
Definition ilu.hpp:152
std::shared_ptr< const typename u_solver_type::Factory > u_solver_factory
Factory for the U solver.
Definition ilu.hpp:147
std::shared_ptr< const typename l_solver_type::Factory > l_solver_factory
Factory for the L solver.
Definition ilu.hpp:141