ORNL / ORNL/cpp-proposals-pub

mdarray notes

Open
#215 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

MDARRAY

mdspan and the allocation issue
  • mdspan only wraps memory, so setting up a multi dimensional array is a bit cumbersome, because I first need parts of mdspan to figure out what the required_span_size is:
// figure out my type
using mdspan_t = mdspan<double, dextents<2>>;
// Create a mapping
typename mdspan_t::mapping_type map(dextents<2>(N,M));
// Allocate my vector
std::vector<double> data(map.required_span_size());
// Create the mdspan
mdspan_t a(data.data(), map);
  • also don't forget to keep the vector around while the mdspan is alive
  • Another problem: map.required_span_size() can't necessarily being used as argument for array
  • And we largely lost CTAD goodness
mdarray makes that all easier
mdarray<double, dextents<2>> a(N,M);
Similarities and differences to mdspan
  • value semantics: constness of mdarray implies constness of data -> ElementType is always non-const
  • want compile time and runtime dimensions -> still use extents
  • want data layouts -> still use layout policy
  • don't need accessor policy:
    • accessor policies are used to change access behavior in restricted scope
    • get a mdspan from the mdarray for this
  • need dynamic sized allocation but also want to support array like behavior
    • particularly for small objects in performance sensitive settings
    • use container type as template parameter instead of accessor policy
template<class ElementType, class Extents, class Layout = layout_right, class AccessPolicy = default_accessor<ElementType>>
class mdspan;

template<class ElementType, class Extents, class Layout = layout_right, class Container = SEE_BELOW>
class mdarray;
  • the default container type is a std::array<ElementType, N> if all extents are known statically, std::vector<ElementType> otherwise.
Interoperability with mdspan
  • It is fairly trivial to create an mdspan from a generic mdarray:
using mdarray_t = mdarray<double, dextents<2>>;
using mdspan_t = mdspan<typename mdarray_t::element_type,
                        typename mdarray_t::extents_type,
                        typename mdarray_t::layout_type>
               
mdarray_t a(N,M);
mdspan_t a_view(a.data(), a.mapping());
  • However we decided to also add a conversion operator:
    • this can convert to any compatible mdspan, as if first creating the natural mdspan from the specific mdarray and then assigning that
using mdarray_t = mdarray<double, dextents<2>>;
mdarray_t a(N,M);
mdspan<double, dextents<2>> a_view;
a_view = a;
mdspan<const double, extents<N,dynamic_extent>> b_view;
b_view = a;

Which constructors should we have?

  • mdspan has four ways to specify extents in the constructor:
    • integer pack
      • mdarray this can't be used for rank-zero, since ambiguous with default constructor
    • array
      • mdarray could have this too: array would be confusing when the container_type is array: so we omitted it
    • extents
    • mapping
  • mdarray furthermore needs to construct the owned container
    • constructors for this can be inspired by container adaptor or containers themselves
    • should have ones with the above options to specify size
    • from container adaptor:
      • SIZE_SPECIFIER (will construct container from size)
      • SIZE_SPECIFIER + ALLOCATOR
      • const container_type& + SIZE_SPECIFIER
      • const container_type& + SIZE_SPECIFIER + ALLOCATOR
      • container_type&& + SIZE_SPECIFIER
      • container_type&& + SIZE_SPECIFIER + ALLOCATOR
      • OTHER_MDARRAY + ALLOCATOR
      • Iterator begin + Iterator end + SIZE_SPECIFIER [+ ALLOCATOR]
        • we left those out since we don't have generally iterator interface, however it could be considered as just another way to specify the initial data for the underlying container, and you could always create and move the container?
        • one could argue constructors from mdspan (+ ALLOCATOR) are the equivalent?
    • from containers:
      • std::initializer_list + SIZE_SPECIFIER [+ALLOCATOR]
        • we have it for now, but that is not what other container adaptors have
        • also mdarray<...> a({{1,2,3,4}}, {2,2}); // HUH??
        • also mdarray<...> a({{1,2,3,4}}, 2,2); // HUH??
    • The constructors which take an allocator, do not allow for size specification via integer packs, might be possible to do but then the argument pack would be integer pack + allocator if the allocator comes last, so we left it out.
Some issues fixed after R1 mailing:
  • fix synopsis missing Alloc argument in some places
  • fix constraints on some constructors to allow std::array as container
  • add missing wording for std::initializer list
Suggested Polls:
  1. mdarray should be constructible from begin and end iterators.
  2. mdarray should be explicitly constructible from mdspan.
  3. mdarray should not be constructible from initializer_list.
  4. mdarray should be constructible from integer packs + allocator.

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 with the issue's mdarray and mdspan design discussion, including the proposed constructors, container choices, and conversions. Review the four suggested polls and determine which API decisions remain unresolved; no implementation files or tests are named, so the issue is not ready to define a concrete done state.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.