Files
openvino/samples/cpp/benchmark_app/statistics_report.cpp

148 lines
5.4 KiB
C++
Raw Normal View History

// Copyright (C) 2018-2021 Intel Corporation
2019-04-12 18:25:53 +03:00
// SPDX-License-Identifier: Apache-2.0
//
// clang-format off
#include <algorithm>
#include <map>
2019-04-12 18:25:53 +03:00
#include <string>
#include <utility>
#include <vector>
2019-04-12 18:25:53 +03:00
#include "statistics_report.hpp"
// clang-format on
void StatisticsReport::addParameters(const Category& category, const Parameters& parameters) {
2019-10-04 19:26:43 +03:00
if (_parameters.count(category) == 0)
_parameters[category] = parameters;
else
_parameters[category].insert(_parameters[category].end(), parameters.begin(), parameters.end());
2019-04-12 18:25:53 +03:00
}
2019-10-04 19:26:43 +03:00
void StatisticsReport::dump() {
CsvDumper dumper(true, _config.report_folder + _separator + "benchmark_report.csv");
2019-08-09 19:02:42 +03:00
auto dump_parameters = [&dumper](const Parameters& parameters) {
2019-10-04 19:26:43 +03:00
for (auto& parameter : parameters) {
dumper << parameter.first << parameter.second;
dumper.endLine();
}
};
if (_parameters.count(Category::COMMAND_LINE_PARAMETERS)) {
dumper << "Command line parameters";
dumper.endLine();
2019-04-12 18:25:53 +03:00
2019-10-04 19:26:43 +03:00
dump_parameters(_parameters.at(Category::COMMAND_LINE_PARAMETERS));
dumper.endLine();
2019-04-12 18:25:53 +03:00
}
2019-10-04 19:26:43 +03:00
if (_parameters.count(Category::RUNTIME_CONFIG)) {
dumper << "Configuration setup";
2019-04-12 18:25:53 +03:00
dumper.endLine();
2019-10-04 19:26:43 +03:00
dump_parameters(_parameters.at(Category::RUNTIME_CONFIG));
2019-04-12 18:25:53 +03:00
dumper.endLine();
}
2019-10-04 19:26:43 +03:00
if (_parameters.count(Category::EXECUTION_RESULTS)) {
dumper << "Execution results";
dumper.endLine();
2019-04-12 18:25:53 +03:00
2019-10-04 19:26:43 +03:00
dump_parameters(_parameters.at(Category::EXECUTION_RESULTS));
2019-04-12 18:25:53 +03:00
dumper.endLine();
}
2019-10-04 19:26:43 +03:00
slog::info << "Statistics report is stored to " << dumper.getFilename() << slog::endl;
2019-04-12 18:25:53 +03:00
}
void StatisticsReport::dumpPerformanceCountersRequest(CsvDumper& dumper, const PerformaceCounters& perfCounts) {
std::chrono::microseconds total = std::chrono::microseconds::zero();
std::chrono::microseconds total_cpu = std::chrono::microseconds::zero();
2019-10-04 19:26:43 +03:00
dumper << "layerName"
<< "execStatus"
<< "layerType"
<< "execType";
dumper << "realTime (ms)"
<< "cpuTime (ms)";
2019-10-04 19:26:43 +03:00
dumper.endLine();
2019-04-12 18:25:53 +03:00
for (const auto& layer : perfCounts) {
dumper << layer.node_name; // layer name
2019-10-04 19:26:43 +03:00
switch (layer.status) {
case ov::runtime::ProfilingInfo::Status::EXECUTED:
dumper << "EXECUTED";
break;
case ov::runtime::ProfilingInfo::Status::NOT_RUN:
dumper << "NOT_RUN";
break;
case ov::runtime::ProfilingInfo::Status::OPTIMIZED_OUT:
dumper << "OPTIMIZED_OUT";
break;
2019-04-12 18:25:53 +03:00
}
dumper << layer.node_type << layer.exec_type;
dumper << std::to_string(layer.real_time.count() / 1000.0) << std::to_string(layer.cpu_time.count() / 1000.0);
total += layer.real_time;
total_cpu += layer.cpu_time;
2019-10-04 19:26:43 +03:00
dumper.endLine();
2019-04-12 18:25:53 +03:00
}
dumper << "Total"
<< ""
<< ""
<< "";
dumper << total.count() / 1000.0 << total_cpu.count() / 1000.0;
2019-10-04 19:26:43 +03:00
dumper.endLine();
dumper.endLine();
2019-04-12 18:25:53 +03:00
}
void StatisticsReport::dumpPerformanceCounters(const std::vector<PerformaceCounters>& perfCounts) {
2019-10-04 19:26:43 +03:00
if ((_config.report_type.empty()) || (_config.report_type == noCntReport)) {
slog::info << "Statistics collecting for performance counters was not "
"requested. No reports are dumped."
<< slog::endl;
2019-10-04 19:26:43 +03:00
return;
}
if (perfCounts.empty()) {
slog::info << "Performance counters are empty. No reports are dumped." << slog::endl;
2019-10-04 19:26:43 +03:00
return;
}
CsvDumper dumper(true, _config.report_folder + _separator + "benchmark_" + _config.report_type + "_report.csv");
if (_config.report_type == detailedCntReport) {
for (auto& pc : perfCounts) {
dumpPerformanceCountersRequest(dumper, pc);
}
} else if (_config.report_type == averageCntReport) {
auto getAveragePerformanceCounters = [&perfCounts]() {
std::vector<ov::runtime::ProfilingInfo> performanceCountersAvg;
2019-10-04 19:26:43 +03:00
// iterate over each processed infer request and handle its PM data
for (size_t i = 0; i < perfCounts.size(); i++) {
// iterate over each layer from sorted vector and add required PM data
// to the per-layer maps
for (const auto& pm : perfCounts[i]) {
int idx = 0;
for (; idx < performanceCountersAvg.size(); idx++) {
if (performanceCountersAvg[idx].node_name == pm.node_name) {
performanceCountersAvg[idx].real_time += pm.real_time;
performanceCountersAvg[idx].cpu_time += pm.cpu_time;
break;
}
}
2022-01-13 22:57:20 +03:00
if (idx == performanceCountersAvg.size()) {
performanceCountersAvg.push_back(pm);
2019-10-04 19:26:43 +03:00
}
}
}
for (auto& pm : performanceCountersAvg) {
pm.real_time /= perfCounts.size();
pm.cpu_time /= perfCounts.size();
2019-10-04 19:26:43 +03:00
}
return performanceCountersAvg;
};
dumpPerformanceCountersRequest(dumper, getAveragePerformanceCounters());
} else {
throw std::logic_error("PM data can only be collected for average or detailed report types");
}
2021-02-16 13:08:54 +09:00
slog::info << "Performance counters report is stored to " << dumper.getFilename() << slog::endl;
2019-04-12 18:25:53 +03:00
}