Skip to content
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
31 changes: 14 additions & 17 deletions libcudacxx/include/cuda/__argument/argument.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
#include <cuda/std/__algorithm/max_element.h>
#include <cuda/std/__algorithm/min_element.h>
#include <cuda/std/__cccl/assert.h>
#include <cuda/std/__iterator/iterator_traits.h>
#include <cuda/std/__iterator/readable_traits.h>
#include <cuda/std/__ranges/concepts.h>
#include <cuda/std/__type_traits/is_arithmetic.h>
#include <cuda/std/__type_traits/is_array.h>
#include <cuda/std/__type_traits/is_integer.h>
#include <cuda/std/__type_traits/is_integral.h>
#include <cuda/std/__type_traits/is_same.h>
Expand Down Expand Up @@ -75,23 +78,13 @@ template <class _Tp>
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 <class _Tp>
inline constexpr bool __is_sequence_v =
!::cuda::std::is_same_v<::cuda::std::remove_cvref_t<_Tp>, __element_type_of_t<_Tp>>;

template <class _Tp>
inline constexpr bool __is_single_value_v = !__is_sequence_v<_Tp>;

template <class _Tp, class = void>
inline constexpr bool __is_iterable_v = false;

template <class _Tp>
inline constexpr bool __is_iterable_v<_Tp,
::cuda::std::void_t<decltype(::cuda::std::declval<const _Tp&>().begin()),
decltype(::cuda::std::declval<const _Tp&>().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
Expand Down Expand Up @@ -121,7 +114,7 @@ struct __constant_sequence
using value_type = ::cuda::std::remove_cvref_t<decltype(_Value)>;
using __element_type = __element_type_of_t<value_type>;

static_assert(__is_sequence_v<value_type>, "constant sequence arguments must have a distinct element type");
static_assert(__is_sequence_v<value_type>, "The value type of __constant_sequence must be a sequence");

[[nodiscard]] _CCCL_API static constexpr value_type value() noexcept
{
Expand Down Expand Up @@ -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
}
else if constexpr (__is_sequence_v<_Arg> && !::cuda::std::__has_random_access_traversal<_Arg>
&& ::cuda::std::is_arithmetic_v<__element_type>)
{
for (const auto& __a : __arg_)
{
Expand Down Expand Up @@ -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<element_type>::lowest();
static constexpr element_type highest = (::cuda::std::numeric_limits<element_type>::max)();
};
Expand Down Expand Up @@ -584,7 +581,7 @@ struct __traits_impl<__constant_sequence<_Value>>
{
using value_type = ::cuda::std::remove_cvref_t<decltype(_Value)>;
using element_type = __element_type_of_t<value_type>;
static_assert(__is_sequence_v<value_type>, "constant sequence arguments must have a distinct element type");
static_assert(__is_sequence_v<value_type>, "The value type of __constant_sequence must be a sequence");
static constexpr bool is_constant = true;
static constexpr bool is_deferred = false;
static constexpr bool is_single_value = false;
Expand Down
44 changes: 26 additions & 18 deletions libcudacxx/test/libcudacxx/cuda/argument/argument_traits.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@
#include <cuda/__argument_>
#include <cuda/iterator>
#include <cuda/std/array>
#include <cuda/std/complex>
#include <cuda/std/expected>
#include <cuda/std/limits>
#include <cuda/std/mdspan>
#include <cuda/std/optional>
#include <cuda/std/span>
#include <cuda/std/tuple>
#include <cuda/std/type_traits>
#include <cuda/std/utility>

#include "test_iterators.h"
#include "test_macros.h"

enum class color
Expand Down Expand Up @@ -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<int>);
static_assert(!cuda::__argument::__is_sequence_v<color>);
static_assert(!cuda::__argument::__is_sequence_v<non_sequence_value>);
static_assert(!cuda::__argument::__is_sequence_v<range_like<int>>);
static_assert(!cuda::__argument::__is_sequence_v<element_type_like<int>>);
static_assert(!cuda::__argument::__is_sequence_v<value_type_like<int>>);
static_assert(!cuda::__argument::__is_sequence_v<cuda::std::complex<float>>);
static_assert(!cuda::__argument::__is_sequence_v<cuda::std::pair<float, int>>);
static_assert(!cuda::__argument::__is_sequence_v<cuda::std::tuple<float, int>>);
static_assert(!cuda::__argument::__is_sequence_v<cuda::std::optional<int>>);
static_assert(!cuda::__argument::__is_sequence_v<cuda::std::expected<int, int>>);

// iterators and pointers can be sequences if they are at least random access
static_assert(cuda::__argument::__is_sequence_v<int*>);
static_assert(cuda::__argument::__is_sequence_v<const int*>);
static_assert(cuda::__argument::__is_sequence_v<cuda::counting_iterator<int>>);
static_assert(!cuda::__argument::__is_sequence_v<bidirectional_iterator<int*>>);

// ranges and arrays are sequences
static_assert(cuda::__argument::__is_sequence_v<int[]>);
static_assert(cuda::__argument::__is_sequence_v<const int[]>);
static_assert(cuda::__argument::__is_sequence_v<int[42]>);
static_assert(cuda::__argument::__is_sequence_v<const int[42]>);
static_assert(cuda::__argument::__is_sequence_v<cuda::std::span<int, 1>>);
static_assert(cuda::__argument::__is_sequence_v<const cuda::std::span<int, 1>&>);
static_assert(cuda::__argument::__is_sequence_v<cuda::std::span<int>>);
static_assert(cuda::__argument::__is_sequence_v<cuda::std::array<int, 3>>);
static_assert(cuda::__argument::__is_sequence_v<range_like<int>>);
static_assert(cuda::__argument::__is_sequence_v<element_type_like<int>>);
static_assert(cuda::__argument::__is_sequence_v<value_type_like<int>>);

static_assert(cuda::__argument::__is_single_value_v<int>);
static_assert(cuda::__argument::__is_single_value_v<float>);
static_assert(cuda::__argument::__is_single_value_v<double>);
static_assert(cuda::__argument::__is_single_value_v<const int>);
static_assert(cuda::__argument::__is_single_value_v<color>);
static_assert(cuda::__argument::__is_single_value_v<non_sequence_value>);
static_assert(!cuda::__argument::__is_single_value_v<int*>);
static_assert(!cuda::__argument::__is_single_value_v<cuda::counting_iterator<int>>);
static_assert(!cuda::__argument::__is_single_value_v<cuda::std::span<int, 1>>);
static_assert(!cuda::__argument::__is_single_value_v<const cuda::std::span<int, 1>&>);
static_assert(!cuda::__argument::__is_single_value_v<cuda::std::span<int>>);
static_assert(!cuda::__argument::__is_single_value_v<cuda::std::span<int, 4>>);
static_assert(!cuda::__argument::__is_single_value_v<cuda::std::array<int, 3>>);

// --- __element_type_of_t ---

Expand Down Expand Up @@ -106,7 +114,7 @@ TEST_FUNC void test()
// --- argument_traits: is_single_value ---

static_assert(cuda::__argument::__traits<int>::is_single_value);
static_assert(!cuda::__argument::__traits<int*>::is_single_value);
static_assert(cuda::__argument::__traits<int*>::is_single_value);
static_assert(cuda::__argument::__traits<cuda::__argument::__immediate<int>>::is_single_value);
static_assert(cuda::__argument::__traits<cuda::__argument::__immediate<int*>>::is_single_value);
static_assert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ TEST_FUNC constexpr bool test()
// __is_single_value_v on unwrapped types
{
static_assert(
cuda::__argument::__is_single_value_v<cuda::__argument::__traits<cuda::__argument::__immediate<int>>::value_type>);
!cuda::__argument::__is_sequence_v<cuda::__argument::__traits<cuda::__argument::__immediate<int>>::value_type>);
static_assert(
!cuda::__argument::__traits<cuda::__argument::__immediate_sequence<cuda::std::span<int>>>::is_single_value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ TEST_FUNC void test()
// Single value: scalar is single, sequence is not
{
static_assert(
cuda::__argument::__is_single_value_v<cuda::__argument::__traits<cuda::__argument::__constant<42>>::value_type>);
!cuda::__argument::__is_sequence_v<cuda::__argument::__traits<cuda::__argument::__constant<42>>::value_type>);
#if TEST_HAS_CLASS_NTTP
static_assert(!cuda::__argument::__traits<
cuda::__argument::__constant_sequence<cuda::std::array<int, 3>{1, 2, 3}>>::is_single_value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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
{
Expand Down
Loading