Notes for mdarray Review
Nobody has claimed this yet.
- Dominant language
- HTML
- Stars
- 29
- Forks
- 26
- PR merge metrics
- No merged PRs in 30d
Description
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
element_type,extentsand- layout policy aspects of
mdspan
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_;
};
This means mdarray does not have the kind of access modality customization point functionality of mdspan, but that functionality is anyway intended for local specialization of accesses, and thus more suited for the view-like class.
Design considerations
Constructors
mdarray is like a container adaptor (e.g. queue). It provides a different interface for the underlying container.
Now the question is what does that mean for constructors.
Due to its mdspan roots it should be constructible from the size like arguments, e.g.
- integer packs,
extents, and- mappings.
For analogy with containers, and container adaptors we also gain construction from the
- underlying container,
- initializer lists,
- iterator pairs and
- ranges.
However, mdarray always needs the size information in addition, since these arguments are simple 1D ranges, making this problem combinatorial.
Furthermore, we likely want versions of each of these with an allocator argument, providing a factor of 2
And then we want all the usual copy/move/conversion constructors.
Putting that all together makes us implement 41 constructors ...
An alternative to explicitly spelling them all out is having pack forwarding constructors:
template<class ... Args>
requires(is_constructible_v<container_type, Args...>)
mdarray(mapping_type map, Args ... args):map_(map), ctr_(args...) {}
Deduction Guides
We like want deduction guides for most all of those constructors, but we haven't added them yet.
An issue with custom containers
Generally, we will construct containers from sizes or iterators, ranges etc.
We need to know that the container is actually large enough after construction to be indexed into up to map_.required_span_size().
mdarray(const mapping_type& map):map_(map),ctr_(map.required_span_size()) {}
template<class InputIterator>
mdarray(InputIterator first, InputIterator last, const mapping_type& map):
map_(map), ctr_(first, last) {}
Generally we can know the intended size:
map.required_span_size()distance(first, last)some_container.size()
We can have preconditions on things like the distance(first, last) being at least the map.required_span_size()
But: How do we know that the constructed container has the right size
- Sequence container requirements have some of semantics
- BUT: we don't want to require sequence container with all its baggage.
Thus we are proposing (somewhat optimistically) a new named container requirement.
- every requirement is optional: i.e. if the following expressions are well formed, they have the specified semantics
- Postcondition for each expression that the size is right.
Size matching of containers and mappings.
-
We explicitly require that if you construct an
mdarrayfrom some existing set of elements (container, iterators, range, etc.), that the implied size of those arguments is larger or equal to the mappingsrequired_span_size(). -
The larger or equal is intentional, because the mapping may already be not exhaustive.
- I.e. the
mdarraymay not end up accessing all elements in its own container. But in that case it is not clear why having unused elements at the end should be different from having unused elements somewhere else in the container.
- I.e. the
Conversion to mdspan
There are a number of possible approaches for getting an mdspan from and mdarray
operator mdspan:mdarrayhas all the information to create anmdspanso conversion operator is possible. We even can make a templated one to possibly avoid double construction in conversion cases.- deduction guide for
mdspan(mdarray): works in conjunction withoperator mdspan. - member function
mdarray::viewwhich returns anmdspan.
Generally there isn't much you can do with the explicit member function you can't do with the combination of operator mdspan and the deduction guide,
however this path is not available to user defined types, which are not allowed to define new deduction guides for classes in the standard library.
Thus we likely need a customization point anyway for creating mdspans and mdarray should likely implement that too.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No files, tests, or implementation entry points are named. Start by reviewing the mdarray design notes in this issue and identify the unresolved constructor, container-requirement, deduction-guide, and mdspan-conversion decisions; done would require an agreed design and a concrete implementation scope.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100