From 323053296ebd2eb9afdf93c9bc2a6d1e8eae3494 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 11:28:51 +0200 Subject: [PATCH 01/18] wip minimal vector interface --- include/ginkgo/core/matrix/multivector.hpp | 141 +++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 include/ginkgo/core/matrix/multivector.hpp diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp new file mode 100644 index 00000000000..0e7b67aa2af --- /dev/null +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: 2025 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#pragma once + +#include + +#include + + +namespace gko { +namespace matrix { + +struct local_span : span {}; + + +class MultiVector : public EnableAbstractPolymorphicObject { +public: + [[nodiscard]] static std::unique_ptr create_with_config_of( + ptr_param other) + { + return other->create_with_same_config_impl(); + } + + [[nodiscard]] static std::unique_ptr create_with_type_of( + ptr_param other, + std::shared_ptr exec, const dim<2>& size, + size_type stride) + { + return other->create_with_type_of_impl(std::move(exec), size, stride); + } + + [[nodiscard]] static std::unique_ptr create_view_of( + ptr_param other) + { + return other->create_view_of_impl(); + } + + [[nodiscard]] static std::unique_ptr + create_const_view_of(ptr_param other) + { + return other->create_const_view_of_impl(); + } + + [[nodiscard]] virtual std::unique_ptr create_absolute_type() + const = 0; + + [[nodiscard]] virtual std::unique_ptr compute_absolute() + const = 0; + + virtual void compute_absolute_inplace() = 0; + + [[nodiscard]] virtual std::unique_ptr make_complex() const = 0; + + virtual void make_complex(ptr_param result) const = 0; + + [[nodiscard]] virtual std::unique_ptr get_real() const = 0; + + virtual void get_real(ptr_param result) const = 0; + + [[nodiscard]] virtual std::unique_ptr get_imag() const = 0; + + virtual void get_imag(ptr_param result) const = 0; + + virtual void scale(ptr_param alpha) = 0; + + virtual void inv_scale(ptr_param alpha) = 0; + + virtual void add_scaled(ptr_param alpha, + ptr_param b) = 0; + + virtual void sub_scaled(ptr_param alpha, + ptr_param b) = 0; + + virtual void compute_dot(ptr_param b, + ptr_param result) const = 0; + + virtual void compute_dot(ptr_param b, ptr_param result, + array& tmp) const = 0; + + virtual void compute_conj_dot(ptr_param b, + ptr_param result) const = 0; + + virtual void compute_conj_dot(ptr_param b, + ptr_param result, + array& tmp) const = 0; + + virtual void compute_norm2(ptr_param result) const = 0; + + virtual void compute_norm2(ptr_param result, + array& tmp) const = 0; + + virtual void compute_norm1(ptr_param result) const = 0; + + virtual void compute_norm1(ptr_param result, + array& tmp) const = 0; + + [[nodiscard]] virtual std::unique_ptr create_real_view() + const = 0; + + [[nodiscard]] virtual std::unique_ptr create_real_view() = 0; + + [[nodiscard]] virtual std::unique_ptr create_subview( + local_span rows, local_span columns); + + [[nodiscard]] virtual std::unique_ptr create_subview( + local_span rows, local_span columns, size_type global_rows, + size_type globals_cols); + + [[nodiscard]] dim<2> get_size() const noexcept { return size_; } + +protected: + explicit MultiVector(std::shared_ptr exec, + const dim<2>& size = dim<2>{}) + : EnableAbstractPolymorphicObject(std::move(exec)), + size_{size} + {} + + [[nodiscard]] virtual std::unique_ptr + create_with_same_config_impl() const = 0; + + [[nodiscard]] virtual std::unique_ptr create_with_type_of_impl( + std::shared_ptr exec, const dim<2>& size, + size_type stride) const = 0; + + [[nodiscard]] virtual std::unique_ptr + create_view_of_impl() = 0; + + [[nodiscard]] virtual std::unique_ptr + create_const_view_of_impl() const = 0; + + void set_size(const dim<2>& size) noexcept { size_ = size; } + +private: + dim<2> size_; +}; + + +} // namespace matrix +} // namespace gko From d2f80c9ada093cdcc168d2902008811535e392c0 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 11:31:56 +0200 Subject: [PATCH 02/18] wip minimal vector interface --- include/ginkgo/core/matrix/multivector.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp index 0e7b67aa2af..a5599d2063e 100644 --- a/include/ginkgo/core/matrix/multivector.hpp +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -4,18 +4,19 @@ #pragma once -#include - #include namespace gko { namespace matrix { + struct local_span : span {}; -class MultiVector : public EnableAbstractPolymorphicObject { +template +class MultiVector + : public EnableAbstractPolymorphicObject> { public: [[nodiscard]] static std::unique_ptr create_with_config_of( ptr_param other) From b578f3bf859b86885173e77489b234e5b0d361bc Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 12:05:24 +0200 Subject: [PATCH 03/18] wip minimal vector interface --- core/CMakeLists.txt | 1 + core/matrix/multivector.cpp | 67 +++++++++++++++ include/ginkgo/core/matrix/multivector.hpp | 94 +++++++++------------- 3 files changed, 107 insertions(+), 55 deletions(-) create mode 100644 core/matrix/multivector.cpp diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index b7342bb03d8..3a1a6fd7ca7 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources( matrix/fft.cpp matrix/hybrid.cpp matrix/identity.cpp + matrix/multivector.cpp matrix/permutation.cpp matrix/row_gatherer.cpp matrix/scaled_permutation.cpp diff --git a/core/matrix/multivector.cpp b/core/matrix/multivector.cpp new file mode 100644 index 00000000000..7cbf71809be --- /dev/null +++ b/core/matrix/multivector.cpp @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2025 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + +namespace gko { +namespace matrix { + + +template +std::unique_ptr> +MultiVector::create_with_config_of( + ptr_param other) +{ + return other->create_with_same_config_impl(); +} + + +template +std::unique_ptr> +MultiVector::create_with_type_of( + ptr_param other, std::shared_ptr exec) +{ + return other->create_with_type_of_impl(std::move(exec), {}, {}, 0); +} + + +template +std::unique_ptr> +MultiVector::create_with_type_of( + ptr_param other, std::shared_ptr exec, + const dim<2>& global_size, const dim<2>& local_size) +{ + GKO_ASSERT_EQUAL_COLS(global_size, local_size); + return other->create_with_type_of_impl(std::move(exec), global_size, + local_size, global_size[1]); +} + + +template +std::unique_ptr> +MultiVector::create_with_type_of( + ptr_param other, std::shared_ptr exec, + const dim<2>& global_size, const dim<2>& local_size, size_type stride) +{ + return other->create_with_type_of_impl(std::move(exec), global_size, + local_size, stride); +} + + +template +dim<2> MultiVector::get_size() const noexcept +{ + return size_; +} + + +template +void MultiVector::set_size(const dim<2>& size) noexcept +{ + size_ = size; +} + + +} // namespace matrix +} // namespace gko diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp index a5599d2063e..889d0fb2d0f 100644 --- a/include/ginkgo/core/matrix/multivector.hpp +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -14,35 +14,25 @@ namespace matrix { struct local_span : span {}; -template -class MultiVector - : public EnableAbstractPolymorphicObject> { +template +class MultiVector : public EnableLinOp { public: [[nodiscard]] static std::unique_ptr create_with_config_of( - ptr_param other) - { - return other->create_with_same_config_impl(); - } + ptr_param other); [[nodiscard]] static std::unique_ptr create_with_type_of( ptr_param other, - std::shared_ptr exec, const dim<2>& size, - size_type stride) - { - return other->create_with_type_of_impl(std::move(exec), size, stride); - } - - [[nodiscard]] static std::unique_ptr create_view_of( - ptr_param other) - { - return other->create_view_of_impl(); - } - - [[nodiscard]] static std::unique_ptr - create_const_view_of(ptr_param other) - { - return other->create_const_view_of_impl(); - } + std::shared_ptr exec); + + [[nodiscard]] static std::unique_ptr create_with_type_of( + ptr_param other, + std::shared_ptr exec, const dim<2>& global_size, + const dim<2>& local_size); + + [[nodiscard]] static std::unique_ptr create_with_type_of( + ptr_param other, + std::shared_ptr exec, const dim<2>& global_size, + const dim<2>& local_size, size_type stride); [[nodiscard]] virtual std::unique_ptr create_absolute_type() const = 0; @@ -64,37 +54,38 @@ class MultiVector virtual void get_imag(ptr_param result) const = 0; - virtual void scale(ptr_param alpha) = 0; + virtual void scale(ptr_param alpha) = 0; - virtual void inv_scale(ptr_param alpha) = 0; + virtual void inv_scale(ptr_param alpha) = 0; - virtual void add_scaled(ptr_param alpha, - ptr_param b) = 0; + virtual void add_scaled(ptr_param alpha, + ptr_param b) = 0; - virtual void sub_scaled(ptr_param alpha, - ptr_param b) = 0; + virtual void sub_scaled(ptr_param alpha, + ptr_param b) = 0; - virtual void compute_dot(ptr_param b, - ptr_param result) const = 0; + virtual void compute_dot(ptr_param b, + ptr_param result) const = 0; - virtual void compute_dot(ptr_param b, ptr_param result, + virtual void compute_dot(ptr_param b, + ptr_param result, array& tmp) const = 0; - virtual void compute_conj_dot(ptr_param b, - ptr_param result) const = 0; + virtual void compute_conj_dot(ptr_param b, + ptr_param result) const = 0; - virtual void compute_conj_dot(ptr_param b, - ptr_param result, + virtual void compute_conj_dot(ptr_param b, + ptr_param result, array& tmp) const = 0; - virtual void compute_norm2(ptr_param result) const = 0; + virtual void compute_norm2(ptr_param result) const = 0; - virtual void compute_norm2(ptr_param result, + virtual void compute_norm2(ptr_param result, array& tmp) const = 0; - virtual void compute_norm1(ptr_param result) const = 0; + virtual void compute_norm1(ptr_param result) const = 0; - virtual void compute_norm1(ptr_param result, + virtual void compute_norm1(ptr_param result, array& tmp) const = 0; [[nodiscard]] virtual std::unique_ptr create_real_view() @@ -103,35 +94,28 @@ class MultiVector [[nodiscard]] virtual std::unique_ptr create_real_view() = 0; [[nodiscard]] virtual std::unique_ptr create_subview( - local_span rows, local_span columns); + local_span rows, local_span columns) = 0; [[nodiscard]] virtual std::unique_ptr create_subview( local_span rows, local_span columns, size_type global_rows, - size_type globals_cols); + size_type globals_cols) = 0; - [[nodiscard]] dim<2> get_size() const noexcept { return size_; } + [[nodiscard]] dim<2> get_size() const noexcept; protected: explicit MultiVector(std::shared_ptr exec, const dim<2>& size = dim<2>{}) - : EnableAbstractPolymorphicObject(std::move(exec)), - size_{size} + : EnableLinOp(std::move(exec)), size_{size} {} [[nodiscard]] virtual std::unique_ptr create_with_same_config_impl() const = 0; [[nodiscard]] virtual std::unique_ptr create_with_type_of_impl( - std::shared_ptr exec, const dim<2>& size, - size_type stride) const = 0; - - [[nodiscard]] virtual std::unique_ptr - create_view_of_impl() = 0; - - [[nodiscard]] virtual std::unique_ptr - create_const_view_of_impl() const = 0; + std::shared_ptr exec, const dim<2>& global_size, + const dim<2>& local_size, size_type stride) const = 0; - void set_size(const dim<2>& size) noexcept { size_ = size; } + void set_size(const dim<2>& size) noexcept; private: dim<2> size_; From 96d13b338ab66d0f958b3098016fb40a1c46339b Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 13:04:46 +0200 Subject: [PATCH 04/18] wip minimal vector interface --- core/matrix/multivector.cpp | 36 ++++++++-------- include/ginkgo/core/matrix/multivector.hpp | 49 ++++++++++++---------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/core/matrix/multivector.cpp b/core/matrix/multivector.cpp index 7cbf71809be..8d4996963ba 100644 --- a/core/matrix/multivector.cpp +++ b/core/matrix/multivector.cpp @@ -8,27 +8,27 @@ namespace gko { namespace matrix { -template -std::unique_ptr> -MultiVector::create_with_config_of( +template +std::unique_ptr> +MultiVector::create_with_config_of( ptr_param other) { return other->create_with_same_config_impl(); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec) { return other->create_with_type_of_impl(std::move(exec), {}, {}, 0); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size) { @@ -38,9 +38,9 @@ MultiVector::create_with_type_of( } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size, size_type stride) { @@ -49,17 +49,17 @@ MultiVector::create_with_type_of( } -template -dim<2> MultiVector::get_size() const noexcept +template +dim<2> MultiVector::get_size() const noexcept { - return size_; + return LinOp::get_size(); } -template -void MultiVector::set_size(const dim<2>& size) noexcept +template +void MultiVector::set_size(const dim<2>& size) noexcept { - size_ = size; + LinOp::set_size(size); } diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp index 889d0fb2d0f..44ce53bc03d 100644 --- a/include/ginkgo/core/matrix/multivector.hpp +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -14,9 +14,14 @@ namespace matrix { struct local_span : span {}; -template -class MultiVector : public EnableLinOp { +template +class MultiVector : public EnableLinOp> { public: + using value_type = ValueType; + using absolute_type = remove_complex; + using real_type = absolute_type; + using complex_type = to_complex; + [[nodiscard]] static std::unique_ptr create_with_config_of( ptr_param other); @@ -34,25 +39,23 @@ class MultiVector : public EnableLinOp { std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size, size_type stride); - [[nodiscard]] virtual std::unique_ptr create_absolute_type() - const = 0; - - [[nodiscard]] virtual std::unique_ptr compute_absolute() + [[nodiscard]] virtual std::unique_ptr compute_absolute() const = 0; virtual void compute_absolute_inplace() = 0; - [[nodiscard]] virtual std::unique_ptr make_complex() const = 0; + [[nodiscard]] virtual std::unique_ptr make_complex() + const = 0; - virtual void make_complex(ptr_param result) const = 0; + virtual void make_complex(ptr_param result) const = 0; - [[nodiscard]] virtual std::unique_ptr get_real() const = 0; + [[nodiscard]] virtual std::unique_ptr get_real() const = 0; - virtual void get_real(ptr_param result) const = 0; + virtual void get_real(ptr_param result) const = 0; - [[nodiscard]] virtual std::unique_ptr get_imag() const = 0; + [[nodiscard]] virtual std::unique_ptr get_imag() const = 0; - virtual void get_imag(ptr_param result) const = 0; + virtual void get_imag(ptr_param result) const = 0; virtual void scale(ptr_param alpha) = 0; @@ -78,20 +81,20 @@ class MultiVector : public EnableLinOp { ptr_param result, array& tmp) const = 0; - virtual void compute_norm2(ptr_param result) const = 0; + virtual void compute_norm2(ptr_param result) const = 0; - virtual void compute_norm2(ptr_param result, + virtual void compute_norm2(ptr_param result, array& tmp) const = 0; - virtual void compute_norm1(ptr_param result) const = 0; + virtual void compute_norm1(ptr_param result) const = 0; - virtual void compute_norm1(ptr_param result, + virtual void compute_norm1(ptr_param result, array& tmp) const = 0; - [[nodiscard]] virtual std::unique_ptr create_real_view() + [[nodiscard]] virtual std::unique_ptr create_real_view() const = 0; - [[nodiscard]] virtual std::unique_ptr create_real_view() = 0; + [[nodiscard]] virtual std::unique_ptr create_real_view() = 0; [[nodiscard]] virtual std::unique_ptr create_subview( local_span rows, local_span columns) = 0; @@ -105,7 +108,7 @@ class MultiVector : public EnableLinOp { protected: explicit MultiVector(std::shared_ptr exec, const dim<2>& size = dim<2>{}) - : EnableLinOp(std::move(exec)), size_{size} + : EnableLinOp(std::move(exec), size) {} [[nodiscard]] virtual std::unique_ptr @@ -115,10 +118,12 @@ class MultiVector : public EnableLinOp { std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size, size_type stride) const = 0; - void set_size(const dim<2>& size) noexcept; + void apply_impl(const LinOp* b, LinOp* x) const override {} + void apply_impl(const LinOp* alpha, const LinOp* b, const LinOp* beta, + LinOp* x) const override + {} -private: - dim<2> size_; + void set_size(const dim<2>& size) noexcept; }; From 57a297a1cb48478677658d44aef03e3707055d3a Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 14:41:06 +0200 Subject: [PATCH 05/18] wip minimal vector interface --- core/matrix/multivector.cpp | 32 +++++++++++----------- include/ginkgo/core/matrix/multivector.hpp | 12 ++++---- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/core/matrix/multivector.cpp b/core/matrix/multivector.cpp index 8d4996963ba..98fd6b6793e 100644 --- a/core/matrix/multivector.cpp +++ b/core/matrix/multivector.cpp @@ -8,27 +8,27 @@ namespace gko { namespace matrix { -template -std::unique_ptr> -MultiVector::create_with_config_of( +template +std::unique_ptr> +MultiVector::create_with_config_of( ptr_param other) { return other->create_with_same_config_impl(); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec) { return other->create_with_type_of_impl(std::move(exec), {}, {}, 0); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size) { @@ -38,9 +38,9 @@ MultiVector::create_with_type_of( } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size, size_type stride) { @@ -49,15 +49,15 @@ MultiVector::create_with_type_of( } -template -dim<2> MultiVector::get_size() const noexcept +template +dim<2> MultiVector::get_size() const noexcept { return LinOp::get_size(); } -template -void MultiVector::set_size(const dim<2>& size) noexcept +template +void MultiVector::set_size(const dim<2>& size) noexcept { LinOp::set_size(size); } diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp index 44ce53bc03d..609b022523c 100644 --- a/include/ginkgo/core/matrix/multivector.hpp +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -13,14 +13,16 @@ namespace matrix { struct local_span : span {}; - -template -class MultiVector : public EnableLinOp> { +// @todo: remove ConcreteType +template +class MultiVector : public EnableLinOp { public: using value_type = ValueType; - using absolute_type = remove_complex; + using absolute_type = + MultiVector, remove_complex>; using real_type = absolute_type; - using complex_type = to_complex; + using complex_type = + MultiVector, to_complex>; [[nodiscard]] static std::unique_ptr create_with_config_of( ptr_param other); From 84df76f9683131b513cb2b90057ee077297a87ed Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 14:55:12 +0200 Subject: [PATCH 06/18] remove concrete type --- core/matrix/multivector.cpp | 32 +++++++++++----------- include/ginkgo/core/matrix/multivector.hpp | 12 ++++---- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/core/matrix/multivector.cpp b/core/matrix/multivector.cpp index 98fd6b6793e..8d4996963ba 100644 --- a/core/matrix/multivector.cpp +++ b/core/matrix/multivector.cpp @@ -8,27 +8,27 @@ namespace gko { namespace matrix { -template -std::unique_ptr> -MultiVector::create_with_config_of( +template +std::unique_ptr> +MultiVector::create_with_config_of( ptr_param other) { return other->create_with_same_config_impl(); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec) { return other->create_with_type_of_impl(std::move(exec), {}, {}, 0); } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size) { @@ -38,9 +38,9 @@ MultiVector::create_with_type_of( } -template -std::unique_ptr> -MultiVector::create_with_type_of( +template +std::unique_ptr> +MultiVector::create_with_type_of( ptr_param other, std::shared_ptr exec, const dim<2>& global_size, const dim<2>& local_size, size_type stride) { @@ -49,15 +49,15 @@ MultiVector::create_with_type_of( } -template -dim<2> MultiVector::get_size() const noexcept +template +dim<2> MultiVector::get_size() const noexcept { return LinOp::get_size(); } -template -void MultiVector::set_size(const dim<2>& size) noexcept +template +void MultiVector::set_size(const dim<2>& size) noexcept { LinOp::set_size(size); } diff --git a/include/ginkgo/core/matrix/multivector.hpp b/include/ginkgo/core/matrix/multivector.hpp index 609b022523c..70b71a7f6cb 100644 --- a/include/ginkgo/core/matrix/multivector.hpp +++ b/include/ginkgo/core/matrix/multivector.hpp @@ -13,16 +13,14 @@ namespace matrix { struct local_span : span {}; -// @todo: remove ConcreteType -template -class MultiVector : public EnableLinOp { +template +class MultiVector + : public EnableAbstractPolymorphicObject> { public: using value_type = ValueType; - using absolute_type = - MultiVector, remove_complex>; + using absolute_type = MultiVector>; using real_type = absolute_type; - using complex_type = - MultiVector, to_complex>; + using complex_type = MultiVector>; [[nodiscard]] static std::unique_ptr create_with_config_of( ptr_param other); From 5f49c0e11054204e7599480ad061f2d7869d0079 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Mon, 14 Jul 2025 17:12:41 +0200 Subject: [PATCH 07/18] meta programming helpers --- .../ginkgo/core/synthesizer/containers.hpp | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/include/ginkgo/core/synthesizer/containers.hpp b/include/ginkgo/core/synthesizer/containers.hpp index 27cdf027804..b89068ac9a6 100644 --- a/include/ginkgo/core/synthesizer/containers.hpp +++ b/include/ginkgo/core/synthesizer/containers.hpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors // // SPDX-License-Identifier: BSD-3-Clause @@ -8,6 +8,7 @@ #include #include +#include namespace gko { @@ -177,6 +178,46 @@ constexpr std::array as_array(value_list vl) return std::array{Value...}; } +namespace detail { + +template