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
jacobi.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_PRECONDITIONER_JACOBI_HPP_
34#define GKO_PUBLIC_CORE_PRECONDITIONER_JACOBI_HPP_
35
36
37#include <ginkgo/core/base/array.hpp>
38#include <ginkgo/core/base/lin_op.hpp>
39#include <ginkgo/core/matrix/csr.hpp>
40#include <ginkgo/core/matrix/dense.hpp>
41#include <ginkgo/core/matrix/diagonal.hpp>
42
43
44namespace gko {
50namespace preconditioner {
51
52
53// TODO: replace this with a custom accessor
62template <typename IndexType>
65
71 {}
72
76 IndexType block_offset;
77
81 IndexType group_offset;
82
89
95 GKO_ATTRIBUTES IndexType get_group_size() const noexcept
96 {
97 return one<IndexType>() << group_power;
98 }
99
112 GKO_ATTRIBUTES size_type
114 {
115 return (num_blocks + 1 == size_type{0})
116 ? size_type{0}
118 }
119
127 GKO_ATTRIBUTES IndexType get_group_offset(IndexType block_id) const noexcept
128 {
129 return group_offset * (block_id >> group_power);
130 }
131
139 GKO_ATTRIBUTES IndexType get_block_offset(IndexType block_id) const noexcept
140 {
141 return block_offset * (block_id & (this->get_group_size() - 1));
142 }
143
151 GKO_ATTRIBUTES IndexType
152 get_global_block_offset(IndexType block_id) const noexcept
153 {
154 return this->get_group_offset(block_id) +
156 }
157
163 GKO_ATTRIBUTES IndexType get_stride() const noexcept
164 {
165 return block_offset << group_power;
166 }
167};
168
169
212template <typename ValueType = default_precision, typename IndexType = int32>
213class Jacobi : public EnableLinOp<Jacobi<ValueType, IndexType>>,
214 public ConvertibleTo<matrix::Dense<ValueType>>,
215 public WritableToMatrixData<ValueType, IndexType>,
216 public Transposable {
217 friend class EnableLinOp<Jacobi>;
218 friend class EnablePolymorphicObject<Jacobi, LinOp>;
219
220public:
221 using EnableLinOp<Jacobi>::convert_to;
222 using EnableLinOp<Jacobi>::move_to;
223 using ConvertibleTo<matrix::Dense<ValueType>>::convert_to;
225 using value_type = ValueType;
226 using index_type = IndexType;
229
238 size_type get_num_blocks() const noexcept { return num_blocks_; }
239
250 {
251 return storage_scheme_;
252 }
253
265 const value_type* get_blocks() const noexcept
266 {
267 return blocks_.get_const_data();
268 }
269
280 {
281 return conditioning_.get_const_data();
282 }
283
290 {
291 return blocks_.get_num_elems();
292 }
293
294 void convert_to(matrix::Dense<value_type>* result) const override;
295
296 void move_to(matrix::Dense<value_type>* result) override;
297
298 void write(mat_data& data) const override;
299
300 std::unique_ptr<LinOp> transpose() const override;
301
302 std::unique_ptr<LinOp> conj_transpose() const override;
303
309
316
322
329
331 {
341
352
370 bool GKO_FACTORY_PARAMETER_SCALAR(skip_sorting, false);
371
398 nullptr);
399
400 private:
401 // See documentation of storage_optimization parameter for details about
402 // this class
403 struct storage_optimization_type {
404 storage_optimization_type(precision_reduction p)
405 : is_block_wise{false}, of_all_blocks{p}
406 {}
407
408 storage_optimization_type(
409 const array<precision_reduction>& block_wise_opt)
410 : is_block_wise{block_wise_opt.get_num_elems() > 0},
411 block_wise{block_wise_opt}
412 {}
413
414 storage_optimization_type(
415 array<precision_reduction>&& block_wise_opt)
416 : is_block_wise{block_wise_opt.get_num_elems() > 0},
417 block_wise{std::move(block_wise_opt)}
418 {}
419
420 operator precision_reduction() { return of_all_blocks; }
421
422 bool is_block_wise;
423 precision_reduction of_all_blocks;
425 };
426
427 public:
495 storage_optimization_type GKO_FACTORY_PARAMETER_VECTOR(
496 storage_optimization, precision_reduction(0, 0));
497
525 accuracy, static_cast<remove_complex<value_type>>(1e-1));
526 };
529
530protected:
536 explicit Jacobi(std::shared_ptr<const Executor> exec)
537 : EnableLinOp<Jacobi>(exec),
538 num_blocks_{},
539 blocks_(exec),
540 conditioning_(exec)
541 {
542 parameters_.block_pointers.set_executor(exec);
543 parameters_.storage_optimization.block_wise.set_executor(exec);
544 }
545
553 explicit Jacobi(const Factory* factory,
554 std::shared_ptr<const LinOp> system_matrix)
555 : EnableLinOp<Jacobi>(factory->get_executor(),
556 gko::transpose(system_matrix->get_size())),
557 parameters_{factory->get_parameters()},
558 storage_scheme_{this->compute_storage_scheme(
559 parameters_.max_block_size, parameters_.max_block_stride)},
560 num_blocks_{parameters_.block_pointers.get_num_elems() - 1},
561 blocks_(factory->get_executor(),
562 storage_scheme_.compute_storage_space(
563 parameters_.block_pointers.get_num_elems() - 1)),
564 conditioning_(factory->get_executor())
565 {
566 parameters_.block_pointers.set_executor(this->get_executor());
567 parameters_.storage_optimization.block_wise.set_executor(
568 this->get_executor());
569 this->generate(system_matrix.get(), parameters_.skip_sorting);
570 }
571
581 uint32 max_block_size, uint32 param_max_block_stride)
582 {
584 // If the executor is hip, the warp size is 32 or 64
585 if (auto hip_exec = std::dynamic_pointer_cast<const gko::HipExecutor>(
586 this->get_executor())) {
587 default_block_stride = hip_exec->get_warp_size();
588 }
589 uint32 max_block_stride = default_block_stride;
590 if (param_max_block_stride != 0) {
591 // if parameter max_block_stride is not zero, set max_block_stride =
592 // param_max_block_stride
593 max_block_stride = param_max_block_stride;
594 if (this->get_executor() != this->get_executor()->get_master() &&
595 max_block_stride != default_block_stride) {
596 // only support the default value on the gpu device
597 GKO_NOT_SUPPORTED(this);
598 }
599 }
600 if (parameters_.max_block_size > max_block_stride ||
601 parameters_.max_block_size < 1) {
602 GKO_NOT_SUPPORTED(this);
603 }
604 const auto group_size = static_cast<uint32>(
605 max_block_stride / get_superior_power(uint32{2}, max_block_size));
606 const auto block_offset = max_block_size;
607 const auto block_stride = group_size * block_offset;
608 const auto group_offset = max_block_size * block_stride;
609 return {static_cast<index_type>(block_offset),
610 static_cast<index_type>(group_offset),
612 }
613
623 void generate(const LinOp* system_matrix, bool skip_sorting);
624
632 void detect_blocks(const matrix::Csr<ValueType, IndexType>* system_matrix);
633
634 void apply_impl(const LinOp* b, LinOp* x) const override;
635
636 void apply_impl(const LinOp* alpha, const LinOp* b, const LinOp* beta,
637 LinOp* x) const override;
638
639private:
640 block_interleaved_storage_scheme<index_type> storage_scheme_{};
641 size_type num_blocks_;
642 array<value_type> blocks_;
644};
645
646
647} // namespace preconditioner
648} // namespace gko
649
650
651#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:499
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
A LinOp implementing this interface can write its data to a matrix_data structure.
Definition lin_op.hpp:689
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition array.hpp:187
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:655
size_type get_num_elems() const noexcept
Returns the number of elements in the array.
Definition array.hpp:637
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:673
Dense is a matrix format which explicitly stores all values of the matrix.
Definition dense.hpp:136
This class is used to encode storage precisions of low precision algorithms.
Definition types.hpp:272
Definition jacobi.hpp:527
A block-Jacobi preconditioner is a block-diagonal linear operator, obtained by inverting the diagonal...
Definition jacobi.hpp:216
const block_interleaved_storage_scheme< index_type > & get_storage_scheme() const noexcept
Returns the storage scheme used for storing Jacobi blocks.
Definition jacobi.hpp:248
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:279
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:265
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:289
size_type get_num_blocks() const noexcept
Returns the number of blocks of the operator.
Definition jacobi.hpp:238
#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:308
#define GKO_FACTORY_PARAMETER_SCALAR(_name, _default)
Creates a scalar factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:473
#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
#define GKO_FACTORY_PARAMETER_VECTOR(_name,...)
Creates a vector factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:489
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
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:1161
std::uint32_t uint32
32-bit unsigned integral type.
Definition types.hpp:160
constexpr int64 ceildiv(int64 num, int64 den)
Performs integer division with rounding up.
Definition math.hpp:641
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:120
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:1179
This structure is used as an intermediate data type to store a sparse matrix.
Definition matrix_data.hpp:155
storage_optimization_type storage_optimization
The precisions to use for the blocks of the matrix.
Definition jacobi.hpp:496
uint32 max_block_size
Maximal size of diagonal blocks.
Definition jacobi.hpp:340
gko::array< index_type > block_pointers
Starting (row / column) indexes of individual blocks.
Definition jacobi.hpp:398
bool skip_sorting
true means it is known that the matrix given to this factory will be sorted first by row,...
Definition jacobi.hpp:370
Defines the parameters of the interleaved block storage scheme used by block-Jacobi blocks.
Definition jacobi.hpp:63
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:139
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:127
uint32 group_power
Then base 2 power of the group.
Definition jacobi.hpp:88
IndexType get_stride() const noexcept
Returns the stride between columns of the block.
Definition jacobi.hpp:163
IndexType group_offset
The offset between two block groups.
Definition jacobi.hpp:81
IndexType get_global_block_offset(IndexType block_id) const noexcept
Returns the offset of the block with the given ID.
Definition jacobi.hpp:152
IndexType block_offset
The offset between consecutive blocks within the group.
Definition jacobi.hpp:76
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:113
IndexType get_group_size() const noexcept
Returns the number of elements in the group.
Definition jacobi.hpp:95