P2897R1 (aligned_accessor)
Brief example with a complete implementation: https://godbolt.org/z/YsnsYhvGc
Last LEWG review
LEWG reviewed P2897R0 on 2023/10/10. Feedback:
- Switch to Mandates elements for alignment conversions
- Discuss lack of explicit ctor from
default_accessor
- Authors will explore mdspan safety, in the post-kona timeframe
Switch to Mandates elements for alignment conversions
DONE. See [mdspan.accessor.aligned.members] para 2.
Discuss lack of explicit ctor from default_accessor
DONE. We added an explicit constructor aligned_accessor(default_accessor<OtherElementType>). (Accessor constructors with preconditions are explicit.)
Authors will explore mdspan safety, in the post-kona timeframe
DONE (at least we think so).
Added a function to check the data handle's precondition
Added constexpr static bool is_sufficiently_aligned(data_handle_type p) member function. This lets users check the data handle's precondition before constructing the mdspan. Before this addition, users had to implement their own precondition check.
- Can it be
constexpr? (Can you bit_cast pointers in constant expressions?)
- Should it be? (Does anyone care about alignment of allocations at compile time?)
aligned_accessor does not introduce more sharp edges
The proposed aligned_accessor introduces no more sharp edges than the C++20 feature assume_aligned, which was not part of the mdspan series of proposals. Similarly, default_accessor introduces no more sharp edges than C++ already has with raw pointer access. Checking the precondition of default_accessor::access means checking whether a pointer plus an offset is valid. C++ currently offers no way to do that in general.
Regarding the precondition of default_accessor::access, we considered adding a new Accessor type whose data_handle_type is span<ElementType, Extent> instead of ElementType*. However, that would just exchange the pointer precondition for another, namely that mapping.required_span_size() <= data_handle.size(). Users can also implement this Accessor type themselves if they wish.
mdspan's constructor cannot generically check the data handle's preconditions
Accessors' constructors do not have access to the mdspan's data handle. The first time an Accessor gets the data handle is in the Accessor's access function, after both the Accessor and the mdspan have been constructed. Also, mdspan generally permits all kinds of Accessors. Their data handles does not need to represent a contiguous range or refer to objects in memory. Accessors may wrap third-party libraries that have no way to check validity of handles until use. As a consequence, mdspan's constructor cannot generically check the data handle's preconditions. Implementations could always add checks to their specializations of mdspan for Standard accessors like default_accessor and the proposed aligned_accessor.
Why it belongs in the Standard
-
aligned_accessor uses assume_aligned (C++20) to decorate pointer access
-
Common vocabulary type for interfaces to declare minimum alignment requirements
-
Extends compilers' potential optimizations of assume_aligned to mdspan accesses
Analogous to atomic_accessor_*
History
-
Was originally an example in P2642 (padded mdspan layouts)
-
Both useful in itself, and improves the value of P2642's layouts. P2642 still has value without aligned_accessor, though.
-
P2642 adopted into the Working Draft for C++26
Key features
-
offset_policy is default_accessor
- Even if a pointer
p is aligned, p + i might not be
-
Constructor permits conversion
-
From nonconst to const ElementType (like default_accessor)
-
From more overalignment to less overalignment (e.g., 128-byte allocation alignment to 64-byte SIMD)
-
explicit constructor from default_accessor (R1)
-
is_sufficiently_aligned checks pointer alignment
public so users can check precondition before using pointer
Questions
- Can
is_sufficiently_aligned check be constexpr? (bit_cast from a pointer cannot be.) We asked this question last time, without a conclusion. It's not deeply important to us for this member function to be constexpr.
Completeness checklist
Implementation experience
Implemented as an example in the reference mdspan implementation.
Demo: https://godbolt.org/z/fGb68oY67 (code generation for raw pointers + std::assume_aligned is the same as for mdspan with aligned_accessor)
P2897R1 (
aligned_accessor)Brief example with a complete implementation: https://godbolt.org/z/YsnsYhvGc
Last LEWG review
LEWG reviewed P2897R0 on 2023/10/10. Feedback:
default_accessorSwitch to Mandates elements for alignment conversions
DONE. See [mdspan.accessor.aligned.members] para 2.
Discuss lack of explicit ctor from
default_accessorDONE. We added an
explicitconstructoraligned_accessor(default_accessor<OtherElementType>). (Accessor constructors with preconditions areexplicit.)Authors will explore mdspan safety, in the post-kona timeframe
DONE (at least we think so).
Added a function to check the data handle's precondition
Added
constexpr static bool is_sufficiently_aligned(data_handle_type p)member function. This lets users check the data handle's precondition before constructing themdspan. Before this addition, users had to implement their own precondition check.constexpr? (Can youbit_castpointers in constant expressions?)aligned_accessordoes not introduce more sharp edgesThe proposed
aligned_accessorintroduces no more sharp edges than the C++20 featureassume_aligned, which was not part of themdspanseries of proposals. Similarly,default_accessorintroduces no more sharp edges than C++ already has with raw pointer access. Checking the precondition ofdefault_accessor::accessmeans checking whether a pointer plus an offset is valid. C++ currently offers no way to do that in general.Regarding the precondition of
default_accessor::access, we considered adding a new Accessor type whosedata_handle_typeisspan<ElementType, Extent>instead ofElementType*. However, that would just exchange the pointer precondition for another, namely thatmapping.required_span_size() <= data_handle.size(). Users can also implement this Accessor type themselves if they wish.mdspan's constructor cannot generically check the data handle's preconditionsAccessors' constructors do not have access to the
mdspan's data handle. The first time an Accessor gets the data handle is in the Accessor'saccessfunction, after both the Accessor and themdspanhave been constructed. Also,mdspangenerally permits all kinds of Accessors. Their data handles does not need to represent a contiguous range or refer to objects in memory. Accessors may wrap third-party libraries that have no way to check validity of handles until use. As a consequence,mdspan's constructor cannot generically check the data handle's preconditions. Implementations could always add checks to their specializations ofmdspanfor Standard accessors likedefault_accessorand the proposedaligned_accessor.Why it belongs in the Standard
aligned_accessorusesassume_aligned(C++20) to decorate pointer accessCommon vocabulary type for interfaces to declare minimum alignment requirements
Extends compilers' potential optimizations of
assume_alignedto mdspan accessesAnalogous to
atomic_accessor_*P2689 (in LEWG review)
Straightforwardly presents existing lower-level Standard Library feature (
assume_aligned/atomic_ref) as mdspan accessorHistory
Was originally an example in P2642 (padded mdspan layouts)
Both useful in itself, and improves the value of P2642's layouts. P2642 still has value without
aligned_accessor, though.P2642 adopted into the Working Draft for C++26
Key features
offset_policyisdefault_accessorpis aligned,p + imight not beConstructor permits conversion
From nonconst to const
ElementType(likedefault_accessor)From more overalignment to less overalignment (e.g., 128-byte allocation alignment to 64-byte SIMD)
explicitconstructor fromdefault_accessor(R1)is_sufficiently_alignedchecks pointer alignmentpublicso users can check precondition before using pointerQuestions
is_sufficiently_alignedcheck beconstexpr? (bit_castfrom a pointer cannot be.) We asked this question last time, without a conclusion. It's not deeply important to us for this member function to beconstexpr.Completeness checklist
Implementation experience
Implemented as an example in the reference mdspan implementation.
Demo: https://godbolt.org/z/fGb68oY67 (code generation for raw pointers +
std::assume_alignedis the same as for mdspan withaligned_accessor)