Ginkgo  Generated from pipelines/2662685947 branch based on develop. Ginkgo version 2.0.0
A numerical linear algebra library targeting many-core architectures
combination.hpp
1 // SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_BASE_COMBINATION_HPP_
6 #define GKO_PUBLIC_CORE_BASE_COMBINATION_HPP_
7 
8 
9 #include <type_traits>
10 #include <vector>
11 
12 #include <ginkgo/core/base/lin_op.hpp>
13 
14 
15 namespace gko {
16 
17 
30 template <typename ValueType = default_precision>
31 class Combination : public LinOp,
32  public EnableCreateMethod<Combination<ValueType>>,
33  public Transposable {
34  friend class EnableCreateMethod<Combination>;
35  GKO_ASSERT_SUPPORTED_VALUE_TYPE;
36 
37 public:
38  using value_type = ValueType;
40 
46  const std::vector<std::shared_ptr<const LinOp>>& get_coefficients()
47  const noexcept
48  {
49  return coefficients_;
50  }
51 
57  const std::vector<std::shared_ptr<const LinOp>>& get_operators()
58  const noexcept
59  {
60  return operators_;
61  }
62 
63  std::unique_ptr<LinOp> transpose() const override;
64 
65  std::unique_ptr<LinOp> conj_transpose() const override;
66 
72 
80 
85  Combination(const Combination&);
86 
93 
94 protected:
95  void add_operators() {}
96 
97  template <typename... Rest>
98  void add_operators(std::shared_ptr<const LinOp> coef,
99  std::shared_ptr<const LinOp> oper, Rest&&... rest)
100  {
101  GKO_ASSERT_EQUAL_DIMENSIONS(coef, dim<2>(1, 1));
102  GKO_ASSERT_EQUAL_DIMENSIONS(oper, this->get_size());
103  auto exec = this->get_executor();
104  coefficients_.push_back(std::move(coef));
105  operators_.push_back(std::move(oper));
106  if (coefficients_.back()->get_executor() != exec) {
107  coefficients_.back() = gko::clone(exec, coefficients_.back());
108  }
109  if (operators_.back()->get_executor() != exec) {
110  operators_.back() = gko::clone(exec, operators_.back());
111  }
112  add_operators(std::forward<Rest>(rest)...);
113  }
114 
120  explicit Combination(std::shared_ptr<const Executor> exec) : LinOp(exec) {}
121 
136  template <
137  typename CoefficientIterator, typename OperatorIterator,
138  typename = std::void_t<
139  typename std::iterator_traits<
140  CoefficientIterator>::iterator_category,
141  typename std::iterator_traits<OperatorIterator>::iterator_category>>
142  explicit Combination(CoefficientIterator coefficient_begin,
143  CoefficientIterator coefficient_end,
144  OperatorIterator operator_begin,
145  OperatorIterator operator_end)
146  : LinOp([&] {
147  if (operator_begin == operator_end) {
148  throw OutOfBoundsError(__FILE__, __LINE__, 1, 0);
149  }
150  return (*operator_begin)->get_executor();
151  }())
152  {
153  GKO_ASSERT_EQ(std::distance(coefficient_begin, coefficient_end),
154  std::distance(operator_begin, operator_end));
155  this->set_size((*operator_begin)->get_size());
156  auto coefficient_it = coefficient_begin;
157  for (auto operator_it = operator_begin; operator_it != operator_end;
158  ++operator_it) {
159  add_operators(*coefficient_it, *operator_it);
160  ++coefficient_it;
161  }
162  }
163 
174  template <typename... Rest>
175  explicit Combination(std::shared_ptr<const LinOp> coef,
176  std::shared_ptr<const LinOp> oper, Rest&&... rest)
177  : Combination(oper->get_executor())
178  {
179  this->set_size(oper->get_size());
180  add_operators(std::move(coef), std::move(oper),
181  std::forward<Rest>(rest)...);
182  }
183 
184  void apply_impl(const LinOp* b, LinOp* x) const override;
185 
186  void apply_impl(const LinOp* alpha, const LinOp* b, const LinOp* beta,
187  LinOp* x) const override;
188 
189 private:
190  std::vector<std::shared_ptr<const LinOp>> coefficients_;
191  std::vector<std::shared_ptr<const LinOp>> operators_;
192 
193  // TODO: solve race conditions when multithreading
194  mutable struct cache_struct {
195  cache_struct() = default;
196  ~cache_struct() = default;
197  cache_struct(const cache_struct& other) {}
198  cache_struct& operator=(const cache_struct& other) { return *this; }
199 
200  std::unique_ptr<LinOp> zero;
201  std::unique_ptr<LinOp> one;
202  std::unique_ptr<LinOp> intermediate_x;
203  } cache_;
204 };
205 
206 
207 } // namespace gko
208 
209 
210 #endif // GKO_PUBLIC_CORE_BASE_COMBINATION_HPP_
gko::Combination
The Combination class can be used to construct a linear combination of multiple linear operators c1 *...
Definition: combination.hpp:31
gko::LinOp
Definition: lin_op.hpp:117
gko::EnableCreateMethod
This mixin implements a static create() method on ConcreteType that dynamically allocates the memory,...
Definition: polymorphic_object.hpp:522
gko::Combination::transpose
std::unique_ptr< LinOp > transpose() const override
Returns a LinOp representing the transpose of the Transposable object.
gko::Transposable
Linear operators which support transposition should implement the Transposable interface.
Definition: lin_op.hpp:392
gko::clone
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition: utils_helper.hpp:425
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::Combination::get_coefficients
const std::vector< std::shared_ptr< const LinOp > > & get_coefficients() const noexcept
Returns a list of coefficients of the combination.
Definition: combination.hpp:46
gko::Combination::Combination
Combination(const Combination &)
Copy-constructs a Combination.
gko::Combination::operator=
Combination & operator=(const Combination &)
Copy-assigns a Combination.
gko::Combination::conj_transpose
std::unique_ptr< LinOp > conj_transpose() const override
Returns a LinOp representing the conjugate transpose of the Transposable object.
gko::PolymorphicObject::get_executor
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition: polymorphic_object.hpp:62
gko::LinOp::get_size
const dim< 2 > & get_size() const noexcept
Returns the size of the operator.
Definition: lin_op.hpp:169
gko::Combination::get_operators
const std::vector< std::shared_ptr< const LinOp > > & get_operators() const noexcept
Returns a list of operators of the combination.
Definition: combination.hpp:57
gko::LinOp::LinOp
LinOp(const LinOp &)=default
Copy-constructs a LinOp.
gko::zero
constexpr T zero()
Returns the additive identity for T.
Definition: math.hpp:626
gko::one
constexpr T one()
Returns the multiplicative identity for T.
Definition: math.hpp:654