From Jason Turner

[linalg.layout.packed]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpzrdgsb3a/{from.md → to.md} +203 -0
tmp/tmpzrdgsb3a/{from.md → to.md} RENAMED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Layouts for packed matrix types <a id="linalg.layout.packed">[[linalg.layout.packed]]</a>
2
+
3
+ #### Overview <a id="linalg.layout.packed.overview">[[linalg.layout.packed.overview]]</a>
4
+
5
+ `layout_blas_packed` is an `mdspan` layout mapping policy that
6
+ represents a square matrix that stores only the entries in one triangle,
7
+ in a packed contiguous format. Its `Triangle` template parameter
8
+ determines whether an `mdspan` with this layout stores the upper or
9
+ lower triangle of the matrix. Its `StorageOrder` template parameter
10
+ determines whether the layout packs the matrix’s elements in
11
+ column-major or row-major order.
12
+
13
+ A `StorageOrder` of `column_major_t` indicates column-major ordering.
14
+ This packs matrix elements starting with the leftmost (least column
15
+ index) column, and proceeding column by column, from the top entry
16
+ (least row index).
17
+
18
+ A `StorageOrder` of `row_major_t` indicates row-major ordering. This
19
+ packs matrix elements starting with the topmost (least row index) row,
20
+ and proceeding row by row, from the leftmost (least column index) entry.
21
+
22
+ [*Note 1*: `layout_blas_packed` describes the data layout used by the
23
+ BLAS’ Symmetric Packed (SP), Hermitian Packed (HP), and Triangular
24
+ Packed (TP) matrix types. — *end note*]
25
+
26
+ ``` cpp
27
+ namespace std::linalg {
28
+ template<class Triangle, class StorageOrder>
29
+ class layout_blas_packed {
30
+ public:
31
+ using triangle_type = Triangle;
32
+ using storage_order_type = StorageOrder;
33
+
34
+ template<class Extents>
35
+ struct mapping {
36
+ public:
37
+ using extents_type = Extents;
38
+ using index_type = extents_type::index_type;
39
+ using size_type = extents_type::size_type;
40
+ using rank_type = extents_type::rank_type;
41
+ using layout_type = layout_blas_packed;
42
+
43
+ // [linalg.layout.packed.cons], constructors
44
+ constexpr mapping() noexcept = default;
45
+ constexpr mapping(const mapping&) noexcept = default;
46
+ constexpr mapping(const extents_type&) noexcept;
47
+ template<class OtherExtents>
48
+ constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
49
+ mapping(const mapping<OtherExtents>& other) noexcept;
50
+
51
+ constexpr mapping& operator=(const mapping&) noexcept = default;
52
+
53
+ // [linalg.layout.packed.obs], observers
54
+ constexpr const extents_type& extents() const noexcept { return extents_; }
55
+
56
+ constexpr index_type required_span_size() const noexcept;
57
+
58
+ template<class Index0, class Index1>
59
+ constexpr index_type operator() (Index0 ind0, Index1 ind1) const noexcept;
60
+
61
+ static constexpr bool is_always_unique() noexcept {
62
+ return (extents_type::static_extent(0) != dynamic_extent &&
63
+ extents_type::static_extent(0) < 2) ||
64
+ (extents_type::static_extent(1) != dynamic_extent &&
65
+ extents_type::static_extent(1) < 2);
66
+ }
67
+ static constexpr bool is_always_exhaustive() noexcept { return true; }
68
+ static constexpr bool is_always_strided() noexcept
69
+ { return is_always_unique(); }
70
+
71
+ constexpr bool is_unique() const noexcept {
72
+ return extents_.extent(0) < 2;
73
+ }
74
+ constexpr bool is_exhaustive() const noexcept { return true; }
75
+ constexpr bool is_strided() const noexcept {
76
+ return extents_.extent(0) < 2;
77
+ }
78
+
79
+ constexpr index_type stride(rank_type) const noexcept;
80
+
81
+ template<class OtherExtents>
82
+ friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept;
83
+
84
+ private:
85
+ extents_type extents_{}; // exposition only
86
+ };
87
+ };
88
+ }
89
+ ```
90
+
91
+ *Mandates:*
92
+
93
+ - `Triangle` is either `upper_triangle_t` or `lower_triangle_t`,
94
+ - `StorageOrder` is either `column_major_t` or `row_major_t`,
95
+ - `Extents` is a specialization of `std::extents`,
96
+ - `Extents::rank()` equals 2,
97
+ - one of
98
+ ``` cpp
99
+ extents_type::static_extent(0) == dynamic_extent,
100
+ extents_type::static_extent(1) == dynamic_extent, or
101
+ extents_type::static_extent(0) == extents_type::static_extent(1)
102
+ ```
103
+
104
+ is `true`, and
105
+ - if `Extents::rank_dynamic() == 0` is `true`, let Nₛ be equal to
106
+ `Extents::static_extent(0)`; then, Nₛ × (Nₛ + 1) is representable as a
107
+ value of type `index_type`.
108
+
109
+ `layout_blas_packed<T, SO>::mapping<E>` is a trivially copyable type
110
+ that models `regular` for each `T`, `SO`, and `E`.
111
+
112
+ #### Constructors <a id="linalg.layout.packed.cons">[[linalg.layout.packed.cons]]</a>
113
+
114
+ ``` cpp
115
+ constexpr mapping(const extents_type& e) noexcept;
116
+ ```
117
+
118
+ *Preconditions:*
119
+
120
+ - Let N be equal to `e.extent(0)`. Then, N × (N+1) is representable as a
121
+ value of type `index_type` [[basic.fundamental]].
122
+ - `e.extent(0)` equals `e.extent(1)`.
123
+
124
+ *Effects:* Direct-non-list-initializes *extents\_* with `e`.
125
+
126
+ ``` cpp
127
+ template<class OtherExtents>
128
+ explicit(!is_convertible_v<OtherExtents, extents_type>)
129
+ constexpr mapping(const mapping<OtherExtents>& other) noexcept;
130
+ ```
131
+
132
+ *Constraints:* `is_constructible_v<extents_type, OtherExtents>` is
133
+ `true`.
134
+
135
+ *Preconditions:* Let N be `other.extents().extent(0)`. Then, N × (N+1)
136
+ is representable as a value of type `index_type` [[basic.fundamental]].
137
+
138
+ *Effects:* Direct-non-list-initializes *extents\_* with
139
+ `other.extents()`.
140
+
141
+ #### Observers <a id="linalg.layout.packed.obs">[[linalg.layout.packed.obs]]</a>
142
+
143
+ ``` cpp
144
+ constexpr index_type required_span_size() const noexcept;
145
+ ```
146
+
147
+ *Returns:* *`extents_`*`.extent(0) * (`*`extents_`*`.extent(0) + 1)/2`.
148
+
149
+ [*Note 1*: For example, a 5 x 5 packed matrix only stores 15 matrix
150
+ elements. — *end note*]
151
+
152
+ ``` cpp
153
+ template<class Index0, class Index1>
154
+ constexpr index_type operator() (Index0 ind0, Index1 ind1) const noexcept;
155
+ ```
156
+
157
+ *Constraints:*
158
+
159
+ - `is_convertible_v<Index0, index_type>` is `true`,
160
+ - `is_convertible_v<Index1, index_type>` is `true`,
161
+ - `is_nothrow_constructible_v<index_type, Index0>` is `true`, and
162
+ - `is_nothrow_constructible_v<index_type, Index1>` is `true`.
163
+
164
+ Let `i` be `extents_type::`*`index-cast`*`(ind0)`, and let `j` be
165
+ `extents_type::`*`index-cast`*`(ind1)`.
166
+
167
+ *Preconditions:* `i, j` is a multidimensional index in
168
+ *extents\_*[[mdspan.overview]].
169
+
170
+ *Returns:* Let `N` be *`extents_`*`.extent(0)`. Then
171
+
172
+ - `(*this)(j, i)` if `i > j` is `true`; otherwise
173
+ - `i + j * (j + 1)/2` if
174
+ ``` cpp
175
+ is_same_v<StorageOrder, column_major_t> && is_same_v<Triangle, upper_triangle_t>
176
+ ```
177
+
178
+ is `true` or
179
+ ``` cpp
180
+ is_same_v<StorageOrder, row_major_t> && is_same_v<Triangle, lower_triangle_t>
181
+ ```
182
+
183
+ is `true`; otherwise
184
+ - `j + N * i - i * (i + 1)/2`.
185
+
186
+ ``` cpp
187
+ constexpr index_type stride(rank_type r) const noexcept;
188
+ ```
189
+
190
+ *Preconditions:*
191
+
192
+ - `is_strided()` is `true`, and
193
+ - `r < extents_type::rank()` is `true`.
194
+
195
+ *Returns:* `1`.
196
+
197
+ ``` cpp
198
+ template<class OtherExtents>
199
+ friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
200
+ ```
201
+
202
+ *Effects:* Equivalent to: `return x.extents() == y.extents();`
203
+