Skip to content
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

Add bound checks for each dimension of mdspan #3065

Merged
merged 20 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/libcudacxx/standard_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,15 @@ Feature availability:

- C++23 ``invoke_r`` in ``<functional>`` is available in C++14.

- C++23 ``<mdspan>`` is available in C++17.
- C++23 ``<mdspan>`` is available in C++14.

- ``mdspan`` is feature complete in C++17 onwards.
- ``mdspan`` is feature complete in C++14 onwards.
- ``mdspan`` on msvc is only supported in C++20 and onwards.

- C++26 ``std::dims`` is available in C++14.

- C++23 ``forward_like``, ``to_underlying`` and ``unreachable`` from ``<utility>`` are available in C++11.

- C++23 ``is_scoped_enum`` in ``<type_traits>`` is available in C++11.

- C++26 ``std::dims`` is available in C++17.

- C++26 tuple protocol to ``complex`` is available in C++11.
5 changes: 3 additions & 2 deletions docs/libcudacxx/standard_api/container_library/mdspan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
Extensions
----------

- All features of ``<mdspan>`` are made available in C++17 onwards
- C++26 ``std::dims`` is made available in C++17 onwards
- All features of ``<mdspan>`` are made available in C++14 onwards
- The C++23 multidimensional ``operator[]`` is replaced with ``operator()``
- C++26 ``std::dims`` is made available in C++14 onwards

Restrictions
------------
Expand Down
30 changes: 27 additions & 3 deletions libcudacxx/include/cuda/std/__mdspan/mdspan.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
# pragma system_header
#endif // no system header

#include <cuda/std/__algorithm/all_of.h>
#include <cuda/std/__functional/identity.h>
#include <cuda/std/__mdspan/compressed_pair.h>
#include <cuda/std/__mdspan/default_accessor.h>
#include <cuda/std/__mdspan/extents.h>
Expand All @@ -64,6 +66,7 @@
#include <cuda/std/__type_traits/is_convertible.h>
#include <cuda/std/__type_traits/is_default_constructible.h>
#include <cuda/std/__type_traits/is_nothrow_constructible.h>
#include <cuda/std/__type_traits/is_signed.h>
#include <cuda/std/__type_traits/rank.h>
#include <cuda/std/__type_traits/remove_all_extents.h>
#include <cuda/std/__type_traits/remove_cv.h>
Expand All @@ -79,6 +82,8 @@ _LIBCUDACXX_BEGIN_NAMESPACE_STD

#if _CCCL_STD_VER >= 2014

_CCCL_NV_DIAG_SUPPRESS(186) // pointless comparison of unsigned integer with zero

template <class _ElementType,
class _Extents,
class _LayoutPolicy = layout_right,
Expand Down Expand Up @@ -108,28 +113,45 @@ class mdspan
return (__self.rank() > 0)
&& __MDSPAN_FOLD_OR((__self.__mapping_ref().extents().template __extent<_Idxs>() == index_type(0)));
}

template <class... _SizeTypes>
_CCCL_NODISCARD _LIBCUDACXX_HIDE_FROM_ABI static constexpr bool
__check_index(_Extents const& exts, _SizeTypes... __indices)
{
# if _CCCL_STD_VER >= 2017
return (((is_unsigned_v<index_type> ? true : static_cast<index_type>(__indices) >= 0)
&& static_cast<index_type>(__indices) < exts.extent(_Idxs))
&& ...);
# else
return true;
# endif // _CCCL_STD_VER >= 2017
}

template <class... _SizeTypes>
_CCCL_NODISCARD _LIBCUDACXX_HIDE_FROM_ABI static constexpr index_type
__index(mdspan const& __self, _SizeTypes... __indices) noexcept
{
_CCCL_ASSERT(__check_index(__self.__mapping_ref().extents(), __indices...),
"cuda::std::mdspan subscript out of range!");
const index_type __res = __self.__mapping_ref()(index_type(__indices)...);
_CCCL_ASSERT(__res < __self.__mapping_ref().required_span_size(), "cuda::std::mdspan subscript out of range!");
return __res;
}
template <class _SizeType, size_t _Np>
_CCCL_NODISCARD _LIBCUDACXX_HIDE_FROM_ABI static constexpr index_type
__index(mdspan const& __self, const _CUDA_VSTD::array<_SizeType, _Np>& __indices) noexcept
{
_CCCL_ASSERT(__check_index(__self.__mapping_ref().extents(), __indices[_Idxs]...),
"cuda::std::mdspan subscript out of range!");
const index_type __res = __self.__mapping_ref()(__indices[_Idxs]...);
_CCCL_ASSERT(__res < __self.__mapping_ref().required_span_size(), "cuda::std::mdspan subscript out of range!");
return __res;
}
template <class _SizeType, size_t _Np>
_CCCL_NODISCARD _LIBCUDACXX_HIDE_FROM_ABI static constexpr index_type
__index(mdspan const& __self, const _CUDA_VSTD::span<_SizeType, _Np>& __indices) noexcept
{
_CCCL_ASSERT(__check_index(__self.__mapping_ref().extents(), __indices[_Idxs]...),
"cuda::std::mdspan subscript out of range!");
const index_type __res = __self.__mapping_ref()(__indices[_Idxs]...);
_CCCL_ASSERT(__res < __self.__mapping_ref().required_span_size(), "cuda::std::mdspan subscript out of range!");
return __res;
}
};
Expand Down Expand Up @@ -488,6 +510,8 @@ _CCCL_HOST_DEVICE mdspan(const typename _AccessorType::data_handle_type, const _
_AccessorType>;
# endif // __MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION

_CCCL_NV_DIAG_DEFAULT(186)

#endif // _CCCL_STD_VER >= 2014

_LIBCUDACXX_END_NAMESPACE_STD
Expand Down
Loading