77 enum class LocalReductionOperation {
83 enum class EntryType {
93 LocalReductionOperation operation;
96 Entry() : name(), type(), operation(), pos() {}
98 Entry(std::string
const& name, EntryType
const& type, LocalReductionOperation
const& operation,
100 : name(name), type(type), operation(operation), pos(pos) {}
106 std::vector<Entry> data;
108 Section() : name(), data() {}
110 Section(std::string
const& name) : name(name), data() {}
113 std::vector<Section> sections;
115 std::vector<double> doubleData;
116 std::vector<long> longData;
117 std::vector<unsigned long> unsignedLongData;
119 size_t usedMemoryIndex;
120 size_t allocatedMemoryIndex;
126 : sections(), doubleData(), longData(), unsignedLongData(), usedMemoryIndex(0), allocatedMemoryIndex(1) {
128 addEntryInternal(
"Total memory used", EntryType::Double, LocalReductionOperation::Sum, doubleData, 0.0);
129 addEntryInternal(
"Total memory allocated", EntryType::Double, LocalReductionOperation::Sum, doubleData, 0.0);
138 LocalReductionOperation operation = LocalReductionOperation::Sum,
bool usedMem =
false,
139 bool allocatedMem =
false) {
140 addEntryInternal(name, EntryType::Double, operation, doubleData, value);
143 doubleData[usedMemoryIndex] += value;
147 doubleData[allocatedMemoryIndex] += value;
153 LocalReductionOperation operation = LocalReductionOperation::Sum) {
154 addEntryInternal(name, EntryType::Long, operation, longData, value);
159 sections.push_back(Section(name));
164 LocalReductionOperation operation = LocalReductionOperation::Sum) {
165 addEntryInternal(name, EntryType::UnsignedLong, operation, unsignedLongData, value);
174 template<
typename Stream = std::ostream>
176 std::string
const hLine =
"-------------------------------------\n";
178 size_t maxNameSize = getMaximumNameLength();
179 size_t maxValueSize = std::max((
size_t)10, getMaximumValueLength());
182 for (Section
const& section : sections) {
183 out << std::left << section.name <<
"\n";
186 for (Entry
const& entry : section.data) {
187 out <<
" " << std::left << std::setw(maxNameSize) << entry.name <<
" : "
188 << formatEntry(entry, maxValueSize) <<
"\n";
191 if (!section.data.empty()) {
198 template<
typename Stream = std::ostream>
201 for (Section
const& section : sections) {
202 for (Entry
const& entry : section.data) {
208 out << section.name <<
"-" << entry.name;
216 template<
typename Stream = std::ostream>
218 size_t maxValueSize = std::max((
size_t)10, getMaximumValueLength());
221 for (Section
const& section : sections) {
222 for (Entry
const& entry : section.data) {
228 out << formatEntry(entry, maxValueSize);
243 codiAssert(this->sections.size() == other.sections.size());
245 for (
size_t section = 0; section < this->sections.size(); ++section) {
246 auto& thisSection = this->sections[section];
247 auto const& otherSection = other.sections[section];
250 codiAssert(thisSection.name == otherSection.name);
253 codiAssert(thisSection.data.size() == otherSection.data.size());
255 for (
size_t entry = 0; entry < thisSection.data.size(); ++entry) {
256 auto& thisEntry = thisSection.data[entry];
257 auto const& otherEntry = otherSection.data[entry];
260 codiAssert(thisEntry.name == otherEntry.name);
261 codiAssert(thisEntry.type == otherEntry.type);
262 codiAssert(thisEntry.operation == otherEntry.operation);
264 switch (thisEntry.type) {
265 case EntryType::Double: {
266 performLocalReduction(this->doubleData[thisEntry.pos], other.doubleData[otherEntry.pos],
267 thisEntry.operation);
270 case EntryType::Long: {
271 performLocalReduction(this->longData[thisEntry.pos], other.longData[otherEntry.pos],
272 thisEntry.operation);
275 case EntryType::UnsignedLong: {
276 performLocalReduction(this->unsignedLongData[thisEntry.pos], other.unsignedLongData[otherEntry.pos],
277 thisEntry.operation);
298 MPI_Allreduce(MPI_IN_PLACE, doubleData.data(), doubleData.size(), MPI_DOUBLE, MPI_SUM, communicator);
299 MPI_Allreduce(MPI_IN_PLACE, longData.data(), longData.size(), MPI_LONG, MPI_SUM, communicator);
300 MPI_Allreduce(MPI_IN_PLACE, unsignedLongData.data(), unsignedLongData.size(), MPI_UNSIGNED_LONG, MPI_SUM,
304 template<
typename Comm>
312 return doubleData[allocatedMemoryIndex];
317 return doubleData[usedMemoryIndex];
322 if (this->sections.size() != other.sections.size() || this->doubleData.size() != other.doubleData.size() ||
323 this->longData.size() != other.longData.size() ||
324 this->unsignedLongData.size() != other.unsignedLongData.size()) {
325 CODI_EXCEPTION(
"Tape values have not the same number of entries.");
329 for (
size_t i = 0; i < result.doubleData.size(); i += 1) {
330 result.doubleData[i] -= other.doubleData[i];
332 for (
size_t i = 0; i < result.longData.size(); i += 1) {
333 result.longData[i] -= other.longData[i];
335 for (
size_t i = 0; i < result.unsignedLongData.size(); i += 1) {
336 result.unsignedLongData[i] -= other.unsignedLongData[i];
347 void performLocalReduction(T& lhs, T
const& rhs, LocalReductionOperation operation) {
349 case LocalReductionOperation::Sum: {
353 case LocalReductionOperation::Max: {
354 lhs = std::max(lhs, rhs);
361 void addEntryInternal(std::string
const& name, EntryType
const& type, LocalReductionOperation
const& operation,
362 std::vector<T>& vector, T
const& value) {
363 size_t entryPos = vector.size();
364 vector.push_back(value);
366 if (sections.empty()) {
370 sections.back().data.push_back(Entry(name, type, operation, entryPos));
373 std::string formatEntry(Entry
const& entry,
int maximumFieldSize)
const {
374 return formatEntryFull(entry,
true, maximumFieldSize);
377 std::string formatEntryFull(Entry
const& entry,
bool outputType,
int maximumFieldSize)
const {
378 std::stringstream ss;
380 switch (entry.type) {
381 case EntryType::Double: {
382 double formattedData = doubleData[entry.pos];
383 std::string typeString =
"";
386 formatSizeHumanReadable(formattedData, typeString);
388 ss << std::right << std::setiosflags(std::ios::fixed) << std::setprecision(2) << std::setw(maximumFieldSize)
389 << formattedData << typeString;
391 case EntryType::Long:
392 ss << std::right << std::setw(maximumFieldSize) << longData[entry.pos];
394 case EntryType::UnsignedLong:
395 ss << std::right << std::setw(maximumFieldSize) << unsignedLongData[entry.pos];
398 CODI_EXCEPTION(
"Unimplemented switch case.");
405 size_t formatEntryLength(Entry
const& entry)
const {
406 return formatEntryFull(entry,
false, 0).size();
409 void formatSizeHumanReadable(
double& size, std::string& type)
const {
410 char const*
const typeList[] = {
"B",
"KB",
"MB",
"GB",
"TB"};
411 size_t typeListSize =
sizeof(typeList) /
sizeof(typeList[0]);
414 while (pos < typeListSize && size > 1024.0) {
420 type += typeList[pos];
423 size_t getMaximumNameLength()
const {
424 size_t maxLength = 0;
425 for (Section
const& section : sections) {
426 for (Entry
const& data : section.data) {
427 maxLength = std::max(maxLength, data.name.size());
434 size_t getMaximumValueLength()
const {
435 size_t maxLength = 0;
436 for (Section
const& section : sections) {
437 for (Entry
const& data : section.data) {
438 maxLength = std::max(maxLength, formatEntryLength(data));
void addDoubleEntry(std::string const &name, double const &value, LocalReductionOperation operation=LocalReductionOperation::Sum, bool usedMem=false, bool allocatedMem=false)
Add double entry. If it is a memory entry, it should be in bytes.
Definition tapeValues.hpp:137