CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
tapeValues.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2024 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://www.scicomp.uni-kl.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://www.scicomp.uni-kl.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <iomanip>
38#include <sstream>
39#include <string>
40#include <vector>
41
42#include "../../config.h"
43#include "../../misc/exceptions.hpp"
44
46namespace codi {
47
73 struct TapeValues {
74 private:
75 enum class EntryType {
76 Double,
77 Long,
78 UnsignedLong
79 };
80
81 struct Entry {
82 public:
83 std::string name;
84 EntryType type;
85 size_t pos;
86
87 Entry() : name(), type(), pos() {}
88
89 Entry(std::string const& name, EntryType const& type, size_t const& pos) : name(name), type(type), pos(pos) {}
90 };
91
92 struct Section {
93 public:
94 std::string name;
95 std::vector<Entry> data;
96
97 Section() : name(), data() {}
98
99 Section(std::string const& name) : name(name), data() {}
100 };
101
102 std::vector<Section> sections;
103
104 std::vector<double> doubleData;
105 std::vector<long> longData;
106 std::vector<unsigned long> unsignedLongData;
107
108 size_t usedMemoryIndex;
109 size_t allocatedMemoryIndex;
110
111 public:
112
114 TapeValues(std::string const& tapeName)
115 : sections(), doubleData(), longData(), unsignedLongData(), usedMemoryIndex(0), allocatedMemoryIndex(1) {
116 addSection(tapeName);
117 addEntryInternal("Total memory used", EntryType::Double, doubleData, 0.0);
118 addEntryInternal("Total memory allocated", EntryType::Double, doubleData, 0.0);
119 }
120
121 /*******************************************************************************/
124
126 void addDoubleEntry(std::string const& name, double const& value, bool usedMem = false,
127 bool allocatedMem = false) {
128 addEntryInternal(name, EntryType::Double, doubleData, value);
129
130 if (usedMem) {
131 doubleData[usedMemoryIndex] += value;
132 }
133
134 if (allocatedMem) {
135 doubleData[allocatedMemoryIndex] += value;
136 }
137 }
138
140 void addLongEntry(std::string const& name, long const& value) {
141 addEntryInternal(name, EntryType::Long, longData, value);
142 }
143
145 void addSection(std::string const& name) {
146 sections.push_back(Section(name));
147 }
148
150 void addUnsignedLongEntry(std::string const& name, unsigned long const& value) {
151 addEntryInternal(name, EntryType::UnsignedLong, unsignedLongData, value);
152 }
153
155 /*******************************************************************************/
158
160 template<typename Stream = std::ostream>
161 void formatDefault(Stream& out = std::cout) const {
162 std::string const hLine = "-------------------------------------\n";
163
164 size_t maxNameSize = getMaximumNameLength();
165 size_t maxValueSize = std::max((size_t)10, getMaximumValueLength());
166
167 out << hLine;
168 for (Section const& section : sections) {
169 out << std::left << section.name << "\n";
170 out << hLine;
171
172 for (Entry const& entry : section.data) {
173 out << " " << std::left << std::setw(maxNameSize) << entry.name << " : "
174 << formatEntry(entry, maxValueSize) << "\n";
175 }
176
177 if (!section.data.empty()) {
178 out << hLine;
179 }
180 }
181 }
182
184 template<typename Stream = std::ostream>
185 void formatHeader(Stream& out = std::cout) const {
186 bool first = true;
187 for (Section const& section : sections) {
188 for (Entry const& entry : section.data) {
189 if (first) {
190 first = false;
191 } else {
192 out << "; ";
193 }
194 out << section.name << "-" << entry.name;
195 }
196 }
197
198 out << "\n";
199 }
200
202 template<typename Stream = std::ostream>
203 void formatRow(Stream& out = std::cout) const {
204 size_t maxValueSize = std::max((size_t)10, getMaximumValueLength());
205
206 bool first = true;
207 for (Section const& section : sections) {
208 for (Entry const& entry : section.data) {
209 if (first) {
210 first = false;
211 } else {
212 out << "; ";
213 }
214 out << formatEntry(entry, maxValueSize);
215 }
216 }
217
218 out << "\n";
219 }
220
222 /*******************************************************************************/
225
227 void combineData() {
228#ifdef MPI_VERSION
229 MPI_Allreduce(MPI_IN_PLACE, doubleData.data(), doubleData.size(), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
230 MPI_Allreduce(MPI_IN_PLACE, longData.data(), longData.size(), MPI_LONG, MPI_SUM, MPI_COMM_WORLD);
231 MPI_Allreduce(MPI_IN_PLACE, unsignedLongData.data(), unsignedLongData.size(), MPI_UNSIGNED_LONG, MPI_SUM,
232 MPI_COMM_WORLD);
233#endif
234 }
235
238 return doubleData[allocatedMemoryIndex];
239 }
240
243 return doubleData[usedMemoryIndex];
244 }
245
247
248 private:
249
250 template<typename T>
251 void addEntryInternal(std::string const& name, EntryType const& type, std::vector<T>& vector, T const& value) {
252 size_t entryPos = vector.size();
253 vector.push_back(value);
254
255 if (sections.empty()) {
256 addSection("General");
257 }
258
259 sections.back().data.push_back(Entry(name, type, entryPos));
260 }
261
262 std::string formatEntry(Entry const& entry, int maximumFieldSize) const {
263 return formatEntryFull(entry, true, maximumFieldSize);
264 }
265
266 std::string formatEntryFull(Entry const& entry, bool outputType, int maximumFieldSize) const {
267 std::stringstream ss;
268
269 switch (entry.type) {
270 case EntryType::Double: {
271 double formattedData = doubleData[entry.pos];
272 std::string typeString = "";
273
274 if (outputType) {
275 formatSizeHumanReadable(formattedData, typeString);
276 }
277 ss << std::right << std::setiosflags(std::ios::fixed) << std::setprecision(2) << std::setw(maximumFieldSize)
278 << formattedData << typeString;
279 } break;
280 case EntryType::Long:
281 ss << std::right << std::setw(maximumFieldSize) << longData[entry.pos];
282 break;
283 case EntryType::UnsignedLong:
284 ss << std::right << std::setw(maximumFieldSize) << unsignedLongData[entry.pos];
285 break;
286 default:
287 CODI_EXCEPTION("Unimplemented switch case.");
288 break;
289 }
290
291 return ss.str();
292 }
293
294 size_t formatEntryLength(Entry const& entry) const {
295 return formatEntryFull(entry, false, 0).size();
296 }
297
298 void formatSizeHumanReadable(double& size, std::string& type) const {
299 char const* const typeList[] = {"B", "KB", "MB", "GB", "TB"};
300 size_t typeListSize = sizeof(typeList) / sizeof(typeList[0]);
301
302 size_t pos = 0;
303 while (pos < typeListSize && size > 1024.0) {
304 size /= 1024.0;
305 pos += 1;
306 }
307
308 type = " ";
309 type += typeList[pos];
310 }
311
312 size_t getMaximumNameLength() const {
313 size_t maxLength = 0;
314 for (Section const& section : sections) {
315 for (Entry const& data : section.data) {
316 maxLength = std::max(maxLength, data.name.size());
317 }
318 }
319
320 return maxLength;
321 }
322
323 size_t getMaximumValueLength() const {
324 size_t maxLength = 0;
325 for (Section const& section : sections) {
326 for (Entry const& data : section.data) {
327 maxLength = std::max(maxLength, formatEntryLength(data));
328 }
329 }
330
331 return maxLength;
332 }
333 };
334}
CoDiPack - Code Differentiation Package.
Definition: codi.hpp:90
Tape information that can be printed in a pretty print format or a table format.
Definition: tapeValues.hpp:73
double getAllocatedMemorySize()
Get the allocated memory in bytes.
Definition: tapeValues.hpp:237
void addDoubleEntry(std::string const &name, double const &value, bool usedMem=false, bool allocatedMem=false)
Add double entry. If it is a memory entry, it should be in bytes.
Definition: tapeValues.hpp:126
TapeValues(std::string const &tapeName)
Constructor.
Definition: tapeValues.hpp:114
double getUsedMemorySize()
Get the used memory in bytes.
Definition: tapeValues.hpp:242
void formatHeader(Stream &out=std::cout) const
Output the header for a table output.
Definition: tapeValues.hpp:185
void formatDefault(Stream &out=std::cout) const
Output in a human readable format. One row per entry.
Definition: tapeValues.hpp:161
void addUnsignedLongEntry(std::string const &name, unsigned long const &value)
Add unsigned long entry.
Definition: tapeValues.hpp:150
void formatRow(Stream &out=std::cout) const
Output this data in one row. One entry per column.
Definition: tapeValues.hpp:203
void combineData()
Perform an MPI_Allreduce with MPI_COMM_WORLD.
Definition: tapeValues.hpp:227
void addSection(std::string const &name)
Add section. All further entries are added under this section.
Definition: tapeValues.hpp:145
void addLongEntry(std::string const &name, long const &value)
Add long entry.
Definition: tapeValues.hpp:140