tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
layout_transpose.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch
3
4#ifndef TETL_LINALG_LAYOUT_TRANSPOSE_HPP
5#define TETL_LINALG_LAYOUT_TRANSPOSE_HPP
6
7#include <etl/_linalg/concepts.hpp>
8#include <etl/_span/dynamic_extent.hpp>
9
10namespace etl::linalg {
11
12namespace detail {
13
14template <typename Extents>
15using transpose_extents_t = extents<typename Extents::index_type, Extents::static_extent(1), Extents::static_extent(0)>;
16
17template <typename Extents>
18 requires(Extents::rank() == 2)
19[[nodiscard]] constexpr auto transpose_extents(Extents const& e) -> transpose_extents_t<Extents>
20{
21 constexpr auto isDynamicE0 = Extents::static_extent(0) == dynamic_extent;
22 constexpr auto isDynamicE1 = Extents::static_extent(1) == dynamic_extent;
23
24 if constexpr (isDynamicE0) {
25 if constexpr (isDynamicE1) {
26 return transpose_extents_t<Extents>{e.extent(1), e.extent(0)};
27 } else {
28 return transpose_extents_t<Extents>{e.extent(0)};
29 }
30 } else {
31 if constexpr (isDynamicE1) {
32 return transpose_extents_t<Extents>{e.extent(1)};
33 } else {
34 return transpose_extents_t<Extents>{};
35 }
36 }
37}
38
39} // namespace detail
40
41/// \ingroup linalg
42template <typename Layout>
44 template <typename Extents>
45 requires(Extents::rank() == 2)
46 struct mapping {
47 private:
48 using nested_mapping_t = typename Layout::template mapping<detail::transpose_extents_t<Extents>>;
49 nested_mapping_t _nestedMapping;
50
51 public:
52 using extents_type = Extents;
53 using size_type = typename extents_type::size_type;
54 using layout_type = layout_transpose;
55
56 constexpr explicit mapping(nested_mapping_t const& map)
57 : _nestedMapping{map}
58 {
59 }
60
61 [[nodiscard]] constexpr auto extents() const noexcept(noexcept(_nestedMapping.extents())) -> extents_type
62 {
63 return detail::transpose_extents(_nestedMapping.extents());
64 }
65
66 [[nodiscard]] constexpr auto required_span_size() const noexcept(noexcept(_nestedMapping.required_span_size()))
67 {
68 return _nestedMapping.required_span_size();
69 }
70
71 template <typename IndexType, typename... Indices>
72 [[nodiscard]] constexpr auto
73 operator()(Indices... rest, IndexType i, IndexType j) const noexcept(noexcept(_nestedMapping(rest..., j, i))) ->
74 typename Extents::size_type
75 {
76 return _nestedMapping(rest..., j, i);
77 }
78
79 [[nodiscard]] constexpr auto nested_mapping() const -> nested_mapping_t
80 {
81 return _nestedMapping;
82 }
83
84 [[nodiscard]] static constexpr auto is_always_unique() -> bool
85 {
86 return nested_mapping_t::is_always_unique();
87 }
88
89 [[nodiscard]] static constexpr auto is_always_contiguous() -> bool
90 {
91 return nested_mapping_t::is_always_contiguous();
92 }
93
94 [[nodiscard]] static constexpr auto is_always_strided() -> bool
95 {
96 return nested_mapping_t::is_always_strided();
97 }
98
99 [[nodiscard]] constexpr auto is_unique() const noexcept(noexcept(_nestedMapping.is_unique())) -> bool
100 {
101 return _nestedMapping.is_unique();
102 }
103
104 [[nodiscard]] constexpr auto is_contiguous() const noexcept(noexcept(_nestedMapping.is_contiguous())) -> bool
105 {
106 return _nestedMapping.is_contiguous();
107 }
108
109 [[nodiscard]] constexpr auto is_strided() const noexcept(noexcept(_nestedMapping.is_strided())) -> bool
110 {
111 return _nestedMapping.is_strided();
112 }
113
114 [[nodiscard]] constexpr auto stride(size_t r) const noexcept(noexcept(_nestedMapping.stride(r))) -> size_type
115 requires(is_always_strided())
116 {
117 if (r == Extents::rank() - 1) {
118 return _nestedMapping.stride(r - 2);
119 }
120 if (r == Extents::rank() - 2) {
121 return _nestedMapping.stride(r - 1);
122 }
123 return _nestedMapping.stride(r);
124 }
125
126 template <typename OtherExtents>
127 requires(Extents::rank() == OtherExtents::rank())
128 friend constexpr auto operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept -> bool
129 {
130 return lhs._nestedMapping == rhs._nestedMapping;
131 }
132 };
133};
134
135} // namespace etl::linalg
136
137#endif // TETL_LINALG_LAYOUT_TRANSPOSE_HPP
constexpr auto dynamic_extent
etl::dynamic_extent is a constant of type etl::size_t that is used to differentiate etl::span of stat...
Definition dynamic_extent.hpp:15
Definition accessor_conjugate.hpp:13
Definition adjacent_find.hpp:9
Definition extents.hpp:23
Definition layout_transpose.hpp:46
static constexpr auto is_always_unique() -> bool
Definition layout_transpose.hpp:84
constexpr auto nested_mapping() const -> nested_mapping_t
Definition layout_transpose.hpp:79
friend constexpr auto operator==(mapping const &lhs, mapping< OtherExtents > const &rhs) noexcept -> bool
Definition layout_transpose.hpp:128
static constexpr auto is_always_contiguous() -> bool
Definition layout_transpose.hpp:89
constexpr auto is_contiguous() const noexcept(noexcept(_nestedMapping.is_contiguous())) -> bool
Definition layout_transpose.hpp:104
constexpr mapping(nested_mapping_t const &map)
Definition layout_transpose.hpp:56
constexpr auto is_unique() const noexcept(noexcept(_nestedMapping.is_unique())) -> bool
Definition layout_transpose.hpp:99
constexpr auto required_span_size() const noexcept(noexcept(_nestedMapping.required_span_size()))
Definition layout_transpose.hpp:66
constexpr auto operator()(Indices... rest, IndexType i, IndexType j) const noexcept(noexcept(_nestedMapping(rest..., j, i))) -> typename Extents::size_type
Definition layout_transpose.hpp:73
constexpr auto is_strided() const noexcept(noexcept(_nestedMapping.is_strided())) -> bool
Definition layout_transpose.hpp:109
constexpr auto extents() const noexcept(noexcept(_nestedMapping.extents())) -> extents_type
Definition layout_transpose.hpp:61
constexpr auto stride(size_t r) const noexcept(noexcept(_nestedMapping.stride(r))) -> size_type requires(is_always_strided())
Definition layout_transpose.hpp:114
static constexpr auto is_always_strided() -> bool
Definition layout_transpose.hpp:94
Definition layout_transpose.hpp:43