From a718a60b00b76a21496c0e19305a44b878b72d0d Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Fri, 5 Jun 2026 10:50:01 +0200 Subject: [PATCH] [libcu++] Move argument bounds helpers to bound file --- libcudacxx/include/cuda/__argument/argument.h | 124 ----------------- .../include/cuda/__argument/argument_bounds.h | 130 +++++++++++++++++- .../cuda/argument/argument_bounds.pass.cpp | 4 +- 3 files changed, 130 insertions(+), 128 deletions(-) diff --git a/libcudacxx/include/cuda/__argument/argument.h b/libcudacxx/include/cuda/__argument/argument.h index fb514d22648..8741451b1d4 100644 --- a/libcudacxx/include/cuda/__argument/argument.h +++ b/libcudacxx/include/cuda/__argument/argument.h @@ -129,130 +129,6 @@ struct __constant_sequence } }; -// ===================================================================== -// __assert_in_range -// ===================================================================== - -template -_CCCL_API constexpr void __assert_in_range([[maybe_unused]] _From __val) noexcept -{ - if constexpr (::cuda::std::__cccl_is_cv_integer_v<_To> && ::cuda::std::__cccl_is_cv_integer_v<_From>) - { - _CCCL_ASSERT(::cuda::std::in_range<::cuda::std::remove_cv_t<_To>>(__val), - "runtime bound value overflows the element type"); - } -} - -template -[[nodiscard]] _CCCL_API constexpr _To __runtime_bound_cast(_From __val) noexcept -{ - __assert_in_range<_To>(__val); - return static_cast<_To>(__val); -} - -template -_CCCL_API constexpr bool __static_bound_in_range() noexcept -{ - using _RawTo = ::cuda::std::remove_cv_t<_To>; - using _RawFrom = ::cuda::std::remove_cv_t; - - if constexpr (::cuda::std::__cccl_is_integer_v<_RawTo> && ::cuda::std::__cccl_is_integer_v<_RawFrom>) - { - return ::cuda::std::in_range<_RawTo>(_Value); - } - else if constexpr (::cuda::std::is_arithmetic_v<_RawTo> && ::cuda::std::is_arithmetic_v<_RawFrom>) - { - return static_cast<_RawFrom>(static_cast<_RawTo>(_Value)) == _Value; - } - else - { - return true; - } -} - -template -inline constexpr bool __valid_static_bounds_v = true; - -template -inline constexpr bool __valid_static_bounds_v<_ElementType, __static_bounds<_Lowest, _Highest>> = - __static_bound_in_range<_ElementType, _Lowest>() && __static_bound_in_range<_ElementType, _Highest>(); - -template -_CCCL_API constexpr _ElementType __wrapper_static_lowest() noexcept -{ - if constexpr (::cuda::std::is_same_v<_StaticBounds, __no_bounds>) - { - return ::cuda::std::numeric_limits<_ElementType>::lowest(); - } - else - { - return static_cast<_ElementType>(_StaticBounds::lower()); - } -} - -template -_CCCL_API constexpr _ElementType __wrapper_static_highest() noexcept -{ - if constexpr (::cuda::std::is_same_v<_StaticBounds, __no_bounds>) - { - return (::cuda::std::numeric_limits<_ElementType>::max)(); - } - else - { - return static_cast<_ElementType>(_StaticBounds::upper()); - } -} - -template -_CCCL_API constexpr _ElementType __effective_lowest(__runtime_bounds<_ElementType> __runtime_bounds) noexcept -{ - auto __static_lowest = __wrapper_static_lowest<_ElementType, _StaticBounds>(); - return __static_lowest > __runtime_bounds.lower() ? __static_lowest : __runtime_bounds.lower(); -} - -template -_CCCL_API constexpr _ElementType __effective_highest(__runtime_bounds<_ElementType> __runtime_bounds) noexcept -{ - auto __static_highest = __wrapper_static_highest<_ElementType, _StaticBounds>(); - return __static_highest < __runtime_bounds.upper() ? __static_highest : __runtime_bounds.upper(); -} - -template -_CCCL_API constexpr bool __has_bounds_intersection(__runtime_bounds<_ElementType> __runtime_bounds) noexcept -{ - return __effective_lowest<_ElementType, _StaticBounds>(__runtime_bounds) - <= __effective_highest<_ElementType, _StaticBounds>(__runtime_bounds); -} - -template -_CCCL_API constexpr void __validate_bounds_intersection(__runtime_bounds<_ElementType> __runtime_bounds) noexcept -{ - static_assert(__valid_static_bounds_v<_ElementType, _StaticBounds>, - "static argument bounds cannot be represented by the element type"); - _CCCL_VERIFY((__has_bounds_intersection<_ElementType, _StaticBounds>(__runtime_bounds)), - "static and runtime argument bounds do not intersect"); -} - -template -_CCCL_API constexpr void __validate_static_element_bounds([[maybe_unused]] const _ElementType& __val) noexcept -{ - if constexpr (!::cuda::std::is_same_v<_StaticBounds, __no_bounds>) - { - _CCCL_ASSERT((__val >= __wrapper_static_lowest<_ElementType, _StaticBounds>()), - "immediate argument value is below static lowest bound"); - _CCCL_ASSERT((__val <= __wrapper_static_highest<_ElementType, _StaticBounds>()), - "immediate argument value is above static highest bound"); - } -} - -template -_CCCL_API constexpr void __validate_runtime_element_bounds( - [[maybe_unused]] const _ElementType& __val, [[maybe_unused]] __runtime_bounds<_ElementType> __runtime_bounds) noexcept -{ - _CCCL_ASSERT((__val >= __runtime_bounds.lower()), "immediate argument value is below runtime lower bound"); - _CCCL_ASSERT((__val <= __runtime_bounds.upper()), "immediate argument value is above runtime upper bound"); -} - // ===================================================================== // __immediate // ===================================================================== diff --git a/libcudacxx/include/cuda/__argument/argument_bounds.h b/libcudacxx/include/cuda/__argument/argument_bounds.h index 11c46c74417..46dd22c370c 100644 --- a/libcudacxx/include/cuda/__argument/argument_bounds.h +++ b/libcudacxx/include/cuda/__argument/argument_bounds.h @@ -22,8 +22,11 @@ #endif // no system header #include +#include #include #include +#include +#include #include #include @@ -136,12 +139,135 @@ template } template -inline constexpr bool __is_static_bounds_cv_v = __is_static_bounds_v<::cuda::std::remove_cv_t<_Tp>>; +inline constexpr bool __is_static_bounds_cv_v = __is_static_bounds_v<::cuda::std::remove_cvref_t<_Tp>>; template -inline constexpr bool __is_runtime_bounds_cv_v = __is_runtime_bounds_v<::cuda::std::remove_cv_t<_Tp>>; +inline constexpr bool __is_runtime_bounds_cv_v = __is_runtime_bounds_v<::cuda::std::remove_cvref_t<_Tp>>; template inline constexpr bool __is_bounds_v = __is_static_bounds_cv_v<_Tp> || __is_runtime_bounds_cv_v<_Tp>; +// ===================================================================== +// __assert_in_range +// ===================================================================== + +template +_CCCL_API constexpr void __assert_in_range([[maybe_unused]] _From __val) noexcept +{ + if constexpr (::cuda::std::__cccl_is_integer_v<_To> && ::cuda::std::__cccl_is_integer_v<_From>) + { + _CCCL_ASSERT(::cuda::std::in_range<_To>(__val), "runtime bound value overflows the element type"); + } +} + +template +[[nodiscard]] _CCCL_API constexpr _To __runtime_bound_cast(_From __val) noexcept +{ + __assert_in_range<_To>(__val); + return static_cast<_To>(__val); +} + +template +_CCCL_API constexpr bool __static_bound_in_range() noexcept +{ + using _From = decltype(_Value); + + if constexpr (::cuda::std::__cccl_is_integer_v<_To> && ::cuda::std::__cccl_is_integer_v<_From>) + { + return ::cuda::std::in_range<_To>(_Value); + } + else if constexpr (::cuda::std::is_arithmetic_v<_To> && ::cuda::std::is_arithmetic_v<_From>) + { + return static_cast<_From>(static_cast<_To>(_Value)) == _Value; + } + else + { + return true; + } +} + +template +inline constexpr bool __valid_static_bounds_v = true; + +template +inline constexpr bool __valid_static_bounds_v<_ElementType, __static_bounds<_Lowest, _Highest>> = + ::cuda::__argument::__static_bound_in_range<_ElementType, _Lowest>() + && ::cuda::__argument::__static_bound_in_range<_ElementType, _Highest>(); + +template +_CCCL_API constexpr _ElementType __wrapper_static_lowest() noexcept +{ + if constexpr (::cuda::std::is_same_v<_StaticBounds, __no_bounds>) + { + return ::cuda::std::numeric_limits<_ElementType>::lowest(); + } + else + { + return static_cast<_ElementType>(_StaticBounds::lower()); + } +} + +template +_CCCL_API constexpr _ElementType __wrapper_static_highest() noexcept +{ + if constexpr (::cuda::std::is_same_v<_StaticBounds, __no_bounds>) + { + return (::cuda::std::numeric_limits<_ElementType>::max)(); + } + else + { + return static_cast<_ElementType>(_StaticBounds::upper()); + } +} + +template +_CCCL_API constexpr _ElementType __effective_lowest(__runtime_bounds<_ElementType> __runtime_bounds) noexcept +{ + auto __static_lowest = ::cuda::__argument::__wrapper_static_lowest<_ElementType, _StaticBounds>(); + return __static_lowest > __runtime_bounds.lower() ? __static_lowest : __runtime_bounds.lower(); +} + +template +_CCCL_API constexpr _ElementType __effective_highest(__runtime_bounds<_ElementType> __runtime_bounds) noexcept +{ + auto __static_highest = ::cuda::__argument::__wrapper_static_highest<_ElementType, _StaticBounds>(); + return __static_highest < __runtime_bounds.upper() ? __static_highest : __runtime_bounds.upper(); +} + +template +_CCCL_API constexpr bool __valid_argument_bounds(__runtime_bounds<_ElementType> __runtime_bounds) noexcept +{ + return ::cuda::__argument::__effective_lowest<_ElementType, _StaticBounds>(__runtime_bounds) + <= ::cuda::__argument::__effective_highest<_ElementType, _StaticBounds>(__runtime_bounds); +} + +template +_CCCL_API constexpr void __validate_bounds_intersection(__runtime_bounds<_ElementType> __runtime_bounds) noexcept +{ + static_assert(__valid_static_bounds_v<_ElementType, _StaticBounds>, + "static argument bounds cannot be represented by the element type"); + _CCCL_VERIFY((::cuda::__argument::__valid_argument_bounds<_ElementType, _StaticBounds>(__runtime_bounds)), + "static and runtime argument bounds do not intersect"); +} + +template +_CCCL_API constexpr void __validate_static_element_bounds([[maybe_unused]] const _ElementType& __val) noexcept +{ + if constexpr (!::cuda::std::is_same_v<_StaticBounds, __no_bounds>) + { + _CCCL_ASSERT((__val >= ::cuda::__argument::__wrapper_static_lowest<_ElementType, _StaticBounds>()), + "immediate argument value is below static lowest bound"); + _CCCL_ASSERT((__val <= ::cuda::__argument::__wrapper_static_highest<_ElementType, _StaticBounds>()), + "immediate argument value is above static highest bound"); + } +} + +template +_CCCL_API constexpr void __validate_runtime_element_bounds( + [[maybe_unused]] const _ElementType& __val, [[maybe_unused]] __runtime_bounds<_ElementType> __runtime_bounds) noexcept +{ + _CCCL_ASSERT((__val >= __runtime_bounds.lower()), "immediate argument value is below runtime lower bound"); + _CCCL_ASSERT((__val <= __runtime_bounds.upper()), "immediate argument value is above runtime upper bound"); +} + _CCCL_END_NAMESPACE_CUDA_ARGUMENT #include diff --git a/libcudacxx/test/libcudacxx/cuda/argument/argument_bounds.pass.cpp b/libcudacxx/test/libcudacxx/cuda/argument/argument_bounds.pass.cpp index c03b685e821..d7f394a0d74 100644 --- a/libcudacxx/test/libcudacxx/cuda/argument/argument_bounds.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/argument/argument_bounds.pass.cpp @@ -82,9 +82,9 @@ TEST_FUNC constexpr bool test() // Static and runtime bounds intersection { - static_assert(cuda::__argument::__has_bounds_intersection>( + static_assert(cuda::__argument::__valid_argument_bounds>( cuda::__argument::__runtime_bounds{50, 200})); - static_assert(!cuda::__argument::__has_bounds_intersection>( + static_assert(!cuda::__argument::__valid_argument_bounds>( cuda::__argument::__runtime_bounds{0, 50})); }