Ginkgo Generated from develop branch based on develop. Ginkgo version 1.8.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
jacobi.hpp
1// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifndef GKO_PUBLIC_CORE_PRECONDITIONER_JACOBI_HPP_
6#define GKO_PUBLIC_CORE_PRECONDITIONER_JACOBI_HPP_
7
8
9#include <ginkgo/core/base/array.hpp>
10#include <ginkgo/core/base/lin_op.hpp>
11#include <ginkgo/core/matrix/csr.hpp>
12#include <ginkgo/core/matrix/dense.hpp>
13#include <ginkgo/core/matrix/diagonal.hpp>
14
15
16namespace gko {
22namespace preconditioner {
23
24
25// TODO: replace this with a custom accessor
34template <typename IndexType>
37
43 {}
44
48 IndexType block_offset;
49
53 IndexType group_offset;
54
61
67 GKO_ATTRIBUTES IndexType get_group_size() const noexcept
68 {
69 return one<IndexType>() << group_power;
70 }
71
84 GKO_ATTRIBUTES size_type
86 {
87 return (num_blocks + 1 == size_type{0})
88 ? size_type{0}
90 }
91
99 GKO_ATTRIBUTES IndexType get_group_offset(IndexType block_id) const noexcept
100 {
101 return group_offset * (block_id >> group_power);
102 }
103
111 GKO_ATTRIBUTES IndexType get_block_offset(IndexType block_id) const noexcept
112 {
113 return block_offset * (block_id & (this->get_group_size() - 1));
114 }
115
123 GKO_ATTRIBUTES IndexType
124 get_global_block_offset(IndexType block_id) const noexcept
125 {
126 return this->get_group_offset(block_id) +
128 }
129
135 GKO_ATTRIBUTES IndexType get_stride() const noexcept
136 {
137 return block_offset << group_power;
138 }
139};
140
141
184template <typename ValueType = default_precision, typename IndexType = int32>
185class Jacobi : public EnableLinOp<Jacobi<ValueType, IndexType>>,
186 public ConvertibleTo<matrix::Dense<ValueType>>,
187 public WritableToMatrixData<ValueType, IndexType>,
188 public Transposable {
189 friend class EnableLinOp<Jacobi>;
190 friend class EnablePolymorphicObject<Jacobi, LinOp>;
191
192public:
193 using EnableLinOp<Jacobi>::convert_to;
194 using EnableLinOp<Jacobi>::move_to;
195 using ConvertibleTo<matrix::Dense<ValueType>>::convert_to;
197 using value_type = ValueType;
198 using index_type = IndexType;
201
210 size_type get_num_blocks() const noexcept { return num_blocks_; }
211
222 {
223 return storage_scheme_;
224 }
225
237 const value_type* get_blocks() const noexcept
238 {
239 return blocks_.get_const_data();
240 }
241
252 {
253 return conditioning_.get_const_data();
254 }
255
262 {
263 return blocks_.get_size();
264 }
265
266 void convert_to(matrix::Dense<value_type>* result) const override;
267
268 void move_to(matrix::Dense<value_type>* result) override;
269
270 void write(mat_data& data) const override;
271
272 std::unique_ptr<LinOp> transpose() const override;
273
274 std::unique_ptr<LinOp> conj_transpose() const override;
275
281
288
294
301
303 {
313
324
342 bool GKO_FACTORY_PARAMETER_SCALAR(skip_sorting, false);
343
370 nullptr);
371
372 private:
373 // See documentation of storage_optimization parameter for details about
374 // this class
375 struct storage_optimization_type {
376 storage_optimization_type(precision_reduction p)
377 : is_block_wise{false}, of_all_blocks{p}
378 {}
379
380 storage_optimization_type(
381 const array<precision_reduction>& block_wise_opt)
382 : is_block_wise{block_wise_opt.get_size() > 0},
383 block_wise{block_wise_opt}
384 {}
385
386 storage_optimization_type(
387 array<precision_reduction>&& block_wise_opt)
388 : is_block_wise{block_wise_opt.get_size() > 0},
389 block_wise{std::move(block_wise_opt)}
390 {}
391
392 operator precision_reduction() { return of_all_blocks; }
393
394 bool is_block_wise;
395 precision_reduction of_all_blocks;
397 };
398
399 public:
467 storage_optimization_type GKO_FACTORY_PARAMETER_VECTOR(
468 storage_optimization, precision_reduction(0, 0));
469
497 accuracy, static_cast<remove_complex<value_type>>(1e-1));
498 };
501
502protected:
508 explicit Jacobi(std::shared_ptr<const Executor> exec)
509 : EnableLinOp<Jacobi>(exec),
510 num_blocks_{},
511 blocks_(exec),
512 conditioning_(exec)
513 {
514 parameters_.block_pointers.set_executor(exec);
515 parameters_.storage_optimization.block_wise.set_executor(exec);
516 }
517
525 explicit Jacobi(const Factory* factory,
526 std::shared_ptr<const LinOp> system_matrix)
527 : EnableLinOp<Jacobi>(factory->get_executor(),
528 gko::transpose(system_matrix->get_size())),
529 parameters_{factory->get_parameters()},
530 storage_scheme_{this->compute_storage_scheme(
531 parameters_.max_block_size, parameters_.max_block_stride)},
532 num_blocks_{parameters_.block_pointers.get_size() - 1},
533 blocks_(factory->get_executor(),
534 storage_scheme_.compute_storage_space(
535 parameters_.block_pointers.get_size() - 1)),
536 conditioning_(factory->get_executor())
537 {
538 parameters_.block_pointers.set_executor(this->get_executor());
539 parameters_.storage_optimization.block_wise.set_executor(
540 this->get_executor());
541 this->generate(system_matrix.get(), parameters_.skip_sorting);
542 }
543
553 uint32 max_block_size, uint32 param_max_block_stride)
554 {
556 // If the executor is hip, the warp size is 32 or 64
557 if (auto hip_exec = std::dynamic_pointer_cast<const gko::HipExecutor>(
558 this->get_executor())) {
559 default_block_stride = hip_exec->get_warp_size();
560 }
561 uint32 max_block_stride = default_block_stride;
562 if (param_max_block_stride != 0) {
563 // if parameter max_block_stride is not zero, set max_block_stride =
564 // param_max_block_stride
565 max_block_stride = param_max_block_stride;
566 if (this->get_executor() != this->get_executor()->get_master() &&
567 max_block_stride != default_block_stride) {
568 // only support the default value on the gpu device
569 GKO_NOT_SUPPORTED(this);
570 }
571 }
572 if (parameters_.max_block_size > max_block_stride ||
573 parameters_.max_block_size < 1) {
574 GKO_NOT_SUPPORTED(this);
575 }
576 const auto group_size = static_cast<uint32>(
577 max_block_stride / get_superior_power(uint32{2}, max_block_size));
578 const auto block_offset = max_block_size;
579 const auto block_stride = group_size * block_offset;
580 const auto group_offset = max_block_size * block_stride;
581 return {static_cast<index_type>(block_offset),
582 static_cast<index_type>(group_offset),
584 }
585
595 void generate(const LinOp* system_matrix, bool skip_sorting);
596
604 void detect_blocks(const matrix::Csr<ValueType, IndexType>* system_matrix);
605
606 void apply_impl(const LinOp* b, LinOp* x) const override;
607
608 void apply_impl(const LinOp* alpha, const LinOp* b, const LinOp* beta,
609 LinOp* x) const override;
610
611private:
612 block_interleaved_storage_scheme<index_type> storage_scheme_{};
613 size_type num_blocks_;
614 array<value_type> blocks_;
616};
617
618
619} // namespace preconditioner
620} // namespace gko
621
622
623#endif // GKO_PUBLIC_CORE_PRECONDITIONER_JACOBI_HPP_
ConvertibleTo interface is used to mark that the implementer can be converted to the object of Result...
Definition polymorphic_object.hpp:471
The EnableLinOp mixin can be used to provide sensible default implementations of the majority of the ...
Definition lin_op.hpp:880
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:663
Definition lin_op.hpp:118
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor of the object.
Definition polymorphic_object.hpp:235
Linear operators which support transposition should implement the Transposable interface.
Definition lin_op.hpp:434
A LinOp implementing this interface can write its data to a matrix_data structure.
Definition lin_op.hpp:661
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition array.hpp:167
const value_type * get_const_data() const noexcept
Returns a constant pointer to the block of memory used to store the elements of the array.
Definition array.hpp:683
void set_executor(std::shared_ptr< const Executor > exec)
Changes the Executor of the array, moving the allocated data to the new Executor.
Definition array.hpp:701
size_type get_size() const noexcept
Returns the number of elements in the array.
Definition array.hpp:657
Dense is a matrix format which explicitly stores all values of the matrix.
Definition dense.hpp:107
This class is used to encode storage precisions of low precision algorithms.
Definition types.hpp:244
Definition jacobi.hpp:499
A block-Jacobi preconditioner is a block-diagonal linear operator, obtained by inverting the diagonal...
Definition jacobi.hpp:188
const block_interleaved_storage_scheme< index_type > & get_storage_scheme() const noexcept
Returns the storage scheme used for storing Jacobi blocks.
Definition jacobi.hpp:220
std::unique_ptr< LinOp > conj_transpose() const override
Returns a LinOp representing the conjugate transpose of the Transposable object.
Jacobi(const Jacobi &other)
Copy-constructs a Jacobi preconditioner.
const remove_complex< value_type > * get_conditioning() const noexcept
Returns an array of 1-norm condition numbers of the blocks.
Definition jacobi.hpp:251
Jacobi(Jacobi &&other)
Move-assigns a Jacobi preconditioner.
std::unique_ptr< LinOp > transpose() const override
Returns a LinOp representing the transpose of the Transposable object.
const value_type * get_blocks() const noexcept
Returns the pointer to the memory used for storing the block data.
Definition jacobi.hpp:237
void write(mat_data &data) const override
Writes a matrix to a matrix_data structure.
Jacobi & operator=(Jacobi &&other)
Move-assigns a Jacobi preconditioner.
Jacobi & operator=(const Jacobi &other)
Copy-assigns a Jacobi preconditioner.
size_type get_num_stored_elements() const noexcept
Returns the number of elements explicitly stored in the matrix.
Definition jacobi.hpp:261
size_type get_num_blocks() const noexcept
Returns the number of blocks of the operator.
Definition jacobi.hpp:210
#define GKO_CREATE_FACTORY_PARAMETERS(_parameters_name, _factory_name)
This Macro will generate a new type containing the parameters for the factory _factory_name.
Definition abstract_factory.hpp:280
#define GKO_FACTORY_PARAMETER_SCALAR(_name, _default)
Creates a scalar factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:445
#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:394
#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:1018
#define GKO_FACTORY_PARAMETER_VECTOR(_name,...)
Creates a vector factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:461
The Ginkgo namespace.
Definition abstract_factory.hpp:20
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:775
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:326
constexpr uint32 get_significant_bit(const T &n, uint32 hint=0u) noexcept
Returns the position of the most significant bit of the number.
Definition math.hpp:1133
std::uint32_t uint32
32-bit unsigned integral type.
Definition types.hpp:132
constexpr int64 ceildiv(int64 num, int64 den)
Performs integer division with rounding up.
Definition math.hpp:613
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:92
constexpr T get_superior_power(const T &base, const T &limit, const T &hint=T{1}) noexcept
Returns the smallest power of base not smaller than limit.
Definition math.hpp:1151
This structure is used as an intermediate data type to store a sparse matrix.
Definition matrix_data.hpp:127
storage_optimization_type storage_optimization
The precisions to use for the blocks of the matrix.
Definition jacobi.hpp:468
uint32 max_block_size
Maximal size of diagonal blocks.
Definition jacobi.hpp:312
gko::array< index_type > block_pointers
Starting (row / column) indexes of individual blocks.
Definition jacobi.hpp:370
bool skip_sorting
true means it is known that the matrix given to this factory will be sorted first by row,...
Definition jacobi.hpp:342
Defines the parameters of the interleaved block storage scheme used by block-Jacobi blocks.
Definition jacobi.hpp:35
IndexType get_block_offset(IndexType block_id) const noexcept
Returns the offset of the block with the given ID within its group.
Definition jacobi.hpp:111
IndexType get_group_offset(IndexType block_id) const noexcept
Returns the offset of the group belonging to the block with the given ID.
Definition jacobi.hpp:99
uint32 group_power
Then base 2 power of the group.
Definition jacobi.hpp:60
IndexType get_stride() const noexcept
Returns the stride between columns of the block.
Definition jacobi.hpp:135
IndexType group_offset
The offset between two block groups.
Definition jacobi.hpp:53
IndexType get_global_block_offset(IndexType block_id) const noexcept
Returns the offset of the block with the given ID.
Definition jacobi.hpp:124
IndexType block_offset
The offset between consecutive blocks within the group.
Definition jacobi.hpp:48
size_type compute_storage_space(size_type num_blocks) const noexcept
Computes the storage space required for the requested number of blocks.
Definition jacobi.hpp:85
IndexType get_group_size() const noexcept
Returns the number of elements in the group.
Definition jacobi.hpp:67