Closed mhoemmen closed 1 month ago
Forwarded to LWG.
Remove constexpr
from is_sufficiently_aligned
, because bit_cast<uintptr_t>(ptr)
is never a constant expression.
Explain that mdspan and all its components have a unified approach to unsafe conversions, which is explicit
constructors. Thus, making unsafe conversions only happen through some cast operator (unsafe_mdspan_cast
) would not make existing code safer.
// Assuming aligned_mdspan alias from proposal's example,
// and the following function:
extern void f(aligned_mdspan<8>);
// with naughty_cast
auto aligned = aligned_mdspan<8>(
unaligned.data_handle(),
unaligned.mapping(),
naughty_cast<aligned_accessor<float, 8>>(unaligned.accessor()));
f(aligned);
// or briefly
f(naughty_cast<aligned_mdspan<8>>(unaligned));
// without naughty_cast
f(aligned_mdspan<8>(unaligned));
There was a question whether is_sufficiently_aligned
could be generic -- if it would make sense for accessors and perhaps also layout mappings to have a static bool
member function for checking preconditions. That would let generic code check preconditions for generic accessors. This shouldn't be called is_valid_*
because we can't e.g., ask at run time if a pointer is valid. On the other hand, it could make sense to make a best-effort check. My only objection is that this is the first of several accessors that even has some precondition that could be checked.
is_sufficiently_aligned
can't be constexpr
constexpr
is_aligned
implementation in clang that seems to work there: https://godbolt.org/z/YKxsj7ehb
There is a builtin for it https://godbolt.org/z/fEn956Gdb
Standard Library function was proposed once: [N4201] LWG: Alignment Helpers for C++ by Matthew Fioravante (2014-08-20)
Discussion why it's hard to make constexpr
: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98641
PR https://github.com/ORNL/cpp-proposals-pub/pull/461 has P2897R2, which I submitted on 2024/07/12.
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_accessor
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
constructoraligned_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_cast
pointers in constant expressions?)aligned_accessor
does not introduce more sharp edgesThe proposed
aligned_accessor
introduces no more sharp edges than the C++20 featureassume_aligned
, which was not part of themdspan
series of proposals. Similarly,default_accessor
introduces no more sharp edges than C++ already has with raw pointer access. Checking the precondition ofdefault_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 whosedata_handle_type
isspan<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'saccess
function, after both the Accessor and themdspan
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 ofmdspan
for Standard accessors likedefault_accessor
and the proposedaligned_accessor
.Why it belongs in the Standard
aligned_accessor
usesassume_aligned
(C++20) to decorate pointer accessCommon vocabulary type for interfaces to declare minimum alignment requirements
Extends compilers' potential optimizations of
assume_aligned
to 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_policy
isdefault_accessor
p
is aligned,p + i
might 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)
explicit
constructor fromdefault_accessor
(R1)is_sufficiently_aligned
checks pointer alignmentpublic
so users can check precondition before using pointerQuestions
is_sufficiently_aligned
check beconstexpr
? (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 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_aligned
is the same as for mdspan withaligned_accessor
)