ORNL / cpp-proposals-pub

Collaborating on papers for the ISO C++ committee - public repo
26 stars 26 forks source link

mdspan revision #389

Open crtrott opened 1 year ago

crtrott commented 1 year ago

Super Brief mdarray introduction

Why we want mdarray

Creating a simple 2D array with mdspan requires multiple steps because mdspan is non-owning.

// Create a mapping:
layout_left map(extents(N,M));

// Create an allocation
vector<int> data(map.required_span_size());

// Create mdspan:
mdspan a(data.data(), map);

mdarray is a multidimensional array with value-semantics and makes the above simpler

// default layout
mdarray a(N,M);
// other layout
mdarray b(layout_left(extents(N,M))); 

What aspects of mdspan does mdarray have

mdarray has the

The accessor policy is replaced by a container type.

template<class ElementType, class Extents, class Layout, class Accessor>
class mdspan {
   public:
   ...
     template<class ... Indices>
     reference operator [] (Indices ... idx) const { return acc_.access(ptr_, map_(idx...)); }
   private:
     typename Accessor::data_handle_type ptr_;
     Layout::mapping<Extents> map_;
     Accessor acc_;
};

template<class ElementType, class Extents, class Layout, class Container>
class mdarray {
   public:
   ...
     template<class ... Indices>
     reference operator [] (Indices ... idx) { return ctr_[map_(idx...)]); }

   private:
     Layout::mapping<Extents> map_;
     Container ctr_;
};

Design issues left at last time

Constructor

Overview Table

The following table gives an overview of the three approaches. In this table we use these shorthands:

Arguments Current Minimal Variadic
`default` `mda_t()` `mda_t()` `mda_t()`
integrals `mda_t(10, 10)` `mda_t(10, 10)` `mda_t(10, 10)`
mapping/extents `mda_t(me)` `mda_t(me)` `mda_t(me)`
container + integrals `mda_t(extents{10, 10}, c)` `mda_t(extents{10, 10}, c)` `mda_t(extents{10, 10}, c)`
move container + integrals `mda_t(extents{10, 10}, move(c))` `mda_t(extents{10, 10}, move(c))` `mda_t(extents{10, 10}, move(c))`
container + mapping/extents `mda_t(me, c)` `mda_t(me, c)` `mda_t(me, c)`
move container + mapping `mda_t(me, move(c))` `mda_t(me, move(c))` `mda_t(me, move(c))`
container + alloc + mapping/extents `mda_t(me, c, a)` `mda_t(me, c_t(c,a))` `mda_t(me, c, a)`
move container + alloc + mapping `mda_t(me, move(c), a)` `mda_t(me, c_t(move(c),a))` `mda_t(me, move(c), a)`
extents + value `mda_t(e, v)` `mda_t(e, c_t(map_t(e).required_span_size(), v))` `mda_t(e, v)`
mapping + value `mda_t(m, v)` `mda_t(m, c_t(m.required_span_size(), v))` `mda_t(m, v)`
mapping + custom container size `mda_t(m, c_t(s))` `mda_t(m, c_t(s))` `mda_t(m, c_t(s))` or `mda_t(m, s)` for integrals not convertible to `value_type`
mapping + custom container size + value `mda_t(m, c_t(s, v))` `mda_t(m, c_t(s, v))` `mda_t(m, s, v)`
extents + value + alloc `mda_t(e, v, a)` `mda_t(e, c_t(map_t(e).required_span_size(), v, a)))` `mda_t(e, v , a)`
mapping + value + alloc `mda_t(m, v, a)` `mda_t(m, move(c_t(m.required_span_size(), v, a)))` `mda_t(m, v, a)`
mapping + custom container size + alloc `mda_t(m, c_t(s, a))` `mda_t(m, c_t(s, a))` `mda_t(m, c_t(s, a))` or `mda_t(m, s, a)` for integrals not convertible to `value_type`
mapping + custom container size + value + alloc `mda_t(m, c_t(s, v, a))` `mda_t(m, c_t(s, v, a))` `mda_t(m, s, v, a)`
iterators `mda_t(m, c_t(begin, end))` `mda_t(m, c_t(begin, end))` `mda_t(m, begin, end)`
range `mda_t(m, c_t(r))` `mda_t(m, c_t(r))` `mda_t(m, r)`
converting mdarray `mda_t(mda)` `mda_t(mda)` `mda_t(mda)`
compatible mdspan `mda_t(mds)` `mda_t(mds)` `mda_t(mds)`
compatible mdspan + allocator `mda_t(mds, a)` `mda_t(mds, a)` `mda_t(mds, a)`