13 #include <unordered_map>
16 #include <cuda_runtime_api.h>
18 #include <cuda/memory_resource>
22 #include <rmm/error.hpp>
25 #include <rapidsmpf/error.hpp>
26 #include <rapidsmpf/memory/scoped_memory_record.hpp>
27 #include <rapidsmpf/utils/misc.hpp>
42 template <cuda::mr::resource_with<cuda::mr::device_accessible> PrimaryMR>
57 : primary_mr_{std::move(primary_mr)} {}
70 template <
typename... Args>
72 : primary_mr_{std::forward<Args>(args)...} {}
88 return this == std::addressof(other);
101 std::lock_guard<std::mutex> lock(mutex_);
107 std::lock_guard<std::mutex> lock(mutex_);
113 std::lock_guard<std::mutex> lock(mutex_);
114 record_stacks_[std::this_thread::get_id()].emplace();
119 std::lock_guard lock(mutex_);
120 auto& stack = record_stacks_.at(std::this_thread::get_id());
123 "calling end_scoped_memory_record() on an empty stack.",
126 auto ret = stack.top();
128 if (!stack.empty()) {
129 stack.top().add_subscope(ret);
143 cuda::stream_ref stream,
147 void* ret = primary_mr_.allocate(stream, bytes, alignment);
148 std::lock_guard<std::mutex> lock(mutex_);
150 if (!record_stacks_.empty()) {
151 auto const thread_id = std::this_thread::get_id();
152 auto& record = record_stacks_[thread_id];
153 if (!record.empty()) {
154 record.top().record_allocation(safe_cast<std::int64_t>(bytes));
156 allocating_threads_.insert({ret, thread_id}).second,
157 "duplicate memory pointer"
173 cuda::stream_ref stream,
179 std::lock_guard<std::mutex> lock(mutex_);
181 if (!allocating_threads_.empty()) {
182 auto const node = allocating_threads_.extract(ptr);
184 auto thread_id = node.mapped();
185 auto& record = record_stacks_[thread_id];
186 if (!record.empty()) {
187 record.top().record_deallocation(safe_cast<std::int64_t>(bytes));
192 primary_mr_.deallocate(stream, ptr, bytes, alignment);
205 auto* ptr =
allocate(sync_stream_, bytes, alignment);
222 deallocate(sync_stream_, ptr, bytes, alignment);
231 mutable std::mutex mutex_;
232 PrimaryMR primary_mr_;
235 std::unordered_map<std::thread::id, std::stack<ScopedMemoryRecord>> record_stacks_;
236 std::unordered_map<void*, std::thread::id> allocating_threads_;
Implementation class for RmmResourceAdaptor.
ScopedMemoryRecord get_main_record() const
Returns a copy of the main memory record.
void deallocate(cuda::stream_ref stream, void *ptr, std::size_t bytes, std::size_t alignment=rmm::CUDA_ALLOCATION_ALIGNMENT) noexcept
Deallocate memory asynchronously on the given stream.
bool operator==(RmmResourceAdaptorImpl const &other) const noexcept
Equality comparison.
void deallocate_sync(void *ptr, std::size_t bytes, std::size_t alignment=rmm::CUDA_ALLOCATION_ALIGNMENT) noexcept
Deallocate memory synchronously.
friend void get_property(RmmResourceAdaptorImpl const &, cuda::mr::device_accessible) noexcept
Tag this resource as device-accessible for the CCCL concept.
PrimaryMR const & get_upstream_resource() const noexcept
Returns a reference to the primary upstream resource.
void * allocate_sync(std::size_t bytes, std::size_t alignment=rmm::CUDA_ALLOCATION_ALIGNMENT)
Allocate memory synchronously.
void * allocate(cuda::stream_ref stream, std::size_t bytes, std::size_t alignment=rmm::CUDA_ALLOCATION_ALIGNMENT)
Allocate memory asynchronously on the given stream.
RmmResourceAdaptorImpl(PrimaryMR primary_mr)
Construct with a primary memory resource.
ScopedMemoryRecord end_scoped_memory_record()
End the current scoped memory record and return it.
void begin_scoped_memory_record()
Begin recording a new scoped memory usage record for the current thread.
RmmResourceAdaptorImpl(std::in_place_t, Args &&... args)
Construct the primary resource in-place from forwarded arguments.
std::int64_t current_allocated() const noexcept
Get the total current allocated memory through this resource.
static constexpr std::size_t CUDA_ALLOCATION_ALIGNMENT
Memory statistics for a specific scope.
std::int64_t current() const noexcept
Returns the current memory usage in bytes.
void record_allocation(std::int64_t nbytes)
Records a memory allocation event.
void record_deallocation(std::int64_t nbytes)
Records a memory deallocation event.