LCOV - code coverage report
Current view: top level - src/Tools/Builder - Pipeline_builder.cpp (source / functions) Hit Total Coverage
Test: streampu_clean.info Lines: 120 166 72.3 %
Date: 2026-01-14 14:49:10 Functions: 36 47 76.6 %

          Line data    Source code
       1             : #include "Tools/Builder/Pipeline_builder.hpp"
       2             : #include "Runtime/Pipeline/Pipeline.hpp"
       3             : 
       4             : using namespace spu;
       5             : using namespace spu::tools;
       6             : 
       7             : Pipeline_builder&
       8           1 : Pipeline_builder::set_tasks_for_checking(const std::vector<runtime::Task*> tasks)
       9             : {
      10           1 :     this->tasks_for_checking.assign(tasks.begin(), tasks.end());
      11           1 :     return *this;
      12             : }
      13             : 
      14             : Pipeline_builder&
      15          10 : Pipeline_builder::add_task_for_checking(runtime::Task* task)
      16             : {
      17          10 :     if (std::find(this->tasks_for_checking.begin(), this->tasks_for_checking.end(), task) !=
      18          20 :         this->tasks_for_checking.end())
      19             :     {
      20           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in tasks for checking.");
      21             :     }
      22             : 
      23          10 :     this->tasks_for_checking.push_back(task);
      24             : 
      25          10 :     return *this;
      26             : }
      27             : 
      28             : Pipeline_builder&
      29          10 : Pipeline_builder::add_task_for_checking(runtime::Task& task)
      30             : {
      31          10 :     return this->add_task_for_checking(&task);
      32             : }
      33             : 
      34             : Pipeline_builder&
      35           0 : Pipeline_builder::remove_task_for_checking(const runtime::Task* task)
      36             : {
      37           0 :     this->tasks_for_checking.erase(std::remove(this->tasks_for_checking.begin(), this->tasks_for_checking.end(), task),
      38           0 :                                    this->tasks_for_checking.end());
      39             : 
      40           0 :     return *this;
      41             : }
      42             : 
      43             : const std::vector<runtime::Task*>
      44          10 : Pipeline_builder::get_tasks_for_checking()
      45             : {
      46          10 :     return this->tasks_for_checking;
      47             : }
      48             : 
      49             : Pipeline_builder&
      50          35 : Pipeline_builder::add_stage(Stage_builder& stage)
      51             : {
      52          35 :     if (std::find(this->stages.begin(), this->stages.end(), &stage) != this->stages.end())
      53             :     {
      54           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The stage is already added.");
      55             :     }
      56             : 
      57          35 :     this->stages.push_back(&stage);
      58             : 
      59          35 :     return *this;
      60             : }
      61             : 
      62             : Pipeline_builder&
      63           4 : Pipeline_builder::remove_stage(const Stage_builder& stage)
      64             : {
      65           4 :     this->stages.erase(std::remove(this->stages.begin(), this->stages.end(), &stage), this->stages.end());
      66             : 
      67           4 :     return *this;
      68             : }
      69             : 
      70             : Pipeline_builder&
      71           0 : Pipeline_builder::remove_stage(const size_t stage_id)
      72             : {
      73           0 :     if (stage_id >= this->stages.size())
      74             :     {
      75           0 :         throw length_error(__FILE__, __LINE__, __func__, "No stage of index 'stage_id' exists.");
      76             :     }
      77             : 
      78           0 :     this->stages.erase(std::remove(this->stages.begin(), this->stages.end(), this->stages[stage_id]),
      79           0 :                        this->stages.end());
      80             : 
      81           0 :     return *this;
      82             : }
      83             : 
      84             : Pipeline_builder::Stage_builder&
      85          13 : Pipeline_builder::get_stage(const size_t stage_id)
      86             : {
      87          13 :     if (stage_id >= this->stages.size())
      88             :     {
      89           0 :         throw length_error(__FILE__, __LINE__, __func__, "No stage of index 'stage_id' exists.");
      90             :     }
      91             : 
      92          13 :     return *this->stages[stage_id];
      93             : }
      94             : 
      95             : Pipeline_builder&
      96          18 : Pipeline_builder::configure_interstage_synchro(Synchro_builder& synchro)
      97             : {
      98          18 :     if (std::find(this->synchros.begin(), this->synchros.end(), &synchro) != this->synchros.end())
      99             :     {
     100           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The interstage synchronization is already added.");
     101             :     }
     102             : 
     103          18 :     this->synchros.push_back(&synchro);
     104             : 
     105          18 :     return *this;
     106             : }
     107             : 
     108             : Pipeline_builder::Synchro_builder&
     109           0 : Pipeline_builder::get_interstage_synchro(const size_t synchro_id)
     110             : {
     111           0 :     if (synchro_id >= this->synchros.size())
     112             :     {
     113           0 :         throw length_error(__FILE__, __LINE__, __func__, "No interstage synchronization of index 'synchro_id' exists.");
     114             :     }
     115             : 
     116           0 :     return *this->synchros[synchro_id];
     117             : }
     118             : 
     119             : spu::tools::Pipeline_builder::pipeline_construct_t
     120          10 : Pipeline_builder::_build()
     121             : {
     122          10 :     spu::tools::Pipeline_builder::pipeline_construct_t pipc;
     123             : 
     124             :     // Build stages
     125          41 :     for (auto it = this->stages.begin(); it != this->stages.end(); it++)
     126             :     {
     127          31 :         Stage_builder* stage = *it;
     128             : 
     129          31 :         pipc.built_stages.push_back(std::make_tuple<std::vector<spu::runtime::Task*>,
     130             :                                                     std::vector<spu::runtime::Task*>,
     131          62 :                                                     std::vector<spu::runtime::Task*>>(
     132          62 :           std::vector<spu::runtime::Task*>(stage->get_first_tasks()),
     133          62 :           std::vector<spu::runtime::Task*>(stage->get_last_tasks()),
     134          62 :           std::vector<spu::runtime::Task*>(stage->get_excluded_tasks())));
     135             : 
     136          31 :         pipc.threads.push_back(stage->get_n_threads());
     137          31 :         pipc.pinning.push_back(stage->is_pinning());
     138          31 :         pipc.pinning_policy += stage->get_pinning_policy();
     139          31 :         if (it < this->stages.end() - 1) pipc.pinning_policy += "|";
     140             :     }
     141             : 
     142             :     // Build synchronization between stages
     143          10 :     Synchro_builder synchro_default;
     144          31 :     for (size_t stage_id = 0; stage_id < this->stages.size() - 1; stage_id++)
     145             :     {
     146          21 :         if (stage_id < this->synchros.size())
     147             :         {
     148          18 :             pipc.buffer_sizes.push_back(this->synchros[stage_id]->get_buffer_size());
     149          18 :             pipc.waitings.push_back(this->synchros[stage_id]->is_active_waiting());
     150             :         }
     151             :         else
     152             :         {
     153           3 :             pipc.buffer_sizes.push_back(synchro_default.get_buffer_size());
     154           3 :             pipc.waitings.push_back(synchro_default.is_active_waiting());
     155             :         }
     156             :     }
     157             : 
     158          20 :     return pipc;
     159           0 : }
     160             : 
     161             : runtime::Pipeline
     162          10 : Pipeline_builder::build()
     163             : {
     164          10 :     pipeline_construct_t pipc = _build();
     165          20 :     return runtime::Pipeline(this->get_tasks_for_checking(),
     166             :                              pipc.built_stages,
     167             :                              pipc.threads,
     168             :                              pipc.buffer_sizes,
     169             :                              pipc.waitings,
     170             :                              pipc.pinning,
     171          20 :                              pipc.pinning_policy);
     172          10 : }
     173             : 
     174             : runtime::Pipeline*
     175           0 : Pipeline_builder::build_ptr()
     176             : {
     177           0 :     pipeline_construct_t pipc = _build();
     178           0 :     return new runtime::Pipeline(this->get_tasks_for_checking(),
     179             :                                  pipc.built_stages,
     180             :                                  pipc.threads,
     181             :                                  pipc.buffer_sizes,
     182             :                                  pipc.waitings,
     183             :                                  pipc.pinning,
     184           0 :                                  pipc.pinning_policy);
     185           0 : }
     186             : 
     187             : size_t
     188           0 : spu::tools::Pipeline_builder::get_n_stages()
     189             : {
     190           0 :     return stages.size();
     191             : }
     192             : 
     193             : Pipeline_builder::Stage_builder&
     194          28 : Pipeline_builder::Stage_builder::set_n_threads(const size_t n)
     195             : {
     196          28 :     this->n_threads = n;
     197          28 :     return *this;
     198             : }
     199             : 
     200             : size_t
     201          31 : Pipeline_builder::Stage_builder::get_n_threads()
     202             : {
     203          31 :     return this->n_threads;
     204             : }
     205             : 
     206             : Pipeline_builder::Stage_builder&
     207           1 : Pipeline_builder::Stage_builder::enable_threads_pinning()
     208             : {
     209           1 :     this->pinning = true;
     210           1 :     return *this;
     211             : }
     212             : 
     213             : Pipeline_builder::Stage_builder&
     214           1 : Pipeline_builder::Stage_builder::disable_threads_pinning()
     215             : {
     216           1 :     this->pinning = false;
     217           1 :     return *this;
     218             : }
     219             : 
     220             : Pipeline_builder::Stage_builder&
     221           2 : Pipeline_builder::Stage_builder::set_threads_pinning(bool pinning)
     222             : {
     223           2 :     return (pinning) ? this->enable_threads_pinning() : this->disable_threads_pinning();
     224             : }
     225             : 
     226             : bool
     227          31 : Pipeline_builder::Stage_builder::is_pinning()
     228             : {
     229          31 :     return this->pinning;
     230             : }
     231             : 
     232             : Pipeline_builder::Stage_builder&
     233           1 : Pipeline_builder::Stage_builder::set_pinning_policy(const std::string pinning_policy)
     234             : {
     235           1 :     this->pinning_policy = pinning_policy;
     236           1 :     return *this;
     237             : }
     238             : 
     239             : const std::string
     240          31 : Pipeline_builder::Stage_builder::get_pinning_policy()
     241             : {
     242          31 :     return this->pinning_policy;
     243             : }
     244             : 
     245             : Pipeline_builder::Stage_builder&
     246           1 : Pipeline_builder::Stage_builder::set_first_tasks(const std::vector<runtime::Task*> first)
     247             : {
     248           1 :     this->first_tasks.assign(first.begin(), first.end());
     249           1 :     return *this;
     250             : }
     251             : 
     252             : Pipeline_builder::Stage_builder&
     253          35 : Pipeline_builder::Stage_builder::add_first_task(runtime::Task* first)
     254             : {
     255          35 :     if (std::find(this->first_tasks.begin(), this->first_tasks.end(), first) != this->first_tasks.end())
     256             :     {
     257           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in first tasks.");
     258             :     }
     259             : 
     260          35 :     this->first_tasks.push_back(first);
     261          35 :     return *this;
     262             : }
     263             : 
     264             : Pipeline_builder::Stage_builder&
     265          35 : Pipeline_builder::Stage_builder::add_first_task(runtime::Task& first)
     266             : {
     267          35 :     return this->add_first_task(&first);
     268             : }
     269             : 
     270             : Pipeline_builder::Stage_builder&
     271           0 : Pipeline_builder::Stage_builder::remove_first_task(const runtime::Task* first)
     272             : {
     273           0 :     this->first_tasks.erase(std::remove(this->first_tasks.begin(), this->first_tasks.end(), first),
     274           0 :                             this->first_tasks.end());
     275             : 
     276           0 :     return *this;
     277             : }
     278             : 
     279             : Pipeline_builder::Stage_builder&
     280           0 : Pipeline_builder::Stage_builder::remove_first_task(const runtime::Task& first)
     281             : {
     282           0 :     return this->remove_first_task(&first);
     283             : }
     284             : 
     285             : const std::vector<runtime::Task*>
     286          39 : Pipeline_builder::Stage_builder::get_first_tasks()
     287             : {
     288          39 :     return this->first_tasks;
     289             : }
     290             : 
     291             : Pipeline_builder::Stage_builder&
     292           1 : Pipeline_builder::Stage_builder::set_last_tasks(const std::vector<runtime::Task*> last)
     293             : {
     294           1 :     this->last_tasks.assign(last.begin(), last.end());
     295           1 :     return *this;
     296             : }
     297             : 
     298             : Pipeline_builder::Stage_builder&
     299          26 : Pipeline_builder::Stage_builder::add_last_task(runtime::Task* last)
     300             : {
     301          26 :     if (std::find(this->last_tasks.begin(), this->last_tasks.end(), last) != this->last_tasks.end())
     302             :     {
     303           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in last tasks.");
     304             :     }
     305             : 
     306          26 :     this->last_tasks.push_back(last);
     307          26 :     return *this;
     308             : }
     309             : 
     310             : Pipeline_builder::Stage_builder&
     311          26 : Pipeline_builder::Stage_builder::add_last_task(runtime::Task& last)
     312             : {
     313          26 :     return this->add_last_task(&last);
     314             : }
     315             : 
     316             : Pipeline_builder::Stage_builder&
     317           0 : Pipeline_builder::Stage_builder::remove_last_task(const runtime::Task* last)
     318             : {
     319           0 :     this->last_tasks.erase(std::remove(this->last_tasks.begin(), this->last_tasks.end(), last), this->last_tasks.end());
     320             : 
     321           0 :     return *this;
     322             : }
     323             : 
     324             : Pipeline_builder::Stage_builder&
     325           0 : Pipeline_builder::Stage_builder::remove_last_task(const runtime::Task& last)
     326             : {
     327           0 :     return this->remove_last_task(&last);
     328             : }
     329             : 
     330             : const std::vector<runtime::Task*>
     331          39 : Pipeline_builder::Stage_builder::get_last_tasks()
     332             : {
     333          39 :     return this->last_tasks;
     334             : }
     335             : 
     336             : Pipeline_builder::Stage_builder&
     337           1 : Pipeline_builder::Stage_builder::set_excluded_tasks(const std::vector<runtime::Task*> excluded)
     338             : {
     339           1 :     this->excluded_tasks.assign(excluded.begin(), excluded.end());
     340           1 :     return *this;
     341             : }
     342             : 
     343             : Pipeline_builder::Stage_builder&
     344           1 : Pipeline_builder::Stage_builder::add_excluded_task(runtime::Task* excluded)
     345             : {
     346           1 :     if (std::find(this->excluded_tasks.begin(), this->excluded_tasks.end(), excluded) != this->excluded_tasks.end())
     347             :     {
     348           0 :         throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in excluded tasks.");
     349             :     }
     350             : 
     351           1 :     this->excluded_tasks.push_back(excluded);
     352           1 :     return *this;
     353             : }
     354             : 
     355             : Pipeline_builder::Stage_builder&
     356           1 : Pipeline_builder::Stage_builder::add_excluded_task(runtime::Task& excluded)
     357             : {
     358           1 :     return this->add_excluded_task(&excluded);
     359             : }
     360             : 
     361             : Pipeline_builder::Stage_builder&
     362           0 : Pipeline_builder::Stage_builder::remove_excluded_task(const runtime::Task* excluded)
     363             : {
     364           0 :     this->excluded_tasks.erase(std::remove(this->excluded_tasks.begin(), this->excluded_tasks.end(), excluded),
     365           0 :                                this->excluded_tasks.end());
     366             : 
     367           0 :     return *this;
     368             : }
     369             : 
     370             : Pipeline_builder::Stage_builder&
     371           0 : Pipeline_builder::Stage_builder::remove_excluded_task(const runtime::Task& excluded)
     372             : {
     373           0 :     return this->remove_excluded_task(&excluded);
     374             : }
     375             : 
     376             : const std::vector<runtime::Task*>
     377          31 : Pipeline_builder::Stage_builder::get_excluded_tasks()
     378             : {
     379          31 :     return this->excluded_tasks;
     380             : }
     381             : 
     382             : Pipeline_builder::Synchro_builder&
     383           3 : Pipeline_builder::Synchro_builder::enable_active_waiting()
     384             : {
     385           3 :     this->active_waiting = true;
     386           3 :     return *this;
     387             : }
     388             : 
     389             : Pipeline_builder::Synchro_builder&
     390          16 : Pipeline_builder::Synchro_builder::disable_active_waiting()
     391             : {
     392          16 :     this->active_waiting = false;
     393          16 :     return *this;
     394             : }
     395             : 
     396             : Pipeline_builder::Synchro_builder&
     397          19 : Pipeline_builder::Synchro_builder::set_active_waiting(bool waiting)
     398             : {
     399          19 :     return (waiting) ? this->enable_active_waiting() : this->disable_active_waiting();
     400             : }
     401             : 
     402             : bool
     403          21 : Pipeline_builder::Synchro_builder::is_active_waiting()
     404             : {
     405          21 :     return this->active_waiting;
     406             : }
     407             : 
     408             : Pipeline_builder::Synchro_builder&
     409          19 : Pipeline_builder::Synchro_builder::set_buffer_size(size_t buffer_size)
     410             : {
     411          19 :     this->buffer_size = buffer_size;
     412          19 :     return *this;
     413             : }
     414             : 
     415             : size_t
     416          21 : Pipeline_builder::Synchro_builder::get_buffer_size()
     417             : {
     418          21 :     return this->buffer_size;
     419             : }

Generated by: LCOV version 1.14