diff --git a/libcudacxx/include/cuda/__argument/argument.h b/libcudacxx/include/cuda/__argument/argument.h index 8741451b1d4..b74506da48c 100644 --- a/libcudacxx/include/cuda/__argument/argument.h +++ b/libcudacxx/include/cuda/__argument/argument.h @@ -25,8 +25,11 @@ #include #include #include +#include #include +#include #include +#include #include #include #include @@ -75,23 +78,13 @@ template using __element_type_of_t = typename __element_type_of<::cuda::std::remove_cvref_t<_Tp>>::type; // ===================================================================== -// __is_sequence_v / __is_single_value_v +// __is_sequence_v // ===================================================================== template inline constexpr bool __is_sequence_v = - !::cuda::std::is_same_v<::cuda::std::remove_cvref_t<_Tp>, __element_type_of_t<_Tp>>; - -template -inline constexpr bool __is_single_value_v = !__is_sequence_v<_Tp>; - -template -inline constexpr bool __is_iterable_v = false; - -template -inline constexpr bool __is_iterable_v<_Tp, - ::cuda::std::void_t().begin()), - decltype(::cuda::std::declval().end())>> = true; + (::cuda::std::is_array_v<::cuda::std::remove_cvref_t<_Tp>> || ::cuda::std::ranges::range<_Tp>) + || ::cuda::std::__has_random_access_traversal<_Tp>; // ===================================================================== // __constant @@ -121,7 +114,7 @@ struct __constant_sequence using value_type = ::cuda::std::remove_cvref_t; using __element_type = __element_type_of_t; - static_assert(__is_sequence_v, "constant sequence arguments must have a distinct element type"); + static_assert(__is_sequence_v, "The value type of __constant_sequence must be a range or an array"); [[nodiscard]] _CCCL_API static constexpr value_type value() noexcept { @@ -208,7 +201,11 @@ struct __immediate_sequence _CCCL_API constexpr void __validate_value() const noexcept { - if constexpr (__is_iterable_v<_Arg> && ::cuda::std::is_arithmetic_v<__element_type>) + if constexpr (::cuda::std::__has_random_access_traversal<_Arg>) + { // FIXME: (miscco) This is broken. we do not know the size of the sequence + __validate_element(*__arg_); + } + else if constexpr (__is_sequence_v<_Arg> && ::cuda::std::is_arithmetic_v<__element_type>) { for (const auto& __a : __arg_) { @@ -547,7 +544,7 @@ struct __traits_impl using element_type = __element_type_of_t<_Tp>; static constexpr bool is_constant = false; static constexpr bool is_deferred = false; - static constexpr bool is_single_value = __is_single_value_v<_Tp>; + static constexpr bool is_single_value = true; static constexpr element_type lowest = ::cuda::std::numeric_limits::lowest(); static constexpr element_type highest = (::cuda::std::numeric_limits::max)(); }; diff --git a/libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp b/libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp index cdcc6665747..13753040f08 100644 --- a/libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp @@ -11,11 +11,17 @@ #include #include #include +#include +#include #include #include +#include #include +#include #include +#include +#include "test_iterators.h" #include "test_macros.h" enum class color @@ -50,32 +56,34 @@ TEST_FUNC void test() { // --- __is_sequence_v / __is_single_value_v --- + // builtin and class type are not sequences static_assert(!cuda::__argument::__is_sequence_v); static_assert(!cuda::__argument::__is_sequence_v); static_assert(!cuda::__argument::__is_sequence_v); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + + // iterators and pointers can be sequences if they are at least random access static_assert(cuda::__argument::__is_sequence_v); + static_assert(cuda::__argument::__is_sequence_v); static_assert(cuda::__argument::__is_sequence_v>); + static_assert(!cuda::__argument::__is_sequence_v>); + + // ranges and arrays are sequences + static_assert(cuda::__argument::__is_sequence_v); + static_assert(cuda::__argument::__is_sequence_v); + static_assert(cuda::__argument::__is_sequence_v); + static_assert(cuda::__argument::__is_sequence_v); static_assert(cuda::__argument::__is_sequence_v>); static_assert(cuda::__argument::__is_sequence_v&>); static_assert(cuda::__argument::__is_sequence_v>); static_assert(cuda::__argument::__is_sequence_v>); - static_assert(cuda::__argument::__is_sequence_v>); - static_assert(cuda::__argument::__is_sequence_v>); - static_assert(cuda::__argument::__is_sequence_v>); - - static_assert(cuda::__argument::__is_single_value_v); - static_assert(cuda::__argument::__is_single_value_v); - static_assert(cuda::__argument::__is_single_value_v); - static_assert(cuda::__argument::__is_single_value_v); - static_assert(cuda::__argument::__is_single_value_v); - static_assert(cuda::__argument::__is_single_value_v); - static_assert(!cuda::__argument::__is_single_value_v); - static_assert(!cuda::__argument::__is_single_value_v>); - static_assert(!cuda::__argument::__is_single_value_v>); - static_assert(!cuda::__argument::__is_single_value_v&>); - static_assert(!cuda::__argument::__is_single_value_v>); - static_assert(!cuda::__argument::__is_single_value_v>); - static_assert(!cuda::__argument::__is_single_value_v>); // --- __element_type_of_t --- @@ -106,7 +114,7 @@ TEST_FUNC void test() // --- argument_traits: is_single_value --- static_assert(cuda::__argument::__traits::is_single_value); - static_assert(!cuda::__argument::__traits::is_single_value); + static_assert(cuda::__argument::__traits::is_single_value); static_assert(cuda::__argument::__traits>::is_single_value); static_assert(cuda::__argument::__traits>::is_single_value); static_assert( diff --git a/libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp b/libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp index eac5e71aa82..c9723304774 100644 --- a/libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/argument/dynamic_argument.pass.cpp @@ -128,7 +128,7 @@ TEST_FUNC constexpr bool test() // __is_single_value_v on unwrapped types { static_assert( - cuda::__argument::__is_single_value_v>::value_type>); + !cuda::__argument::__is_sequence_v>::value_type>); static_assert( !cuda::__argument::__traits>>::is_single_value); } diff --git a/libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp b/libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp index 7d40183070b..85ccaf1c8a0 100644 --- a/libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/argument/static_argument.pass.cpp @@ -113,7 +113,7 @@ TEST_FUNC void test() // Single value: scalar is single, sequence is not { static_assert( - cuda::__argument::__is_single_value_v>::value_type>); + !cuda::__argument::__is_sequence_v>::value_type>); #if TEST_HAS_CLASS_NTTP static_assert(!cuda::__argument::__traits< cuda::__argument::__constant_sequence{1, 2, 3}>>::is_single_value); diff --git a/libcudacxx/test/libcudacxx/cuda/argument/usage_example.pass.cpp b/libcudacxx/test/libcudacxx/cuda/argument/usage_example.pass.cpp index e3a752b780a..8cc239585ac 100644 --- a/libcudacxx/test/libcudacxx/cuda/argument/usage_example.pass.cpp +++ b/libcudacxx/test/libcudacxx/cuda/argument/usage_example.pass.cpp @@ -82,6 +82,7 @@ TEST_FUNC constexpr bool test() assert(process_segments(100) == 100); } +#if 0 // FIXME(miscco): This should not work // Plain span: per-segment, no bounds, global memory { int sizes[3] = {64, 128, 96}; @@ -90,6 +91,7 @@ TEST_FUNC constexpr bool test() assert(compute_buffer_size(seg, 3) == default_max_segment_size * 3); assert(process_segments(seg) == 64 + 128 + 96); } +#endif // static_argument: scalar, fits in shared memory, buffer = value {