[CCCL] 瘦身 + 补全: 移除 cudax/python/libcudacxx-tests 冗余文件, 新增 c2h 测试助手 + cmake 构建系统 + 8 个 CUDA thrust examples

变更摘要:
- 删除: cudax/ (783 files, 7.2M) — 实验性组件,竞赛不需要
- 删除: python/ (226 files, 2.0M) — Python 绑定,竞赛不需要
- 删除: libcudacxx/{test,benchmarks,codegen,cmake,share} (4432 files, 31M)
  保留: libcudacxx/include/ (1463 headers, cuda::std 编译依赖)
- 新增: c2h/ (27 files) — CUB Catch2 测试辅助头文件,编译 243 个测试必需
- 新增: cmake/ (29 files) — CCCL 原生 CMake 构建系统
- 新增: thrust/examples/cuda/ (7 files) + cpp_integration/ (1 file)
  async_reduce, custom_temporary_allocation, explicit_cuda_stream,
  global_device_vector, range_view, unwrap_pointer, wrap_pointer, device

结果: cccl_upstream 从 74M→35M (瘦身 53%), 核心内容 100% 保留:
  27/27 tuning headers, 78 benchmarks, 243 tests,
  60 thrust examples, 18 CUB examples, 全部编译头文件
This commit is contained in:
muh-bot
2026-08-03 12:39:26 +00:00
parent a2a5dd8f00
commit 24ef6a91b5
5439 changed files with 0 additions and 719516 deletions

View File

