Project
Loading...
Searching...
No Matches
ResourcesMonitoringHelper.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
13#include <rapidjson/prettywriter.h>
14#include <rapidjson/ostreamwrapper.h>
15
16#include <ostream>
17#include <string>
18#include <string_view>
19#include <algorithm>
20#include <cassert>
21#include <regex>
22
23using namespace o2::framework;
24
25template <typename T>
26void fillNodeWithValue(rapidjson::Writer<rapidjson::OStreamWrapper>& w,
27 size_t filledMetrics,
28 MetricsStorage<T> const& metricsStorage,
29 TimestampsStorage<T> const& timestampsStorage)
30{
31 unsigned int loopRange = std::min(filledMetrics, metricsStorage.size());
32
33 w.StartArray();
34 for (unsigned int idx = 0; idx < loopRange; ++idx) {
35 w.StartObject();
36 w.Key("timestamp");
37 std::string s = std::to_string(timestampsStorage[idx]);
38 w.String(s.c_str(), s.size());
39 w.Key("value");
40 if constexpr (std::is_arithmetic_v<T>) {
41 w.String(std::to_string(metricsStorage[idx]).c_str());
42 } else {
43 w.String(metricsStorage[idx].data);
44 }
45 w.EndObject();
46 }
47 w.EndArray();
48}
49
50bool ResourcesMonitoringHelper::dumpMetricsToJSON(const std::vector<DeviceMetricsInfo>& metrics,
51 const DeviceMetricsInfo& driverMetrics,
52 const std::vector<DeviceSpec>& specs,
53 std::vector<std::regex> const& performanceMetricsRegex,
54 std::ostream& out) noexcept
55{
56 assert(metrics.size() == specs.size());
57
58 if (metrics.empty()) {
59 return false;
60 }
61
62 rapidjson::OStreamWrapper osw(out);
63 rapidjson::PrettyWriter<rapidjson::OStreamWrapper> w(osw);
64
65 // Top level obejct for all the metrics
66 w.StartObject();
67
68 for (unsigned int idx = 0; idx < metrics.size(); ++idx) {
69 w.Key(specs[idx].id.c_str());
70 const auto& deviceMetrics = metrics[idx];
71
72 w.StartObject();
73 for (size_t mi = 0; mi < deviceMetrics.metricLabels.size(); mi++) {
74 std::string_view metricLabel{deviceMetrics.metricLabels[mi].label, deviceMetrics.metricLabels[mi].size};
75
76 auto same = [metricLabel](std::regex const& matcher) -> bool {
77 return std::regex_match(metricLabel.begin(), metricLabel.end(), matcher);
78 };
79 // check if we are interested
80 if (std::find_if(std::begin(performanceMetricsRegex), std::end(performanceMetricsRegex), same) == performanceMetricsRegex.end()) {
81 continue;
82 }
83 auto storeIdx = deviceMetrics.metrics[mi].storeIdx;
84
85 size_t filledMetrics = deviceMetrics.metrics[mi].filledMetrics;
86 if (deviceMetrics.metrics[mi].filledMetrics == 0) {
87 continue;
88 }
89 w.Key(metricLabel.data(), metricLabel.size());
90 switch (deviceMetrics.metrics[mi].type) {
91 case MetricType::Int:
92 fillNodeWithValue(w, filledMetrics, deviceMetrics.intMetrics[storeIdx],
93 deviceMetrics.intTimestamps[storeIdx]);
94 break;
95
96 case MetricType::Float:
97 fillNodeWithValue(w, filledMetrics, deviceMetrics.floatMetrics[storeIdx],
98 deviceMetrics.floatTimestamps[storeIdx]);
99 break;
100
101 case MetricType::String:
102 fillNodeWithValue(w, filledMetrics, deviceMetrics.stringMetrics[storeIdx],
103 deviceMetrics.stringTimestamps[storeIdx]);
104 break;
105
106 case MetricType::Uint64:
107 fillNodeWithValue(w, filledMetrics, deviceMetrics.uint64Metrics[storeIdx],
108 deviceMetrics.uint64Timestamps[storeIdx]);
109 break;
110
111 default:
112 continue;
113 }
114 }
115
116 w.EndObject();
117 }
118
119 w.Key("driver");
120 w.StartObject();
121 for (size_t mi = 0; mi < driverMetrics.metricLabels.size(); mi++) {
122 std::string_view const metricLabel{driverMetrics.metricLabels[mi].label, driverMetrics.metricLabels[mi].size};
123 auto same = [metricLabel](std::regex const& matcher) -> bool {
124 return std::regex_match(metricLabel.begin(), metricLabel.end(), matcher);
125 };
126
127 // check if we are interested
128 if (std::find_if(std::begin(performanceMetricsRegex), std::end(performanceMetricsRegex), same) == performanceMetricsRegex.end()) {
129 continue;
130 }
131
132 auto storeIdx = driverMetrics.metrics[mi].storeIdx;
133 // and if data is there
134 size_t filledMetrics = driverMetrics.metrics[mi].filledMetrics;
135 if (filledMetrics == 0) {
136 continue;
137 }
138
139 w.Key(metricLabel.data(), metricLabel.size());
140 switch (driverMetrics.metrics[mi].type) {
141 case MetricType::Int:
142 fillNodeWithValue(w, filledMetrics, driverMetrics.intMetrics[storeIdx],
143 driverMetrics.intTimestamps[storeIdx]);
144 break;
145
146 case MetricType::Float:
147 fillNodeWithValue(w, filledMetrics, driverMetrics.floatMetrics[storeIdx],
148 driverMetrics.floatTimestamps[storeIdx]);
149 break;
150
151 case MetricType::String:
152 fillNodeWithValue(w, filledMetrics, driverMetrics.stringMetrics[storeIdx],
153 driverMetrics.stringTimestamps[storeIdx]);
154 break;
155
156 case MetricType::Uint64:
157 fillNodeWithValue(w, filledMetrics, driverMetrics.uint64Metrics[storeIdx],
158 driverMetrics.uint64Timestamps[storeIdx]);
159 break;
160
161 default:
162 continue;
163 }
164 }
165 w.EndObject();
166 w.EndObject();
167
168 return true;
169}
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
void fillNodeWithValue(rapidjson::Writer< rapidjson::OStreamWrapper > &w, size_t filledMetrics, MetricsStorage< T > const &metricsStorage, TimestampsStorage< T > const &timestampsStorage)
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
Definition glcorearb.h:5500
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
std::array< size_t, metricStorageSize< T >()> TimestampsStorage
std::array< T, metricStorageSize< T >()> MetricsStorage
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
static bool dumpMetricsToJSON(std::vector< DeviceMetricsInfo > const &metrics, DeviceMetricsInfo const &driverMetrics, std::vector< DeviceSpec > const &specs, std::vector< std::regex > const &metricsToDump, std::ostream &out) noexcept