Ginkgo Generated from branch based on main. Ginkgo version 1.11.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
jacobi.hpp
1// SPDX-FileCopyrightText: 2017 - 2025 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/config/config.hpp>
12#include <ginkgo/core/config/registry.hpp>
13#include <ginkgo/core/matrix/csr.hpp>
14#include <ginkgo/core/matrix/dense.hpp>
15#include <ginkgo/core/matrix/diagonal.hpp>
16
17
18namespace gko {
24namespace preconditioner {
25
26
27// TODO: replace this with a custom accessor
36template <typename IndexType>
37struct block_interleaved_storage_scheme {
38 block_interleaved_storage_scheme() = default;
39
40 block_interleaved_storage_scheme(IndexType block_offset,
45 {}
46
50 IndexType block_offset;
51
55 IndexType group_offset;
56
63
69 GKO_ATTRIBUTES IndexType get_group_size() const noexcept
70 {
71 return one<IndexType>() << group_power;
72 }
73
86 GKO_ATTRIBUTES size_type
87 compute_storage_space(size_type num_blocks) const noexcept
88 {
89 return (num_blocks + 1 == size_type{0})
90 ? size_type{0}
91 : ceildiv(num_blocks, this->get_group_size()) * group_offset;
92 }
93
101 GKO_ATTRIBUTES IndexType get_group_offset(IndexType block_id) const noexcept
102 {
103 return group_offset * (block_id >> group_power);
104 }
105
113 GKO_ATTRIBUTES IndexType get_block_offset(IndexType block_id) const noexcept
114 {
115 return block_offset * (block_id & (this->get_group_size() - 1));
116 }
117
125 GKO_ATTRIBUTES IndexType
126 get_global_block_offset(IndexType block_id) const noexcept
127 {
128 return this->get_group_offset(block_id) +
129 this->get_block_offset(block_id);
130 }
131
137 GKO_ATTRIBUTES IndexType get_stride() const noexcept
138 {
139 return block_offset << group_power;
140 }
141};
142
143
186template <typename ValueType = default_precision, typename IndexType = int32>
187class Jacobi : public EnableLinOp<Jacobi<ValueType, IndexType>>,
188 public ConvertibleTo<matrix::Dense<ValueType>>,
189 public WritableToMatrixData<ValueType, IndexType>,
190 public Transposable {
191 friend class EnableLinOp<Jacobi>;
192 friend class EnablePolymorphicObject<Jacobi, LinOp>;
193 GKO_ASSERT_SUPPORTED_VALUE_AND_INDEX_TYPE;
194
195public:
196 using EnableLinOp<Jacobi>::convert_to;
197 using EnableLinOp<Jacobi>::move_to;
198 using ConvertibleTo<matrix::Dense<ValueType>>::convert_to;
199 using ConvertibleTo<matrix::Dense<ValueType>>::move_to;
200 using value_type = ValueType;
201 using index_type = IndexType;
202 using mat_data = matrix_data<ValueType, IndexType>;
203 using transposed_type = Jacobi<ValueType, IndexType>;
204
213 size_type get_num_blocks() const noexcept { return num_blocks_; }
214
224 const noexcept
225 {
226 return storage_scheme_;
227 }
228
240 const value_type* get_blocks() const noexcept
241 {
242 return blocks_.get_const_data();
243 }
244
255 {
256 return conditioning_.get_const_data();
257 }
258
265 {
266 return blocks_.get_size();
267 }
268
269 void convert_to(matrix::Dense<value_type>* result) const override;
270
271 void move_to(matrix::Dense<value_type>* result) override;
272
273 void write(mat_data& data) const override;
274
275 std::unique_ptr<LinOp> transpose() const override;
276
277 std::unique_ptr<LinOp> conj_transpose() const override;
278
283 Jacobi& operator=(const Jacobi& other);
284
291
296 Jacobi(const Jacobi& other);
297
303 Jacobi(Jacobi&& other);
304
306 {
316
327
346
373 nullptr);
374
387
388 private:
389 // See documentation of storage_optimization parameter for details about
390 // this class
391 struct storage_optimization_type {
392 storage_optimization_type(precision_reduction p)
393 : is_block_wise{false}, of_all_blocks{p}
394 {}
395
396 storage_optimization_type(
397 const array<precision_reduction>& block_wise_opt)
398 : is_block_wise{block_wise_opt.get_size() > 0},
399 block_wise{block_wise_opt}
400 {}
401
402 storage_optimization_type(
403 array<precision_reduction>&& block_wise_opt)
404 : is_block_wise{block_wise_opt.get_size() > 0},
405 block_wise{std::move(block_wise_opt)}
406 {}
407
408 operator precision_reduction() { return of_all_blocks; }
409
410 bool is_block_wise;
411 precision_reduction of_all_blocks;
413 };
414
415 public:
483 storage_optimization_type GKO_FACTORY_PARAMETER_VECTOR(
485
514 };
515 GKO_ENABLE_LIN_OP_FACTORY(Jacobi, parameters, Factory);
517
534 static parameters_type parse(
535 const config::pnode& config, const config::registry& context,
536 const config::type_descriptor& td_for_child =
537 config::make_type_descriptor<ValueType, IndexType>());
538
539protected:
545 explicit Jacobi(std::shared_ptr<const Executor> exec)
546 : EnableLinOp<Jacobi>(exec),
547 num_blocks_{},
548 blocks_(exec),
549 conditioning_(exec)
550 {
551 parameters_.block_pointers.set_executor(exec);
552 parameters_.storage_optimization.block_wise.set_executor(exec);
553 }
554
562 explicit Jacobi(const Factory* factory,
563 std::shared_ptr<const LinOp> system_matrix)
564 : EnableLinOp<Jacobi>(factory->get_executor(),
565 gko::transpose(system_matrix->get_size())),
566 parameters_{factory->get_parameters()},
567 storage_scheme_{this->compute_storage_scheme(
568 parameters_.max_block_size, parameters_.max_block_stride)},
569 num_blocks_{parameters_.block_pointers.get_size() - 1},
570 blocks_(factory->get_executor(),
571 storage_scheme_.compute_storage_space(
572 parameters_.block_pointers.get_size() - 1)),
573 conditioning_(factory->get_executor())
574 {
575 parameters_.block_pointers.set_executor(this->get_executor());
576 parameters_.storage_optimization.block_wise.set_executor(
577 this->get_executor());
578 this->generate(system_matrix.get(), parameters_.skip_sorting);
579 }
580
589 block_interleaved_storage_scheme<index_type> compute_storage_scheme(
590 uint32 max_block_size, uint32 param_max_block_stride)
591 {
592 uint32 default_block_stride = 32;
593 // If the executor is hip, the warp size is 32 or 64
594 if (auto hip_exec = std::dynamic_pointer_cast<const gko::HipExecutor>(
595 this->get_executor())) {
596 default_block_stride = hip_exec->get_warp_size();
597 }
598 uint32 max_block_stride = default_block_stride;
599 if (param_max_block_stride != 0) {
600 // if parameter max_block_stride is not zero, set max_block_stride =
601 // param_max_block_stride
602 max_block_stride = param_max_block_stride;
603 if (this->get_executor() != this->get_executor()->get_master() &&
604 max_block_stride != default_block_stride) {
605 // only support the default value on the gpu device
606 GKO_NOT_SUPPORTED(this);
607 }
608 }
609 if (parameters_.max_block_size > max_block_stride ||
610 parameters_.max_block_size < 1) {
611 GKO_NOT_SUPPORTED(this);
612 }
613 const auto group_size = static_cast<uint32>(
614 max_block_stride / get_superior_power(uint32{2}, max_block_size));
615 const auto block_offset = max_block_size;
616 const auto block_stride = group_size * block_offset;
617 const auto group_offset = max_block_size * block_stride;
618 return {static_cast<index_type>(block_offset),
619 static_cast<index_type>(group_offset),
620 get_significant_bit(group_size)};
621 }
622
632 void generate(const LinOp* system_matrix, bool skip_sorting);
633
641 void detect_blocks(const matrix::Csr<ValueType, IndexType>* system_matrix);
642
643 void apply_impl(const LinOp* b, LinOp* x) const override;
644
645 void apply_impl(const LinOp* alpha, const LinOp* b, const LinOp* beta,
646 LinOp* x) const override;
647
648private:
649 block_interleaved_storage_scheme<index_type> storage_scheme_{};
650 size_type num_blocks_;
651 array<value_type> blocks_;
653};
654
655
656} // namespace preconditioner
657} // namespace gko
658
659
660#endif // GKO_PUBLIC_CORE_PRECONDITIONER_JACOBI_HPP_
The EnableLinOp mixin can be used to provide sensible default implementations of the majority of the ...
Definition lin_op.hpp:879
This mixin inherits from (a subclass of) PolymorphicObject and provides a base implementation of a ne...
Definition polymorphic_object.hpp:668
Definition lin_op.hpp:117
Linear operators which support transposition should implement the Transposable interface.
Definition lin_op.hpp:433
A LinOp implementing this interface can write its data to a matrix_data structure.
Definition lin_op.hpp:660
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition array.hpp:166
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:714
pnode describes a tree of properties.
Definition property_tree.hpp:28
This class stores additional context for creating Ginkgo objects from configuration files.
Definition registry.hpp:167
This class describes the value and index types to be used when building a Ginkgo type from a configur...
Definition type_descriptor.hpp:39
Dense is a matrix format which explicitly stores all values of the matrix.
Definition dense.hpp:120
This class is used to encode storage precisions of low precision algorithms.
Definition types.hpp:239
Definition jacobi.hpp:515
A block-Jacobi preconditioner is a block-diagonal linear operator, obtained by inverting the diagonal...
Definition jacobi.hpp:190
const block_interleaved_storage_scheme< index_type > & get_storage_scheme() const noexcept
Returns the storage scheme used for storing Jacobi blocks.
Definition jacobi.hpp:223
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:254
Jacobi(Jacobi &&other)
Move-assigns a Jacobi preconditioner.
static parameters_type parse(const config::pnode &config, const config::registry &context, const config::type_descriptor &td_for_child=config::make_type_descriptor< ValueType, IndexType >())
Create the parameters from the property_tree.
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:240
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:264
size_type get_num_blocks() const noexcept
Returns the number of blocks of the operator.
Definition jacobi.hpp:213
#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:1017
#define GKO_FACTORY_PARAMETER_VECTOR(_name,...)
Creates a vector factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:461
The Preconditioner namespace.
Definition gauss_seidel.hpp:19
The Ginkgo namespace.
Definition abstract_factory.hpp:20
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:654
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:264
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:1057
virtual void move_to(result_type *result)=0
Converts the implementer to an object of type result_type by moving data from this object.
virtual void convert_to(result_type *result) const =0
ConvertibleTo interface is used to mark that the implementer can be converted to the object of Result...
std::uint32_t uint32
32-bit unsigned integral type.
Definition types.hpp:130
constexpr int64 ceildiv(int64 num, int64 den)
Performs integer division with rounding up.
Definition math.hpp:614
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:90
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:119
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:1075
@ array
The matrix should be written as dense matrix in column-major order.
Definition mtx_io.hpp:97
void write(StreamType &&os, MatrixPtrType &&matrix, layout_type layout=detail::mtx_io_traits< std::remove_cv_t< detail::pointee< MatrixPtrType > > >::default_layout)
Writes a matrix into an output stream in matrix market format.
Definition mtx_io.hpp:299
STL namespace.
This structure is used as an intermediate data type to store a sparse matrix.
Definition matrix_data.hpp:126
uint32 max_block_stride
Stride between two columns of a block (as number of elements).
Definition jacobi.hpp:326
storage_optimization_type storage_optimization
The precisions to use for the blocks of the matrix.
Definition jacobi.hpp:484
uint32 max_block_size
Maximal size of diagonal blocks.
Definition jacobi.hpp:315
remove_complex< value_type > accuracy
The relative accuracy of the adaptive Jacobi variant.
Definition jacobi.hpp:513
gko::array< index_type > block_pointers
Starting (row / column) indexes of individual blocks.
Definition jacobi.hpp:373
bool skip_sorting
true means it is known that the matrix given to this factory will be sorted first by row,...
Definition jacobi.hpp:345
bool aggregate_l1
Use L1 Jacboi, which is introduced in the paper A.
Definition jacobi.hpp:386
Defines the parameters of the interleaved block storage scheme used by block-Jacobi blocks.
Definition jacobi.hpp:37
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:113
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:101
uint32 group_power
Then base 2 power of the group.
Definition jacobi.hpp:62
IndexType get_stride() const noexcept
Returns the stride between columns of the block.
Definition jacobi.hpp:137
IndexType group_offset
The offset between two block groups.
Definition jacobi.hpp:55
IndexType get_global_block_offset(IndexType block_id) const noexcept
Returns the offset of the block with the given ID.
Definition jacobi.hpp:126
IndexType block_offset
The offset between consecutive blocks within the group.
Definition jacobi.hpp:50
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:87
IndexType get_group_size() const noexcept
Returns the number of elements in the group.
Definition jacobi.hpp:69