Line data Source code
1 : #include <iomanip>
2 : #include <sstream>
3 : #include <utility>
4 :
5 : #include "Module/Stateful/Probe/Probe.hpp"
6 :
7 : #include "Tools/Reporter/Probe/Reporter_probe.hpp"
8 :
9 : using namespace spu;
10 : using namespace spu::tools;
11 :
12 56 : Reporter_probe::Reporter_probe(const std::string& group_name, const std::string& group_description)
13 : : Reporter()
14 : , Interface_get_set_n_frames()
15 56 : , n_frames(1)
16 56 : , mtx(100)
17 : {
18 56 : if (group_name.empty())
19 : {
20 0 : std::stringstream message;
21 0 : message << "'group_name' can't be empty.";
22 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
23 0 : }
24 :
25 56 : this->cols_groups.push_back(
26 112 : std::make_pair(std::make_tuple(group_name, group_description, 0), std::vector<Reporter::title_t>()));
27 56 : }
28 :
29 14 : Reporter_probe::Reporter_probe(const std::string& group_name)
30 14 : : Reporter_probe(group_name, "")
31 : {
32 14 : }
33 :
34 : void
35 1729 : Reporter_probe::probe(const module::AProbe& probe, const void* data, const size_t /*frame_id*/)
36 : {
37 1729 : std::string col_name = probe.get_col_name();
38 1729 : const int col = this->name_to_col[col_name];
39 : // bool can_push = false;
40 1729 : if (this->datatypes[col] == typeid(double))
41 266 : this->push<double>(col, (double*)data);
42 1463 : else if (this->datatypes[col] == typeid(float))
43 0 : this->push<float>(col, (float*)data);
44 1463 : else if (this->datatypes[col] == typeid(int64_t))
45 399 : this->push<int64_t>(col, (int64_t*)data);
46 1064 : else if (this->datatypes[col] == typeid(uint64_t))
47 798 : this->push<uint64_t>(col, (uint64_t*)data);
48 266 : else if (this->datatypes[col] == typeid(int32_t))
49 0 : this->push<int32_t>(col, (int32_t*)data);
50 266 : else if (this->datatypes[col] == typeid(uint32_t))
51 133 : this->push<uint32_t>(col, (uint32_t*)data);
52 133 : else if (this->datatypes[col] == typeid(int16_t))
53 0 : this->push<int16_t>(col, (int16_t*)data);
54 133 : else if (this->datatypes[col] == typeid(uint16_t))
55 0 : this->push<uint16_t>(col, (uint16_t*)data);
56 133 : else if (this->datatypes[col] == typeid(int8_t))
57 0 : this->push<int8_t>(col, (int8_t*)data);
58 133 : else if (this->datatypes[col] == typeid(uint8_t))
59 133 : this->push<uint8_t>(col, (uint8_t*)data);
60 : else
61 : {
62 0 : std::stringstream message;
63 0 : message << "Unsupported type.";
64 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
65 0 : }
66 1729 : }
67 :
68 : void
69 0 : Reporter_probe::reset()
70 : {
71 0 : std::fill(this->head.begin(), this->head.end(), 0);
72 0 : std::fill(this->tail.begin(), this->tail.end(), 0);
73 0 : for (size_t p = 0; p < this->probes.size(); p++)
74 0 : this->probes[p]->reset();
75 0 : }
76 :
77 : template<typename T>
78 : bool
79 1911 : Reporter_probe::format_values(const int col, std::stringstream& temp_stream)
80 : {
81 1911 : std::vector<T> buff(this->data_sizes[col]);
82 1911 : const auto can_pull = this->pull<T>(col, buff.data());
83 1911 : if (this->display_as_str[col])
84 : {
85 0 : for (const auto& v : buff)
86 0 : temp_stream.write(reinterpret_cast<const char*>(&v), sizeof(T));
87 : }
88 : else
89 : {
90 1911 : if (this->data_sizes[col] > 1 && can_pull) temp_stream << "[";
91 275891 : for (size_t v = 0; v < this->data_sizes[col] && can_pull; v++)
92 : {
93 547960 : const std::string s = std::string((v != 0) ? ", " : "") + std::string((buff[v] >= 0) ? " " : "");
94 273980 : temp_stream << std::setprecision(this->precisions[col]) << s << +buff[v];
95 : }
96 1911 : if (this->data_sizes[col] > 1 && can_pull) temp_stream << "]";
97 : }
98 1911 : return can_pull;
99 1911 : }
100 :
101 : Reporter::report_t
102 468 : Reporter_probe::report(bool final)
103 : {
104 468 : if (this->cols_groups[0].second.size() == 0)
105 : {
106 0 : std::stringstream message;
107 0 : message << "'cols_groups[0].second.size()' has to be greater than 0 ('cols_groups[0].second.size()' = "
108 0 : << this->cols_groups[0].second.size() << ").";
109 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
110 0 : }
111 :
112 468 : Reporter::report_t the_report(this->cols_groups.size());
113 468 : auto& probe_report = the_report[0];
114 468 : if (final)
115 : {
116 : bool can_pull;
117 56 : do
118 : {
119 56 : can_pull = false;
120 56 : std::vector<std::stringstream> streams(this->buffer.size());
121 238 : for (size_t col = 0; col < this->buffer.size(); col++)
122 : {
123 182 : std::stringstream temp_stream;
124 182 : temp_stream.flags(this->format_flags[col]);
125 182 : bool c_pull = false;
126 182 : if (this->datatypes[col] == typeid(double))
127 28 : c_pull = format_values<double>(col, temp_stream);
128 154 : else if (this->datatypes[col] == typeid(float))
129 0 : c_pull = format_values<float>(col, temp_stream);
130 154 : else if (this->datatypes[col] == typeid(int64_t))
131 42 : c_pull = format_values<int64_t>(col, temp_stream);
132 112 : else if (this->datatypes[col] == typeid(uint64_t))
133 84 : c_pull = format_values<uint64_t>(col, temp_stream);
134 28 : else if (this->datatypes[col] == typeid(int32_t))
135 0 : c_pull = format_values<int32_t>(col, temp_stream);
136 28 : else if (this->datatypes[col] == typeid(uint32_t))
137 14 : c_pull = format_values<uint32_t>(col, temp_stream);
138 14 : else if (this->datatypes[col] == typeid(int16_t))
139 0 : c_pull = format_values<int16_t>(col, temp_stream);
140 14 : else if (this->datatypes[col] == typeid(uint16_t))
141 0 : c_pull = format_values<uint16_t>(col, temp_stream);
142 14 : else if (this->datatypes[col] == typeid(int8_t))
143 0 : c_pull = format_values<int8_t>(col, temp_stream);
144 14 : else if (this->datatypes[col] == typeid(uint8_t))
145 14 : c_pull = format_values<uint8_t>(col, temp_stream);
146 : else
147 : {
148 0 : std::stringstream message;
149 0 : message << "Unsupported type.";
150 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
151 0 : }
152 :
153 182 : streams[col] << std::setprecision(this->precisions[col] + 1) << temp_stream.str();
154 :
155 182 : can_pull = can_pull || c_pull;
156 182 : }
157 :
158 56 : if (can_pull)
159 0 : for (auto& s : streams)
160 0 : probe_report.push_back(s.str());
161 56 : } while (can_pull);
162 :
163 56 : return the_report;
164 : }
165 : else
166 : {
167 944 : for (size_t f = 0; f < this->get_n_frames(); f++)
168 : {
169 2261 : for (size_t col = 0; col < this->buffer.size(); col++)
170 : {
171 1729 : std::stringstream stream, temp_stream;
172 1729 : temp_stream.flags(this->format_flags[col]);
173 1729 : if (this->datatypes[col] == typeid(double))
174 266 : format_values<double>(col, temp_stream);
175 1463 : else if (this->datatypes[col] == typeid(float))
176 0 : format_values<float>(col, temp_stream);
177 1463 : else if (this->datatypes[col] == typeid(int64_t))
178 399 : format_values<int64_t>(col, temp_stream);
179 1064 : else if (this->datatypes[col] == typeid(uint64_t))
180 798 : format_values<uint64_t>(col, temp_stream);
181 266 : else if (this->datatypes[col] == typeid(int32_t))
182 0 : format_values<int32_t>(col, temp_stream);
183 266 : else if (this->datatypes[col] == typeid(uint32_t))
184 133 : format_values<uint32_t>(col, temp_stream);
185 133 : else if (this->datatypes[col] == typeid(int16_t))
186 0 : format_values<int16_t>(col, temp_stream);
187 133 : else if (this->datatypes[col] == typeid(uint16_t))
188 0 : format_values<uint16_t>(col, temp_stream);
189 133 : else if (this->datatypes[col] == typeid(int8_t))
190 0 : format_values<int8_t>(col, temp_stream);
191 133 : else if (this->datatypes[col] == typeid(uint8_t))
192 133 : format_values<uint8_t>(col, temp_stream);
193 : else
194 : {
195 0 : std::stringstream message;
196 0 : message << "Unsupported type.";
197 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
198 0 : }
199 :
200 1729 : stream << std::setprecision(this->precisions[col] + 1) << temp_stream.str();
201 1729 : probe_report.push_back(stream.str());
202 1729 : }
203 : }
204 :
205 412 : return the_report;
206 : }
207 0 : }
208 :
209 : size_t
210 468 : B_from_datatype(const std::type_index& type)
211 : {
212 468 : if (type == typeid(double)) return 8;
213 396 : if (type == typeid(float)) return 4;
214 396 : if (type == typeid(int64_t)) return 8;
215 288 : if (type == typeid(uint64_t)) return 8;
216 72 : if (type == typeid(int32_t)) return 4;
217 72 : if (type == typeid(uint32_t)) return 4;
218 36 : if (type == typeid(int16_t)) return 2;
219 36 : if (type == typeid(uint16_t)) return 2;
220 36 : if (type == typeid(int8_t)) return 1;
221 36 : if (type == typeid(uint8_t)) return 1;
222 :
223 0 : std::stringstream message;
224 0 : message << "Unsupported type.";
225 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
226 0 : }
227 :
228 : void
229 0 : Reporter_probe::create_probe_checks(const std::string& name)
230 : {
231 0 : if (name_to_col.count(name))
232 : {
233 0 : std::stringstream message;
234 0 : message << "'name' already exist in this reporter ('name' = " << name << ").";
235 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
236 0 : }
237 :
238 0 : if (this->buffer.size() > 100)
239 : {
240 0 : std::stringstream message;
241 0 : message << "'buffer.size()' has to be smaller than 'mtx.size()' ('buffer.size()' = " << this->buffer.size()
242 0 : << ", 'mtx.size()' = " << this->mtx.size() << ").";
243 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
244 0 : }
245 0 : }
246 :
247 : void
248 182 : Reporter_probe::register_probe(module::AProbe& probe,
249 : const size_t data_size,
250 : const std::type_index data_type,
251 : const std::string& unit,
252 : const size_t buffer_size,
253 : const std::ios_base::fmtflags ff,
254 : const size_t precision)
255 : {
256 182 : if (probe.get_col_name().empty())
257 : {
258 0 : std::stringstream message;
259 0 : message << "'probe->get_col_name()' cannot be empty.";
260 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
261 0 : }
262 :
263 182 : if (buffer_size == 0)
264 : {
265 0 : std::stringstream message;
266 0 : message << "'buffer_size' has to be higher than 0.";
267 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
268 0 : }
269 :
270 462 : for (auto p : this->probes)
271 280 : if (p == &probe)
272 : {
273 0 : std::stringstream message;
274 : message << "'probe' has already been registered to this reporter ('probe.get_col_name()' = "
275 0 : << probe.get_col_name() << ").";
276 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
277 0 : }
278 :
279 182 : probe.set_n_frames(this->get_n_frames());
280 182 : this->probes.push_back(&probe);
281 182 : this->head.push_back(0);
282 182 : this->tail.push_back(0);
283 364 : this->buffer.push_back(std::vector<std::vector<int8_t>>(
284 364 : this->get_n_frames() * buffer_size, std::vector<int8_t>(data_size * B_from_datatype(data_type))));
285 182 : this->datatypes.push_back(data_type);
286 182 : this->format_flags.push_back(ff);
287 182 : this->precisions.push_back(precision);
288 182 : this->data_sizes.push_back(data_size);
289 182 : this->cols_groups[0].second.push_back(std::make_tuple(probe.get_col_name(), unit, 0));
290 182 : this->name_to_col[probe.get_col_name()] = this->buffer.size() - 1;
291 182 : this->col_to_name[this->buffer.size() - 1] = probe.get_col_name();
292 182 : this->display_as_str.push_back(probe.get_str_display());
293 182 : size_t col_size = probe.get_col_name().length() + 2; // Column header
294 182 : if (probe.get_str_display()) col_size = std::max(col_size, data_size + 2);
295 182 : probe.set_col_size(col_size);
296 182 : }
297 :
298 : void
299 104 : Reporter_probe::set_n_frames(const size_t n_frames)
300 : {
301 104 : const size_t old_n_frames = this->get_n_frames();
302 104 : if (n_frames != old_n_frames)
303 : {
304 32 : this->n_frames = n_frames;
305 136 : for (size_t p = 0; p < this->probes.size(); p++)
306 : {
307 104 : this->probes[p]->set_n_frames(n_frames);
308 104 : auto buffer_size = this->buffer[p].size() / old_n_frames;
309 208 : this->buffer[p].resize(n_frames * buffer_size,
310 208 : std::vector<int8_t>(this->data_sizes[p] * B_from_datatype(this->datatypes[p])));
311 : }
312 : }
313 104 : }
314 :
315 : size_t
316 1594 : Reporter_probe::get_n_frames() const
317 : {
318 1594 : return this->n_frames;
319 : }
320 :
321 : size_t
322 630 : Reporter_probe::get_probe_index(const module::AProbe& prb)
323 : {
324 1708 : for (size_t p = 0; p < probes.size(); p++)
325 1708 : if (probes[p] == &prb) return p;
326 :
327 0 : std::stringstream message;
328 0 : message << "Current probe is not contained in the reporter ('prb.get_name()' = " << prb.get_name()
329 0 : << ", 'Reporter_probe.name' = " << std::get<0>(this->cols_groups[0].first) << ").";
330 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
331 0 : }
332 :
333 : void
334 98 : Reporter_probe::set_col_unit(const std::string& unit, const module::AProbe& prb)
335 : {
336 98 : size_t p = this->get_probe_index(prb);
337 98 : std::string name = std::get<0>(this->cols_groups[0].second[p]);
338 98 : size_t col_size = std::get<2>(this->cols_groups[0].second[p]);
339 98 : this->cols_groups[0].second[p] = std::make_tuple(name, unit, col_size);
340 98 : }
341 :
342 : void
343 14 : Reporter_probe::set_cols_unit(const std::string& unit)
344 : {
345 98 : for (auto& p : this->probes)
346 84 : this->set_col_unit(unit, *p);
347 14 : }
348 :
349 : void
350 182 : Reporter_probe::set_col_buff_size(const size_t buffer_size, const module::AProbe& prb)
351 : {
352 182 : size_t p = this->get_probe_index(prb);
353 364 : this->buffer[p].resize(this->get_n_frames() * buffer_size,
354 364 : std::vector<int8_t>(this->data_sizes[p] * B_from_datatype(this->datatypes[p])));
355 182 : }
356 :
357 : void
358 56 : Reporter_probe::set_cols_buff_size(const size_t buffer_size)
359 : {
360 238 : for (auto& p : this->probes)
361 182 : this->set_col_buff_size(buffer_size, *p);
362 56 : }
363 :
364 : void
365 0 : Reporter_probe::set_col_fmtflags(const std::ios_base::fmtflags ff, const module::AProbe& prb)
366 : {
367 0 : size_t p = this->get_probe_index(prb);
368 0 : this->format_flags[p] = ff;
369 0 : }
370 :
371 : void
372 0 : Reporter_probe::set_cols_fmtflags(const std::ios_base::fmtflags ff)
373 : {
374 0 : for (auto& p : this->probes)
375 0 : this->set_col_fmtflags(ff, *p);
376 0 : }
377 :
378 : void
379 14 : Reporter_probe::set_col_prec(const size_t precision, const module::AProbe& prb)
380 : {
381 14 : size_t p = this->get_probe_index(prb);
382 14 : this->precisions[p] = precision;
383 14 : }
384 :
385 : void
386 0 : Reporter_probe::set_cols_prec(const size_t precision)
387 : {
388 0 : for (auto& p : this->probes)
389 0 : this->set_col_prec(precision, *p);
390 0 : }
391 :
392 : void
393 336 : Reporter_probe::set_col_size(const size_t col_size, const module::AProbe& prb)
394 : {
395 336 : size_t p = this->get_probe_index(prb);
396 336 : std::string name = std::get<0>(this->cols_groups[0].second[p]);
397 336 : std::string unit = std::get<1>(this->cols_groups[0].second[p]);
398 336 : this->cols_groups[0].second[p] = std::make_tuple(name, unit, col_size);
399 336 : }
400 :
401 : void
402 14 : Reporter_probe::set_cols_size(const size_t col_size)
403 : {
404 98 : for (auto& p : this->probes)
405 84 : this->set_col_size(col_size, *p);
406 14 : }
407 :
408 : void
409 56 : Reporter_probe::register_probes(const std::vector<module::AProbe*>& probes)
410 : {
411 238 : for (auto p : probes)
412 : {
413 182 : if (p == nullptr)
414 : {
415 0 : std::stringstream message;
416 0 : message << "'p' cannot be nullptr.";
417 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
418 0 : }
419 182 : p->register_reporter(this);
420 : }
421 56 : }
|