WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
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
231 changes: 223 additions & 8 deletions cpp/include/rmm/detail/cccl_adaptors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,133 @@
#include <rmm/cuda_stream_view.hpp>
#include <rmm/detail/cuda_memory_resource.hpp>
#include <rmm/detail/export.hpp>
#include <rmm/mr/detail/device_memory_resource_view.hpp>
#include <rmm/mr/device_memory_resource.hpp>

#include <cstddef>
#include <type_traits>
#include <utility>

namespace RMM_NAMESPACE {

namespace detail {

// Helper base class to hold the view (Base from Member idiom)
// This is initialized before the main base class, allowing us to pass it to the base constructor
struct view_holder {
view_holder() = default;
view_holder(rmm::mr::device_memory_resource* ptr) : view_{ptr} {}
rmm::mr::detail::device_memory_resource_view view_;
};

template <typename ResourceType>
class cccl_resource_ref : public ResourceType {
class cccl_resource_ref : private view_holder, public ResourceType {
public:
using base = ResourceType;

using base::base;
/**
* @brief Constructs a resource reference from a raw `device_memory_resource` pointer.
*
* This constructor enables compatibility with CCCL 3.2 by wrapping the pointer in a
* `device_memory_resource_view`, which is copyable unlike the virtual base class.
*
* @param ptr Non-null pointer to a `device_memory_resource`
*/
cccl_resource_ref(rmm::mr::device_memory_resource* ptr)
: view_holder{ptr}, base{view_holder::view_}
{
}

/**
* @brief Constructs a resource reference from a `device_memory_resource` reference.
*
* This constructor enables compatibility with CCCL 3.2 by wrapping the address in a
* `device_memory_resource_view`, which is copyable unlike the virtual base class.
*
* @param res Reference to a `device_memory_resource`
*/
cccl_resource_ref(rmm::mr::device_memory_resource& res)
: view_holder{&res}, base{view_holder::view_}
{
}

/**
* @brief Constructs a resource reference from a CCCL resource_ref directly.
*
* This constructor enables interoperability with CCCL 3.2 resource_ref types,
* allowing RMM resource_ref types to be constructed from CCCL resource_ref types.
*
* @param ref A CCCL resource_ref of the appropriate type
*/
cccl_resource_ref(ResourceType const& ref) : view_holder{}, base{ref} {}

/**
* @brief Constructs a resource reference from a CCCL resource_ref directly (move).
*
* This constructor enables interoperability with CCCL 3.2 resource_ref types,
* allowing RMM resource_ref types to be constructed from CCCL resource_ref types
* using move semantics.
*
* @param ref A CCCL resource_ref of the appropriate type
*/
cccl_resource_ref(ResourceType&& ref) : view_holder{}, base{std::move(ref)} {}

/**
* @brief Copy constructor that properly reconstructs the base to point to the new view.
*/
cccl_resource_ref(cccl_resource_ref const& other)
: view_holder{static_cast<view_holder const&>(other)}, base{view_holder::view_}
{
}

cccl_resource_ref(base const& other) : base(other) {}
/**
* @brief Move constructor that properly reconstructs the base to point to the new view.
*/
cccl_resource_ref(cccl_resource_ref&& other) noexcept
: view_holder{static_cast<view_holder&&>(other)}, base{view_holder::view_}
{
}

cccl_resource_ref(base&& other) : base(std::move(other)) {}
/**
* @brief Conversion constructor from a cccl_resource_ref with a convertible ResourceType.
*
* This enables conversions like host_device_resource_ref -> device_resource_ref,
* where the source type has a superset of properties compared to the target type.
* The underlying CCCL resource_ref types handle the actual property compatibility check.
*
* @tparam OtherResourceType A CCCL resource_ref type that is convertible to ResourceType
* @param other The source resource_ref to convert from
*/
template <typename OtherResourceType,
typename = std::enable_if_t<std::is_constructible_v<ResourceType, OtherResourceType>>>
cccl_resource_ref(cccl_resource_ref<OtherResourceType> const& other)
: view_holder{}, base{static_cast<OtherResourceType const&>(other)}
{
}

/**
* @brief Copy assignment operator.
*/
cccl_resource_ref& operator=(cccl_resource_ref const& other)
{
if (this != &other) {
view_holder::view_ = other.view_;
base::operator=(base(view_holder::view_));
}
return *this;
}

/**
* @brief Move assignment operator.
*/
cccl_resource_ref& operator=(cccl_resource_ref&& other) noexcept
{
if (this != &other) {
view_holder::view_ = std::move(other.view_);
base::operator=(base(view_holder::view_));
}
return *this;
}

void* allocate_sync(std::size_t bytes) { return base::allocate_sync(bytes); }

Expand All @@ -42,14 +154,117 @@ class cccl_resource_ref : public ResourceType {
};

template <typename ResourceType>
class cccl_async_resource_ref : public ResourceType {
class cccl_async_resource_ref : private view_holder, public ResourceType {
public:
using base = ResourceType;

using base::base;
/**
* @brief Constructs an async resource reference from a raw `device_memory_resource` pointer.
*
* This constructor enables compatibility with CCCL 3.2 by wrapping the pointer in a
* `device_memory_resource_view`, which is copyable unlike the virtual base class.
*
* @param ptr Non-null pointer to a `device_memory_resource`
*/
cccl_async_resource_ref(rmm::mr::device_memory_resource* ptr)
: view_holder{ptr}, base{view_holder::view_}
{
}

/**
* @brief Constructs an async resource reference from a `device_memory_resource` reference.
*
* This constructor enables compatibility with CCCL 3.2 by wrapping the address in a
* `device_memory_resource_view`, which is copyable unlike the virtual base class.
*
* @param res Reference to a `device_memory_resource`
*/
cccl_async_resource_ref(rmm::mr::device_memory_resource& res)
: view_holder{&res}, base{view_holder::view_}
{
}

/**
* @brief Constructs an async resource reference from a CCCL resource_ref directly.
*
* This constructor enables interoperability with CCCL 3.2 resource_ref types,
* allowing RMM async resource_ref types to be constructed from CCCL resource_ref types.
*
* @param ref A CCCL async resource_ref of the appropriate type
*/
cccl_async_resource_ref(ResourceType const& ref) : view_holder{}, base{ref} {}

/**
* @brief Constructs an async resource reference from a CCCL resource_ref directly (move).
*
* This constructor enables interoperability with CCCL 3.2 resource_ref types,
* allowing RMM async resource_ref types to be constructed from CCCL resource_ref types
* using move semantics.
*
* @param ref A CCCL async resource_ref of the appropriate type
*/
cccl_async_resource_ref(ResourceType&& ref) : view_holder{}, base{std::move(ref)} {}

/**
* @brief Copy constructor that properly reconstructs the base to point to the new view.
*
* The implicit copy constructor would copy the view_holder correctly, but the base
* would still point to the original object's view. We need to reconstruct the base
* to point to our own view.
*/
cccl_async_resource_ref(cccl_async_resource_ref const& other)
: view_holder{static_cast<view_holder const&>(other)}, base{view_holder::view_}
{
}

/**
* @brief Move constructor that properly reconstructs the base to point to the new view.
*/
cccl_async_resource_ref(cccl_async_resource_ref&& other) noexcept
: view_holder{static_cast<view_holder&&>(other)}, base{view_holder::view_}
{
}

/**
* @brief Conversion constructor from a cccl_async_resource_ref with a convertible ResourceType.
*
* This enables conversions like host_device_async_resource_ref -> device_async_resource_ref,
* where the source type has a superset of properties compared to the target type.
* The underlying CCCL resource_ref types handle the actual property compatibility check.
*
* @tparam OtherResourceType A CCCL async resource_ref type that is convertible to ResourceType
* @param other The source async resource_ref to convert from
*/
template <typename OtherResourceType,
typename = std::enable_if_t<std::is_constructible_v<ResourceType, OtherResourceType>>>
cccl_async_resource_ref(cccl_async_resource_ref<OtherResourceType> const& other)
: view_holder{}, base{static_cast<OtherResourceType const&>(other)}
{
}

cccl_async_resource_ref(base const& other) : base(other) {}
cccl_async_resource_ref(base&& other) : base(std::move(other)) {}
/**
* @brief Copy assignment operator.
*/
cccl_async_resource_ref& operator=(cccl_async_resource_ref const& other)
{
if (this != &other) {
view_holder::view_ = other.view_;
base::operator=(base(view_holder::view_));
}
return *this;
}

/**
* @brief Move assignment operator.
*/
cccl_async_resource_ref& operator=(cccl_async_resource_ref&& other) noexcept
{
if (this != &other) {
view_holder::view_ = std::move(other.view_);
base::operator=(base(view_holder::view_));
}
return *this;
}

void* allocate_sync(std::size_t bytes) { return base::allocate_sync(bytes); }

Expand Down
2 changes: 1 addition & 1 deletion cpp/include/rmm/mr/binning_memory_resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class binning_memory_resource final : public device_memory_resource {
} else if (resource_bins_.count(allocation_size) == 0) { // do nothing if bin already exists
owned_bin_resources_.push_back(
std::make_unique<fixed_size_memory_resource<Upstream>>(upstream_mr_, allocation_size));
resource_bins_.insert({allocation_size, owned_bin_resources_.back().get()});
resource_bins_.insert({allocation_size, *owned_bin_resources_.back()});
}
}

Expand Down
Loading