Ginkgo Generated from branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
lin_op.hpp
1/*******************************<GINKGO LICENSE>******************************
2Copyright (c) 2017-2023, the Ginkgo authors
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
91. Redistributions of source code must retain the above copyright
10notice, this list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright
13notice, this list of conditions and the following disclaimer in the
14documentation and/or other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its
17contributors may be used to endorse or promote products derived from
18this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31******************************<GINKGO LICENSE>*******************************/
32
33#ifndef GKO_PUBLIC_CORE_BASE_LIN_OP_HPP_
34#define GKO_PUBLIC_CORE_BASE_LIN_OP_HPP_
35
36
37#include <memory>
38#include <type_traits>
39#include <utility>
40
41
42#include <ginkgo/core/base/abstract_factory.hpp>
43#include <ginkgo/core/base/device_matrix_data.hpp>
44#include <ginkgo/core/base/dim.hpp>
45#include <ginkgo/core/base/exception_helpers.hpp>
46#include <ginkgo/core/base/math.hpp>
47#include <ginkgo/core/base/matrix_assembly_data.hpp>
48#include <ginkgo/core/base/matrix_data.hpp>
49#include <ginkgo/core/base/polymorphic_object.hpp>
50#include <ginkgo/core/base/types.hpp>
51#include <ginkgo/core/base/utils.hpp>
52#include <ginkgo/core/log/logger.hpp>
53
54
55namespace gko {
56namespace matrix {
57
58
59template <typename ValueType>
60class Diagonal;
61
62
63} // namespace matrix
64
65
147public:
159 {
160 this->template log<log::Logger::linop_apply_started>(this, b.get(),
161 x.get());
162 this->validate_application_parameters(b.get(), x.get());
163 auto exec = this->get_executor();
164 this->apply_impl(make_temporary_clone(exec, b).get(),
165 make_temporary_clone(exec, x).get());
166 this->template log<log::Logger::linop_apply_completed>(this, b.get(),
167 x.get());
168 return this;
169 }
170
175 {
176 this->template log<log::Logger::linop_apply_started>(this, b.get(),
177 x.get());
178 this->validate_application_parameters(b.get(), x.get());
179 auto exec = this->get_executor();
180 this->apply_impl(make_temporary_clone(exec, b).get(),
181 make_temporary_clone(exec, x).get());
182 this->template log<log::Logger::linop_apply_completed>(this, b.get(),
183 x.get());
184 return this;
185 }
186
199 {
201 this, alpha.get(), b.get(), beta.get(), x.get());
202 this->validate_application_parameters(alpha.get(), b.get(), beta.get(),
203 x.get());
204 auto exec = this->get_executor();
205 this->apply_impl(make_temporary_clone(exec, alpha).get(),
206 make_temporary_clone(exec, b).get(),
207 make_temporary_clone(exec, beta).get(),
208 make_temporary_clone(exec, x).get());
210 this, alpha.get(), b.get(), beta.get(), x.get());
211 return this;
212 }
213
219 {
221 this, alpha.get(), b.get(), beta.get(), x.get());
222 this->validate_application_parameters(alpha.get(), b.get(), beta.get(),
223 x.get());
224 auto exec = this->get_executor();
225 this->apply_impl(make_temporary_clone(exec, alpha).get(),
226 make_temporary_clone(exec, b).get(),
227 make_temporary_clone(exec, beta).get(),
228 make_temporary_clone(exec, x).get());
230 this, alpha.get(), b.get(), beta.get(), x.get());
231 return this;
232 }
233
239 const dim<2>& get_size() const noexcept { return size_; }
240
248 virtual bool apply_uses_initial_guess() const { return false; }
249
251 LinOp& operator=(const LinOp&) = default;
252
259 {
260 if (this != &other) {
262 this->set_size(other.get_size());
263 other.set_size({});
264 }
265 return *this;
266 }
267
269 LinOp(const LinOp&) = default;
270
277 size_{std::exchange(other.size_, dim<2>{})}
278 {}
279
280protected:
287 explicit LinOp(std::shared_ptr<const Executor> exec,
288 const dim<2>& size = dim<2>{})
289 : EnableAbstractPolymorphicObject<LinOp>(exec), size_{size}
290 {}
291
297 void set_size(const dim<2>& value) noexcept { size_ = value; }
298
308 virtual void apply_impl(const LinOp* b, LinOp* x) const = 0;
309
319 virtual void apply_impl(const LinOp* alpha, const LinOp* b,
320 const LinOp* beta, LinOp* x) const = 0;
321
329 void validate_application_parameters(const LinOp* b, const LinOp* x) const
330 {
331 GKO_ASSERT_CONFORMANT(this, b);
332 GKO_ASSERT_EQUAL_ROWS(this, x);
333 GKO_ASSERT_EQUAL_COLS(b, x);
334 }
335
345 void validate_application_parameters(const LinOp* alpha, const LinOp* b,
346 const LinOp* beta,
347 const LinOp* x) const
348 {
349 this->validate_application_parameters(b, x);
350 GKO_ASSERT_EQUAL_DIMENSIONS(alpha, dim<2>(1, 1));
351 GKO_ASSERT_EQUAL_DIMENSIONS(beta, dim<2>(1, 1));
352 }
353
354private:
355 dim<2> size_{};
356};
357
358
415public:
416 using AbstractFactory<LinOp, std::shared_ptr<const LinOp>>::AbstractFactory;
417
418 std::unique_ptr<LinOp> generate(std::shared_ptr<const LinOp> input) const
419 {
420 this->template log<log::Logger::linop_factory_generate_started>(
421 this, input.get());
422 const auto exec = this->get_executor();
423 std::unique_ptr<LinOp> generated;
424 if (input->get_executor() == exec) {
425 generated = this->AbstractFactory::generate(input);
426 } else {
427 generated =
428 this->AbstractFactory::generate(gko::clone(exec, input));
429 }
430 this->template log<log::Logger::linop_factory_generate_completed>(
431 this, input.get(), generated.get());
432 return generated;
433 }
434};
435
436
463public:
464 virtual ~Transposable() = default;
465
471 virtual std::unique_ptr<LinOp> transpose() const = 0;
472
479 virtual std::unique_ptr<LinOp> conj_transpose() const = 0;
480};
481
482
512template <typename IndexType>
514public:
515 virtual ~Permutable() = default;
516
531 virtual std::unique_ptr<LinOp> permute(
532 const array<IndexType>* permutation_indices) const
533 {
534 return as<Permutable>(this->row_permute(permutation_indices))
535 ->column_permute(permutation_indices);
536 }
537
552 virtual std::unique_ptr<LinOp> inverse_permute(
553 const array<IndexType>* permutation_indices) const
554 {
555 return as<Permutable>(this->inverse_row_permute(permutation_indices))
556 ->inverse_column_permute(permutation_indices);
557 }
558
572 virtual std::unique_ptr<LinOp> row_permute(
573 const array<IndexType>* permutation_indices) const = 0;
574
589 virtual std::unique_ptr<LinOp> column_permute(
590 const array<IndexType>* permutation_indices) const = 0;
591
605 virtual std::unique_ptr<LinOp> inverse_row_permute(
606 const array<IndexType>* permutation_indices) const = 0;
607
622 virtual std::unique_ptr<LinOp> inverse_column_permute(
623 const array<IndexType>* permutation_indices) const = 0;
624};
625
626
633template <typename ValueType, typename IndexType>
635public:
636 using value_type = ValueType;
637 using index_type = IndexType;
638
639 virtual ~ReadableFromMatrixData() = default;
640
646 virtual void read(const matrix_data<ValueType, IndexType>& data) = 0;
647
654 {
655 this->read(data.get_ordered_data());
656 }
657
664 {
665 this->read(data.copy_to_host());
666 }
667
675 {
676 this->read(data.copy_to_host());
677 data.empty_out();
678 }
679};
680
681
688template <typename ValueType, typename IndexType>
690public:
691 using value_type = ValueType;
692 using index_type = IndexType;
693
694 virtual ~WritableToMatrixData() = default;
695
701 virtual void write(matrix_data<ValueType, IndexType>& data) const = 0;
702};
703
704
712public:
713 virtual ~Preconditionable() = default;
714
720 virtual std::shared_ptr<const LinOp> get_preconditioner() const
721 {
722 return preconditioner_;
723 }
724
731 virtual void set_preconditioner(std::shared_ptr<const LinOp> new_precond)
732 {
733 preconditioner_ = new_precond;
734 }
735
736private:
737 std::shared_ptr<const LinOp> preconditioner_{};
738};
739
740
752public:
753 virtual ~DiagonalLinOpExtractable() = default;
754
760 virtual std::unique_ptr<LinOp> extract_diagonal_linop() const = 0;
761};
762
763
771template <typename ValueType>
773public:
774 using value_type = ValueType;
775
776 virtual ~DiagonalExtractable() = default;
777
778 std::unique_ptr<LinOp> extract_diagonal_linop() const override;
779
785 virtual std::unique_ptr<matrix::Diagonal<ValueType>> extract_diagonal()
786 const = 0;
787};
788
789
796public:
802 virtual std::unique_ptr<LinOp> compute_absolute_linop() const = 0;
803
807 virtual void compute_absolute_inplace() = 0;
808};
809
810
822template <typename AbsoluteLinOp>
824public:
825 using absolute_type = AbsoluteLinOp;
826
827 virtual ~EnableAbsoluteComputation() = default;
828
829 std::unique_ptr<LinOp> compute_absolute_linop() const override
830 {
831 return this->compute_absolute();
832 }
833
839 virtual std::unique_ptr<absolute_type> compute_absolute() const = 0;
840};
841
842
848public:
858 {
859 GKO_ASSERT_IS_SCALAR(a);
860 GKO_ASSERT_IS_SCALAR(b);
861 auto ae = make_temporary_clone(as<LinOp>(this)->get_executor(), a);
862 auto be = make_temporary_clone(as<LinOp>(this)->get_executor(), b);
863 add_scaled_identity_impl(ae.get(), be.get());
864 }
865
866private:
867 virtual void add_scaled_identity_impl(const LinOp* a, const LinOp* b) = 0;
868};
869
870
905template <typename ConcreteLinOp, typename PolymorphicBase = LinOp>
907 : public EnablePolymorphicObject<ConcreteLinOp, PolymorphicBase>,
908 public EnablePolymorphicAssignment<ConcreteLinOp> {
909public:
910 using EnablePolymorphicObject<ConcreteLinOp,
911 PolymorphicBase>::EnablePolymorphicObject;
912
913 const ConcreteLinOp* apply(ptr_param<const LinOp> b,
914 ptr_param<LinOp> x) const
915 {
916 PolymorphicBase::apply(b, x);
917 return self();
918 }
919
920 ConcreteLinOp* apply(ptr_param<const LinOp> b, ptr_param<LinOp> x)
921 {
922 PolymorphicBase::apply(b, x);
923 return self();
924 }
925
926 const ConcreteLinOp* apply(ptr_param<const LinOp> alpha,
929 ptr_param<LinOp> x) const
930 {
931 PolymorphicBase::apply(alpha, b, beta, x);
932 return self();
933 }
934
935 ConcreteLinOp* apply(ptr_param<const LinOp> alpha, ptr_param<const LinOp> b,
937 {
938 PolymorphicBase::apply(alpha, b, beta, x);
939 return self();
940 }
941
942protected:
943 GKO_ENABLE_SELF(ConcreteLinOp);
944};
945
946
964template <typename ConcreteFactory, typename ConcreteLinOp,
965 typename ParametersType, typename PolymorphicBase = LinOpFactory>
967 EnableDefaultFactory<ConcreteFactory, ConcreteLinOp, ParametersType,
968 PolymorphicBase>;
969
970
1046#define GKO_ENABLE_LIN_OP_FACTORY(_lin_op, _parameters_name, _factory_name) \
1047public: \
1048 const _parameters_name##_type& get_##_parameters_name() const \
1049 { \
1050 return _parameters_name##_; \
1051 } \
1052 \
1053 class _factory_name \
1054 : public ::gko::EnableDefaultLinOpFactory<_factory_name, _lin_op, \
1055 _parameters_name##_type> { \
1056 friend class ::gko::EnablePolymorphicObject<_factory_name, \
1057 ::gko::LinOpFactory>; \
1058 friend class ::gko::enable_parameters_type<_parameters_name##_type, \
1059 _factory_name>; \
1060 explicit _factory_name(std::shared_ptr<const ::gko::Executor> exec) \
1061 : ::gko::EnableDefaultLinOpFactory<_factory_name, _lin_op, \
1062 _parameters_name##_type>( \
1063 std::move(exec)) \
1064 {} \
1065 explicit _factory_name(std::shared_ptr<const ::gko::Executor> exec, \
1066 const _parameters_name##_type& parameters) \
1067 : ::gko::EnableDefaultLinOpFactory<_factory_name, _lin_op, \
1068 _parameters_name##_type>( \
1069 std::move(exec), parameters) \
1070 {} \
1071 }; \
1072 friend ::gko::EnableDefaultLinOpFactory<_factory_name, _lin_op, \
1073 _parameters_name##_type>; \
1074 \
1075 \
1076private: \
1077 _parameters_name##_type _parameters_name##_; \
1078 \
1079public: \
1080 static_assert(true, \
1081 "This assert is used to counter the false positive extra " \
1082 "semi-colon warnings")
1083
1084
1085} // namespace gko
1086
1087
1088#endif // GKO_PUBLIC_CORE_BASE_LIN_OP_HPP_
The AbsoluteComputable is an interface that allows to get the component wise absolute of a LinOp.
Definition lin_op.hpp:795
virtual void compute_absolute_inplace()=0
Compute absolute inplace on each element.
virtual std::unique_ptr< LinOp > compute_absolute_linop() const =0
Gets the absolute LinOp.
The AbstractFactory is a generic interface template that enables easy implementation of the abstract ...
Definition abstract_factory.hpp:75
The diagonal of a LinOp implementing this interface can be extracted.
Definition lin_op.hpp:772
std::unique_ptr< LinOp > extract_diagonal_linop() const override
Extracts the diagonal entries of the matrix into a vector.
virtual std::unique_ptr< matrix::Diagonal< ValueType > > extract_diagonal() const =0
Extracts the diagonal entries of the matrix into a vector.
The diagonal of a LinOp can be extracted.
Definition lin_op.hpp:751
virtual std::unique_ptr< LinOp > extract_diagonal_linop() const =0
Extracts the diagonal entries of the matrix into a vector.
The EnableAbsoluteComputation mixin provides the default implementations of compute_absolute_linop an...
Definition lin_op.hpp:823
virtual std::unique_ptr< absolute_type > compute_absolute() const =0
Gets the AbsoluteLinOp.
std::unique_ptr< LinOp > compute_absolute_linop() const override
Gets the absolute LinOp.
Definition lin_op.hpp:829
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:374
This mixin provides a default implementation of a concrete factory.
Definition abstract_factory.hpp:154
The EnableLinOp mixin can be used to provide sensible default implementations of the majority of the ...
Definition lin_op.hpp:908
This mixin is used to enable a default PolymorphicObject::copy_from() implementation for objects that...
Definition polymorphic_object.hpp:752
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:691
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition lin_op.hpp:414
Definition lin_op.hpp:146
LinOp * apply(ptr_param< const LinOp > alpha, ptr_param< const LinOp > b, ptr_param< const LinOp > beta, ptr_param< LinOp > x)
Performs the operation x = alpha * op(b) + beta * x.
Definition lin_op.hpp:197
LinOp(const LinOp &)=default
Copy-constructs a LinOp.
virtual bool apply_uses_initial_guess() const
Returns true if the linear operator uses the data given in x as an initial guess.
Definition lin_op.hpp:248
LinOp * apply(ptr_param< const LinOp > b, ptr_param< LinOp > x)
Applies a linear operator to a vector (or a sequence of vectors).
Definition lin_op.hpp:158
const dim< 2 > & get_size() const noexcept
Returns the size of the operator.
Definition lin_op.hpp:239
LinOp(LinOp &&other)
Move-constructs a LinOp.
Definition lin_op.hpp:275
LinOp & operator=(LinOp &&other)
Move-assigns a LinOp.
Definition lin_op.hpp:258
const LinOp * apply(ptr_param< const LinOp > b, ptr_param< LinOp > x) const
Definition lin_op.hpp:174
const LinOp * apply(ptr_param< const LinOp > alpha, ptr_param< const LinOp > b, ptr_param< const LinOp > beta, ptr_param< LinOp > x) const
Definition lin_op.hpp:217
LinOp & operator=(const LinOp &)=default
Copy-assigns a LinOp.
Linear operators which support permutation should implement the Permutable interface.
Definition lin_op.hpp:513
virtual std::unique_ptr< LinOp > inverse_column_permute(const array< IndexType > *permutation_indices) const =0
Returns a LinOp representing the row permutation of the inverse permuted object.
virtual std::unique_ptr< LinOp > row_permute(const array< IndexType > *permutation_indices) const =0
Returns a LinOp representing the row permutation of the Permutable object.
virtual std::unique_ptr< LinOp > inverse_row_permute(const array< IndexType > *permutation_indices) const =0
Returns a LinOp representing the row permutation of the inverse permuted object.
virtual std::unique_ptr< LinOp > inverse_permute(const array< IndexType > *permutation_indices) const
Returns a LinOp representing the symmetric inverse row and column permutation of the Permutable objec...
Definition lin_op.hpp:552
virtual std::unique_ptr< LinOp > column_permute(const array< IndexType > *permutation_indices) const =0
Returns a LinOp representing the column permutation of the Permutable object.
virtual std::unique_ptr< LinOp > permute(const array< IndexType > *permutation_indices) const
Returns a LinOp representing the symmetric row and column permutation of the Permutable object.
Definition lin_op.hpp:531
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition polymorphic_object.hpp:263
A LinOp implementing this interface can be preconditioned.
Definition lin_op.hpp:711
virtual void set_preconditioner(std::shared_ptr< const LinOp > new_precond)
Sets the preconditioner operator used by the Preconditionable.
Definition lin_op.hpp:731
virtual std::shared_ptr< const LinOp > get_preconditioner() const
Returns the preconditioner operator used by the Preconditionable.
Definition lin_op.hpp:720
A LinOp implementing this interface can read its data from a matrix_data structure.
Definition lin_op.hpp:634
virtual void read(const device_matrix_data< ValueType, IndexType > &data)
Reads a matrix from a device_matrix_data structure.
Definition lin_op.hpp:663
virtual void read(device_matrix_data< ValueType, IndexType > &&data)
Reads a matrix from a device_matrix_data structure.
Definition lin_op.hpp:674
void read(const matrix_assembly_data< ValueType, IndexType > &data)
Reads a matrix from a matrix_assembly_data structure.
Definition lin_op.hpp:653
virtual void read(const matrix_data< ValueType, IndexType > &data)=0
Reads a matrix from a matrix_data structure.
Adds the operation M <- a I + b M for matrix M, identity operator I and scalars a and b,...
Definition lin_op.hpp:847
void add_scaled_identity(ptr_param< const LinOp > const a, ptr_param< const LinOp > const b)
Scales this and adds another scalar times the identity to it.
Definition lin_op.hpp:856
Linear operators which support transposition should implement the Transposable interface.
Definition lin_op.hpp:462
virtual std::unique_ptr< LinOp > conj_transpose() const =0
Returns a LinOp representing the conjugate transpose of the Transposable object.
virtual std::unique_ptr< LinOp > transpose() const =0
Returns a LinOp representing the transpose of the Transposable object.
A LinOp implementing this interface can write its data to a matrix_data structure.
Definition lin_op.hpp:689
virtual void write(matrix_data< ValueType, IndexType > &data) const =0
Writes a matrix to a matrix_data structure.
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition array.hpp:187
This type is a device-side equivalent to matrix_data.
Definition device_matrix_data.hpp:63
host_type copy_to_host() const
Copies the device_matrix_data entries to the host to return a regular matrix_data object with the sam...
This structure is used as an intermediate type to assemble a sparse matrix.
Definition matrix_assembly_data.hpp:88
matrix_data< ValueType, IndexType > get_ordered_data() const
Definition matrix_assembly_data.hpp:169
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:71
T * get() const
Definition utils_helper.hpp:105
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:203
std::unique_ptr< MatrixType > read(StreamType &&is, MatrixArgs &&... args)
Reads a matrix stored in matrix market format from an input stream.
Definition mtx_io.hpp:188
detail::temporary_clone< detail::pointee< Ptr > > make_temporary_clone(std::shared_ptr< const Executor > exec, Ptr &&ptr)
Creates a temporary_clone.
Definition temporary_clone.hpp:207
A type representing the dimensions of a multidimensional object.
Definition dim.hpp:55
This structure is used as an intermediate data type to store a sparse matrix.
Definition matrix_data.hpp:155