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->data_sizes[col] > 1 && can_pull) temp_stream << "[";
84 275891 : for (size_t v = 0; v < this->data_sizes[col] && can_pull; v++)
85 : {
86 547960 : const std::string s = std::string((v != 0) ? ", " : "") + std::string((buff[v] >= 0) ? " " : "");
87 273980 : temp_stream << std::setprecision(this->precisions[col]) << s << +buff[v];
88 : }
89 1911 : if (this->data_sizes[col] > 1 && can_pull) temp_stream << "]";
90 1911 : return can_pull;
91 1911 : }
92 :
93 : Reporter::report_t
94 468 : Reporter_probe::report(bool final)
95 : {
96 468 : if (this->cols_groups[0].second.size() == 0)
97 : {
98 0 : std::stringstream message;
99 0 : message << "'cols_groups[0].second.size()' has to be greater than 0 ('cols_groups[0].second.size()' = "
100 0 : << this->cols_groups[0].second.size() << ").";
101 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
102 0 : }
103 :
104 468 : Reporter::report_t the_report(this->cols_groups.size());
105 468 : auto& probe_report = the_report[0];
106 468 : if (final)
107 : {
108 : bool can_pull;
109 56 : do
110 : {
111 56 : can_pull = false;
112 56 : std::vector<std::stringstream> streams(this->buffer.size());
113 238 : for (size_t col = 0; col < this->buffer.size(); col++)
114 : {
115 182 : std::stringstream temp_stream;
116 182 : temp_stream.flags(this->format_flags[col]);
117 182 : bool c_pull = false;
118 182 : if (this->datatypes[col] == typeid(double))
119 28 : c_pull = format_values<double>(col, temp_stream);
120 154 : else if (this->datatypes[col] == typeid(float))
121 0 : c_pull = format_values<float>(col, temp_stream);
122 154 : else if (this->datatypes[col] == typeid(int64_t))
123 42 : c_pull = format_values<int64_t>(col, temp_stream);
124 112 : else if (this->datatypes[col] == typeid(uint64_t))
125 84 : c_pull = format_values<uint64_t>(col, temp_stream);
126 28 : else if (this->datatypes[col] == typeid(int32_t))
127 0 : c_pull = format_values<int32_t>(col, temp_stream);
128 28 : else if (this->datatypes[col] == typeid(uint32_t))
129 14 : c_pull = format_values<uint32_t>(col, temp_stream);
130 14 : else if (this->datatypes[col] == typeid(int16_t))
131 0 : c_pull = format_values<int16_t>(col, temp_stream);
132 14 : else if (this->datatypes[col] == typeid(uint16_t))
133 0 : c_pull = format_values<uint16_t>(col, temp_stream);
134 14 : else if (this->datatypes[col] == typeid(int8_t))
135 0 : c_pull = format_values<int8_t>(col, temp_stream);
136 14 : else if (this->datatypes[col] == typeid(uint8_t))
137 14 : c_pull = format_values<uint8_t>(col, temp_stream);
138 : else
139 : {
140 0 : std::stringstream message;
141 0 : message << "Unsupported type.";
142 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
143 0 : }
144 :
145 182 : streams[col] << std::setprecision(this->precisions[col] + 1) << temp_stream.str();
146 :
147 182 : can_pull = can_pull || c_pull;
148 182 : }
149 :
150 56 : if (can_pull)
151 0 : for (auto& s : streams)
152 0 : probe_report.push_back(s.str());
153 56 : } while (can_pull);
154 :
155 56 : return the_report;
156 : }
157 : else
158 : {
159 944 : for (size_t f = 0; f < this->get_n_frames(); f++)
160 : {
161 2261 : for (size_t col = 0; col < this->buffer.size(); col++)
162 : {
163 1729 : std::stringstream stream, temp_stream;
164 1729 : temp_stream.flags(this->format_flags[col]);
165 1729 : if (this->datatypes[col] == typeid(double))
166 266 : format_values<double>(col, temp_stream);
167 1463 : else if (this->datatypes[col] == typeid(float))
168 0 : format_values<float>(col, temp_stream);
169 1463 : else if (this->datatypes[col] == typeid(int64_t))
170 399 : format_values<int64_t>(col, temp_stream);
171 1064 : else if (this->datatypes[col] == typeid(uint64_t))
172 798 : format_values<uint64_t>(col, temp_stream);
173 266 : else if (this->datatypes[col] == typeid(int32_t))
174 0 : format_values<int32_t>(col, temp_stream);
175 266 : else if (this->datatypes[col] == typeid(uint32_t))
176 133 : format_values<uint32_t>(col, temp_stream);
177 133 : else if (this->datatypes[col] == typeid(int16_t))
178 0 : format_values<int16_t>(col, temp_stream);
179 133 : else if (this->datatypes[col] == typeid(uint16_t))
180 0 : format_values<uint16_t>(col, temp_stream);
181 133 : else if (this->datatypes[col] == typeid(int8_t))
182 0 : format_values<int8_t>(col, temp_stream);
183 133 : else if (this->datatypes[col] == typeid(uint8_t))
184 133 : format_values<uint8_t>(col, temp_stream);
185 : else
186 : {
187 0 : std::stringstream message;
188 0 : message << "Unsupported type.";
189 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
190 0 : }
191 :
192 1729 : stream << std::setprecision(this->precisions[col] + 1) << temp_stream.str();
193 1729 : probe_report.push_back(stream.str());
194 1729 : }
195 : }
196 :
197 412 : return the_report;
198 : }
199 0 : }
200 :
201 : size_t
202 468 : B_from_datatype(const std::type_index& type)
203 : {
204 468 : if (type == typeid(double)) return 8;
205 396 : if (type == typeid(float)) return 4;
206 396 : if (type == typeid(int64_t)) return 8;
207 288 : if (type == typeid(uint64_t)) return 8;
208 72 : if (type == typeid(int32_t)) return 4;
209 72 : if (type == typeid(uint32_t)) return 4;
210 36 : if (type == typeid(int16_t)) return 2;
211 36 : if (type == typeid(uint16_t)) return 2;
212 36 : if (type == typeid(int8_t)) return 1;
213 36 : if (type == typeid(uint8_t)) return 1;
214 :
215 0 : std::stringstream message;
216 0 : message << "Unsupported type.";
217 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
218 0 : }
219 :
220 : void
221 0 : Reporter_probe::create_probe_checks(const std::string& name)
222 : {
223 0 : if (name_to_col.count(name))
224 : {
225 0 : std::stringstream message;
226 0 : message << "'name' already exist in this reporter ('name' = " << name << ").";
227 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
228 0 : }
229 :
230 0 : if (this->buffer.size() > 100)
231 : {
232 0 : std::stringstream message;
233 0 : message << "'buffer.size()' has to be smaller than 'mtx.size()' ('buffer.size()' = " << this->buffer.size()
234 0 : << ", 'mtx.size()' = " << this->mtx.size() << ").";
235 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
236 0 : }
237 0 : }
238 :
239 : void
240 182 : Reporter_probe::register_probe(module::AProbe& probe,
241 : const size_t data_size,
242 : const std::type_index data_type,
243 : const std::string& unit,
244 : const size_t buffer_size,
245 : const std::ios_base::fmtflags ff,
246 : const size_t precision)
247 : {
248 182 : if (probe.get_col_name().empty())
249 : {
250 0 : std::stringstream message;
251 0 : message << "'probe->get_col_name()' cannot be empty.";
252 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
253 0 : }
254 :
255 182 : if (buffer_size == 0)
256 : {
257 0 : std::stringstream message;
258 0 : message << "'buffer_size' has to be higher than 0.";
259 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
260 0 : }
261 :
262 462 : for (auto p : this->probes)
263 280 : if (p == &probe)
264 : {
265 0 : std::stringstream message;
266 : message << "'probe' has already been registered to this reporter ('probe.get_col_name()' = "
267 0 : << probe.get_col_name() << ").";
268 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
269 0 : }
270 :
271 182 : probe.set_n_frames(this->get_n_frames());
272 182 : this->probes.push_back(&probe);
273 182 : this->head.push_back(0);
274 182 : this->tail.push_back(0);
275 364 : this->buffer.push_back(std::vector<std::vector<int8_t>>(
276 364 : this->get_n_frames() * buffer_size, std::vector<int8_t>(data_size * B_from_datatype(data_type))));
277 182 : this->datatypes.push_back(data_type);
278 182 : this->format_flags.push_back(ff);
279 182 : this->precisions.push_back(precision);
280 182 : this->data_sizes.push_back(data_size);
281 182 : this->cols_groups[0].second.push_back(std::make_tuple(probe.get_col_name(), unit, 0));
282 182 : this->name_to_col[probe.get_col_name()] = this->buffer.size() - 1;
283 182 : this->col_to_name[this->buffer.size() - 1] = probe.get_col_name();
284 182 : }
285 :
286 : void
287 104 : Reporter_probe::set_n_frames(const size_t n_frames)
288 : {
289 104 : const size_t old_n_frames = this->get_n_frames();
290 104 : if (n_frames != old_n_frames)
291 : {
292 32 : this->n_frames = n_frames;
293 136 : for (size_t p = 0; p < this->probes.size(); p++)
294 : {
295 104 : this->probes[p]->set_n_frames(n_frames);
296 104 : auto buffer_size = this->buffer[p].size() / old_n_frames;
297 208 : this->buffer[p].resize(n_frames * buffer_size,
298 208 : std::vector<int8_t>(this->data_sizes[p] * B_from_datatype(this->datatypes[p])));
299 : }
300 : }
301 104 : }
302 :
303 : size_t
304 1594 : Reporter_probe::get_n_frames() const
305 : {
306 1594 : return this->n_frames;
307 : }
308 :
309 : size_t
310 448 : Reporter_probe::get_probe_index(const module::AProbe& prb)
311 : {
312 1246 : for (size_t p = 0; p < probes.size(); p++)
313 1246 : if (probes[p] == &prb) return p;
314 :
315 0 : std::stringstream message;
316 0 : message << "Current probe is not contained in the reporter ('prb.get_name()' = " << prb.get_name()
317 0 : << ", 'Reporter_probe.name' = " << std::get<0>(this->cols_groups[0].first) << ").";
318 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
319 0 : }
320 :
321 : void
322 98 : Reporter_probe::set_col_unit(const std::string& unit, const module::AProbe& prb)
323 : {
324 98 : size_t p = this->get_probe_index(prb);
325 98 : std::string name = std::get<0>(this->cols_groups[0].second[p]);
326 98 : size_t col_size = std::get<2>(this->cols_groups[0].second[p]);
327 98 : this->cols_groups[0].second[p] = std::make_tuple(name, unit, col_size);
328 98 : }
329 :
330 : void
331 14 : Reporter_probe::set_cols_unit(const std::string& unit)
332 : {
333 98 : for (auto& p : this->probes)
334 84 : this->set_col_unit(unit, *p);
335 14 : }
336 :
337 : void
338 182 : Reporter_probe::set_col_buff_size(const size_t buffer_size, const module::AProbe& prb)
339 : {
340 182 : size_t p = this->get_probe_index(prb);
341 364 : this->buffer[p].resize(this->get_n_frames() * buffer_size,
342 364 : std::vector<int8_t>(this->data_sizes[p] * B_from_datatype(this->datatypes[p])));
343 182 : }
344 :
345 : void
346 56 : Reporter_probe::set_cols_buff_size(const size_t buffer_size)
347 : {
348 238 : for (auto& p : this->probes)
349 182 : this->set_col_buff_size(buffer_size, *p);
350 56 : }
351 :
352 : void
353 0 : Reporter_probe::set_col_fmtflags(const std::ios_base::fmtflags ff, const module::AProbe& prb)
354 : {
355 0 : size_t p = this->get_probe_index(prb);
356 0 : this->format_flags[p] = ff;
357 0 : }
358 :
359 : void
360 0 : Reporter_probe::set_cols_fmtflags(const std::ios_base::fmtflags ff)
361 : {
362 0 : for (auto& p : this->probes)
363 0 : this->set_col_fmtflags(ff, *p);
364 0 : }
365 :
366 : void
367 14 : Reporter_probe::set_col_prec(const size_t precision, const module::AProbe& prb)
368 : {
369 14 : size_t p = this->get_probe_index(prb);
370 14 : this->precisions[p] = precision;
371 14 : }
372 :
373 : void
374 0 : Reporter_probe::set_cols_prec(const size_t precision)
375 : {
376 0 : for (auto& p : this->probes)
377 0 : this->set_col_prec(precision, *p);
378 0 : }
379 :
380 : void
381 154 : Reporter_probe::set_col_size(const size_t col_size, const module::AProbe& prb)
382 : {
383 154 : size_t p = this->get_probe_index(prb);
384 154 : std::string name = std::get<0>(this->cols_groups[0].second[p]);
385 154 : std::string unit = std::get<1>(this->cols_groups[0].second[p]);
386 154 : this->cols_groups[0].second[p] = std::make_tuple(name, unit, col_size);
387 154 : }
388 :
389 : void
390 14 : Reporter_probe::set_cols_size(const size_t col_size)
391 : {
392 98 : for (auto& p : this->probes)
393 84 : this->set_col_size(col_size, *p);
394 14 : }
395 :
396 : void
397 56 : Reporter_probe::register_probes(const std::vector<module::AProbe*>& probes)
398 : {
399 238 : for (auto p : probes)
400 : {
401 182 : if (p == nullptr)
402 : {
403 0 : std::stringstream message;
404 0 : message << "'p' cannot be nullptr.";
405 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
406 0 : }
407 182 : p->register_reporter(this);
408 : }
409 56 : }
|