18 #include <rmm/detail/error.hpp>
19 #include <rmm/detail/stack_trace.hpp>
20 #include <rmm/logger.hpp>
28 #include <shared_mutex>
52 template <
typename Upstream>
57 std::shared_lock<std::shared_timed_mutex>;
59 std::unique_lock<std::shared_timed_mutex>;
67 std::unique_ptr<rmm::detail::stack_trace>
strace;
79 return capture_stack ? std::make_unique<rmm::detail::stack_trace>() :
nullptr;
81 allocation_size{size} {};
94 : capture_stacks_{capture_stacks}, allocated_bytes_{0}, upstream_{upstream}
96 RMM_EXPECTS(
nullptr != upstream,
"Unexpected null upstream resource pointer.");
111 Upstream* get_upstream() const noexcept {
return upstream_; }
128 return upstream_->supports_get_mem_info();
168 std::ostringstream oss;
170 if (!allocations_.empty()) {
171 for (
auto const& alloc : allocations_) {
172 oss << alloc.first <<
": " << alloc.second.allocation_size <<
" B";
173 if (alloc.second.strace !=
nullptr) {
174 oss <<
" : callstack:" << std::endl << *alloc.second.strace;
189 #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
190 RMM_LOG_DEBUG(
"Outstanding Allocations: {}", get_outstanding_allocations_str());
210 void* ptr = upstream_->allocate(bytes, stream);
214 write_lock_t lock(mtx_);
215 allocations_.emplace(ptr, allocation_info{bytes, capture_stacks_});
217 allocated_bytes_ += bytes;
229 void do_deallocate(
void* ptr, std::size_t bytes, cuda_stream_view stream)
override
231 upstream_->deallocate(ptr, bytes, stream);
233 write_lock_t lock(mtx_);
235 const auto found = allocations_.find(ptr);
238 if (found == allocations_.end()) {
242 "Deallocating a pointer that was not tracked. Ptr: {:p} [{}B], Current Num. Allocations: "
246 this->allocations_.size());
248 allocations_.erase(found);
250 auto allocated_bytes = found->second.allocation_size;
252 if (allocated_bytes != bytes) {
256 "Alloc bytes ({}) and Dealloc bytes ({}) do not match", allocated_bytes, bytes);
258 bytes = allocated_bytes;
262 allocated_bytes_ -= bytes;
272 bool do_is_equal(device_memory_resource
const& other)
const noexcept
override
274 if (
this == &other) {
return true; }
275 auto cast =
dynamic_cast<tracking_resource_adaptor<Upstream> const*
>(&other);
276 return cast !=
nullptr ? upstream_->is_equal(*cast->get_upstream())
277 : upstream_->is_equal(other);
288 std::pair<std::size_t, std::size_t> do_get_mem_info(cuda_stream_view stream)
const override
290 return upstream_->get_mem_info(stream);
293 bool capture_stacks_;
294 std::map<void*, allocation_info> allocations_;
295 std::atomic<std::size_t> allocated_bytes_;
296 std::shared_timed_mutex
mutable mtx_;
308 template <
typename Upstream>
Strongly-typed non-owning wrapper for CUDA streams with default constructor.
Definition: cuda_stream_view.hpp:41
Base class for all libcudf device memory allocation.
Definition: device_memory_resource.hpp:89
Resource that uses Upstream to allocate memory and tracks allocations.
Definition: tracking_resource_adaptor.hpp:53
tracking_resource_adaptor(Upstream *upstream, bool capture_stacks=false)
Construct a new tracking resource adaptor using upstream to satisfy allocation requests.
Definition: tracking_resource_adaptor.hpp:93
bool supports_get_mem_info() const noexcept override
Query whether the resource supports the get_mem_info API.
Definition: tracking_resource_adaptor.hpp:126
bool supports_streams() const noexcept override
Checks whether the upstream resource supports streams.
Definition: tracking_resource_adaptor.hpp:119
std::size_t get_allocated_bytes() const noexcept
Query the number of bytes that have been allocated. Note that this can not be used to know how large ...
Definition: tracking_resource_adaptor.hpp:152
std::shared_lock< std::shared_timed_mutex > read_lock_t
Type of lock used to synchronize read access.
Definition: tracking_resource_adaptor.hpp:57
std::unique_lock< std::shared_timed_mutex > write_lock_t
Type of lock used to synchronize write access.
Definition: tracking_resource_adaptor.hpp:59
tracking_resource_adaptor(tracking_resource_adaptor &&) noexcept=default
Default move constructor.
std::string get_outstanding_allocations_str() const
Gets a string containing the outstanding allocation pointers, their size, and optionally the stack tr...
Definition: tracking_resource_adaptor.hpp:164
std::map< void *, allocation_info > const & get_outstanding_allocations() const noexcept
Get the outstanding allocations map.
Definition: tracking_resource_adaptor.hpp:138
void log_outstanding_allocations() const
Log any outstanding allocations via RMM_LOG_DEBUG.
Definition: tracking_resource_adaptor.hpp:187
tracking_resource_adaptor< Upstream > make_tracking_adaptor(Upstream *upstream)
Convenience factory to return a tracking_resource_adaptor around the upstream resource upstream.
Definition: tracking_resource_adaptor.hpp:309
Information stored about an allocation. Includes the size and a stack trace if the tracking_resource_...
Definition: tracking_resource_adaptor.hpp:66
std::unique_ptr< rmm::detail::stack_trace > strace
Stack trace of the allocation.
Definition: tracking_resource_adaptor.hpp:67
std::size_t allocation_size
Size of the allocation.
Definition: tracking_resource_adaptor.hpp:68
allocation_info(std::size_t size, bool capture_stack)
Construct a new allocation info object.
Definition: tracking_resource_adaptor.hpp:77