P2642R2: LEWG 2023/06/14 presentation
Nobody has claimed this yet.
- Dominant language
- HTML
- Stars
- 29
- Forks
- 26
- PR merge metrics
- No merged PRs in 30d
Description
P2642 (padded mdspan layouts)
Use cases
-
Overaligned start of each contiguous segment of elements
-
aligned_accessor(P2897R0) only constrains.data() -
Compile-time stride lets compilers prove overalignment of every row / column
-
Easier for compilers to vectorize; can skip loop prelude & postlude (less code)
-
-
Any submatrix of a row-major or column-major matrix
-
Layout of every contiguous submatrix of a
layout_leftorlayout_rightmatrix -
Layout of BLAS and LAPACK
-
Preserve stride-1 access in one dimension
-
Alternatives
-
Just use
layout_stride?-
No compile-time strides
-
Function taking
layout_stridemdspan must check {left, right}most stride at run time to guarantee contiguous access
-
-
Hypothetical strided layout that permits any combination of compile- & run-time strides?
-
Common case of strided layouts: subview of existing
layout_leftorlayout_right. Any run-time extent makes all strides to its left / right run-time values. The larger the rank, the less the overall benefit.- Example:
submdspanoflayout_left::mapping<extents<int, dynamic_extent, 5, 7, 11>>has all dynamic strides, even if subview's extents are known at compile time.
- Example:
-
Fully compile-time extents and strides could support features of a specific computer architecture (e.g., specialized matrix-matrix multiply hardware). However, these hardware features are "atoms"; their input and output layouts are indivisible, so subviews aren't meaningful.
-
Why we allow padding_stride=0 (also at compile time)
Leftmost (for layout_left_padded; rightmost for layout_right_padded) extent is zero at compile time: extents<Integral, 0, ...>.
template<int Value>
using Int = integral_constant<int, Value>;
layout_left::mapping<extents<int, 0, 10>> mapping{};
mdspan m{nullptr, mapping};
auto m_sub = submdspan(m, tuple{Int<0>{}, Int<0>{}}, full_extent);
| P2642? | m_sub.mapping() |
|---|---|
| Before | layout_stride::mapping<extents<int, 0, 10>> |
| After | layout_left_padded<0>::mapping<extents<int, 0, 10>> |
Errata
-
Consider renaming
padding_stridetemplate parameter, as it's not the "actual" compile-time padding stride -
.extents()returns by value, not by const reference-
[mdspan.layout.reqmts] specifies that
.extents()returnsconst extents_type&, butlayout_{left,right}_padded::mapping::extentsin P2642 returnsextents_type. -
layout_{left,right}_padded::mappingdoes not store the user'sextentsobject-
It stores the "padded extents"
-
Effectively a "
layout_{left,right}of a bigger array"
-
-
Fix: Change to return
const extents_type&; still return a new object, but rely on lifetime extension
-
-
Specification of
layout_left_padded<ps>::mapping(const layout_left_padded<ps>::mapping<OtherExtents>&)converting constructors andoperator==may need adjustments, so that the spec as written can deduce the inputpadding_stridetemplate argument.- Consider adding a public member to
layout_{left,right}_padded::mappingso users can get thepadding_stridetemplate argument without needing to write a traits class
- Consider adding a public member to
Implementation
PR 237 in https://github.com/kokkos/mdspan
Design suggestions from Tomasz Kamiński via reflector
layout_left::padded<ps>::mapping instead of layout_left_padded<ps>::mapping
The padding_stride template parameter must live outside the mapping.
Otherwise, it wouldn't be possible to construct the mapping from just
an extents object.
Layout mapping conversion customization point?
Current design: Explicit converting constructors
Current design includes converting constructors from less constrained to more constrained mappings, e.g., layout_left_padded to layout_left mapping. These constructors are conditionally explicit if there are nontrivial preconditions.
We did this because it matches existing conversions like layout_stride to layout_left.
Tomasz points out two disadvantages of the current approach.
-
Conditionally
explicitmdspan constructor is also used to convert dynamic-extent to static-extent mdspan. -
Adding additional layouts with the current approach would require modifying existing layout classes to add constructors.
Also, users could not define conversions from custom layout mappings to Standard layout mappings.
Alternative: assume_layout customization point
Tomasz proposes an alternative design, where mdspan provides an assume_layout<Layout> customization point, that changes layout from more to less generic (e.g., strided -> padded -> left).
Advantages:
- Customizable for custom -> Standard layout mapping
- Avoids O(n^2) problem of adding new layout mappings
Disadvantages:
- Would we have to change the existing specification of
mdspan's converting constructor? - Use of
explicitmdspan converting constructor is not common
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the P2642R2 presentation notes, including the errata and the assume_layout alternative, then inspect implementation PR 237. A useful outcome would require a settled design and explicit scope for the padded layouts, conversion rules, and naming before implementation can begin.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100