LCOV - code coverage report
Current view: top level - src/Tools/Display/Statistics - Statistics.cpp (source / functions) Hit Total Coverage
Test: streampu_clean.info Lines: 151 306 49.3 %
Date: 2024-07-31 15:48:41 Functions: 11 25 44.0 %

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

Generated by: LCOV version 1.14