Add implementation of span, mdspan and mdarray
-
Review changes -
-
Download -
Patches
-
Plain diff
Summary
This MR provides a reference implementation of std::span
, std::mdspan
, and std::mdarray
including all its utilities, std::dynamic_extent
, std::extents
, std::layout_[left|right|stride]
, and std::default_accessor
, plus a few backports of c++20 standard library functions, e.g. std::to_address
. All these entities are put into the Dune::Std
namespace including an import of the actual standard implementation if available.
Motivation
In Dune we do not have tensor data structures. The containers and views provided in this MR can be the basis for such an implementation. A reference code is available in https://gitlab.dune-project.org/simon.praetorius/dune-tensor. Also, these types could be the start of a reimplementation of DenseVector
and DenseMatrix
and all their derived types.
Deprecation
While posting these implementations here, they are meant to be deprecated once the standard libraries we support in Dune all ship their implementation of these classes. Currently, it is only the most recent version, clang-18, with its libc++ that supports at least std::mdspan
. In the module dune-tensor there are already CI jobs testing with this compiler and this library. Other classes, like std::span
or the utility std::to_address
might be deprecated more early, once we support only c++20 compatible compilers. The implementation in this MR is (mostly) c++17 compatible.
Provided classes
Dune::Std::span
A contiguous sequence of elements with static or dynamic extent. The implementation is based on the C++ standard working draft https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf and the documentation provided in https://en.cppreference.com/w/cpp/container/span.
Example
std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// view data as contiguous memory representing 10 elements
auto s1 = Dune::Std::span(v.data(), 10);
// view data as contiguous memory with static size
auto s2 = Dune::Std::span<int,10>(v.data());
// write data using 2D view
for (std::size_t i = 0; i != s1.size(); i++)
s1[i] = 2*i;
Not that dynamic extents are specified by the constant Dune::Std::dynamic_extent
.
Dune::Std::mdspan
A multi-dimensional non-owning array view. The implementation is based in the standard proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r17.html and the C++ standard working draft https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4971.pdf.
Example
std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// view data as contiguous memory representing 2 rows and 5 columns
// with row-major ordering.
auto ms = Dune::Std::mdspan(v.data(), 2, 5);
// or with static shape given by Std::extents
auto ms2 = Dune::Std::mdspan<int,Dune::Std::extents<int,2,5>>(v.data());
// write data using 2D view
for (std::size_t i = 0; i != ms.extent(0); i++)
for (std::size_t j = 0; j != ms.extent(1); j++)
ms(i, j) = i + j; // or ms[i, j]
Dune::Std::mdarray
An owning multi-dimensional array analog of mdspan. The implementation is inspired by the mdarray c++ standard proposals https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1684r5.html.
Example
// two-dimensional array with 2 rows and 6 columns of static shape
Dune::Std::mdarray<double, Dune::Std::extents<std::size_t,2,6>> m1{};
// same two-dimensional array but with dynamic shape
Dune::Std::mdarray<double, Dune::Std::dextents<std::size_t,2>> m2{2,6};
// storage type similar to the Dune::FieldMatrix
template <class T, int m, int n>
using FieldMatrix = Dune::Std::mdarray<T,
Dune::Std::extents<int,m,n>, Dune::Std::layout_right, std::array<T,m*n>>;
// store data into the array using two indices
for (std::size_t i = 0; i != m1.extent(0); i++)
for (std::size_t j = 0; j != m1.extent(1); j++)
m1(i, j) = i + j; // or m1[i, j]
Note that std::mdarray
is not yet fully standardized, but hopefully will be in c++26. There is also no other reference implementation following the recent proposal. The Kokkos implementation (in the current stable
branch) still follows the proposal version R4.
Merge request reports
- version 2350513406
- version 22c8d413df
- version 2193012736
- version 20e2e3a2ca
- version 19accad1ab
- version 18f11ce770
- version 1705ecdcc6
- version 1631da0f12
- version 15f779c754
- version 14684bf0d2
- version 130494a779
- version 12bc9e7310
- version 11b332128a
- version 1094addea0
- version 9530e4b82
- version 852c1db6b
- version 78ef431c8
- version 658fca43d
- version 5223b2e04
- version 4fc97b1e3
- version 3a20ed097
- version 2f7219be9
- version 12be9674b
- master (base)
- latest versionb85f384e2 commits,
- version 235051340611 commits,
- version 22c8d413df10 commits,
- version 21930127369 commits,
- version 20e2e3a2ca8 commits,
- version 19accad1ab8 commits,
- version 18f11ce7707 commits,
- version 1705ecdcc67 commits,
- version 1631da0f127 commits,
- version 15f779c7546 commits,
- version 14684bf0d27 commits,
- version 130494a7794 commits,
- version 12bc9e73102 commits,
- version 11b332128a1 commit,
- version 1094addea01 commit,
- version 9530e4b821 commit,
- version 852c1db6b1 commit,
- version 78ef431c83 commits,
- version 658fca43d4 commits,
- version 5223b2e043 commits,
- version 4fc97b1e33 commits,
- version 3a20ed0972 commits,
- version 2f7219be91 commit,
- version 12be9674b1 commit,
- Side-by-side
- Inline