NEURON
memory_usage.cpp
Go to the documentation of this file.
1 #include <neuron/model_data.hpp>
3 #include <stdexcept>
4 #include "oc_ansi.h"
5 #include "hocdec.h"
6 
7 #include <fmt/format.h>
8 
9 namespace neuron::container {
11  auto nodes = memory_usage(model.node_data());
12 
13  auto mechanisms = StorageMemoryUsage();
14  model.apply_to_mechanisms([&mechanisms](const auto& md) { mechanisms += memory_usage(md); });
15 
16  return {nodes, mechanisms};
17 }
18 
19 cache::ModelMemoryUsage memory_usage(const std::optional<neuron::cache::Model>& model) {
21 }
23  VectorMemoryUsage thread(model.thread);
24  for (const auto& t: model.thread) {
25  thread += VectorMemoryUsage(t.mechanism_offset);
26  }
27 
29  for (const auto& m: model.mechanism) {
30  mechanism += VectorMemoryUsage(m.pdata_ptr_cache);
31 
32  mechanism += VectorMemoryUsage(m.pdata);
33  for (const auto& pd: m.pdata) {
35  }
36 
37  mechanism += VectorMemoryUsage(m.pdata_hack);
38  for (const auto& pdd: m.pdata_hack) {
40  }
41  }
42 
43  return {thread, mechanism};
44 }
45 
47  return MemoryUsage{memory_usage(model()),
50 }
51 
52 namespace detail {
53 template <class T>
55  size_t per_element_size) {
56  if (v) {
57  size_t size = v->size() * (sizeof(T) + per_element_size);
58  size_t capacity = size + (v->capacity() - v->size()) * sizeof(T);
59 
60  return {size, capacity};
61  }
62 
63  return {0ul, 0ul};
64 }
65 
66 
69 }
70 } // namespace detail
71 
72 
73 /** @brief Format the memory sizes as human readable strings.
74  *
75  * Currently, the intended use is in aligned tables in the memory usage
76  * report. Hence, the string has two digits and is 9 characters long
77  * (without the null char).
78  */
79 std::string format_memory(size_t bytes) {
80  static std::vector<std::string> suffixes{" ", " kB", " MB", " GB", " TB", " PB"};
81 
82  size_t suffix_id = std::min(size_t(std::floor(std::log10(std::max(1.0, double(bytes))))) / 3,
83  suffixes.size() - 1);
84  auto suffix = suffixes[suffix_id];
85 
86  double value = double(bytes) / std::pow(10.0, suffix_id * 3.0);
87 
88  char formatted[64];
89  if (suffix_id == 0) {
90  snprintf(formatted, sizeof(formatted), "% 6ld", bytes);
91  } else {
92  snprintf(formatted, sizeof(formatted), "%6.2f", value);
93  }
94 
95  return formatted + suffix;
96 }
97 
99  return format_memory(memory_usage.size) + " " + format_memory(memory_usage.capacity);
100 }
101 
102 std::string format_memory_usage(const MemoryUsage& usage) {
103  const auto& model = usage.model;
104  const auto& cache_model = usage.cache_model;
105  const auto& stable_pointers = usage.stable_pointers;
106  const auto& total = usage.compute_total();
107  const auto& summary = MemoryUsageSummary(usage);
108 
109  std::stringstream os;
110 
111  os << " size capacity \n";
112  os << "Model \n";
113  os << " nodes \n";
114  os << " data " << format_memory_usage(model.nodes.heavy_data) << "\n";
115  os << " stable_identifiers " << format_memory_usage(model.nodes.stable_identifiers) << "\n";
116  os << " mechanisms \n";
117  os << " data " << format_memory_usage(model.mechanisms.heavy_data) << "\n";
118  os << " stable_identifiers " << format_memory_usage(model.mechanisms.stable_identifiers)
119  << "\n";
120  os << "cache::Model \n";
121  os << " threads " << format_memory_usage(cache_model.threads) << "\n";
122  os << " mechanisms " << format_memory_usage(cache_model.mechanisms) << "\n";
123  os << "deferred deletion \n";
124  os << " stable_pointers " << format_memory_usage(stable_pointers) << "\n";
125  os << "\n";
126  os << "total " << format_memory_usage(total) << "\n";
127  os << "\n";
128  os << "Summary\n";
129  os << " required " << format_memory(summary.required) << "\n";
130  os << " convenient " << format_memory(summary.convenient) << "\n";
131  os << " oversized " << format_memory(summary.oversized) << "\n";
132  os << " leaked " << format_memory(summary.leaked) << "\n";
133 
134 
135  return os.str();
136 }
137 
138 
140  Printf(fmt::format("{}\n", format_memory_usage(memory_usage)).c_str());
141 }
142 
143 } // namespace neuron::container
144 
146  if (!ifarg(0)) {
147  hoc_execerror("print_local_memory_usage doesn't support any arguments.", nullptr);
148  }
149 
151 
152  hoc_retpushx(1.);
153 }
#define v
Definition: md1redef.h:11
void hoc_retpushx(double x)
Definition: hocusr.cpp:154
floor
Definition: extdef.h:4
log10
Definition: extdef.h:4
pow
Definition: extdef.h:4
static const char * mechanism[]
Definition: capac.cpp:19
void hoc_execerror(const char *s1, const char *s2)
Definition: nrnoc_aux.cpp:39
std::optional< Model > model
Definition: container.cpp:59
std::vector< void * > * defer_delete_storage
Defer deleting pointers to deallocated memory.
Definition: container.cpp:95
VectorMemoryUsage compute_defer_delete_storage_size()
void print_memory_usage(const MemoryUsage &usage)
MemoryUsage local_memory_usage()
Gather memory usage of this process.
std::string format_memory_usage(const VectorMemoryUsage &memory_usage)
Aligned, human readable representation of memory_usage.
std::string format_memory(size_t bytes)
Utility to format memory as a human readable string.
cache::ModelMemoryUsage memory_usage(const std::optional< neuron::cache::Model > &model)
Model & model()
Access the global Model instance.
Definition: model_data.hpp:206
static char suffix[256]
Definition: nocpout.cpp:135
void print_local_memory_usage()
int ifarg(int)
Definition: code.cpp:1607
HOC interpreter function declarations (included by hocdec.h)
static uint32_t value
Definition: scoprand.cpp:25
Top-level structure.
Definition: model_data.hpp:18
void apply_to_mechanisms(Callable const &callable)
Apply a function to each non-null Mechanism.
Definition: model_data.hpp:37
container::Node::storage & node_data()
Access the structure containing the data of all Nodes.
Definition: model_data.hpp:24
Overall SoA datastructures related memory usage.
VectorMemoryUsage compute_total() const
cache::ModelMemoryUsage cache_model
VectorMemoryUsage stable_pointers
Memory usage of a neuron::Model.
Memory usage of a storage/soa container.
Size and capacity in bytes.
Memory usage of a neuron::cache::Model.
int Printf(const char *fmt, Args... args)
Definition: logger.hpp:18