hyper.deal
Loading...
Searching...
No Matches
memory_consumption.h
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2020 by the hyper.deal authors
4//
5// This file is part of the hyper.deal library.
6//
7// The hyper.deal library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 3.0 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.MD at
12// the top level directory of hyper.deal.
13//
14// ---------------------------------------------------------------------
15
16#ifndef HYPERDEAL_MEMORY_CONSUMPTION
17#define HYPERDEAL_MEMORY_CONSUMPTION
18
19#include <hyper.deal/base/config.h>
20
21#include <deal.II/base/utilities.h>
22
23#include <iomanip>
24#include <vector>
25
26namespace hyperdeal
27{
28 namespace internal
29 {
30 template <typename StreamType, long unsigned int N>
31 void
32 print(
33 StreamType & stream,
34 const MPI_Comm & comm,
35 const std::vector<std::pair<std::string, std::array<double, N>>> &list,
36 const std::vector<std::string> & labels,
37 const unsigned int mm)
38 {
39 std::vector<double> temp1(list.size() * N);
40
41 for (unsigned int i = 0, k = 0; i < list.size(); i++)
42 for (unsigned int j = 0; j < N; j++, k++)
43 temp1[k] = list[i].second[j];
44
45
46 const auto temp2 = dealii::Utilities::MPI::min_max_avg(temp1, comm);
47
48 std::vector<std::pair<std::string,
49 std::array<dealii::Utilities::MPI::MinMaxAvg, N>>>
50 list_min_max(list.size());
51
52 for (unsigned int i = 0, k = 0; i < list.size(); i++)
53 {
54 list_min_max[i].first = list[i].first;
55 for (unsigned int j = 0; j < N; j++, k++)
56 list_min_max[i].second[j] = temp2[k];
57 }
58
59
60 const auto max_width =
61 std::max_element(list_min_max.begin(),
62 list_min_max.end(),
63 [](const auto &a, const auto &b) {
64 return a.first.size() < b.first.size();
65 })
66 ->first.size();
67
68
69 // print header
70 const auto print_lines = [&]() {
71 stream << "+-" << std::string(max_width + 2, '-') << "+";
72
73 for (unsigned int i = 0; i < labels.size(); i++)
74 {
75 auto j = list_min_max[mm].second[i];
76 auto label = labels[i];
77
78 // clang-format off
79 const unsigned int width = static_cast<unsigned int>(4 + std::log(j.sum) / log(10.0))+
80 static_cast<unsigned int>(8)+
81 static_cast<unsigned int>(4 + std::log(j.min) / log(10.0))+
82 static_cast<unsigned int>(4 + std::log(j.avg) / log(10.0))+
83 static_cast<unsigned int>(4 + std::log(j.max) / log(10.0));
84
85 stream << std::string(width, '-');
86 stream << "-+";
87 // clang-format on
88 }
89 stream << std::endl;
90 };
91
92 print_lines();
93 {
94 stream << "| " << std::left << std::setw(max_width + 2) << ""
95 << "|";
96
97 for (unsigned int i = 0; i < labels.size(); i++)
98 {
99 auto j = list_min_max[mm].second[i];
100 auto label = labels[i];
101
102 // clang-format off
103 const unsigned int width = static_cast<unsigned int>(4 + std::log(j.sum) / log(10.0))+
104 static_cast<unsigned int>(8)+
105 static_cast<unsigned int>(4 + std::log(j.min) / log(10.0))+
106 static_cast<unsigned int>(4 + std::log(j.avg) / log(10.0))+
107 static_cast<unsigned int>(4 + std::log(j.max) / log(10.0));
108
109 stream << std::setw((width-label.size())/2) << "" << label << std::setw(width - label.size() - (width-label.size())/2) << "" ;
110 stream << " |";
111 // clang-format on
112 }
113 stream << std::endl;
114 }
115
116 // print header
117 {
118 stream << "| " << std::left << std::setw(max_width + 2) << ""
119 << "|";
120
121 for (auto j : list_min_max[mm].second)
122 {
123 // clang-format off
124 stream << std::setw(4 + std::log(j.sum) / log(10.0)) << std::right << "total";
125 stream << std::setw(8) << "%";
126 stream << std::setw(4 + std::log(j.min) / log(10.0)) << std::right << "min";
127 stream << std::setw(4 + std::log(j.avg) / log(10.0)) << std::right << "avg";
128 stream << std::setw(4 + std::log(j.max) / log(10.0)) << std::right << "max";
129 stream << " |";
130 // clang-format on
131 }
132 stream << std::endl;
133 }
134 print_lines();
135
136 // print rows
137 for (auto j : list_min_max)
138 {
139 stream << "| " << std::left << std::setw(max_width + 2) << j.first
140 << "|";
141
142 for (unsigned int col = 0; col < j.second.size(); col++)
143 {
144 auto i = j.second[col];
145 auto m = list_min_max[mm].second[col];
146 // clang-format off
147 stream << std::fixed << std::setprecision(0) << std::setw(4 + std::log(m.sum) / log(10.0)) << std::right << i.sum;
148 stream << std::fixed << std::setprecision(2) << std::setw(8) << std::right << (i.sum * 100 / m.sum);
149 stream << std::fixed << std::setprecision(0) << std::setw(4 + std::log(m.min) / log(10.0)) << std::right << i.min;
150 stream << std::fixed << std::setprecision(0) << std::setw(4 + std::log(m.avg) / log(10.0)) << std::right << i.avg;
151 stream << std::fixed << std::setprecision(0) << std::setw(4 + std::log(m.max) / log(10.0)) << std::right << i.max;
152 stream << " |";
153 // clang-format on
154 }
155 stream << std::endl;
156 }
157 print_lines();
158 stream << std::endl << std::endl;
159 }
160
161
162 template <typename StreamType, long unsigned int N>
163 void
164 print_(
165 StreamType & stream,
166 const MPI_Comm & comm,
167 const std::vector<std::pair<std::string, std::array<double, N>>> &list,
168 const std::vector<std::pair<std::string, unsigned int>> &list_count,
169 const std::vector<std::string> & labels,
170 const unsigned int mm)
171 {
172 unsigned int max_count = 0;
173
174 for (const auto &i : list_count)
175 max_count = std::max(max_count, i.second);
176
177 std::vector<double> temp1(list.size() * N);
178
179 for (unsigned int i = 0, k = 0; i < list.size(); i++)
180 for (unsigned int j = 0; j < N; j++, k++)
181 temp1[k] = list[i].second[j];
182
183
184 const auto temp2 = dealii::Utilities::MPI::min_max_avg(temp1, comm);
185
186 std::vector<std::pair<std::string,
187 std::array<dealii::Utilities::MPI::MinMaxAvg, N>>>
188 list_min_max(list.size());
189
190 for (unsigned int i = 0, k = 0; i < list.size(); i++)
191 {
192 list_min_max[i].first = list[i].first;
193 for (unsigned int j = 0; j < N; j++, k++)
194 list_min_max[i].second[j] = temp2[k];
195 }
196
197
198 const auto max_width =
199 std::max_element(list_min_max.begin(),
200 list_min_max.end(),
201 [](const auto &a, const auto &b) {
202 return a.first.size() < b.first.size();
203 })
204 ->first.size();
205
206
207 // print header
208 const auto print_lines = [&]() {
209 stream << "+-" << std::string(max_width + 2, '-') << "+";
210
211 for (unsigned int i = 0; i < labels.size(); i++)
212 {
213 auto j = list_min_max[mm].second[i];
214 auto label = labels[i];
215
216 // clang-format off
217 const unsigned int width = static_cast<unsigned int>(3 + std::log(max_count) / log(10.0))+
218 static_cast<unsigned int>(8)+
219 static_cast<unsigned int>(8 + std::log(j.min) / log(10.0))+
220 static_cast<unsigned int>(8 + std::log(j.avg) / log(10.0))+
221 static_cast<unsigned int>(8 + std::log(j.max) / log(10.0));
222
223 stream << std::string(width, '-');
224 stream << "-+";
225 // clang-format on
226 }
227 stream << std::endl;
228 };
229
230 print_lines();
231 {
232 stream << "| " << std::left << std::setw(max_width + 2) << ""
233 << "|";
234
235 for (unsigned int i = 0; i < labels.size(); i++)
236 {
237 auto j = list_min_max[mm].second[i];
238 auto label = labels[i];
239
240 // clang-format off
241 const unsigned int width = static_cast<unsigned int>(3 + std::log(max_count) / log(10.0))+
242 static_cast<unsigned int>(8)+
243 static_cast<unsigned int>(8 + std::log(j.min) / log(10.0))+
244 static_cast<unsigned int>(8 + std::log(j.avg) / log(10.0))+
245 static_cast<unsigned int>(8 + std::log(j.max) / log(10.0));
246
247 stream << std::setw((width-label.size())/2) << "" << label << std::setw(width - label.size() - (width-label.size())/2) << "" ;
248 stream << " |";
249 // clang-format on
250 }
251 stream << std::endl;
252 }
253
254 // print header
255 {
256 stream << "| " << std::left << std::setw(max_width + 2) << ""
257 << "|";
258
259 for (auto j : list_min_max[mm].second)
260 {
261 // clang-format off
262 stream << std::setw(3 + std::log(max_count) / log(10.0)) << std::right << "#";
263 stream << std::setw(8) << "%";
264 stream << std::setw(8 + std::log(j.min) / log(10.0)) << std::right << "min";
265 stream << std::setw(8 + std::log(j.avg) / log(10.0)) << std::right << "avg";
266 stream << std::setw(8 + std::log(j.max) / log(10.0)) << std::right << "max";
267 stream << " |";
268 // clang-format on
269 }
270 stream << std::endl;
271 }
272 print_lines();
273
274 // print rows
275 unsigned int row = 0;
276 for (auto j : list_min_max)
277 {
278 stream << "| " << std::left << std::setw(max_width + 2) << j.first
279 << "|";
280
281 for (unsigned int col = 0; col < j.second.size(); col++)
282 {
283 auto i = j.second[col];
284 auto m = list_min_max[mm].second[col];
285 // clang-format off
286 stream << std::fixed << std::setw(3 + std::log(max_count) / log(10.0)) << std::right << list_count[row].second;
287 stream << std::fixed << std::setprecision(2) << std::setw(8) << std::right << (i.sum * 100 / m.sum);
288 stream << std::fixed << std::setprecision(2) << std::setw(8 + std::log(m.min) / log(10.0)) << std::right << i.min;
289 stream << std::fixed << std::setprecision(2) << std::setw(8 + std::log(m.avg) / log(10.0)) << std::right << i.avg;
290 stream << std::fixed << std::setprecision(2) << std::setw(8 + std::log(m.max) / log(10.0)) << std::right << i.max;
291 stream << " |";
292 // clang-format on
293 }
294 stream << std::endl;
295
296 row++;
297 }
298 print_lines();
299 stream << std::endl << std::endl;
300 }
301 } // namespace internal
302
304 {
305 public:
306 MemoryStatMonitor(const MPI_Comm &comm)
307 : comm(comm)
308 {}
309
310 void
311 monitor(const std::string &label)
312 {
313 MPI_Barrier(comm);
314 dealii::Utilities::System::MemoryStats stats;
315 dealii::Utilities::System::get_memory_stats(stats);
316
317 list.emplace_back(label,
318 std::array<double, 4>{
319 {static_cast<double>(stats.VmPeak),
320 static_cast<double>(stats.VmSize),
321 static_cast<double>(stats.VmHWM),
322 static_cast<double>(stats.VmRSS)}});
323
324 MPI_Barrier(comm);
325 }
326
327 template <typename StreamType>
328 void
329 print(StreamType &stream, const bool do_monitor = true)
330 {
331 if (do_monitor)
332 this->monitor("");
333
334 internal::print(
335 stream,
336 comm,
337 list,
338 {"VmPeak [kB]", "VmSize [kB]", "VmHWM [kB]", "VmRSS [kB]"},
339 list.size() - 1);
340 }
341
342 private:
343 const MPI_Comm &comm;
344
345 std::vector<std::pair<std::string, std::array<double, 4>>> list;
346 };
347
349 {
350 public:
351 MemoryConsumption(std::string label, const std::size_t &val = 0)
352 : label(label)
353 , memory_consumpition_leaf(val)
354 {}
355
356 void
357 insert(const MemoryConsumption &m)
358 {
359 vec.emplace_back(m);
360 }
361
362 void
363 insert(const std::string &label, const std::size_t &val)
364 {
365 vec.emplace_back(label, val);
366 }
367
368 template <typename StreamType>
369 void
370 print(const MPI_Comm &comm, StreamType &stream) const
371 {
372 const std::vector<std::pair<std::string, std::size_t>> collection =
373 collect();
374
375 std::vector<std::pair<std::string, std::array<double, 1>>> collection_(
376 collection.size());
377
378 for (unsigned int i = 0; i < collection.size(); i++)
379 collection_[i] = std::pair<std::string, std::array<double, 1>>{
380 collection[i].first,
381 std::array<double, 1>{{static_cast<double>(collection[i].second)}}};
382
383 internal::print(
384 stream, comm, collection_, {"Memory consumption [Byte]"}, 0);
385 }
386
387 std::size_t
388 memory_consumption() const
389 {
390 return std::accumulate(vec.begin(),
391 vec.end(),
392 memory_consumpition_leaf,
393 [](const auto &a, const auto &b) {
394 return a + b.memory_consumption();
395 });
396 }
397
398
399 private:
400 std::vector<std::pair<std::string, std::size_t>>
401 collect() const
402 {
403 std::vector<std::pair<std::string, std::size_t>> all;
404
405 all.emplace_back(label, this->memory_consumption());
406
407 for (const auto &v : vec)
408 for (const auto &i : v.collect())
409 all.emplace_back(label + ":" + i.first, i.second);
410
411 return all;
412 }
413
414 const std::string label;
415 const std::size_t memory_consumpition_leaf;
416
417 std::vector<MemoryConsumption> vec;
418 };
419} // namespace hyperdeal
420
421#endif
Definition memory_consumption.h:349
Definition memory_consumption.h:304