Files
project_6/cccl_upstream/thrust/thrust/detail/raw_reference_cast.h
EngineX CI 56fd68e7dd [INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides:
- CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk)
- Thrust: high-level parallel algorithms (transform_reduce, sort, scan)
- libcudacxx: CUDA C++ standard library (atomics, barriers, memory)
- cudax: experimental features (memory resources, allocators)
- Tuning policies: per-SM hardware-specific algorithm parameters

Competition optimization vectors mapped to CCCL:
- Output TPS (83% weight): warp_reduce, block_reduce, device_topk
- Input TPS (14% weight): device_scan, block_load, prefetch
- Cache TPS (3% weight): prefix caching strategy patterns
- Memory (0.9 util): pooled/cached/buddy allocators

Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only)
License: Apache-2.0
2026-07-30 09:35:51 +00:00

181 lines
6.2 KiB
C++

// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <thrust/detail/config.h>
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
# pragma GCC system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
# pragma clang system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
# pragma system_header
#endif // no system header
#include <thrust/detail/raw_pointer_cast.h>
#include <thrust/detail/type_traits.h>
#include <thrust/detail/type_traits/has_nested_type.h>
#include <cuda/std/__memory/pointer_traits.h>
#include <cuda/std/__tuple_dir/apply.h>
#include <cuda/std/__type_traits/add_lvalue_reference.h>
#include <cuda/std/__type_traits/enable_if.h>
#include <cuda/std/__type_traits/remove_cv.h>
#include <cuda/std/__type_traits/type_identity.h>
#include <cuda/std/__utility/forward.h>
#include <cuda/std/tuple>
// the order of declarations and definitions in this file is totally goofy
// this header defines raw_reference_cast, which has a few overloads towards the bottom of the file
// raw_reference_cast depends on metafunctions such as is_unwrappable and raw_reference
// we need to be sure that these metafunctions are completely defined (including specializations) before they are
// instantiated by raw_reference_cast
THRUST_NAMESPACE_BEGIN
namespace detail
{
template <typename... Ts>
class tuple_of_iterator_references;
__THRUST_DEFINE_HAS_NESTED_TYPE(is_wrapped_reference, wrapped_reference_hint)
// wrapped reference-like things which aren't strictly wrapped references
// (e.g. tuples of wrapped references) are considered unwrappable
template <typename T>
inline constexpr bool can_unwrap = is_wrapped_reference<T>::value;
// specialize is_unwrappable
// a tuple is_unwrappable if any of its elements is_unwrappable
template <typename... Ts>
inline constexpr bool can_unwrap<::cuda::std::tuple<Ts...>> = (can_unwrap<Ts> || ...);
// specialize is_unwrappable
// a tuple_of_iterator_references is_unwrappable if any of its elements is_unwrappable
template <typename... Ts>
inline constexpr bool can_unwrap<tuple_of_iterator_references<Ts...>> = (can_unwrap<Ts> || ...);
namespace raw_reference_detail
{
template <typename T, typename SFINAE = void>
struct raw_reference_impl : ::cuda::std::add_lvalue_reference<T>
{};
template <typename T>
struct raw_reference_impl<T, ::cuda::std::enable_if_t<is_wrapped_reference<::cuda::std::remove_cv_t<T>>::value>>
: ::cuda::std::add_lvalue_reference<typename ::cuda::std::pointer_traits<typename T::pointer>::element_type>
{};
template <typename T>
struct raw_reference_impl<T, ::cuda::std::enable_if_t<is_proxy_reference_v<::cuda::std::remove_cv_t<T>>>>
{
using type = T;
};
} // namespace raw_reference_detail
template <typename T>
struct raw_reference : raw_reference_detail::raw_reference_impl<T>
{};
template <typename T>
using raw_reference_t = typename raw_reference<T>::type;
namespace raw_reference_detail
{
// unlike raw_reference,
// raw_reference_tuple_helper needs to return a value
// when it encounters one, rather than a reference
// upon encountering tuple, recurse
//
// we want the following behavior:
// 1. T -> T
// 2. T& -> T&
// 3. null_type -> null_type
// 4. reference<T> -> T&
// 5. tuple_of_iterator_references<T> -> tuple_of_iterator_references<raw_reference_tuple_helper<T>::type>
// wrapped references are unwrapped using raw_reference, otherwise, return T
template <typename T>
struct raw_reference_tuple_helper
: eval_if<can_unwrap<::cuda::std::remove_cv_t<T>>, raw_reference<T>, ::cuda::std::type_identity<T>>
{};
// recurse on tuples
template <typename... Ts>
struct raw_reference_tuple_helper<::cuda::std::tuple<Ts...>>
{
using type = ::cuda::std::tuple<typename raw_reference_tuple_helper<Ts>::type...>;
};
template <typename... Ts>
struct raw_reference_tuple_helper<tuple_of_iterator_references<Ts...>>
{
using type = tuple_of_iterator_references<typename raw_reference_tuple_helper<Ts>::type...>;
};
} // namespace raw_reference_detail
// a couple of specializations of raw_reference for tuples follow
// if a tuple "tuple_type" is_unwrappable,
// then the raw_reference of tuple_type is a tuple of its members' raw_references
// else the raw_reference of tuple_type is tuple_type &
template <typename... Ts>
struct raw_reference<::cuda::std::tuple<Ts...>>
{
private:
using tuple_type = ::cuda::std::tuple<Ts...>;
public:
using type = typename eval_if<can_unwrap<tuple_type>,
raw_reference_detail::raw_reference_tuple_helper<tuple_type>,
::cuda::std::add_lvalue_reference<tuple_type>>::type;
};
template <typename... Ts>
struct raw_reference<tuple_of_iterator_references<Ts...>>
{
using type = typename raw_reference_detail::raw_reference_tuple_helper<tuple_of_iterator_references<Ts...>>::type;
};
} // namespace detail
// provide declarations of raw_reference_cast's overloads for raw_reference_caster below
template <typename T>
_CCCL_HOST_DEVICE typename detail::raw_reference<T>::type raw_reference_cast(T& ref)
{
return *thrust::raw_pointer_cast(&ref);
}
template <typename T>
_CCCL_HOST_DEVICE typename detail::raw_reference<const T>::type raw_reference_cast(const T& ref)
{
return *thrust::raw_pointer_cast(&ref);
}
template <typename T, ::cuda::std::enable_if_t<detail::is_proxy_reference_v<::cuda::std::remove_cv_t<T>>, int> = 0>
_CCCL_HOST_DEVICE typename detail::raw_reference<T>::type raw_reference_cast(T&& t)
{
return t;
}
template <typename... Ts>
_CCCL_HOST_DEVICE auto raw_reference_cast(detail::tuple_of_iterator_references<Ts...> t) ->
typename detail::raw_reference<detail::tuple_of_iterator_references<Ts...>>::type
{
if constexpr (detail::can_unwrap<detail::tuple_of_iterator_references<Ts...>>)
{
using ResultTuple =
::cuda::std::tuple<typename detail::raw_reference_detail::raw_reference_tuple_helper<Ts>::type...>;
return ::cuda::std::apply(
[](auto&&... refs) {
return ResultTuple{raw_reference_cast(::cuda::std::forward<decltype(refs)>(refs))...};
},
static_cast<::cuda::std::tuple<Ts...>&>(t));
}
else
{
return t;
}
}
THRUST_NAMESPACE_END