[PATCH v6 2/7] libstdc++: Implement submdspan and submdspan_mapping for layout_left. [PR110352]

Luc Grosheintz luc.grosheintz@gmail.com
Tue Dec 9 12:51:44 GMT 2025



On 12/9/25 10:58, Jonathan Wakely wrote:
> On Tue, 9 Dec 2025 at 09:37, Tomasz Kamiński <tkaminsk@redhat.com> wrote:
>>
>> From: Luc Grosheintz <luc.grosheintz@gmail.com>
>>
>> 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 <tkaminsk@redhat.com>
>> Signed-off-by: Luc Grosheintz <luc.grosheintz@gmail.com>
>> ---
>> 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.



More information about the Libstdc++ mailing list