-
Notifications
You must be signed in to change notification settings - Fork 81
Fix standard compliance #285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The initalization change for the array was necessary to avoid an issue with unintitialized members of std:;array for libcxx with length zero.
|
Outstanding FIXMEs: |
| for (size_type r = 0; r < m_rank; r++) | ||
| if(rhs.extent(r) != lhs.extent(r)) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| for (size_type r = 0; r < m_rank; r++) | |
| if(rhs.extent(r) != lhs.extent(r)) return false; | |
| for (size_type r = 0; r < m_rank; r++) { | |
| if (rhs.extent(r) != lhs.extent(r)) { | |
| return false; | |
| } | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposing to run the whole thing through clang-format and starting to enforce it.
mhoemmen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one lambda with explicit template parameters [&] <size_t...> { /* ... */ } requires C++20, but it's not protected with a macro. Otherwise, this is great! : - )
mhoemmen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AWESOME
bcdb5e0 to
8328f29
Compare
| MDSPAN_STATIC_TEST( | ||
| std::is_constructible<LS2, AStridedLayout<true>::mapping<E1>>::value && | ||
| std::is_convertible<AStridedLayout<true>::mapping<E1>, LS2>::value | ||
| !std::is_convertible<AStridedLayout<true>::mapping<E1>, LS2>::value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only std:: layouts are convertible, everything else is explicit in the standard.
| #ifdef __cpp_lib_span | ||
| MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, | ||
| /* requires */ (N == m_size_dynamic)) | ||
| /* requires */ (N == m_size_dynamic && N > 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needed a separate constructor to make this work warning free, and make it work in constant expressions. Same strategy as with the from std::array ctor.
| /* requires */ | ||
| ( | ||
| _MDSPAN_TRAIT(std::is_convertible, OtherIndexType, index_type) && | ||
| _MDSPAN_TRAIT(std::is_convertible, const OtherIndexType&, index_type) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the standard says.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same below. The LLVM tests catch the difference.
| extents(IndexTypes...) | ||
| -> extents<size_t, | ||
| size_t((IndexTypes(), ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent))...>; | ||
| ((void) sizeof(IndexTypes), ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent)...>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't require default constructibility of IndexTypes to make the deduction guide work.
| for(rank_type r=0; r<__extents.rank(); r++) { | ||
| if(stride != static_cast<index_type>(other.stride(r))) { | ||
| // Note this throw will lead to a terminate if triggered since this function is marked noexcept | ||
| throw std::runtime_error("Assigning layout_stride to layout_left with invalid strides."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
complains about throw in noexcept on various compilers (warning).
| MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what the standard says.
| MDSPAN_TEMPLATE_REQUIRES( | ||
| class OtherExtents, | ||
| /* requires */ ( Extents::rank() == OtherExtents::rank()) | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constraint in the standard.
| class OtherExtents, | ||
| /* requires */ ( Extents::rank() == OtherExtents::rank()) | ||
| ) | ||
| MDSPAN_INLINE_FUNCTION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constraint in the standard.
| for(rank_type r=__extents.rank(); r>0; r--) { | ||
| if(stride != static_cast<index_type>(other.stride(r-1))) { | ||
| // Note this throw will lead to a terminate if triggered since this function is marked noexcept | ||
| throw std::runtime_error("Assigning layout_stride to layout_right with invalid strides."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of warning and make it work in constant expression
| MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } | ||
| MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
standard says so
| //---------------------------------------------------------------------------- | ||
|
|
||
| using __strides_storage_t = std::array<index_type, extents_type::rank()>; | ||
| using __strides_storage_t = detail::possibly_empty_array<index_type, extents_type::rank()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of use of std::array, for GPUs etc. actually this is what the LLVM implementation does too, will make the class empty for rank-0 with clang (where std:;array actually contains a char).
| && _MDSPAN_FOLD_AND((self.extents().extent(Idxs) == other.extents().extent(Idxs)) /* || ... */); | ||
| using common_t = std::common_type_t<index_type, typename OtherExtents::index_type>; | ||
| return _MDSPAN_FOLD_AND((static_cast<common_t>(self.stride(Idxs)) == static_cast<common_t>(other.stride(Idxs))) /* && ... */) | ||
| && _MDSPAN_FOLD_AND((static_cast<common_t>(self.extents().extent(Idxs)) == static_cast<common_t>(other.extents().extent(Idxs))) /* || ... */); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these and others like it eliminate warning for different signedness.
| MDSPAN_INLINE_FUNCTION | ||
| static constexpr std::array<index_type, extents_type::rank()> return_strides(const __strides_storage_t& s) { | ||
| return std::array<index_type, extents_type::rank()>{s[Idxs]...}; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need this becasue we don't store a std::array for strides anymore.
| : __members{ | ||
| #else | ||
| : __base_t(__base_t{__member_pair_t( | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to create "layout_right" strides in default construction.
| !(std::is_convertible<typename StridedLayoutMapping::extents_type, extents_type>::value && | ||
| (detail::__is_mapping_of<layout_left, StridedLayoutMapping> || | ||
| detail::__is_mapping_of<layout_right, StridedLayoutMapping> || | ||
| detail::__is_mapping_of<layout_stride, StridedLayoutMapping>)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was just wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LLVM tests catch this.
| } else { | ||
| return required_span_size() == __get_size(extents(), std::make_index_sequence<extents_type::rank()>()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now fully implement corner case required_span_size.
| using common_t = std::common_type_t<index_type, typename StridedLayoutMapping::index_type>; | ||
| for(rank_type r = 0; r < extents_type::rank(); r++) | ||
| strides_match = strides_match && (static_cast<common_t>(x.stride(r)) == static_cast<common_t>(y.stride(r))); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of warning
| _MDSPAN_TRAIT(std::is_convertible, SizeType, index_type) && | ||
| _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, SizeType) && | ||
| _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && | ||
| _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is what the standard actually says.
This fixes most everything identified in the llvm tests which is wrong with our reference implementation, and where we haven't backported fixes yet from when we contributed our implementation to LLVM.
I haven't done mdspan yet.