LCOV - code coverage report
Current view: top level - src/Tools/Display/Statistics - Statistics.cpp (source / functions) Hit Total Coverage
Test: streampu_clean.info Lines: 223 331 67.4 %
Date: 2025-03-14 12:33:06 Functions: 13 25 52.0 %

          Line data    Source code
       1             : #include <algorithm>
       2             : #include <iomanip>
       3             : #include <ios>
       4             : #include <map>
       5             : #include <sstream>
       6             : #include <type_traits>
       7             : 
       8             : #include "Tools/Display/Statistics/Statistics.hpp"
       9             : #include "Tools/Display/rang_format/rang_format.h"
      10             : #include "Tools/Exception/exception.hpp"
      11             : 
      12             : using namespace spu;
      13             : using namespace spu::tools;
      14             : 
      15             : void
      16          84 : Statistics::separation1(const bool display_thr, std::ostream& stream)
      17             : {
      18             :     // clang-format off
      19          84 :     if (display_thr)
      20           0 :         stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------||--------------------------------" << rang::style::reset << std::endl;
      21             :     else
      22          84 :         stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------" << rang::style::reset << std::endl;
      23             :     // clang-format on
      24          84 : }
      25             : 
      26             : void
      27         126 : Statistics::separation2(const bool display_thr, std::ostream& stream)
      28             : {
      29             :     // clang-format off
      30         126 :     if (display_thr)
      31           0 :         stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------||----------|----------|----------" << rang::style::reset << std::endl;
      32             :     else
      33         126 :         stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------" << rang::style::reset << std::endl;
      34             :     // clang-format on
      35         126 : }
      36             : 
      37             : void
      38          42 : Statistics::show_header(const bool display_thr, std::ostream& stream)
      39             : {
      40             :     // clang-format off
      41          42 :     Statistics::separation1(display_thr, stream);
      42          42 :     if (display_thr)
      43             :     {
      44             : //      stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------||--------------------------------" << rang::style::reset << std::endl;
      45           0 :         stream << "# " << rang::style::bold << "                 Statistics for the given task                 ||       Basic statistics       ||       Measured throughput      ||        Measured latency        " << rang::style::reset << std::endl;
      46           0 :         stream << "# " << rang::style::bold << "              ('*' = any, '-' = same as previous)              ||          on the task         ||   considering the last socket  ||                                " << rang::style::reset << std::endl;
      47             : //      stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------||--------------------------------" << rang::style::reset << std::endl;
      48             :     }
      49             :     else
      50             :     {
      51             : //      stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------" << rang::style::reset << std::endl;
      52          42 :         stream << "# " << rang::style::bold << "                 Statistics for the given task                 ||       Basic statistics       ||        Measured latency        " << rang::style::reset << std::endl;
      53          42 :         stream << "# " << rang::style::bold << "              ('*' = any, '-' = same as previous)              ||          on the task         ||                                " << rang::style::reset << std::endl;
      54             : //      stream << "# " << rang::style::bold << "---------------------------------------------------------------||------------------------------||--------------------------------" << rang::style::reset << std::endl;
      55             :     }
      56          42 :     Statistics::separation1(display_thr, stream);
      57          42 :     Statistics::separation2(display_thr, stream);
      58          42 :     if (display_thr)
      59             :     {
      60             : //      stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------||----------|----------|----------" << rang::style::reset << std::endl;
      61           0 :         stream << "# " << rang::style::bold << "       MODULE NAME |         TASK NAME | REP | ORDER |   TIMER ||    CALLS |     TIME |   PERC ||  AVERAGE |  MINIMUM |  MAXIMUM ||  AVERAGE |  MINIMUM |  MAXIMUM " << rang::style::reset << std::endl;
      62           0 :         stream << "# " << rang::style::bold << "                   |                   |     |       |         ||          |      (s) |    (%) ||   (Mb/s) |   (Mb/s) |   (Mb/s) ||     (us) |     (us) |     (us) " << rang::style::reset << std::endl;
      63             : //      stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------||----------|----------|----------" << rang::style::reset << std::endl;
      64             :     }
      65             :     else
      66             :     {
      67             : //      stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------" << rang::style::reset << std::endl;
      68          42 :         stream << "# " << rang::style::bold << "       MODULE NAME |         TASK NAME | REP | ORDER |   TIMER ||    CALLS |     TIME |   PERC ||  AVERAGE |  MINIMUM |  MAXIMUM " << rang::style::reset << std::endl;
      69          42 :         stream << "# " << rang::style::bold << "                   |                   |     |       |         ||          |      (s) |    (%) ||     (us) |     (us) |     (us) " << rang::style::reset << std::endl;
      70             : //      stream << "# " << rang::style::bold << "-------------------|-------------------|-----|-------|---------||----------|----------|--------||----------|----------|----------" << rang::style::reset << std::endl;
      71             :     }
      72          42 :     Statistics::separation2(display_thr, stream);
      73             :     // clang-format on
      74          42 : }
      75             : 
      76             : void
      77         264 : Statistics::show_task(const float total_sec,
      78             :                       const std::string& module_name,
      79             :                       const std::string& task_name,
      80             :                       const bool task_replicability,
      81             :                       const int task_order,
      82             :                       const size_t task_n_elmts,
      83             :                       const uint32_t task_n_calls,
      84             :                       const std::chrono::nanoseconds task_tot_duration,
      85             :                       const std::chrono::nanoseconds task_min_duration,
      86             :                       const std::chrono::nanoseconds task_max_duration,
      87             :                       const bool display_thr,
      88             :                       std::ostream& stream)
      89             : {
      90             :     // clang-format off
      91         264 :     if (task_n_calls == 0)
      92          14 :         return;
      93             : 
      94         250 :     auto tot_dur = ((float)task_tot_duration.count()) * 0.000000001f;
      95         250 :     auto percent = (tot_dur / total_sec) * 100.f;
      96         250 :     auto avg_thr = (float)(task_n_calls * task_n_elmts) / ((float)task_tot_duration.count() * 0.001f);
      97         250 :     auto min_thr = (float)(1.f          * task_n_elmts) / ((float)task_max_duration.count() * 0.001f);
      98         250 :     auto max_thr = (float)(1.f          * task_n_elmts) / ((float)task_min_duration.count() * 0.001f);
      99         250 :     auto avg_lat = (float)(task_tot_duration.count() * 0.001f) / task_n_calls;
     100         250 :     auto min_lat = (float)(task_min_duration.count() * 0.001f);
     101         250 :     auto max_lat = (float)(task_max_duration.count() * 0.001f);
     102             : 
     103             : #ifdef _WIN32
     104             :     auto P = 1;
     105             : #else
     106         250 :     auto P = 2;
     107             : #endif
     108             : 
     109         250 :     unsigned l1 = 99999999;
     110         250 :     float    l2 = 99999.99f;
     111             : 
     112         250 :     std::stringstream ssmodule, ssprocess, ssrep, ssorder, sssp, ssn_calls, sstot_dur, sspercent;
     113         250 :     std::stringstream ssavg_thr, ssmin_thr, ssmax_thr;
     114         250 :     std::stringstream ssavg_lat, ssmin_lat, ssmax_lat;
     115             : 
     116         250 :     ssmodule  << std::setprecision(                        2) <<                                        std::fixed  << std::setw(18) << module_name;
     117         250 :     ssprocess << std::setprecision(                        2) <<                                        std::fixed  << std::setw(17) << task_name;
     118         250 :     ssrep     << std::setprecision(                        2) <<                                        std::fixed  << std::setw( 3) << (task_replicability ? "yes" : "no");
     119         250 :     if (task_order >= 0)
     120         208 :         ssorder << std::setprecision(                      2) <<                                        std::fixed  << std::setw( 5) << task_order;
     121             :     else
     122          42 :         ssorder << std::setprecision(                      2) <<                                        std::fixed  << std::setw( 5) << "*";
     123         250 :     sssp      << std::setprecision(                        2) <<                                        std::fixed  << std::setw( 7) << "*";
     124         250 :     ssn_calls << std::setprecision(task_n_calls > l1 ? P : 2) << (task_n_calls > l1 ? std::scientific : std::fixed) << std::setw( 8) << task_n_calls;
     125         250 :     sstot_dur << std::setprecision(tot_dur      > l1 ? P : 2) << (tot_dur      > l1 ? std::scientific : std::fixed) << std::setw( 8) << tot_dur;
     126         250 :     sspercent << std::setprecision(                        2) <<                                        std::fixed  << std::setw( 6) << percent;
     127         250 :     ssavg_thr << std::setprecision(avg_thr      > l1 ? P : 2) << (avg_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << avg_thr;
     128         250 :     ssmin_thr << std::setprecision(min_thr      > l1 ? P : 2) << (min_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << min_thr;
     129         250 :     ssmax_thr << std::setprecision(max_thr      > l1 ? P : 2) << (max_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << max_thr;
     130         250 :     ssavg_lat << std::setprecision(avg_lat      > l1 ? P : 2) << (avg_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << avg_lat;
     131         250 :     ssmin_lat << std::setprecision(min_lat      > l1 ? P : 2) << (min_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << min_lat;
     132         250 :     ssmax_lat << std::setprecision(max_lat      > l1 ? P : 2) << (max_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << max_lat;
     133             : 
     134         250 :     stream << "# ";
     135         250 :     stream << ssmodule .str() << rang::style::bold << " | "  << rang::style::reset
     136         500 :            << ssprocess.str() << rang::style::bold << " | "  << rang::style::reset
     137         500 :            << ssrep    .str() << rang::style::bold << " | "  << rang::style::reset
     138         500 :            << ssorder  .str() << rang::style::bold << " | "  << rang::style::reset
     139         500 :            << sssp     .str() << rang::style::bold << " || " << rang::style::reset
     140         500 :            << ssn_calls.str() << rang::style::bold << " | "  << rang::style::reset
     141         250 :            << sstot_dur.str() << rang::style::bold << " | "  << rang::style::reset;
     142             : 
     143         250 :          if (percent > 50.0f) stream << rang::fg::red    << sspercent.str() << rang::style::reset;
     144         184 :     else if (percent > 25.0f) stream << rang::fg::yellow << sspercent.str() << rang::style::reset;
     145         155 :     else if (percent > 12.5f) stream << rang::fg::green  << sspercent.str() << rang::style::reset;
     146         116 :     else if (percent <  5.0f) stream << rang::fg::gray   << sspercent.str() << rang::style::reset;
     147          51 :     else                      stream <<                     sspercent.str();
     148             : 
     149         250 :     if (display_thr)
     150           0 :         stream <<                    rang::style::bold << " || " << rang::style::reset
     151           0 :                << ssavg_thr.str() << rang::style::bold << " | "  << rang::style::reset
     152           0 :                << ssmin_thr.str() << rang::style::bold << " | "  << rang::style::reset
     153           0 :                << ssmax_thr.str() << rang::style::bold << " || " << rang::style::reset
     154           0 :                << ssavg_lat.str() << rang::style::bold << " | "  << rang::style::reset
     155           0 :                << ssmin_lat.str() << rang::style::bold << " | "  << rang::style::reset
     156           0 :                << ssmax_lat.str() << ""
     157           0 :                << std::endl;
     158             :     else
     159         250 :         stream <<                    rang::style::bold << " || " << rang::style::reset
     160         500 :                << ssavg_lat.str() << rang::style::bold << " | "  << rang::style::reset
     161         500 :                << ssmin_lat.str() << rang::style::bold << " | "  << rang::style::reset
     162         500 :                << ssmax_lat.str() << ""
     163         250 :                << std::endl;
     164             :     // clang-format on
     165         250 : }
     166             : 
     167             : void
     168           0 : Statistics::show_timer(const float total_sec,
     169             :                        const uint32_t task_n_calls,
     170             :                        const size_t timer_n_elmts,
     171             :                        const std::string& timer_name,
     172             :                        const uint32_t timer_n_calls,
     173             :                        const std::chrono::nanoseconds timer_tot_duration,
     174             :                        const std::chrono::nanoseconds timer_min_duration,
     175             :                        const std::chrono::nanoseconds timer_max_duration,
     176             :                        std::ostream& stream)
     177             : {
     178             :     // clang-format off
     179           0 :     if (task_n_calls == 0 || timer_n_calls == 0)
     180           0 :         return;
     181             : 
     182           0 :     auto rn_elmts = (timer_n_elmts * task_n_calls) / timer_n_calls;
     183           0 :     auto rtot_dur = ((float)timer_tot_duration.count()) * 0.000000001f;
     184           0 :     auto rpercent = (rtot_dur / total_sec) * 100.f;
     185           0 :     auto ravg_thr = (float)(timer_n_calls * rn_elmts) / ((float)timer_tot_duration.count() * 0.001f);
     186           0 :     auto rmin_thr = (float)(1.f           * rn_elmts) / ((float)timer_max_duration.count() * 0.001f);
     187           0 :     auto rmax_thr = (float)(1.f           * rn_elmts) / ((float)timer_min_duration.count() * 0.001f);
     188           0 :     auto ravg_lat = (float)(timer_tot_duration.count() * 0.001f) / timer_n_calls;
     189           0 :     auto rmin_lat = (float)(timer_min_duration.count() * 0.001f);
     190           0 :     auto rmax_lat = (float)(timer_max_duration.count() * 0.001f);
     191             : 
     192             : #ifdef _WIN32
     193             :     auto P = 1;
     194             : #else
     195           0 :     auto P = 2;
     196             : #endif
     197             : 
     198           0 :     unsigned l1 = 99999999;
     199           0 :     float    l2 = 99999.99f;
     200             : 
     201           0 :     std::stringstream spaces, ssprocess, ssrep, ssorder, sssp, ssrn_calls, ssrtot_dur, ssrpercent;
     202           0 :     std::stringstream ssravg_thr, ssrmin_thr, ssrmax_thr;
     203           0 :     std::stringstream ssravg_lat, ssrmin_lat, ssrmax_lat;
     204             : 
     205           0 :     spaces     <<                                                                                          std::fixed  << std::setw(18) << "-";
     206           0 :     ssprocess  << std::setprecision(                         2) <<                                         std::fixed  << std::setw(17) << "-";
     207           0 :     ssrep      << std::setprecision(                         2) <<                                         std::fixed  << std::setw( 3) << "-";
     208           0 :     ssorder    << std::setprecision(                         2) <<                                         std::fixed  << std::setw( 5) << "-";
     209           0 :     sssp       << std::setprecision(                         2) <<                                         std::fixed  << std::setw( 7) << timer_name;
     210           0 :     ssrn_calls << std::setprecision(timer_n_calls > l1 ? P : 2) << (timer_n_calls > l1 ? std::scientific : std::fixed) << std::setw( 8) << timer_n_calls;
     211           0 :     ssrtot_dur << std::setprecision(rtot_dur      > l1 ? P : 2) << (rtot_dur      > l1 ? std::scientific : std::fixed) << std::setw( 8) << rtot_dur;
     212           0 :     ssrpercent << std::setprecision(                         2) <<                                         std::fixed  << std::setw( 6) << rpercent;
     213           0 :     ssravg_thr << std::setprecision(ravg_thr      > l1 ? P : 2) << (ravg_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << ravg_thr;
     214           0 :     ssrmin_thr << std::setprecision(rmin_thr      > l1 ? P : 2) << (rmin_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << rmin_thr;
     215           0 :     ssrmax_thr << std::setprecision(rmax_thr      > l1 ? P : 2) << (rmax_thr      > l2 ? std::scientific : std::fixed) << std::setw( 8) << rmax_thr;
     216           0 :     ssravg_lat << std::setprecision(ravg_lat      > l1 ? P : 2) << (ravg_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << ravg_lat;
     217           0 :     ssrmin_lat << std::setprecision(rmin_lat      > l1 ? P : 2) << (rmin_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << rmin_lat;
     218           0 :     ssrmax_lat << std::setprecision(rmax_lat      > l1 ? P : 2) << (rmax_lat      > l2 ? std::scientific : std::fixed) << std::setw( 8) << rmax_lat;
     219             : 
     220           0 :     stream << "# ";
     221           0 :     stream << spaces.str()                                                  << rang::style::bold << " | "  << rang::style::reset
     222           0 :            << rang::style::italic << ssprocess .str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     223           0 :            << rang::style::italic << ssrep     .str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     224           0 :            << rang::style::italic << ssorder   .str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     225           0 :            << rang::style::italic << sssp      .str() << rang::style::reset << rang::style::bold << " || " << rang::style::reset
     226           0 :            << rang::style::italic << ssrn_calls.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     227           0 :            << rang::style::italic << ssrtot_dur.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     228           0 :            << rang::style::italic << ssrpercent.str() << rang::style::reset << rang::style::bold << " || " << rang::style::reset
     229           0 :            << rang::style::italic << ssravg_thr.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     230           0 :            << rang::style::italic << ssrmin_thr.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     231           0 :            << rang::style::italic << ssrmax_thr.str() << rang::style::reset << rang::style::bold << " || " << rang::style::reset
     232           0 :            << rang::style::italic << ssravg_lat.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     233           0 :            << rang::style::italic << ssrmin_lat.str() << rang::style::reset << rang::style::bold << " | "  << rang::style::reset
     234           0 :            << rang::style::italic << ssrmax_lat.str() << rang::style::reset << ""
     235           0 :            << std::endl;
     236             :     // clang-format on
     237           0 : }
     238             : 
     239             : template<class MODULE_OR_TASK>
     240             : void
     241             : Statistics::show(std::vector<MODULE_OR_TASK*> modules_or_tasks,
     242             :                  const bool ordered,
     243             :                  const bool display_thr,
     244             :                  std::ostream& stream)
     245             : {
     246             :     std::stringstream message;
     247             :     message << "The 'Statistics::show' method expect a 'std::vector' of 'module::Module' or 'runtime::Task'.";
     248             :     throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
     249             : }
     250             : 
     251             : namespace spu
     252             : {
     253             : namespace tools
     254             : {
     255             : 
     256             : template<>
     257             : void
     258           0 : Statistics::show<module::Module>(std::vector<module::Module*> modules,
     259             :                                  const bool ordered,
     260             :                                  const bool display_thr,
     261             :                                  std::ostream& stream)
     262             : {
     263           0 :     Statistics::show_modules<module::Module>(modules, ordered, display_thr, stream);
     264           0 : }
     265             : 
     266             : template<>
     267             : void
     268           0 : Statistics::show<const module::Module>(std::vector<const module::Module*> modules,
     269             :                                        const bool ordered,
     270             :                                        const bool display_thr,
     271             :                                        std::ostream& stream)
     272             : {
     273           0 :     Statistics::show_modules<const module::Module>(modules, ordered, display_thr, stream);
     274           0 : }
     275             : 
     276             : template<>
     277             : void
     278          11 : Statistics::show<runtime::Task>(std::vector<runtime::Task*> tasks,
     279             :                                 const bool ordered,
     280             :                                 const bool display_thr,
     281             :                                 std::ostream& stream)
     282             : {
     283          11 :     Statistics::show_tasks<runtime::Task>(tasks, ordered, display_thr, stream);
     284          11 : }
     285             : 
     286             : template<>
     287             : void
     288           0 : Statistics::show<const runtime::Task>(std::vector<const runtime::Task*> tasks,
     289             :                                       const bool ordered,
     290             :                                       const bool display_thr,
     291             :                                       std::ostream& stream)
     292             : {
     293           0 :     Statistics::show_tasks<const runtime::Task>(tasks, ordered, display_thr, stream);
     294           0 : }
     295             : 
     296             : }
     297             : }
     298             : 
     299             : template<class MODULE>
     300             : void
     301           0 : Statistics::show_modules(std::vector<MODULE*> modules, const bool ordered, const bool display_thr, std::ostream& stream)
     302             : {
     303           0 :     std::vector<const runtime::Task*> tasks;
     304           0 :     for (auto& m : modules)
     305           0 :         if (m != nullptr)
     306           0 :             for (auto& t : m->tasks)
     307           0 :                 if (t->get_n_calls()) tasks.push_back(t.get());
     308             : 
     309           0 :     Statistics::show_tasks(tasks, ordered, display_thr, stream);
     310           0 : }
     311             : 
     312             : template<class TASK>
     313             : void
     314          11 : Statistics::show_tasks(std::vector<TASK*> tasks, const bool ordered, const bool display_thr, std::ostream& stream)
     315             : {
     316          70 :     for (size_t t = 0; t < tasks.size(); t++)
     317          59 :         if (tasks[t] == nullptr) tasks.erase(tasks.begin() + t);
     318             : 
     319          11 :     std::map<const spu::runtime::Task*, size_t> tasks_order;
     320          70 :     for (size_t t = 0; t < tasks.size(); t++)
     321          59 :         tasks_order[(const spu::runtime::Task*)tasks[t]] = t;
     322             : 
     323          11 :     if (ordered)
     324             :     {
     325           0 :         std::sort(tasks.begin(),
     326             :                   tasks.end(),
     327           0 :                   [](const runtime::Task* t1, const runtime::Task* t2)
     328           0 :                   { return t1->get_duration_total() > t2->get_duration_total(); });
     329             :     }
     330             : 
     331          11 :     auto ttask_tot_duration = std::chrono::nanoseconds(0);
     332          11 :     auto ttask_min_duration = std::chrono::nanoseconds(0);
     333          11 :     auto ttask_max_duration = std::chrono::nanoseconds(0);
     334             : 
     335          70 :     for (auto* t : tasks)
     336          59 :         ttask_tot_duration += t->get_duration_total();
     337          11 :     auto total_sec = ((float)ttask_tot_duration.count()) * 0.000000001f;
     338             : 
     339          11 :     if (ttask_tot_duration.count())
     340             :     {
     341          11 :         Statistics::show_header(display_thr, stream);
     342             : 
     343          11 :         size_t ttask_n_elmts = 0;
     344          11 :         uint32_t ttask_n_calls = 0;
     345             : 
     346          11 :         auto is_first = true;
     347          70 :         for (auto* t : tasks)
     348             :         {
     349          59 :             auto task_n_elmts = t->sockets.end()[-2]->get_n_elmts();
     350          59 :             auto task_n_calls = t->get_n_calls();
     351             : 
     352          59 :             if (is_first)
     353             :             {
     354          11 :                 if (task_n_calls)
     355             :                 {
     356          11 :                     ttask_n_elmts = task_n_elmts;
     357          11 :                     ttask_n_calls = task_n_calls;
     358          11 :                     is_first = false;
     359             :                 }
     360             :             }
     361             :             else
     362             :             {
     363          48 :                 ttask_n_elmts = task_n_elmts ? std::min(ttask_n_elmts, task_n_elmts) : ttask_n_elmts;
     364          48 :                 ttask_n_calls = task_n_calls ? std::min(ttask_n_calls, task_n_calls) : ttask_n_calls;
     365             :             }
     366             :         }
     367             : 
     368          11 :         bool all_replicable = true;
     369          70 :         for (auto* t : tasks)
     370             :         {
     371         114 :             auto module_name = t->get_module().get_custom_name().empty() ? t->get_module().get_short_name()
     372          55 :                                                                          : t->get_module().get_custom_name();
     373          59 :             auto task_n_elmts = t->sockets.end()[-2]->get_n_elmts();
     374          59 :             auto task_name = t->get_name();
     375          59 :             bool task_replicability = t->is_replicable();
     376          59 :             if (!task_replicability) all_replicable = false;
     377          59 :             auto task_n_calls = t->get_n_calls();
     378          59 :             auto task_tot_duration = t->get_duration_total();
     379          59 :             auto task_min_duration = t->get_duration_min();
     380          59 :             auto task_max_duration = t->get_duration_max();
     381             : 
     382          59 :             ttask_min_duration += (task_min_duration * task_n_calls) / ttask_n_calls;
     383          59 :             ttask_max_duration += (task_max_duration * task_n_calls) / ttask_n_calls;
     384             : 
     385         118 :             Statistics::show_task(total_sec,
     386             :                                   module_name,
     387             :                                   task_name,
     388             :                                   task_replicability,
     389          59 :                                   tasks_order[t],
     390             :                                   task_n_elmts,
     391             :                                   task_n_calls,
     392             :                                   task_tot_duration,
     393             :                                   task_min_duration,
     394             :                                   task_max_duration,
     395             :                                   display_thr,
     396             :                                   stream);
     397             : 
     398          59 :             auto task_total_sec = ((float)task_tot_duration.count()) * 0.000000001f;
     399             : 
     400          59 :             auto timers_name = t->get_timers_name();
     401          59 :             auto timers_n_elmts = task_n_elmts;
     402          59 :             auto timers_n_calls = t->get_timers_n_calls();
     403          59 :             auto timers_tot_duration = t->get_timers_total();
     404          59 :             auto timers_min_duration = t->get_timers_min();
     405          59 :             auto timers_max_duration = t->get_timers_max();
     406             : 
     407          59 :             for (size_t i = 0; i < timers_name.size(); i++)
     408             :             {
     409           0 :                 Statistics::show_timer(task_total_sec,
     410             :                                        task_n_calls,
     411             :                                        timers_n_elmts,
     412           0 :                                        timers_name[i],
     413           0 :                                        timers_n_calls[i],
     414           0 :                                        timers_tot_duration[i],
     415           0 :                                        timers_min_duration[i],
     416           0 :                                        timers_max_duration[i],
     417             :                                        stream);
     418             :             }
     419             :         }
     420          11 :         Statistics::separation2(display_thr, stream);
     421             : 
     422          11 :         Statistics::show_task(total_sec,
     423             :                               "TOTAL",
     424             :                               "*",
     425             :                               all_replicable,
     426             :                               -1,
     427             :                               ttask_n_elmts,
     428             :                               ttask_n_calls,
     429             :                               ttask_tot_duration,
     430             :                               ttask_min_duration,
     431             :                               ttask_max_duration,
     432             :                               display_thr,
     433             :                               stream);
     434             :     }
     435             :     else
     436             :     {
     437           0 :         stream << rang::tag::comment << rang::tag::info
     438           0 :                << "Statistics are unavailable. Did you enable the statistics in the tasks?" << std::endl;
     439             :     }
     440          11 : }
     441             : 
     442             : template<class MODULE_OR_TASK>
     443             : void
     444             : Statistics::show(std::vector<std::vector<MODULE_OR_TASK*>> modules_or_tasks,
     445             :                  const bool ordered,
     446             :                  const bool display_thr,
     447             :                  std::ostream& stream)
     448             : {
     449             :     std::stringstream message;
     450             :     message << "The 'Statistics::show' method expect a 'std::vector' of 'std::vector' of 'module::Module' or "
     451             :             << "'runtime::Task'.";
     452             :     throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
     453             : }
     454             : 
     455             : namespace spu
     456             : {
     457             : namespace tools
     458             : {
     459             : 
     460             : template<>
     461             : void
     462           2 : Statistics::show<module::Module>(std::vector<std::vector<module::Module*>> modules,
     463             :                                  const bool ordered,
     464             :                                  const bool display_thr,
     465             :                                  std::ostream& stream)
     466             : {
     467           2 :     Statistics::show_modules<module::Module>(modules, ordered, display_thr, stream);
     468           2 : }
     469             : 
     470             : template<>
     471             : void
     472           0 : Statistics::show<const module::Module>(std::vector<std::vector<const module::Module*>> modules,
     473             :                                        const bool ordered,
     474             :                                        const bool display_thr,
     475             :                                        std::ostream& stream)
     476             : {
     477           0 :     Statistics::show_modules<const module::Module>(modules, ordered, display_thr, stream);
     478           0 : }
     479             : 
     480             : template<>
     481             : void
     482          29 : Statistics::show<runtime::Task>(std::vector<std::vector<runtime::Task*>> tasks,
     483             :                                 const bool ordered,
     484             :                                 const bool display_thr,
     485             :                                 std::ostream& stream)
     486             : {
     487          29 :     Statistics::show_tasks<runtime::Task>(tasks, ordered, display_thr, stream);
     488          29 : }
     489             : 
     490             : template<>
     491             : void
     492           0 : Statistics::show<const runtime::Task>(std::vector<std::vector<const runtime::Task*>> tasks,
     493             :                                       const bool ordered,
     494             :                                       const bool display_thr,
     495             :                                       std::ostream& stream)
     496             : {
     497           0 :     Statistics::show_tasks<const runtime::Task>(tasks, ordered, display_thr, stream);
     498           0 : }
     499             : 
     500             : }
     501             : }
     502             : 
     503             : template<class MODULE>
     504             : void
     505           2 : Statistics::show_modules(std::vector<std::vector<MODULE*>> modules,
     506             :                          const bool ordered,
     507             :                          const bool display_thr,
     508             :                          std::ostream& stream)
     509             : {
     510           2 :     std::vector<std::vector<const runtime::Task*>> tasks;
     511          33 :     for (auto& vm : modules)
     512          31 :         if (vm.size() > 0 && vm[0] != nullptr)
     513             :         {
     514          31 :             auto& tasks0 = vm[0]->tasks;
     515          76 :             for (size_t t = 0; t < tasks0.size(); t++)
     516             :             {
     517          45 :                 std::vector<const runtime::Task*> tsk;
     518          90 :                 for (auto& m : vm)
     519          45 :                     tsk.push_back(m->tasks[t].get());
     520          45 :                 tasks.push_back(tsk);
     521             :             }
     522             :         }
     523             : 
     524           2 :     Statistics::show_tasks(tasks, ordered, display_thr, stream);
     525           2 : }
     526             : 
     527             : template<class TASK>
     528             : void
     529          31 : Statistics::show_tasks(std::vector<std::vector<TASK*>> tasks,
     530             :                        const bool ordered,
     531             :                        const bool display_thr,
     532             :                        std::ostream& stream)
     533             : {
     534             :     using namespace std::chrono;
     535             : 
     536          31 :     if (tasks.size())
     537         220 :         for (size_t t = 0; t < tasks[0].size(); t++)
     538         189 :             if (tasks[0][t] == nullptr)
     539           0 :                 for (size_t i = 0; i < tasks.size(); i++)
     540           0 :                     tasks[i].erase(tasks[i].begin() + t);
     541             : 
     542          31 :     std::map<const spu::runtime::Task*, size_t> tasks_order;
     543          31 :     if (tasks.size())
     544         194 :         for (size_t t = 0; t < tasks.size(); t++)
     545         163 :             tasks_order[(const spu::runtime::Task*)tasks[t][0]] = t;
     546             : 
     547          31 :     if (ordered)
     548             :     {
     549          31 :         std::sort(tasks.begin(),
     550             :                   tasks.end(),
     551         442 :                   [](const std::vector<TASK*>& t1, const std::vector<TASK*>& t2)
     552             :                   {
     553         442 :                       auto total1 = nanoseconds(0);
     554         442 :                       auto total2 = nanoseconds(0);
     555        5113 :                       for (auto* t : t1)
     556        4671 :                           total1 += t->get_duration_total();
     557        5113 :                       for (auto* t : t2)
     558        4671 :                           total2 += t->get_duration_total();
     559         884 :                       return total1 > total2;
     560             :                   });
     561             :     }
     562             : 
     563          31 :     auto ttask_tot_duration = nanoseconds(0);
     564          31 :     auto ttask_min_duration = nanoseconds(0);
     565          31 :     auto ttask_max_duration = nanoseconds(0);
     566             : 
     567         194 :     for (auto& vt : tasks)
     568        1636 :         for (auto* t : vt)
     569        1473 :             ttask_tot_duration += t->get_duration_total();
     570          31 :     auto total_sec = ((float)ttask_tot_duration.count()) * 0.000000001f;
     571             : 
     572          31 :     if (ttask_tot_duration.count())
     573             :     {
     574          31 :         Statistics::show_header(display_thr, stream);
     575             : 
     576          31 :         size_t ttask_n_elmts = 0;
     577          31 :         auto ttask_n_calls = 0;
     578             : 
     579          31 :         auto is_first = true;
     580         194 :         for (auto& vt : tasks)
     581             :         {
     582         163 :             auto task_n_elmts = vt[0]->sockets.size() >= 2 ? vt[0]->sockets.end()[-2]->get_n_elmts() : 0;
     583         163 :             auto task_n_calls = 0;
     584             : 
     585        1636 :             for (auto* t : vt)
     586        1473 :                 task_n_calls += t->get_n_calls();
     587             : 
     588         163 :             if (is_first)
     589             :             {
     590          31 :                 if (task_n_calls)
     591             :                 {
     592          31 :                     ttask_n_elmts = task_n_elmts;
     593          31 :                     ttask_n_calls = task_n_calls;
     594          31 :                     is_first = false;
     595             :                 }
     596             :             }
     597             :             else
     598             :             {
     599         132 :                 ttask_n_elmts = task_n_elmts ? std::min(ttask_n_elmts, task_n_elmts) : ttask_n_elmts;
     600         132 :                 ttask_n_calls = task_n_calls ? std::min(ttask_n_calls, task_n_calls) : ttask_n_calls;
     601             :             }
     602             :         }
     603             : 
     604          31 :         bool all_replicable = true;
     605         194 :         for (auto& vt : tasks)
     606             :         {
     607         292 :             auto module_name = vt[0]->get_module().get_custom_name().empty() ? vt[0]->get_module().get_short_name()
     608         129 :                                                                              : vt[0]->get_module().get_custom_name();
     609         163 :             auto task_n_elmts = vt[0]->sockets.size() >= 2 ? vt[0]->sockets.end()[-2]->get_n_elmts() : 0;
     610         163 :             auto task_name = vt[0]->get_name();
     611         163 :             bool task_replicability = vt[0]->is_replicable();
     612         163 :             if (!task_replicability) all_replicable = false;
     613         163 :             auto task_n_calls = 0;
     614         163 :             auto task_tot_duration = nanoseconds(0);
     615         163 :             auto task_min_duration = ttask_tot_duration;
     616         163 :             auto task_max_duration = nanoseconds(0);
     617             : 
     618        1636 :             for (auto* t : vt)
     619             :             {
     620        1473 :                 task_n_calls += t->get_n_calls();
     621        1473 :                 task_tot_duration += t->get_duration_total();
     622        1473 :                 task_min_duration = std::min(task_min_duration, t->get_duration_min());
     623        1473 :                 task_max_duration = std::max(task_max_duration, t->get_duration_max());
     624             :             }
     625             : 
     626         163 :             ttask_min_duration += (task_min_duration * task_n_calls) / ttask_n_calls;
     627         163 :             ttask_max_duration += (task_max_duration * task_n_calls) / ttask_n_calls;
     628             : 
     629         326 :             Statistics::show_task(total_sec,
     630             :                                   module_name,
     631             :                                   task_name,
     632             :                                   task_replicability,
     633         163 :                                   tasks_order[vt[0]],
     634             :                                   task_n_elmts,
     635             :                                   task_n_calls,
     636             :                                   task_tot_duration,
     637             :                                   task_min_duration,
     638             :                                   task_max_duration,
     639             :                                   display_thr,
     640             :                                   stream);
     641             : 
     642         163 :             auto task_total_sec = ((float)task_tot_duration.count()) * 0.000000001f;
     643             : 
     644         163 :             auto timers_name = vt[0]->get_timers_name();
     645         163 :             auto timers_n_elmts = task_n_elmts;
     646         163 :             auto timers_n_calls = std::vector<uint32_t>(timers_name.size(), 0);
     647         163 :             auto timers_tot_duration = std::vector<nanoseconds>(timers_name.size(), nanoseconds(0));
     648         163 :             auto timers_min_duration = std::vector<nanoseconds>(timers_name.size(), ttask_tot_duration);
     649         163 :             auto timers_max_duration = std::vector<nanoseconds>(timers_name.size(), nanoseconds(0));
     650             : 
     651         163 :             for (size_t tn = 0; tn < vt[0]->get_timers_name().size(); tn++)
     652             :             {
     653           0 :                 for (auto* t : vt)
     654             :                 {
     655           0 :                     timers_n_calls[tn] += t->get_timers_n_calls()[tn];
     656           0 :                     timers_tot_duration[tn] += t->get_timers_total()[tn];
     657           0 :                     timers_min_duration[tn] = std::min(task_min_duration, t->get_timers_min()[tn]);
     658           0 :                     timers_max_duration[tn] = std::max(task_max_duration, t->get_timers_max()[tn]);
     659             :                 }
     660             : 
     661           0 :                 Statistics::show_timer(task_total_sec,
     662             :                                        task_n_calls,
     663             :                                        timers_n_elmts,
     664           0 :                                        timers_name[tn],
     665             :                                        timers_n_calls[tn],
     666             :                                        timers_tot_duration[tn],
     667             :                                        timers_min_duration[tn],
     668             :                                        timers_max_duration[tn],
     669             :                                        stream);
     670             :             }
     671             :         }
     672          31 :         Statistics::separation2(display_thr, stream);
     673             : 
     674          31 :         Statistics::show_task(total_sec,
     675             :                               "TOTAL",
     676             :                               "*",
     677             :                               all_replicable,
     678             :                               -1,
     679             :                               ttask_n_elmts,
     680             :                               ttask_n_calls,
     681             :                               ttask_tot_duration,
     682             :                               ttask_min_duration,
     683             :                               ttask_max_duration,
     684             :                               display_thr,
     685             :                               stream);
     686             :     }
     687             :     else
     688             :     {
     689           0 :         stream << rang::tag::comment << rang::tag::info
     690           0 :                << "Statistics are unavailable. Did you enable the statistics in the tasks?" << std::endl;
     691             :     }
     692          31 : }

Generated by: LCOV version 1.14