18 #include <rmm/detail/error.hpp>
19 #include <rmm/detail/stack_trace.hpp>
20 #include <rmm/mr/device/device_memory_resource.hpp>
25 #include <shared_mutex>
44 template <
typename Upstream>
48 using read_lock_t = std::shared_lock<std::shared_timed_mutex>;
49 using write_lock_t = std::unique_lock<std::shared_timed_mutex>;
58 std::unique_ptr<rmm::detail::stack_trace> strace;
59 std::size_t allocation_size;
64 return capture_stack ? std::make_unique<rmm::detail::stack_trace>() :
nullptr;
66 allocation_size{size} {};
79 : capture_stacks_{capture_stacks}, allocated_bytes_{0}, upstream_{upstream}
81 RMM_EXPECTS(
nullptr != upstream,
"Unexpected null upstream resource pointer.");
89 tracking_resource_adaptor& operator=(tracking_resource_adaptor&&) noexcept = default;
113 return upstream_->supports_get_mem_info();
151 read_lock_t lock(mtx_);
153 std::ostringstream oss;
155 if (!allocations_.empty()) {
156 for (
auto const& alloc : allocations_) {
157 oss << alloc.first <<
": " << alloc.second.allocation_size <<
" B";
158 if (alloc.second.strace !=
nullptr) {
159 oss <<
" : callstack:" << std::endl << *alloc.second.strace;
174 #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
176 #endif // SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
195 void* ptr = upstream_->allocate(bytes, stream);
199 write_lock_t lock(mtx_);
200 allocations_.emplace(ptr, allocation_info{bytes, capture_stacks_});
202 allocated_bytes_ += bytes;
216 void do_deallocate(
void* ptr, std::size_t bytes, cuda_stream_view stream)
override
218 upstream_->deallocate(ptr, bytes, stream);
220 write_lock_t lock(mtx_);
222 const auto found = allocations_.find(ptr);
225 if (found == allocations_.end()) {
229 "Deallocating a pointer that was not tracked. Ptr: {:p} [{}B], Current Num. Allocations: "
233 this->allocations_.size());
235 allocations_.erase(found);
237 auto allocated_bytes = found->second.allocation_size;
239 if (allocated_bytes != bytes) {
243 "Alloc bytes ({}) and Dealloc bytes ({}) do not match", allocated_bytes, bytes);
245 bytes = allocated_bytes;
249 allocated_bytes_ -= bytes;
261 bool do_is_equal(device_memory_resource
const& other)
const noexcept
override
263 if (
this == &other) {
return true; }
264 auto cast =
dynamic_cast<tracking_resource_adaptor<Upstream> const*
>(&other);
265 return cast !=
nullptr ? upstream_->is_equal(*cast->get_upstream())
266 : upstream_->is_equal(other);
277 std::pair<std::size_t, std::size_t> do_get_mem_info(cuda_stream_view stream)
const override
279 return upstream_->get_mem_info(stream);
282 bool capture_stacks_;
283 std::map<void*, allocation_info> allocations_;
284 std::atomic<std::size_t> allocated_bytes_;
285 std::shared_timed_mutex
mutable mtx_;
296 template <
typename Upstream>
297 tracking_resource_adaptor<Upstream> make_tracking_adaptor(Upstream* upstream)
299 return tracking_resource_adaptor<Upstream>{upstream};