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

Generated by: LCOV version 1.14