Skip to content

P2897R1 (aligned_accessor): LEWG presentation 2024/06 #458

@mhoemmen

Description

@mhoemmen

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:

  1. Switch to Mandates elements for alignment conversions
  2. Discuss lack of explicit ctor from default_accessor
  3. 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_*

  • P2689 (in LEWG review)

  • Straightforwardly presents existing lower-level Standard Library feature (assume_aligned / atomic_ref) as mdspan 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

  • Version macro
  • Wording
  • Implementation experience

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions