[libcxx-commits] [PATCH] D151267: mdspan: implement layout_right
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Fri May 26 10:38:00 PDT 2023
ldionne added inline comments.
================
Comment at: libcxx/include/__mdspan/extents.h:459
+ requires(is_integral_v<_From>)
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_multidimensional_index_in(_IndexType __extent, _From __value) {
+ if constexpr (is_signed_v<_From>) {
----------------
`__is_index_in_extent`
================
Comment at: libcxx/include/__mdspan/extents.h:480
+_LIBCPP_HIDE_FROM_ABI constexpr bool
+__is_multidimensional_index_in(index_sequence<_Idxs...>, _Extents __ext, _From... __values) {
+ return (__mdspan_detail::__is_multidimensional_index_in(__ext.extent(_Idxs), __values) && ...);
----------------
Either rename to `_impl` or inline it via a lambda below.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:17
+
+#ifndef _LIBCPP___MDSPAN_LAYOUT_RIGHT_MAPPING_H
+#define _LIBCPP___MDSPAN_LAYOUT_RIGHT_MAPPING_H
----------------
Let's make this `__mdspan/layout_right.h` since we're basically implementing the whole class here even though we have a "fwd decl" somewhere else.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:28
+#include <__utility/integer_sequence.h>
+#include <__utility/unreachable.h>
+#include <cinttypes>
----------------
Not necessary anymore?
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:46-47
+class layout_right::mapping {
+ static_assert(__mdspan_detail::__is_extents<_Extents>::value,
+ "layout_right::mapping template argument must be a specialization of extents.");
+
----------------
Do you have a `.verify.cpp` test for this diagnostic?
I think you want something like:
```
//expected-error-re@*:* {{{{(static_assert|static assertion)}} failed {{.*}}MESSAGE}}
```
see `libcxx/test/libcxx/algorithms/bad_iterator_traits.verify.cpp` for example.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:50-54
+ using extents_type = _Extents;
+ using index_type = typename extents_type::index_type;
+ using size_type = typename extents_type::size_type;
+ using rank_type = typename extents_type::rank_type;
+ using layout_type = layout_right;
----------------
Note to self: those are tested (thanks!).
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:57
+private:
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(extents_type __ext) {
+ if constexpr (extents_type::rank() == 0)
----------------
I don't think we need to make a copy here.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:63-66
+ for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
+ if (__prod > (__num_max / __ext.extent(__r)))
+ return false;
+ __prod *= __ext.extent(__r);
----------------
I think we could do this instead:
```
index_type __prod = __ext.extent(0);
for (rank_type __r = 1; __r < extents_type::rank(); __r++) {
bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod);
if (__overflowed)
return false;
}
```
This would avoid the division.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:78
+ _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
+ _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
+ _LIBCPP_ASSERT(__required_span_size_is_representable(__ext),
----------------
Do you have a test for the `noexcept`-ness? Edit: Yes.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:84
+ template <class _OtherExtents>
+ requires(is_constructible_v<extents_type, _OtherExtents>)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
----------------
Do you have a test that checks that `mapping` is not constructible (using a type trait) if the extents are not constructible? This is important to make sure that you implemented this using `requires` (or `enable_if`) as opposed to it just being a hard error.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:116
+
+private:
+ // Helper functions to compute the offset
----------------
Can we move this `private` block to the end of the class? I usually don't mind implementation details in the middle of the class, but this one is quite large so it obscures the public API a bit too much.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:150
+ template <class... _Indices>
+ requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
+ (is_nothrow_constructible_v<index_type, _Indices> && ...))
----------------
Please make sure you have SFINAE (or better, concepts) tests for those requirements.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:155
+ "layout_right::mapping: out of bounds indexing");
+ return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(__idx)...);
+ }
----------------
```
return [&]<size_t ..._Pos>(index_sequence<_Pos...>) {
index_type __result = 0;
((result = __idx + __extents_.extent(_Pos) * __result))...; // exercise for the reader :-)
return __result;
}(index_sequence_for<_Indices...>{});
```
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:170
+ _LIBCPP_ASSERT(__r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index");
+ if constexpr (extents_type::rank() > 0) {
+ index_type __s = 1;
----------------
This is always true, so can be removed.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:176
+ }
+ __libcpp_unreachable();
+ }
----------------
And this isn't necessary anymore either.
================
Comment at: libcxx/include/__mdspan/layout_right_mapping.h:180
+ template <class _OtherExtents>
+ requires(_OtherExtents::rank() == extents_type::rank())
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool
----------------
Can you make sure you have a test that we SFINAE away when the ranks are different?
================
Comment at: libcxx/include/__mdspan/layouts.h:17
+
+#ifndef _LIBCPP___MDSPAN_LAYOUTS_H
+#define _LIBCPP___MDSPAN_LAYOUTS_H
----------------
Let's move this to `libcxx/include/__fwd/mdspan_layouts.h`. While those are technically not forward declarations, they're close enough.
================
Comment at: libcxx/include/__mdspan/layouts.h:48-55
+// Will be implemented with follow on revision
+# if 0
+// Layout policy with a unique mapping where strides are arbitrary
+struct layout_stride {
+ template<class Extents>
+ class mapping;
+};
----------------
+1 let's remove those until they are implemented, or make them a comment.
================
Comment at: libcxx/test/std/containers/views/mdspan/layout_right/conversion.pass.cpp:1
+//===----------------------------------------------------------------------===//
+//
----------------
Let's name this `ctor.mapping.pass.cpp`
================
Comment at: libcxx/test/std/containers/views/mdspan/layout_right/ctor_default.pass.cpp:1
+//===----------------------------------------------------------------------===//
+//
----------------
Let's use `ctor.default.pass.cpp`, it's more consistent with what we're doing recently.
================
Comment at: libcxx/test/std/containers/views/mdspan/layout_right/ctor_extents.pass.cpp:1
+//===----------------------------------------------------------------------===//
+//
----------------
`ctor.extents.pass.cpp`
================
Comment at: libcxx/test/std/containers/views/mdspan/layout_right/properties.pass.cpp:36
+template <class E>
+void test_layout_mapping_right() {
+ using M = std::layout_right::template mapping<E>;
----------------
Please use a classic `constexpr` test here -- I'd like to make sure that these can also be called at runtime.
For example, your test (as currently written) would pass if we did something like:
```
static constexpr bool is_always_unique() noexcept {
if (!std::is_constant_evaluated())
throw "ahah";
return true;
}
```
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151267/new/
https://reviews.llvm.org/D151267
More information about the libcxx-commits
mailing list