@@ -1,318 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#ifndef _CUDAX__CONTAINER_GRAPH_BUFFER_CUH
#define _CUDAX__CONTAINER_GRAPH_BUFFER_CUH
#include <cuda/std/detail/__config>
#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
#if _CCCL_CTK_AT_LEAST(12, 2)
# include <cuda/__memory_resource/properties.h>
# include <cuda/__runtime/api_wrapper.h>
# include <cuda/__stream/invalid_stream.h>
# include <cuda/__stream/stream_ref.h>
# include <cuda/__type_traits/is_trivially_copyable.h>
# include <cuda/__utility/no_init.h>
# include <cuda/std/__utility/exchange.h>
# include <cuda/std/__utility/move.h>
# include <cuda/std/cstddef>
# include <cuda/std/initializer_list>
# include <cuda/std/span>
# include <cuda/experimental/__graph/copy_bytes.cuh>
# include <cuda/experimental/__graph/fill_bytes.cuh>
# include <cuda/experimental/__graph/graph_memory_resource.cuh>
# include <cuda/experimental/__graph/graph_node_ref.cuh>
# include <cuda/experimental/__graph/path_builder.cuh>
# include <cuda/std/__cccl/prologue.h>
namespace cuda::experimental
{
//! @rst
//! .. _cudax-container-graph-buffer:
//!
//! Graph buffer
//! ------------
//!
//! ``graph_buffer`` provides typed device memory allocated as a CUDA graph node.
//! It mirrors the API of ``cuda::buffer`` but takes a ``path_builder&`` instead of
//! a ``stream_ref``. Allocation inserts a ``cuGraphAddMemAllocNode`` into the graph.
//!
//! Memory can be freed in three ways:
//! - ``destroy(path_builder&)`` — inserts a free node into the graph
//! - ``destroy(stream_ref)`` — frees asynchronously on a stream (for memory that outlives the graph)
//! - Destructor — frees on the stored stream if one was set via ``set_stream()``
//!
//! If the destructor runs with no stream set and the buffer is non-empty, it asserts
//! in debug mode. In release mode the memory leaks.
//!
//! @endrst
//! @tparam _Tp The element type stored in the buffer. Must be trivially copyable.
template <class _Tp>
class graph_buffer
{
static_assert(::cuda::is_trivially_copyable_v<_Tp>, "graph_buffer requires T to be trivially copyable.");
public:
using value_type = _Tp;
using pointer = _Tp*;
using const_pointer = const _Tp*;
using size_type = ::cuda::std::size_t;
using properties_list = ::cuda::mr::properties_list<::cuda::mr::device_accessible>;
private:
graph_memory_resource __mr_;
size_type __count_ = 0;
_Tp* __buf_ = nullptr;
::cudaStream_t __stream_ = ::cuda::__invalid_stream();
[[nodiscard]] _CCCL_HOST_API pointer __get_data() const noexcept
{
return __buf_;
}
//! @brief Causes the buffer to be treated as a span when passed to cudax::launch.
[[nodiscard]] _CCCL_HOST_API friend auto transform_launch_argument(::cuda::stream_ref, graph_buffer& __self) noexcept
-> ::cuda::std::span<_Tp>
{
return {__self.__get_data(), __self.__count_};
}
//! @brief Causes the buffer to be treated as a const span when passed to cudax::launch.
[[nodiscard]] _CCCL_HOST_API friend auto
transform_launch_argument(::cuda::stream_ref, const graph_buffer& __self) noexcept -> ::cuda::std::span<const _Tp>
{
return {__self.__get_data(), __self.__count_};
}
public:
graph_buffer() = delete;
//! @brief Allocates uninitialized storage for \p __count elements.
_CCCL_HOST_API graph_buffer(path_builder& __pb, graph_memory_resource __mr, size_type __count, ::cuda::no_init_t)
: __mr_(::cuda::std::move(__mr))
, __count_(__count)
, __buf_(__count_ == 0 ? nullptr : static_cast<_Tp*>(__mr_.allocate(__pb, __count_ * sizeof(_Tp), alignof(_Tp))))
{}
//! @brief Allocates storage and fills with \p __value.
_CCCL_HOST_API graph_buffer(path_builder& __pb, graph_memory_resource __mr, size_type __count, const _Tp& __value)
: __mr_(::cuda::std::move(__mr))
, __count_(__count)
, __buf_(__count_ == 0 ? nullptr : static_cast<_Tp*>(__mr_.allocate(__pb, __count_ * sizeof(_Tp), alignof(_Tp))))
{
if (__count_ > 0)
{
if constexpr (sizeof(_Tp) == 1)
{
::cuda::std::uint8_t __byte_val =
static_cast<::cuda::std::uint8_t>(reinterpret_cast<const unsigned char&>(__value));
::cuda::experimental::fill_bytes(__pb, ::cuda::std::span<_Tp>(__get_data(), __count_), __byte_val);
}
else
{
// TODO: support non-zero multi-byte values via a kernel node
::cuda::experimental::fill_bytes(
__pb, ::cuda::std::span<_Tp>(__get_data(), __count_), static_cast<::cuda::std::uint8_t>(0));
}
}
}
//! @brief Allocates storage and copies from a contiguous span.
_CCCL_HOST_API graph_buffer(path_builder& __pb, graph_memory_resource __mr, ::cuda::std::span<const _Tp> __src)
: __mr_(::cuda::std::move(__mr))
, __count_(__src.size())
, __buf_(__count_ == 0 ? nullptr : static_cast<_Tp*>(__mr_.allocate(__pb, __count_ * sizeof(_Tp), alignof(_Tp))))
{
if (__count_ > 0)
{
::cuda::experimental::copy_bytes(__pb, __src, ::cuda::std::span<_Tp>{__get_data(), __count_});
}
}
//! @brief Allocates storage and copies from an initializer list.
_CCCL_HOST_API graph_buffer(path_builder& __pb, graph_memory_resource __mr, ::cuda::std::initializer_list<_Tp> __ilist)
: graph_buffer(__pb, ::cuda::std::move(__mr), ::cuda::std::span<const _Tp>{__ilist.begin(), __ilist.size()})
{}
graph_buffer(const graph_buffer&) = delete;
graph_buffer& operator=(const graph_buffer&) = delete;
//! @brief Move-constructs from another graph_buffer.
_CCCL_HOST_API graph_buffer(graph_buffer&& __other) noexcept
: __mr_(::cuda::std::move(__other.__mr_))
, __count_(::cuda::std::exchange(__other.__count_, 0))
, __buf_(::cuda::std::exchange(__other.__buf_, nullptr))
, __stream_(::cuda::std::exchange(__other.__stream_, ::cuda::__invalid_stream()))
{}
//! @brief Move-assigns from another graph_buffer.
_CCCL_HOST_API graph_buffer& operator=(graph_buffer&& __other) noexcept
{
if (this != &__other)
{
_CCCL_ASSERT(__buf_ == nullptr || __stream_ != ::cuda::__invalid_stream(),
"graph_buffer move-assigned over non-empty buffer with no stream set");
if (__buf_ != nullptr && __stream_ != ::cuda::__invalid_stream())
{
destroy(::cuda::stream_ref{__stream_});
}
__mr_ = ::cuda::std::move(__other.__mr_);
__count_ = ::cuda::std::exchange(__other.__count_, 0);
__buf_ = ::cuda::std::exchange(__other.__buf_, nullptr);
__stream_ = ::cuda::std::exchange(__other.__stream_, ::cuda::__invalid_stream());
}
return *this;
}
//! @brief Destructor. Frees device memory on the stored stream if one was set.
_CCCL_HOST_API ~graph_buffer()
{
if (__buf_ != nullptr)
{
_CCCL_ASSERT(__stream_ != ::cuda::__invalid_stream(),
"graph_buffer destroyed with live memory but no stream set. "
"Call set_stream(), destroy(stream_ref), or destroy(path_builder&) before destruction.");
if (__stream_ != ::cuda::__invalid_stream())
{
destroy(::cuda::stream_ref{__stream_});
}
}
}
//! @brief Set the stream to use for automatic cleanup in the destructor.
_CCCL_HOST_API void set_stream(::cuda::stream_ref __stream) noexcept
{
__stream_ = __stream.get();
}
//! @brief Returns the stream set for automatic cleanup.
[[nodiscard]] _CCCL_HOST_API ::cuda::stream_ref stream() const noexcept
{
return ::cuda::stream_ref{__stream_};
}
//! @brief Insert a free node into the graph to deallocate the buffer.
_CCCL_HOST_API graph_node_ref destroy(path_builder& __pb)
{
if (__buf_ == nullptr)
{
return graph_node_ref{};
}
__mr_.deallocate(__pb, __buf_, __count_ * sizeof(_Tp), alignof(_Tp));
auto __free_node = __pb.get_dependencies()[0];
__buf_ = nullptr;
__count_ = 0;
return graph_node_ref{__free_node, __pb.get_native_graph_handle()};
}
//! @brief Free the buffer's device memory asynchronously on a stream.
_CCCL_HOST_API void destroy(::cuda::stream_ref __stream)
{
if (__buf_ != nullptr)
{
__mr_.deallocate(__stream, __buf_, __count_ * sizeof(_Tp), alignof(_Tp));
__buf_ = nullptr;
__count_ = 0;
}
}
[[nodiscard]] _CCCL_HOST_API pointer data() noexcept
{
return __get_data();
}
[[nodiscard]] _CCCL_HOST_API const_pointer data() const noexcept
{
return __get_data();
}
[[nodiscard]] _CCCL_HOST_API pointer begin() noexcept
{
return __get_data();
}
[[nodiscard]] _CCCL_HOST_API const_pointer begin() const noexcept
{
return __get_data();
}
[[nodiscard]] _CCCL_HOST_API pointer end() noexcept
{
return __get_data() + __count_;
}
[[nodiscard]] _CCCL_HOST_API const_pointer end() const noexcept
{
return __get_data() + __count_;
}
[[nodiscard]] _CCCL_HOST_API constexpr size_type size() const noexcept
{
return __count_;
}
[[nodiscard]] _CCCL_HOST_API constexpr size_type size_bytes() const noexcept
{
return __count_ * sizeof(_Tp);
}
[[nodiscard]] _CCCL_HOST_API constexpr bool empty() const noexcept
{
return __count_ == 0;
}
[[nodiscard]] _CCCL_HOST_API const graph_memory_resource& memory_resource() const noexcept
{
return __mr_;
}
};
//! @brief Create a graph_buffer with uninitialized storage.
template <class _Tp>
[[nodiscard]] _CCCL_HOST_API graph_buffer<_Tp>
make_buffer(path_builder& __pb, graph_memory_resource __mr, ::cuda::std::size_t __count, ::cuda::no_init_t)
{
return graph_buffer<_Tp>{__pb, ::cuda::std::move(__mr), __count, ::cuda::no_init};
}
//! @brief Create a graph_buffer filled with a value.
template <class _Tp>
[[nodiscard]] _CCCL_HOST_API graph_buffer<_Tp>
make_buffer(path_builder& __pb, graph_memory_resource __mr, ::cuda::std::size_t __count, const _Tp& __value)
{
return graph_buffer<_Tp>{__pb, ::cuda::std::move(__mr), __count, __value};
}
//! @brief Create a graph_buffer from a span of data.
template <class _Tp>
[[nodiscard]] _CCCL_HOST_API graph_buffer<_Tp>
make_buffer(path_builder& __pb, graph_memory_resource __mr, ::cuda::std::span<const _Tp> __src)
{
return graph_buffer<_Tp>{__pb, ::cuda::std::move(__mr), __src};
}
} // namespace cuda::experimental
# include <cuda/std/__cccl/epilogue.h>
#endif // _CCCL_CTK_AT_LEAST(12, 2)
#endif // _CUDAX__CONTAINER_GRAPH_BUFFER_CUH

