LCOV - code coverage report
Current view: top level - src/Tools/Reporter/Probe - Reporter_probe.cpp (source / functions) Hit Total Coverage
Test: streampu_clean.info Lines: 183 280 65.4 %
Date: 2025-04-07 19:44:34 Functions: 22 32 68.8 %

          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 : }

Generated by: LCOV version 1.14