On 12/9/25 10:58, Jonathan Wakely wrote:
On Tue, 9 Dec 2025 at 09:37, Tomasz Kamiński <[email protected]> wrote:
From: Luc Grosheintz <[email protected]>
Implements `submdspan` and `submdspan_mapping` for layout_left as
described in P3663 (Future proofing mdspan).
When computing the offset of the submdspan, one must check that the
lower bound of the slice range isn't out-of-range. There's a few
cases when the lower bound is never out-of-range:
- full_extent and exts.extent(k) != 0,
- collapsing slice types.
If those conditions are known to hold, no checks are generated.
Similarly, if all slices are full_extent, there's no need to call
mapping(0,...,0) for standardized mappings.
The implementation prepares to use the symmetry between layout_left and
layout_right and introduces concepts like a "layout side", i.e. left,
right or unknown/strided.
The tests use an iterator to replace nested for-loops. Which also makes
it easier to write the core test logic in a rank-independent manner.
PR libstdc++/110352
libstdc++-v3/ChangeLog:
* include/std/mdspan (__mdspan::__is_submdspan_mapping_result)
(__mdspan::__submdspan_mapping_result, __mdspan::__fwd_prod)
(__mdspan::__acceptable_slice_type, __mdspan::__slice_begin)
(__mdspan::__suboffset, __mdspan::_LayoutSide,
__mdspan::__mapping_side)
(__mdspan::_StridesTrait, __mdspan::__substrides_generic)
(__mdspan::__substrides_standardized, __mdspan::__substrides)
(__mdspan::__is_unit_stride_slice, __mdspan::_SliceKind)
(__mdspan::__make_slice_kind, __mdspan::__make_slice_kind_array)
(__mdspan::__is_block, __mdspan::__padded_block_begin_generic)
(__mdspan::__padded_block_begin, __mpdspan::_SubMdspanMapping)
(__mdspan::__submdspan_mapping_impl): Define.
(__mdspan::__dynamic_slice_extent, __mdspan::__static_slice_extent)
(__mdspan::__subextents): Move eariel in the file.
"earlier"
(layout_left::mapping::submdspan_mapping,
__mdspan::__sliceable_mapping)
(__mdspan::__submapping, submdspan): Define.
* src/c++23/std.cc.in: Add submdspan.
* testsuite/23_containers/mdspan/submdspan/generic.cc: New test.
* testsuite/23_containers/mdspan/submdspan/selections/left.cc:
Instantiate selection tests for layout_left.
* testsuite/23_containers/mdspan/submdspan/selections/testcases.h:
Generic
tests different selections.
* testsuite/23_containers/mdspan/submdspan/submdspan_mapping.cc: New
test.
* testsuite/23_containers/mdspan/submdspan/submdspan_neg.cc: New test.
Reviewed-by: Tomasz Kamiński <[email protected]>
Signed-off-by: Luc Grosheintz <[email protected]>
---
v7:
- list all new entries in changes.
- move submdspan_mapping poison pill before concept,
- use const mapping as argument to concept
- refactor __submdspan into __submapping funciton.
Tested *mdspan* locally.
We've reached the point where I no longer understand the <mdspan>
code! But this looks OK for trunk, with the typo above fixed.
This part of <mdspan> was more tricky than others; and longer. To
figure out how it computes the kind of sublayout, this is one
intuitive way of reading the spec:
- an unpadded (sub-)layout can't have any gaps. An example of
what the spec describes is: x[1, 2, 2:5, :, :] or as a two-
dimensional A[2:5, :]. The key to realize is that it can't
describe anything with gaps.
- the padded layouts allow us to have a gap after the fastest
index. Hence, this time the fastest index can be pair-like. We
can then follow up with collapsing slices (because we simply
increase the gap after the first index). Eventually, we need a
compact run, because we're no longer able to add gaps. It can't
lead with collapsing indexes, because if it did, then the inner
most stride wouldn't be 1 (but all padded layouts have inner-
most stride equal to 1).
- the rest are corner cases; or the generic case which uses
layout_stride which permits gaps after every coordinate.
Let me know if there's anything I can do to make it clearer.