31 if (print_at_program_end_) {
41 std::exit(EXIT_FAILURE);
49 print_at_program_end_ = print;
53 print_at_malloc_free_ = print;
71 for (
const auto& value_pair : statistics_) {
73 const auto& device = value_pair.first;
74 const auto& statistics = value_pair.second;
80 if (!statistics.IsBalanced()) {
81 int64_t count_leaking =
82 statistics.count_malloc_ - statistics.count_free_;
84 size_t leaking_byte_size = std::accumulate(
85 statistics.active_allocations_.begin(),
86 statistics.active_allocations_.end(), 0,
87 [](
size_t count,
auto ptr_byte_size) ->
size_t {
88 return count + ptr_byte_size.second;
92 device.ToString(), statistics.count_malloc_,
93 statistics.count_free_, count_leaking,
96 for (
const auto& leak : statistics.active_allocations_) {
102 statistics.count_malloc_, statistics.count_free_);
112 return std::any_of(statistics_.begin(), statistics_.end(),
113 [](
const auto& value_pair) ->
bool {
114 return !value_pair.second.IsBalanced();
121 std::lock_guard<std::mutex> lock(statistics_mutex_);
124 if (ptr ==
nullptr && byte_size == 0) {
128 auto it = statistics_[device].active_allocations_.emplace(ptr, byte_size);
130 statistics_[device].count_malloc_++;
131 if (print_at_malloc_free_) {
133 fmt::sprintf(
"%6s", device.
ToString()),
134 fmt::ptr(ptr), byte_size);
138 "{} @ {} bytes on {} is still active and was not freed before",
139 fmt::ptr(ptr), byte_size, device.
ToString());
144 std::lock_guard<std::mutex> lock(statistics_mutex_);
147 if (ptr ==
nullptr) {
151 auto num_to_erase = statistics_[device].active_allocations_.count(ptr);
152 if (num_to_erase == 1) {
153 if (print_at_malloc_free_) {
155 fmt::sprintf(
"%6s", device.
ToString()),
157 statistics_[device].active_allocations_.at(ptr));
159 statistics_[device].active_allocations_.erase(ptr);
160 statistics_[device].count_free_++;
161 }
else if (num_to_erase == 0) {
167 "Invalid number of erased allocations {} for {} on {}",
168 num_to_erase, fmt::ptr(ptr), device.
ToString());
173 std::lock_guard<std::mutex> lock(statistics_mutex_);
178 return count_malloc_ == count_free_;
std::string ToString() const
Returns string representation of device, e.g. "CPU:0", "CUDA:0".
@ None
No statistics are printed.
void SetPrintAtMallocFree(bool print)
Enables or disables printing at each malloc and free.
~MemoryManagerStatistic()
void Print() const
Prints statistics for all recorded devices depending on the print level.
void SetPrintLevel(PrintLevel level)
Sets the level of provided information for printing.
void Reset()
Resets the statistics.
void CountFree(void *ptr, const Device &device)
static MemoryManagerStatistic & GetInstance()
void CountMalloc(void *ptr, size_t byte_size, const Device &device)
Adds the given allocation to the statistics.
void SetPrintAtProgramEnd(bool print)
void ResetPrintFunction()
Reset the print function to the default one (print to console).
static Logger & GetInstance()
Get Logger global singleton instance.
void SetVerbosityLevel(VerbosityLevel level)
VerbosityLevel GetVerbosityLevel()
Get global verbosity level of CloudViewer.
Generic file read and write utility for python interface.