View File

@@ -1,292 +0,0 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//
#ifndef __CUDAX__CONTAINERS_UNINITIALIZED_BUFFER_H
#define __CUDAX__CONTAINERS_UNINITIALIZED_BUFFER_H
#include <cuda/std/detail/__config>
#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 <cuda/__memory_resource/any_resource.h>
#include <cuda/__memory_resource/properties.h>
#include <cuda/std/__memory/align.h>
#include <cuda/std/__new/launder.h>
#include <cuda/std/__type_traits/type_set.h>
#include <cuda/std/__utility/exchange.h>
#include <cuda/std/__utility/move.h>
#include <cuda/std/__utility/swap.h>
#include <cuda/std/span>
#include <cuda/std/__cccl/prologue.h>
//! @file
//! The \c uninitialized_buffer class provides a typed buffer allocated from a given memory resource.
namespace cuda::experimental
{
//! @rst
//! .. _cudax-containers-uninitialized-buffer:
//!
//! Uninitialized type-safe memory storage
//! ---------------------------------------
//!
//! ``uninitialized_buffer`` provides a typed buffer allocated from a given :ref:`memory resource
//! <libcudacxx-extended-api-memory-resources-resource>`. It handles alignment and release of the allocation.
//! The memory is uninitialized, so that a user needs to ensure elements are properly constructed.
//!
//! In addition to being type-safe, ``uninitialized_buffer`` also takes a set of :ref:`properties
//! <libcudacxx-extended-api-memory-resources-properties>` to ensure that e.g. execution space constraints are checked
//! at compile time. However, we can only forward stateless properties. If a user wants to use a stateful one, then they
//! need to implement :ref:`get_property(const device_buffer&, Property)
//! <libcudacxx-extended-api-memory-resources-properties>`.
//!
//! @endrst
//! @tparam _Tp the type to be stored in the buffer
//! @tparam _Properties... The properties the allocated memory satisfies
template <class _Tp, class... _Properties>
class uninitialized_buffer
{
private:
static_assert(::cuda::mr::__contains_execution_space_property<_Properties...>,
"The properties of cuda::experimental::uninitialized_buffer must contain at least one execution space "
"property!");
using __resource = ::cuda::mr::any_synchronous_resource<_Properties...>;
__resource __mr_;
size_t __count_ = 0;
void* __buf_ = nullptr;
template <class, class...>
friend class uninitialized_buffer;
//! @brief Helper to check whether a different buffer still satisfies all properties of this one
template <class... _OtherProperties>
static constexpr bool __properties_match =
!::cuda::std::is_same_v<::cuda::std::__make_type_set<_Properties...>,
::cuda::std::__make_type_set<_OtherProperties...>>
&& ::cuda::std::__type_set_contains_v<::cuda::std::__make_type_set<_OtherProperties...>, _Properties...>;
//! @brief Determines the allocation size given the alignment and size of `T`
[[nodiscard]] _CCCL_HIDE_FROM_ABI static constexpr size_t __get_allocation_size(const size_t __count) noexcept
{
constexpr size_t __alignment = alignof(_Tp);
return (__count * sizeof(_Tp) + (__alignment - 1)) & ~(__alignment - 1);
}
//! @brief Determines the properly aligned start of the buffer given the alignment and size of `T`
[[nodiscard]] _CCCL_HIDE_FROM_ABI _Tp* __get_data() const noexcept
{
constexpr size_t __alignment = alignof(_Tp);
size_t __space = __get_allocation_size(__count_);
void* __ptr = __buf_;
return ::cuda::std::launder(
static_cast<_Tp*>(::cuda::std::align(__alignment, __count_ * sizeof(_Tp), __ptr, __space)));
}
//! @brief Causes the buffer to be treated as a span when passed to cudax::launch.
//! @pre The buffer must have the cuda::mr::device_accessible property.
template <class _Tp2 = _Tp>
[[nodiscard]] _CCCL_HIDE_FROM_ABI friend auto
transform_launch_argument(::cuda::stream_ref, uninitialized_buffer& __self) noexcept
_CCCL_TRAILING_REQUIRES(::cuda::std::span<_Tp>)(
::cuda::std::same_as<_Tp, _Tp2>&& ::cuda::std::__is_included_in_v<::cuda::mr::device_accessible, _Properties...>)
{
return {__self.__get_data(), __self.size()};
}
//! @brief Causes the buffer to be treated as a span when passed to cudax::launch
//! @pre The buffer must have the cuda::mr::device_accessible property.
template <class _Tp2 = _Tp>
[[nodiscard]] _CCCL_HIDE_FROM_ABI friend auto
transform_launch_argument(::cuda::stream_ref, const uninitialized_buffer& __self) noexcept
_CCCL_TRAILING_REQUIRES(::cuda::std::span<const _Tp>)(
::cuda::std::same_as<_Tp, _Tp2>&& ::cuda::std::__is_included_in_v<::cuda::mr::device_accessible, _Properties...>)
{
return {__self.__get_data(), __self.size()};
}
public:
using value_type = _Tp;
using reference = _Tp&;
using const_reference = const _Tp&;
using pointer = _Tp*;
using const_pointer = const _Tp*;
using size_type = size_t;
//! @brief Constructs an \c uninitialized_buffer and allocates sufficient storage for \p __count elements through
//! \p __mr
//! @param __mr The memory resource to allocate the buffer with.
//! @param __count The desired size of the buffer.
//! @note Depending on the alignment requirements of `T` the size of the underlying allocation might be larger
//! than `count * sizeof(T)`.
//! @note Only allocates memory when \p __count > 0
_CCCL_HIDE_FROM_ABI uninitialized_buffer(__resource __mr, const size_t __count)
: __mr_(::cuda::std::move(__mr))
, __count_(__count)
, __buf_(__count_ == 0 ? nullptr : __mr_.allocate_sync(__get_allocation_size(__count_), alignof(_Tp)))
{}
_CCCL_HIDE_FROM_ABI uninitialized_buffer(const uninitialized_buffer&) = delete;
_CCCL_HIDE_FROM_ABI uninitialized_buffer& operator=(const uninitialized_buffer&) = delete;
//! @brief Move-constructs a \c uninitialized_buffer from \p __other
//! @param __other Another \c uninitialized_buffer
//! Takes ownership of the allocation in \p __other and resets it
_CCCL_HIDE_FROM_ABI uninitialized_buffer(uninitialized_buffer&& __other) noexcept
: __mr_(::cuda::std::move(__other.__mr_))
, __count_(::cuda::std::exchange(__other.__count_, 0))
, __buf_(::cuda::std::exchange(__other.__buf_, nullptr))
{}
//! @brief Move-constructs a \c uninitialized_buffer from another \c uninitialized_buffer with matching properties
//! @param __other Another \c uninitialized_buffer
//! Takes ownership of the allocation in \p __other and resets it
_CCCL_TEMPLATE(class... _OtherProperties)
_CCCL_REQUIRES(__properties_match<_OtherProperties...>)
_CCCL_HIDE_FROM_ABI uninitialized_buffer(uninitialized_buffer<_Tp, _OtherProperties...>&& __other) noexcept
: __mr_(::cuda::std::move(__other.__mr_))
, __count_(::cuda::std::exchange(__other.__count_, 0))
, __buf_(::cuda::std::exchange(__other.__buf_, nullptr))
{}
//! @brief Move-assigns a \c uninitialized_buffer from \p __other
//! @param __other Another \c uninitialized_buffer
//! Deallocates the current allocation and then takes ownership of the allocation in \p __other and resets it
_CCCL_HIDE_FROM_ABI uninitialized_buffer& operator=(uninitialized_buffer&& __other) noexcept
{
if (this == ::cuda::std::addressof(__other))
{
return *this;
}
if (__buf_)
{
__mr_.deallocate_sync(__buf_, __get_allocation_size(__count_), alignof(_Tp));
}
__mr_ = ::cuda::std::move(__other.__mr_);
__count_ = ::cuda::std::exchange(__other.__count_, 0);
__buf_ = ::cuda::std::exchange(__other.__buf_, nullptr);
return *this;
}
//! @brief Destroys an \c uninitialized_buffer, deallocates the buffer and destroys the memory resource
//! @warning destroy does not destroy any objects that may or may not reside within the buffer. It is the
//! user's responsibility to ensure that all objects within the buffer have been properly destroyed.
_CCCL_HIDE_FROM_ABI void destroy()
{
if (__buf_)
{
__mr_.deallocate_sync(__buf_, __get_allocation_size(__count_), alignof(_Tp));
__buf_ = nullptr;
__count_ = 0;
}
auto __tmp_mr = ::cuda::std::move(__mr_);
}
//! @brief Destroys an \c uninitialized_buffer, deallocates the buffer and destroys the memory resource
//! @warning The destructor does not destroy any objects that may or may not reside within the buffer. It is the
//! user's responsibility to ensure that all objects within the buffer have been properly destroyed.
_CCCL_HIDE_FROM_ABI ~uninitialized_buffer()
{
destroy();
}
//! @brief Returns an aligned pointer to the first element in the buffer
[[nodiscard]] _CCCL_HIDE_FROM_ABI pointer begin() noexcept
{
return __get_data();
}
//! @overload
[[nodiscard]] _CCCL_HIDE_FROM_ABI const_pointer begin() const noexcept
{
return __get_data();
}
//! @brief Returns an aligned pointer to the element following the last element of the buffer.
//! This element acts as a placeholder; attempting to access it results in undefined behavior.
[[nodiscard]] _CCCL_HIDE_FROM_ABI pointer end() noexcept
{
return __get_data() + __count_;
}
//! @overload
[[nodiscard]] _CCCL_HIDE_FROM_ABI const_pointer end() const noexcept
{
return __get_data() + __count_;
}
//! @brief Returns an aligned pointer to the first element in the buffer
[[nodiscard]] _CCCL_HIDE_FROM_ABI pointer data() noexcept
{
return __get_data();
}
//! @overload
[[nodiscard]] _CCCL_HIDE_FROM_ABI const_pointer data() const noexcept
{
return __get_data();
}
//! @brief Returns the size of the allocation
[[nodiscard]] _CCCL_HIDE_FROM_ABI constexpr size_type size() const noexcept
{
return __count_;
}
//! @brief Returns the size of the buffer in bytes
[[nodiscard]] _CCCL_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept
{
return __count_ * sizeof(_Tp);
}
//! @rst
//! Returns a \c const reference to the :ref:`any_resource <libcudacxx-memory-resource-any-resource>`
//! that holds the memory resource used to allocate the buffer
//! @endrst
[[nodiscard]] _CCCL_HIDE_FROM_ABI const __resource& memory_resource() const noexcept
{
return __mr_;
}
//! @brief Forwards the passed Properties
_CCCL_TEMPLATE(class _Property)
_CCCL_REQUIRES((!property_with_value<_Property>) _CCCL_AND ::cuda::std::__is_included_in_v<_Property, _Properties...>)
_CCCL_HIDE_FROM_ABI friend constexpr void get_property(const uninitialized_buffer&, _Property) noexcept {}
//! @brief Internal method to grow the allocation to a new size \p __count.
//! @param __count The new size of the allocation.
//! @return An \c uninitialized_buffer that holds the previous allocation
//! @warning This buffer must outlive the returned buffer
_CCCL_HIDE_FROM_ABI uninitialized_buffer __replace_allocation(const size_t __count)
{
// Create a new buffer with a reference to the stored memory resource and swap allocation information
uninitialized_buffer __ret{::cuda::mr::synchronous_resource_ref<_Properties...>{__mr_}, __count};
::cuda::std::swap(__count_, __ret.__count_);
::cuda::std::swap(__buf_, __ret.__buf_);
return __ret;
}
};
template <class _Tp>
using uninitialized_device_buffer = uninitialized_buffer<_Tp, ::cuda::mr::device_accessible>;
} // namespace cuda::experimental
#include <cuda/std/__cccl/epilogue.h>
#endif //__CUDAX__CONTAINERS_UNINITIALIZED_BUFFER_H