19 #include <rmm/detail/aligned.hpp>
20 #include <rmm/detail/error.hpp>
26 #include <unordered_map>
53 template <
typename Upstream>
68 std::size_t alignment = rmm::detail::CUDA_ALLOCATION_ALIGNMENT,
70 : upstream_{upstream}, alignment_{alignment}, alignment_threshold_{alignment_threshold}
72 RMM_EXPECTS(
nullptr != upstream,
"Unexpected null upstream resource pointer.");
73 RMM_EXPECTS(rmm::detail::is_supported_alignment(alignment),
74 "Allocation alignment is not a power of 2.");
96 return upstream_->supports_streams();
106 return upstream_->supports_get_mem_info();
115 using lock_guard = std::lock_guard<std::mutex>;
130 if (alignment_ == rmm::detail::CUDA_ALLOCATION_ALIGNMENT || bytes < alignment_threshold_) {
131 return upstream_->allocate(bytes, stream);
133 auto const size = upstream_allocation_size(bytes);
134 void* pointer = upstream_->allocate(size, stream);
136 auto const address =
reinterpret_cast<std::size_t
>(pointer);
137 auto const aligned_address = rmm::detail::align_up(address, alignment_);
139 void* aligned_pointer =
reinterpret_cast<void*
>(aligned_address);
140 if (pointer != aligned_pointer) {
141 lock_guard lock(mtx_);
142 pointers_.emplace(aligned_pointer, pointer);
144 return aligned_pointer;
154 void do_deallocate(
void* ptr, std::size_t bytes,
cuda_stream_view stream)
override
156 if (alignment_ == rmm::detail::CUDA_ALLOCATION_ALIGNMENT || bytes < alignment_threshold_) {
157 upstream_->deallocate(ptr, bytes, stream);
160 lock_guard lock(mtx_);
161 auto const iter = pointers_.find(ptr);
162 if (iter != pointers_.end()) {
164 pointers_.erase(iter);
167 upstream_->deallocate(ptr, upstream_allocation_size(bytes), stream);
178 [[nodiscard]]
bool do_is_equal(device_memory_resource
const& other)
const noexcept
override
180 if (
this == &other) {
return true; }
181 auto cast =
dynamic_cast<aligned_resource_adaptor<Upstream> const*
>(&other);
182 return cast !=
nullptr && upstream_->is_equal(*cast->get_upstream()) &&
183 alignment_ == cast->alignment_ && alignment_threshold_ == cast->alignment_threshold_;
196 [[nodiscard]] std::pair<std::size_t, std::size_t> do_get_mem_info(
197 cuda_stream_view stream)
const override
199 return upstream_->get_mem_info(stream);
209 std::size_t upstream_allocation_size(std::size_t bytes)
const
211 auto const aligned_size = rmm::detail::align_up(bytes, alignment_);
212 return aligned_size + alignment_ - rmm::detail::CUDA_ALLOCATION_ALIGNMENT;
216 std::unordered_map<void*, void*> pointers_;
217 std::size_t alignment_;
218 std::size_t alignment_threshold_;
219 mutable std::mutex mtx_;
Strongly-typed non-owning wrapper for CUDA streams with default constructor.
Definition: cuda_stream_view.hpp:41
Resource that adapts Upstream memory resource to allocate memory in a specified alignment size.
Definition: aligned_resource_adaptor.hpp:54
bool supports_get_mem_info() const noexcept override
Query whether the resource supports the get_mem_info API.
Definition: aligned_resource_adaptor.hpp:104
static constexpr std::size_t default_alignment_threshold
The default alignment used by the adaptor.
Definition: aligned_resource_adaptor.hpp:112
aligned_resource_adaptor(Upstream *upstream, std::size_t alignment=rmm::detail::CUDA_ALLOCATION_ALIGNMENT, std::size_t alignment_threshold=default_alignment_threshold)
Construct an aligned resource adaptor using upstream to satisfy allocation requests.
Definition: aligned_resource_adaptor.hpp:67
Upstream * get_upstream() const noexcept
Get the upstream memory resource.
Definition: aligned_resource_adaptor.hpp:89
bool supports_streams() const noexcept override
Query whether the resource supports use of non-null CUDA streams for allocation/deallocation.
Definition: aligned_resource_adaptor.hpp:94
Base class for all libcudf device memory allocation.
Definition: device_memory_resource.hpp:89