ORNL / ORNL/cpp-proposals-pub

Notes for P0009 Review 11/22/2022

Open
#183 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
29
Forks
26
PR merge metrics
No merged PRs in 30d

Description

MDSPAN P0009R14

  • addressed action items from last review on 11/1/2021
  • harmonized more with span
  • most of the work is constructor and conversion related
    • i.e. what is explicit vs implicit
      • guiding principle: if it can fail at runtime it is then explicit
    • as part of that also completed some layout conversions (previously we only had layout_{left,right} to layout_stride)
    • Thanks to Tomasz for reviewing in a bit more detail
  • implemented all of this
LEWG Review 11/01/2021
  • ACTION: Maybe a default constructible accessor should imply default constructible mdspans. Default constructible spans are important in many cases.
    • DONE: defaulted default constructor only exists if all members are default initialized. Removed requirement for accessors and mappings to be default constructible.
  • ACTION: Make extents constructor conditionally explicit when converting from dynamic to static extents.
    • DONE (https://godbolt.org/z/KbbK1e9jc)
      is_constructible_v<extents<2,3>,extents<2,dynamic_extent>>==true
      is_convertible_v<extents<2,dynamic_extent>,extents<2,3>>==false
      is_assignable_v<extents<2,3>,extents<2,dynamic_extent>>==false
      
      is_constructible_v<extents<2,dynamic_extent>,extents<2,3>>==true
      is_convertible_v<extents<2,3>,extents<2,dynamic_extent>>==true
      is_assignable_v<extents<2,dynamic_extent>,extents<2,3>>==true
      
  • ACTION: Make layout and mdspan converting constructors conditionally explicit based upon the underlying types
    • DONE
  • ACTION: constructing extents from std::array needs a deduction guide?
    • NOT DONE: you can't do this since you can't use alias and you can't return a parameter pack
  • QUESTION: Extents parameter pack ctor needs to be explicit? Deduction guide needs to be explicit?
    • DONE: constructing from sizes paramemter pack is now unconditionally explicit
  • QUESTION: submdspan constructor can take tuple<size_t, size_t> and get pair<size_t, size_t> for free (could add specific type for submdspan, so long as it can be converted from pair and tuple).
    • DONE: we changed submdspan to take things convertible to tuple<size_t,size_t>
  • ACTION: needs feature test macro
    • DONE: __cpp_lib_mdspan
  • QUESTION: Can get rid of mdspan ctor takes pointer + array? Can construct extent from array. Disagreement amongst authors on this one.
    • NOT DONE: would remove ctad from array
  • ACTION: Explore modifying the requirements on which extents need to be provided when constructing an mdspan or extents object.
    • DONE
    • Authors decided to enable construction from both dynamic extents only, and all extents (for both integer packs and arrays)
        mdspan<int, extents<dyn,3,dyn>> a(ptr, N, K); // always valid
        mdspan<int, extents<dyn,3,dyn>> b(ptr, N, M, K); // M needs to be 3
      
      • did not add full_extent_t placeholder value for construction
      • made this change for both extents and mdspan
        • layout mappings only have the constructors from extents not integer packs or array, so the issue doesn't affect them.
    • Why allow allow construction from dynamic extents only:
      • no redundant information
      • precondition free constructor
      • enables fully static extents mdspan construction from ptr only
      • pretty common case: left most or right most extents are static
        • e.g. construct N 3x3 matrices: mdspan<float,extents<dynamic_extent, 3, 3>> a(ptr, N);
    • Why allow construction from all extents:
      • no confusion what extent a given argument is associated with
      • enables easier writing of certain types of generic code e.g.:
        template<class mds1_t, class mds2_t>
        auto alloc_gemm_result(mds1_t mdspan1, mds2_t mdspan2) {
           using return_t = mdspan<double,
             Extents< mds1_t::extents_type::static_extent<0>,
                      mds2_t::extents_type::static_extent<1>>;
           double* ptr = new double[mdspan1.extent(0)*mdspan2.extent(1)];
           return return_t(ptr, mdspan1.extent(0),mdspan2.extent(1));
         }
        
Changes from R13

(A) denotes Action Item related change

  • changes to harmonize with std::span
    • (A) made extents converting constructor conditionally explicit, for cases where dynamic extents are turned into static extents
    • made convertibility of default_accessor depend on convertibility of element_type(*)[] instead of pointer to prevent derived class to base class assignment
    • remove converting assignment operators throughout
  • (A) made layout mapping converting constructors conditionally explicit, depending on extents being not implicitly convertible
  • (A) made mdspan converting constructor conditionally explicit, for cases where any of the exposition only members or the template parameters are only explicitly convertible
  • Improve submdspan wording
    • the wording defines more clearly how the submdspan is constructed, not just through ensures
  • made layout wording style consistent
  • (A) don't require default constructibility from accessors and mappings (still require it for pointer though)
  • fixed layout_stride conversion construction
  • (A) made deduction guide from integers for extents/mdspan explicit
  • tweaked constraints on mdspan to not include element type and the full extents
    • left pointer, since mdspan converts those in its converting constructor
    • also left some specific constraints regarding extents to prevent custom layouts from changing rank or assigning different sized static extents
  • (A) add feature test macro
  • (A) accept tuple instead of pair for subslice arguments in submdspan.
  • remove mdspan::unique_size
    • for contiguous layouts this is equivalent to required_span_size and for unique layouts its equivalent to size
    • for non-unique, non-contiguous layouts this is not implementable with an algorithm taking constant time
  • fix layout_stride constructor to be flexible with integral types of strides array
    • i.e. this is now harmonized with extents and mdspan constructor which takes array
  • (A) make extents and mdspan constructors accept either rank_dynamic or rank integer arguments (or an array of that size)
  • remove mdspan trivially default constructible clause: it never is because we value initialize pointer inline
  • remove nonowning word from mdspan description: there is not really a reason to have it. Would allow shared_ptr as pointer
  • Enable more layout mapping conversions
    • allow implicit conversion for 1D layout_left to layout_right mapping and vice versa
      • both represent contiguous 1D arrays of elements, i.e. the mapping is equivalent
      • reduces duplicated code
      void foo(mdspan<int, dextents<1>, layout_left> a) { ... }
      void bar(mdspan<int, dextents<1>, layout_right> b) {
        foo(b);
      }
      
    • allow implicit conversion for rank-0 layout_left, layout_right, and layout_stride mappings to each other
      • all of them just represent a single value ...
    • allow explicit conversion from layout_stride to layout_left and layout_right
      • previously only allowed layout_{left,right} to layout_stride, now you can convert back.
      • useful for first doing type erasure but then specializing again
      • https://godbolt.org/z/zMr65hvbb
Implementation
  • Updated implemenation at https://github.com/kokkos/mdspan to reflect all changes done in R14.
    • we believe this is a faithful implementation of the proposal
  • Works with GCC, Clang and largely with MSVC
    • Implemented backport to C++14/17/20
    • In C++20 mode all constraints etc. are fully implemented, only difference is use of paren operator instead of subscript
      • except on MSVC where conditional explicit clauses are missing, looks like compiler bug for conditional explicit involving fold expressions (https://godbolt.org/z/8aj98zanr)
    • In C++17 and before, conditional explicit clauses are missing
    • In C++14 CTAD is missing
  • Using Corentins beta compiler implementing subscript operator changes, tested subscript operator
    • Works except for rank-0, we believe the compiler doesn't implement that correct and it should be valid to have [] without arguments.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the review notes in this issue and then inspect the linked kokkos/mdspan implementation. The issue records completed proposal changes and compiler status, but names no file, test, or remaining task, so there is no clear definition of done for a newcomer.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.