Add SimpleArray::as_span() and as_mdspan<N>()#777
Conversation
| template <typename... Args> | ||
| value_type * vptr(Args... args) { return m_body + buffer_offset(m_stride, args...); } | ||
|
|
||
| std::span<value_type> as_span() { return std::span<value_type>(data(), size()); } |
| std::span<value_type const> as_span() const { return std::span<value_type const>(data(), size()); } | ||
|
|
||
| template <size_t N> | ||
| std::mdspan<value_type, std::dextents<size_t, N>> as_mdspan() |
| { | ||
| if (ndim() != N) | ||
| { | ||
| throw std::out_of_range( |
| } | ||
| std::array<size_t, N> exts; | ||
| for (size_t i = 0; i < N; ++i) { exts[i] = shape(i); } | ||
| return std::mdspan<value_type, std::dextents<size_t, N>>(data(), exts); |
There was a problem hiding this comment.
Use data(). Disregard ghost information.
| #error "Python.h should not be included." | ||
| #endif | ||
|
|
||
| TEST(SimpleArray, mdspan_1d) |
| EXPECT_EQ(sp[3], 99.0); | ||
| } | ||
|
|
||
| TEST(SimpleArray, mdspan_1d_const) |
| for (size_t i = 0; i < 6; ++i) { EXPECT_EQ(sp[i], 5.0); } | ||
| } | ||
|
|
||
| TEST(SimpleArray, mdspan_1d_ghost) |
| { | ||
| for (size_t j = 0; j < 4; ++j) | ||
| { | ||
| arr(i, j) = static_cast<double>(i * 4 + j); |
There was a problem hiding this comment.
2D test. A little bit interesting.
| } | ||
| } | ||
|
|
||
| // Linear view over the C-contiguous buffer; sp[i*4+j] == arr(i, j). |
There was a problem hiding this comment.
Linear view for 2D buffer.
| for (size_t k = 0; k < sp.size(); ++k) { EXPECT_EQ(sp[k], arr.data(k)); } | ||
| } | ||
|
|
||
| TEST(SimpleArray, mdspan_3d) |
There was a problem hiding this comment.
So on and so forth for 3D and 4D.
| sudo ln -fs "$(which clang-tidy-22)" "/usr/local/bin/clang-tidy" | ||
|
|
||
| - name: Install and configure gcc-14 | ||
| - name: Install and configure gcc-16 |
There was a problem hiding this comment.
The GCC 14 and 15 with the ubuntu package did not have mdspan.
There was a problem hiding this comment.
Although we may face CI error when ubuntu PPA dies again, it seems that GCC 16 is necessary.
|
@tigercosmos @ExplorerRay @ThreeMonth03 please help take a look. |
| std::format("SimpleArray::as_mdspan: rank {} does not match ndim() {}", N, ndim())); | ||
| } | ||
| std::array<size_t, N> exts; | ||
| for (size_t i = 0; i < N; ++i) { exts[i] = shape(i); } |
There was a problem hiding this comment.
It may be checked whether SimpleArray is contiguous. The size of shape may not equal to the size of data().
There was a problem hiding this comment.
Good catch. Added above.
Expose C++23 view types over the contiguous buffer: - `as_span()` returns `std::span<value_type>` over the contiguous body. - `as_mdspan<N>()` returns `std::mdspan<value_type, std::dextents<size_t, N>>` built from `shape()`. Ghost indices are not subtracted. The view spans the full underlying storage. Add `gtests/test_nopython_mdspan.cpp` covering 1D-4D shapes, ghost arrays for each rank, and the `as_span()` linear view.
gcc-14 and gcc-15 from ppa:ubuntu-toolchain-r/test does not ship <mdspan> in libstdc++-15-dev.
Both views assume linear row-major storage of prod(shape) elements starting at data(). Reject a non-C-contiguous array (e.g., padded or strided view) with std::runtime_error. Add `SimpleArray.mdspan_non_contiguous` to cover the new guard.
| std::format("SimpleArray::as_mdspan: rank {} does not match ndim() {}", N, ndim())); | ||
| } | ||
| std::array<size_t, N> exts; | ||
| for (size_t i = 0; i < N; ++i) { exts[i] = shape(i); } |
There was a problem hiding this comment.
Good catch. Added above.
| throw std::out_of_range( | ||
| std::format("SimpleArray::as_mdspan: rank {} does not match ndim() {}", N, ndim())); | ||
| } | ||
| if (!is_c_contiguous()) |
There was a problem hiding this comment.
Throw if the buffer is not C-contiguous.
| EXPECT_THROW(arr.as_mdspan<3>(), std::out_of_range); | ||
| } | ||
|
|
||
| TEST(SimpleArray, mdspan_non_contiguous) |
There was a problem hiding this comment.
Test for non-C-contiguous.
|
Rebased to latest |
ThreeMonth03
left a comment
There was a problem hiding this comment.
LGTM. We may consider the non cotiguous case by another pull request.
| throw std::out_of_range( | ||
| std::format("SimpleArray::as_mdspan: rank {} does not match ndim() {}", N, ndim())); | ||
| } | ||
| if (!is_c_contiguous()) |
|
One of the linter runs keeps timeout. It should be false alarm and I'll merge. |
Tracking noncontiguous support in issue #784 . |
Expose C++23 view types over the contiguous buffer:
as_span()returnsstd::span<value_type>over the contiguous body.as_mdspan<N>()returnsstd::mdspan<value_type, std::dextents<size_t, N>>built fromshape(). Ghost indices are not subtracted. The view spans the full underlying storage.Add
gtests/test_nopython_mdspan.cppcovering 1D-4D shapes, ghost arrays for each rank, and theas_span()linear view.This is for issue #771 .