[libcxx-commits] [PATCH] D157171: [libc++] mdspan - implement layout_stride

Nikolas Klauser via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Aug 10 15:07:37 PDT 2023


philnik added subscribers: var-const, philnik.
philnik added inline comments.


================
Comment at: libcxx/docs/Status/Cxx23Papers.csv:94-96
 "`P2599R2 <https://wg21.link/P2599R2>`__","LWG","``mdspan::size_type`` should be ``index_type``","July 2022","",""
 "`P2604R0 <https://wg21.link/P2604R0>`__","LWG","mdspan: rename pointer and contiguous","July 2022","",""
 "`P2613R1 <https://wg21.link/P2613R1>`__","LWG","Add the missing ``empty`` to ``mdspan``","July 2022","",""
----------------
These should all be completed with this patch too.


================
Comment at: libcxx/include/__mdspan/layout_stride.h:148
+        }(make_index_sequence<__rank_>())) {
+    _LIBCPP_ASSERT(([&]<size_t... _Pos>(index_sequence<_Pos...>) {
+                     // For integrals we can do a pre-conversion check, for other types not
----------------
Throughout. @var-const Do you have any thoughts here?


================
Comment at: libcxx/include/__mdspan/layout_stride.h:163
+            // basically sort the dimensions based on strides and extents, sorting is represented in permute array
+            std::array<rank_type, __rank_> __permute{_Pos...};
+            for (rank_type __i = __rank_ - 1; __i > 0; __i--) {
----------------



================
Comment at: libcxx/include/__mdspan/layout_stride.h:227
+    _LIBCPP_ASSERT(([&]<size_t... _Pos>(index_sequence<_Pos...>) {
+                     return static_cast<index_type>(0) == static_cast<index_type>(__other((_Pos ? 0 : 0)...));
+                   }(make_index_sequence<__rank_>())),
----------------
Maybe?


================
Comment at: libcxx/include/__mdspan/layout_stride.h:267
+    // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
+    _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
+                   "layout_stride::mapping: out of bounds indexing");
----------------



================
Comment at: libcxx/include/__mdspan/layout_stride.h:290
+        if constexpr (__rank_ == 1)
+          return true;
+        else {
----------------
Test!


================
Comment at: libcxx/include/__mdspan/layout_stride.h:311
+  _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
+    requires(__rank_ > 0)
+  {
----------------
Where does this come from?


================
Comment at: libcxx/include/__mdspan/layout_stride.h:313
+  {
+    _LIBCPP_ASSERT(__r < __rank_, "layout_stride::mapping::stride(): invalid rank index");
+    return __strides_[__r];
----------------



================
Comment at: libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp:79
+    std::extents<int, D, D> arg_exts{100, 5};
+    std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1,100});
+    // check extents would be constructible
----------------
Maybe try to trigger the edge case here? Just ignore the comment if it doesn't work.


================
Comment at: libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp:83
+    // but the product is not, so we can't use it for layout_stride
+    TEST_LIBCPP_ASSERT_FAILURE(
+        ([=] { std::layout_stride::template mapping<std::extents<char, D, 5>> m(arg); }()),
----------------
Possible future work: Add tests to make sure that `mdspan` and friends work with `_BitInt`.


================
Comment at: libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp:52
+    // check that if we first overflow in strides conversion we also fail
+    assert(static_cast<unsigned char>(257u) == 1);
+    TEST_LIBCPP_ASSERT_FAILURE(
----------------



================
Comment at: libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp:53
+    // check that if we first overflow in strides conversion we also fail
+    assert(static_cast<unsigned char>(257u) == 1);
+    TEST_LIBCPP_ASSERT_FAILURE(
----------------



================
Comment at: libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp:82
+          std::layout_stride::template mapping<std::extents<unsigned, D, 5, 7>>
+            m(std::extents<unsigned, D, 5, 7>(20), std::array<unsigned, 3>{4, 1, 200});
+        }()),
----------------
This should be a span!


================
Comment at: libcxx/test/std/containers/views/mdspan/CustomTestLayouts.h:278
       size *= extents_.extent(r);
-    return size;
+    return std::max(size*scaling_ + offset_, offset_);
   }
----------------



================
Comment at: libcxx/test/std/containers/views/mdspan/layout_stride/comparison.pass.cpp:49-55
+constexpr X compare_layout_mappings(...) { return {}; }
+
+template <class E1, class E2>
+constexpr auto compare_layout_mappings(E1 e1, std::array<int, E1::rank()> s1, E2 e2, std::array<int, E2::rank()> s2)
+    -> decltype(std::layout_stride::mapping<E1>(e1, s1) == std::layout_stride::mapping<E2>(e2, s2)) {
+  return true;
+}
----------------
```lang=c++
template <class E1, class E2>
concept layout_mapping_comparble = requires(E1 e1, E2 e2) { std::layout_stride::mapping<E1>(e1, s1) == std::layout_stride::mapping<E2>(e2, s2); }
```
should also work, right?


================
Comment at: libcxx/test/std/containers/views/mdspan/layout_stride/ctor.default.pass.cpp:37
+  // check correct extents are returned
+  ASSERT_NOEXCEPT(m.extents());
+  assert(m.extents() == e);
----------------
Please add a test to make sure `extents()` is const qualified. Also for `required_span_size()` and `strides()`.


================
Comment at: libcxx/test/std/containers/views/mdspan/layout_stride/ctor.extents_array.pass.cpp:1
+//===----------------------------------------------------------------------===//
+//
----------------
Note to self: Continue here.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157171/new/

https://reviews.llvm.org/D157171



More information about the libcxx-commits mailing list