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 some simple utilities for manipulating lists of types #2370

Merged
merged 38 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
302ead2
fix the cudax `vector_add` sample
ericniebler Sep 4, 2024
321b94f
add some simple utilities for manipulating lists of types
ericniebler Sep 4, 2024
1982988
obey C++11 constexpr function rules in `aligned_storage`
ericniebler Sep 4, 2024
94fd59a
add `__type_cartesian_product`, `__type_remove`, and `__type_iota`
ericniebler Sep 5, 2024
db5ec7e
review feedback and compiler work-arounds
ericniebler Sep 5, 2024
7c321ff
work around old clang compiler bugs
ericniebler Sep 5, 2024
92743c8
work around more compiler bugs
ericniebler Sep 5, 2024
e47e27c
add missing host/device annotations to keep nvrtc happy
ericniebler Sep 6, 2024
32da9b7
try to placate msvc
ericniebler Sep 6, 2024
1aa29bb
fix typo
ericniebler Sep 6, 2024
5107f7d
Merge remote-tracking branch 'origin/main' into mini-meta-programming…
ericniebler Sep 6, 2024
e87085d
add `_CCCL_CUDACC_BELOW_12_0` config macro; use it in `type_list.h`
ericniebler Sep 6, 2024
7c13a3f
use a simpler and faster fall-back implementation of pack indexing
ericniebler Sep 6, 2024
bc4002b
Merge remote-tracking branch 'origin/main' into mini-meta-programming…
ericniebler Sep 6, 2024
cb8047d
replace variable template with a class template for the sake of C++11
ericniebler Sep 6, 2024
b9b16aa
add `_CCCL_PP_REPEAT` in a new `__cccl/preprocessor.h` header
ericniebler Sep 8, 2024
fde31b4
generalize `_CCCL_PP_REPEAT` macro; implement `__type_fold_[left|righ…
ericniebler Sep 9, 2024
fec8cc6
reformat
ericniebler Sep 9, 2024
4c80ec5
add missing type and alias attribute annotations
ericniebler Sep 9, 2024
1fc4f95
Merge remote-tracking branch 'origin/main' into mini-meta-programming…
ericniebler Sep 9, 2024
8fef688
add tests for the type-list utilities
ericniebler Sep 10, 2024
ad7cd10
try to make `__type_callable` acceptable to msvc
ericniebler Sep 10, 2024
e4b6cc3
add execution space annotations to functions to keep nvrtc happy
ericniebler Sep 10, 2024
ac95264
comment out `__type_callable` and `__type_defer` for now
ericniebler Sep 10, 2024
3d30fa0
[pre-commit.ci] auto code formatting
pre-commit-ci[bot] Sep 10, 2024
a2f2fef
Merge remote-tracking branch 'upstream/main' into mini-meta-programmi…
ericniebler Sep 10, 2024
a028fa5
Merge branch 'mini-meta-programming-library' of github.com:ericnieble…
ericniebler Sep 10, 2024
fd634fa
remove unneeded #include
ericniebler Sep 10, 2024
edc5eb4
formulate `__type_callable` such that nvcc-11 will accept it
ericniebler Sep 10, 2024
ed3e0d7
avoid the identifier `_C` which is #define-d somewhere
ericniebler Sep 10, 2024
255326f
prefer `cuda::std::size_t` over `std::size_t` in tests for NVRTC
ericniebler Sep 10, 2024
6ba0796
Merge branch 'mini-meta-programming-library' of github.com:ericnieble…
ericniebler Sep 10, 2024
c01fdd3
use a different formulation of `__type_call_indirect` for nvcc < 12.2
ericniebler Sep 10, 2024
0695756
Apply review comments
miscco Sep 11, 2024
fb84f7c
Revert "use a different formulation of `__type_call_indirect` for nvc…
ericniebler Sep 11, 2024
a7bb648
nvcc prior to 12.2 could not reliably do SFINAE during alias instanti…
ericniebler Sep 12, 2024
3583414
Merge remote-tracking branch 'origin/main' into mini-meta-programming…
ericniebler Sep 12, 2024
858368b
skip meta-programming SFINAE tests with the Intel compiler
ericniebler Sep 12, 2024
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
7 changes: 0 additions & 7 deletions cub/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ endif()
include("${CUB_SOURCE_DIR}/cmake/CPM.cmake")
CPMAddPackage("gh:catchorg/[email protected]")

option(METAL_BUILD_DOC OFF)
option(METAL_BUILD_EXAMPLES OFF)
option(METAL_BUILD_TESTS OFF)
CPMAddPackage("gh:brunocodutra/[email protected]")

CPMAddPackage(
NAME NVTX
GITHUB_REPOSITORY NVIDIA/NVTX
Expand Down Expand Up @@ -224,7 +219,6 @@ function(cub_add_test target_name_var test_name test_src cub_target launcher_id)
target_link_libraries(${config_c2run_target} PRIVATE
${cub_target}
${config_c2h_target}
Metal
Catch2::Catch2)
cub_clone_target_properties(${config_c2run_target} ${cub_target})
cub_configure_cuda_target(${config_c2run_target} RDC ${cdp_val})
Expand Down Expand Up @@ -264,7 +258,6 @@ function(cub_add_test target_name_var test_name test_src cub_target launcher_id)
target_link_libraries(${test_target} PRIVATE
${cub_target}
${config_c2h_target}
Metal
Catch2::Catch2
)
cub_clone_target_properties(${test_target} ${cub_target})
Expand Down
2 changes: 1 addition & 1 deletion cub/test/catch2_test_device_histogram.cu
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ CUB_TEST("DeviceHistogram::Histogram* basic use", "[histogram][device]", types)

// TODO(bgruber): float produces INFs in the HistogramRange test setup AND the HistogramEven implementation
// This test covers int32 and int64 arithmetic for bin computation
CUB_TEST("DeviceHistogram::Histogram* large levels", "[histogram][device]", metal::remove<types, float>)
CUB_TEST("DeviceHistogram::Histogram* large levels", "[histogram][device]", c2h::remove<types, float>)
{
using sample_t = c2h::get<0, TestType>;
using level_t = sample_t;
Expand Down
20 changes: 11 additions & 9 deletions cub/test/catch2_test_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

#include "cuda/std/__cccl/diagnostic.h"
#include "test_util_vec.h"
#include <metal.hpp>

#if __CUDACC_VER_MAJOR__ == 11
_CCCL_NV_DIAG_SUPPRESS(177) // catch2 may contain unused variableds
Expand All @@ -60,31 +59,34 @@ namespace c2h
{

template <typename... Ts>
using type_list = metal::list<Ts...>;
using type_list = ::cuda::std::__type_list<Ts...>;

template <typename TypeList>
using size = metal::size<TypeList>;
using size = ::cuda::std::__type_list_size<TypeList>;

template <std::size_t Index, typename TypeList>
using get = metal::at<TypeList, metal::number<Index>>;
using get = ::cuda::std::__type_at_c<Index, TypeList>;

template <class... TypeLists>
using cartesian_product = metal::cartesian<TypeLists...>;
using cartesian_product = ::cuda::std::__type_cartesian_product<TypeLists...>;

template <typename T, T... Ts>
using enum_type_list = c2h::type_list<std::integral_constant<T, Ts>...>;

template <typename T0, typename T1>
using pair = metal::pair<T0, T1>;
using pair = ::cuda::std::__type_pair<T0, T1>;

template <typename P>
using first = metal::first<P>;
using first = ::cuda::std::__type_pair_first<P>;

template <typename P>
using second = metal::second<P>;
using second = ::cuda::std::__type_pair_second<P>;

template <std::size_t start, std::size_t size, std::size_t stride = 1>
using iota = metal::iota<metal::number<start>, metal::number<size>, metal::number<stride>>;
using iota = ::cuda::std::__type_iota<start, size, stride>;

template <typename TypeList, typename T>
using remove = ::cuda::std::__type_remove<TypeList, T>;

} // namespace c2h

Expand Down
2 changes: 1 addition & 1 deletion cub/test/catch2_test_iterator.cu
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

using scalar_types = c2h::type_list<std::int8_t, std::int16_t, std::int32_t, std::int64_t, float, double>;

using types = metal::append<
using types = ::cuda::std::__type_push_back<
scalar_types,
char2,
short2,
Expand Down
3 changes: 2 additions & 1 deletion libcudacxx/include/cuda/std/__type_traits/make_signed.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ typedef __type_list<signed char,
signed short,
signed int,
signed long,
signed long long,
signed long long
# ifndef _LIBCUDACXX_HAS_NO_INT128
,
__int128_t
# endif
>
Expand Down
3 changes: 2 additions & 1 deletion libcudacxx/include/cuda/std/__type_traits/make_unsigned.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ typedef __type_list<unsigned char,
unsigned short,
unsigned int,
unsigned long,
unsigned long long,
unsigned long long
# ifndef _LIBCUDACXX_HAS_NO_INT128
,
__uint128_t
# endif
>
Expand Down
148 changes: 143 additions & 5 deletions libcudacxx/include/cuda/std/__type_traits/type_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# pragma system_header
#endif // no system header

#include <cuda/std/__cccl/visibility.h>
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
#include <cuda/std/__type_traits/conditional.h>
#include <cuda/std/__type_traits/integral_constant.h>
#include <cuda/std/__type_traits/is_same.h>
Expand Down Expand Up @@ -50,6 +51,14 @@ using __type = typename _Tp::type;
template <class _Fn, class... _Ts>
using __type_call = typename _Fn::template __apply<_Ts...>;

//! @brief Evaluate a unary meta-callable with the given argument
template <class _Fn, class _Ty>
using __type_call1 = typename _Fn::template __apply<_Ty>;

//! @brief Evaluate a binary meta-callable with the given arguments
template <class _Fn, class _Ty, class _Uy>
using __type_call2 = typename _Fn::template __apply<_Ty, _Uy>;

//! @brief Turns a class or alias template into a meta-callable
template <template <class...> class _Fn>
struct __type_quote
Expand All @@ -58,6 +67,49 @@ struct __type_quote
using __apply = _Fn<_Ts...>;
};

//! @brief Turns a unary class or alias template into a meta-callable
template <template <class> class _Fn>
struct __type_quote1
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
{
template <class _Ty>
using __apply = _Fn<_Ty>;
};
ericniebler marked this conversation as resolved.
Show resolved Hide resolved

//! @brief Turns a unary class or alias template into a meta-callable
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
template <template <class, class> class _Fn>
struct __type_quote2
{
template <class _Ty, class _Uy>
using __apply = _Fn<_Ty, _Uy>;
};

//! @brief Turns a trait class template \c F into a meta-callable \c C such that
//! \c C::__apply<Ts...> is equivalent to \c F<Ts...>::type.
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
template <template <class...> class _Fn>
struct __type_quote_trait
{
template <class... _Ts>
using __apply = __type<_Fn<_Ts...>>;
};

//! @brief Turns a unary trait class template \c F into a meta-callable \c C such that
//! \c C::__apply<T> is equivalent to \c F<T>::type.
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
template <template <class> class _Fn>
struct __type_quote_trait1
{
template <class _Ty>
using __apply = __type<_Fn<_Ty>>;
};

//! @brief Turns a binary trait class template \c F into a meta-callable \c C such that
//! `C::__apply<T, U>` is equivalent to `F<T, U>::type`.
template <template <class, class> class _Fn>
struct __type_quote_trait2
{
template <class _Ty, class _Uy>
using __apply = __type<_Fn<_Ty, _Uy>>;
};

//! @brief A meta-callable that composes two meta-callables
template <class _Fn1, class _Fn2>
struct __type_compose
Expand Down Expand Up @@ -102,13 +154,17 @@ template <class... _Ts>
constexpr size_t const __type_list<_Ts...>::__size;
# endif

//! @brief Return the size of a type list.
template <class _List>
using __type_list_size = _CUDA_VSTD::integral_constant<size_t, _List::__size>;

//! @brief Given a type list and a list of types, append the types to the list.
template <class _List, class... _Ts>
using __type_push_back = __type_call<_List, __type_quote<__type_list>, _Ts...>;

//! @brief Given a type list and a list of types, prepend the types to the list.
template <class _List, class... _Ts>
using __type_push_front = __type_call<__type_list<__type_quote<__type_list>, _Ts...>, _List>;
using __type_push_front = __type_call<_List, __type_bind_front<__type_quote<__type_list>, _Ts...>>;

namespace detail
{
Expand Down Expand Up @@ -194,7 +250,7 @@ template <size_t>
using __void_ptr = void*;

template <class _Ty>
using __type_ptr = _CUDA_VSTD::type_identity<_Ty>*;
using __type_ptr = _CUDA_VSTD::__type_identity<_Ty>*;

template <size_t _Ip, class _Ty = _CUDA_VSTD::make_index_sequence<_Ip>>
struct __type_index_fn;
Expand Down Expand Up @@ -282,6 +338,12 @@ struct __type_concat_fn
template <class... _Lists>
using __type_concat = __type_call<detail::__type_concat_fn, _Lists...>;

//! @brief Given a list of type lists, concatenate all the lists into one.
//!
//! When passed an empty type list, \c __type_flatten returns an empty type list.
template <class _ListOfLists>
using __type_flatten = __type_call<_ListOfLists, __type_quote<__type_concat>>;

namespace detail
{
template <bool _IsEmpty>
Expand Down Expand Up @@ -324,7 +386,7 @@ template <class _Fn>
struct __type_transform_fn
{
template <class... _Ts>
using __apply = __type_list<__type_call<_Fn, _Ts>...>;
using __apply = __type_list<__type_call1<_Fn, _Ts>...>;
};
} // namespace detail

Expand All @@ -343,7 +405,7 @@ struct __type_maybe_fold_right_fn
{
template <class _Fn, class _State, class _Head, class... _Tail>
using __apply =
__type_call<__type_maybe_fold_right_fn<sizeof...(_Tail) == 0>, _Fn, __type_call<_Fn, _State, _Head>, _Tail...>;
__type_call<__type_maybe_fold_right_fn<sizeof...(_Tail) == 0>, _Fn, __type_call2<_Fn, _State, _Head>, _Tail...>;
};

template <>
Expand All @@ -365,7 +427,7 @@ struct __type_maybe_fold_left_fn
{
template <class _Fn, class _State, class _Head, class... _Tail>
using __apply =
__type_call<_Fn, __type_call<__type_maybe_fold_left_fn<sizeof...(_Tail) == 0>, _Fn, _State, _Tail...>, _Head>;
__type_call2<_Fn, __type_call<__type_maybe_fold_left_fn<sizeof...(_Tail) == 0>, _Fn, _State, _Tail...>, _Head>;
};

template <>
Expand Down Expand Up @@ -394,6 +456,52 @@ using __type_fold_right = __type_call<_List, detail::__type_fold_right_fn<_Init,
template <class _List, class _Init, class _Fn>
using __type_fold_left = __type_call<_List, detail::__type_fold_left_fn<_Init, _Fn>>;

namespace detail
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
{
template <class _Ty>
struct __type_remove_fn
{
template <class _Uy>
using __apply = _CUDA_VSTD::_If<_CCCL_TRAIT(_CUDA_VSTD::is_same, _Ty, _Uy), __type_list<>, __type_list<_Uy>>;
ericniebler marked this conversation as resolved.
Show resolved Hide resolved
};
} // namespace detail

//! @brief Remove all occurances of a type from a type list
template <class _List, class _Ty>
using __type_remove = __type_flatten<__type_transform<_List, detail::__type_remove_fn<_Ty>>>;

namespace detail
{
// _State is the list of type lists being built by the __type_fold_left
template <class _State, class _List>
struct __type_cartesian_product_fn
{
template <class _Ty>
struct __lambda0
{
template <class _List2>
using __lambda1 = __type_list<__type_push_front<_List2, _Ty>>;

using type = __type_flatten<__type_transform<_State, __type_quote1<__lambda1>>>;
};

using type = __type_flatten<__type_transform<_List, __type_quote_trait1<__lambda0>>>;
};
} // namespace detail
/// \endcond

//! @brief Given a list of lists \c _Lists, return a new list of lists that is
//! the cartesian product.
//!
//! \par Complexity
//! `O(N * M)`, where `N` is the size of the outer list, and
//! `M` is the size of the inner lists.
template <class... _Lists>
using __type_cartesian_product =
__type_fold_left<__type_list<_Lists...>,
__type_list<__type_list<>>,
__type_quote_trait2<detail::__type_cartesian_product_fn>>;

// A unary meta-callable for converting a type to its size in bytes
struct __type_sizeof
{
Expand Down Expand Up @@ -486,6 +594,36 @@ struct __type_greater_equal
using __apply = _CUDA_VSTD::bool_constant<(_Ty::value >= _Uy::value)>;
};

//! @brief A pair of types
template <class _First, class _Second>
struct __type_pair
{
using __first = _First;
using __second = _Second;
};

//! @brief Retreive the first of a pair of types
//! @pre \c _Pair is a specialization of \c __type_pair
template <class _Pair>
using __type_pair_first = typename _Pair::__first;

//! @brief Retreive the second of a pair of types
//! @pre \c _Pair is a specialization of \c __type_pair
template <class _Pair>
using __type_pair_second = typename _Pair::__second;

namespace detail
{
template <size_t _Start, size_t _Stride, size_t... _Is>
_CUDA_VSTD::index_sequence<(_Start + (_Is * _Stride))...> __type_iota_fn(_CUDA_VSTD::index_sequence<_Is...>*);
} // namespace detail

//! @brief Return an \c index_sequence of size \c _Size starting at \c _Start
//! and incrementing by \c _Stride.
template <size_t _Start, size_t _Size, size_t _Stride = 1>
using __type_iota =
decltype(detail::__type_iota_fn<_Start, _Stride>(static_cast<_CUDA_VSTD::make_index_sequence<_Size>*>(nullptr)));

#endif // DOXYGEN_SHOULD_SKIP_THIS

_LIBCUDACXX_END_NAMESPACE_STD
Expand Down
Loading