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 9 : Pipeline_builder::add_task_for_checking(runtime::Task* task)
16 : {
17 9 : if (std::find(this->tasks_for_checking.begin(), this->tasks_for_checking.end(), task) !=
18 18 : 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 9 : this->tasks_for_checking.push_back(task);
24 :
25 9 : return *this;
26 : }
27 :
28 : Pipeline_builder&
29 9 : Pipeline_builder::add_task_for_checking(runtime::Task& task)
30 : {
31 9 : 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 9 : Pipeline_builder::get_tasks_for_checking()
45 : {
46 9 : return this->tasks_for_checking;
47 : }
48 :
49 : Pipeline_builder&
50 32 : Pipeline_builder::add_stage(Stage_builder& stage)
51 : {
52 32 : 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 32 : this->stages.push_back(&stage);
58 :
59 32 : 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 16 : Pipeline_builder::configure_interstage_synchro(Synchro_builder& synchro)
97 : {
98 16 : 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 16 : this->synchros.push_back(&synchro);
104 :
105 16 : 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 : runtime::Pipeline
120 9 : Pipeline_builder::build()
121 : {
122 : std::vector<
123 : std::tuple<std::vector<spu::runtime::Task*>, std::vector<spu::runtime::Task*>, std::vector<spu::runtime::Task*>>>
124 9 : built_stages;
125 9 : std::vector<size_t> threads;
126 9 : std::vector<bool> pinning;
127 9 : std::vector<size_t> buffer_sizes;
128 9 : std::vector<bool> waitings;
129 9 : std::string pinning_policy("");
130 :
131 : // Build stages
132 37 : for (auto it = this->stages.begin(); it != this->stages.end(); it++)
133 : {
134 28 : Stage_builder* stage = *it;
135 :
136 28 : built_stages.push_back(std::make_tuple<std::vector<spu::runtime::Task*>,
137 : std::vector<spu::runtime::Task*>,
138 56 : std::vector<spu::runtime::Task*>>(
139 56 : std::vector<spu::runtime::Task*>(stage->get_first_tasks()),
140 56 : std::vector<spu::runtime::Task*>(stage->get_last_tasks()),
141 56 : std::vector<spu::runtime::Task*>(stage->get_excluded_tasks())));
142 :
143 28 : threads.push_back(stage->get_n_threads());
144 28 : pinning.push_back(stage->is_pinning());
145 28 : pinning_policy += stage->get_pinning_policy();
146 28 : if (it < this->stages.end() - 1) pinning_policy += "|";
147 : }
148 :
149 : // Build synchronization between stages
150 9 : Synchro_builder synchro_default;
151 28 : for (size_t stage_id = 0; stage_id < this->stages.size() - 1; stage_id++)
152 : {
153 19 : if (stage_id < this->synchros.size())
154 : {
155 16 : buffer_sizes.push_back(this->synchros[stage_id]->get_buffer_size());
156 16 : waitings.push_back(this->synchros[stage_id]->is_active_waiting());
157 : }
158 : else
159 : {
160 3 : buffer_sizes.push_back(synchro_default.get_buffer_size());
161 3 : waitings.push_back(synchro_default.is_active_waiting());
162 : }
163 : }
164 :
165 : return runtime::Pipeline(
166 27 : this->get_tasks_for_checking(), built_stages, threads, buffer_sizes, waitings, pinning, pinning_policy);
167 9 : }
168 :
169 : Pipeline_builder::Stage_builder&
170 25 : Pipeline_builder::Stage_builder::set_n_threads(const size_t n)
171 : {
172 25 : this->n_threads = n;
173 25 : return *this;
174 : }
175 :
176 : const size_t
177 28 : Pipeline_builder::Stage_builder::get_n_threads()
178 : {
179 28 : return this->n_threads;
180 : }
181 :
182 : Pipeline_builder::Stage_builder&
183 1 : Pipeline_builder::Stage_builder::enable_threads_pinning()
184 : {
185 1 : this->pinning = true;
186 1 : return *this;
187 : }
188 :
189 : Pipeline_builder::Stage_builder&
190 1 : Pipeline_builder::Stage_builder::disable_threads_pinning()
191 : {
192 1 : this->pinning = false;
193 1 : return *this;
194 : }
195 :
196 : Pipeline_builder::Stage_builder&
197 2 : Pipeline_builder::Stage_builder::set_threads_pinning(bool pinning)
198 : {
199 2 : return (pinning) ? this->enable_threads_pinning() : this->disable_threads_pinning();
200 : }
201 :
202 : const bool
203 28 : Pipeline_builder::Stage_builder::is_pinning()
204 : {
205 28 : return this->pinning;
206 : }
207 :
208 : Pipeline_builder::Stage_builder&
209 1 : Pipeline_builder::Stage_builder::set_pinning_policy(const std::string pinning_policy)
210 : {
211 1 : this->pinning_policy = pinning_policy;
212 1 : return *this;
213 : }
214 :
215 : const std::string
216 28 : Pipeline_builder::Stage_builder::get_pinning_policy()
217 : {
218 28 : return this->pinning_policy;
219 : }
220 :
221 : Pipeline_builder::Stage_builder&
222 1 : Pipeline_builder::Stage_builder::set_first_tasks(const std::vector<runtime::Task*> first)
223 : {
224 1 : this->first_tasks.assign(first.begin(), first.end());
225 1 : return *this;
226 : }
227 :
228 : Pipeline_builder::Stage_builder&
229 32 : Pipeline_builder::Stage_builder::add_first_task(runtime::Task* first)
230 : {
231 32 : if (std::find(this->first_tasks.begin(), this->first_tasks.end(), first) != this->first_tasks.end())
232 : {
233 0 : throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in first tasks.");
234 : }
235 :
236 32 : this->first_tasks.push_back(first);
237 32 : return *this;
238 : }
239 :
240 : Pipeline_builder::Stage_builder&
241 32 : Pipeline_builder::Stage_builder::add_first_task(runtime::Task& first)
242 : {
243 32 : return this->add_first_task(&first);
244 : }
245 :
246 : Pipeline_builder::Stage_builder&
247 0 : Pipeline_builder::Stage_builder::remove_first_task(const runtime::Task* first)
248 : {
249 0 : this->first_tasks.erase(std::remove(this->first_tasks.begin(), this->first_tasks.end(), first),
250 0 : this->first_tasks.end());
251 :
252 0 : return *this;
253 : }
254 :
255 : Pipeline_builder::Stage_builder&
256 0 : Pipeline_builder::Stage_builder::remove_first_task(const runtime::Task& first)
257 : {
258 0 : return this->remove_first_task(&first);
259 : }
260 :
261 : const std::vector<runtime::Task*>
262 36 : Pipeline_builder::Stage_builder::get_first_tasks()
263 : {
264 36 : return this->first_tasks;
265 : }
266 :
267 : Pipeline_builder::Stage_builder&
268 1 : Pipeline_builder::Stage_builder::set_last_tasks(const std::vector<runtime::Task*> last)
269 : {
270 1 : this->last_tasks.assign(last.begin(), last.end());
271 1 : return *this;
272 : }
273 :
274 : Pipeline_builder::Stage_builder&
275 24 : Pipeline_builder::Stage_builder::add_last_task(runtime::Task* last)
276 : {
277 24 : if (std::find(this->last_tasks.begin(), this->last_tasks.end(), last) != this->last_tasks.end())
278 : {
279 0 : throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in last tasks.");
280 : }
281 :
282 24 : this->last_tasks.push_back(last);
283 24 : return *this;
284 : }
285 :
286 : Pipeline_builder::Stage_builder&
287 24 : Pipeline_builder::Stage_builder::add_last_task(runtime::Task& last)
288 : {
289 24 : return this->add_last_task(&last);
290 : }
291 :
292 : Pipeline_builder::Stage_builder&
293 0 : Pipeline_builder::Stage_builder::remove_last_task(const runtime::Task* last)
294 : {
295 0 : this->last_tasks.erase(std::remove(this->last_tasks.begin(), this->last_tasks.end(), last), this->last_tasks.end());
296 :
297 0 : return *this;
298 : }
299 :
300 : Pipeline_builder::Stage_builder&
301 0 : Pipeline_builder::Stage_builder::remove_last_task(const runtime::Task& last)
302 : {
303 0 : return this->remove_last_task(&last);
304 : }
305 :
306 : const std::vector<runtime::Task*>
307 36 : Pipeline_builder::Stage_builder::get_last_tasks()
308 : {
309 36 : return this->last_tasks;
310 : }
311 :
312 : Pipeline_builder::Stage_builder&
313 1 : Pipeline_builder::Stage_builder::set_excluded_tasks(const std::vector<runtime::Task*> excluded)
314 : {
315 1 : this->excluded_tasks.assign(excluded.begin(), excluded.end());
316 1 : return *this;
317 : }
318 :
319 : Pipeline_builder::Stage_builder&
320 1 : Pipeline_builder::Stage_builder::add_excluded_task(runtime::Task* excluded)
321 : {
322 1 : if (std::find(this->excluded_tasks.begin(), this->excluded_tasks.end(), excluded) != this->excluded_tasks.end())
323 : {
324 0 : throw invalid_argument(__FILE__, __LINE__, __func__, "The task is already added in excluded tasks.");
325 : }
326 :
327 1 : this->excluded_tasks.push_back(excluded);
328 1 : return *this;
329 : }
330 :
331 : Pipeline_builder::Stage_builder&
332 1 : Pipeline_builder::Stage_builder::add_excluded_task(runtime::Task& excluded)
333 : {
334 1 : return this->add_excluded_task(&excluded);
335 : }
336 :
337 : Pipeline_builder::Stage_builder&
338 0 : Pipeline_builder::Stage_builder::remove_excluded_task(const runtime::Task* excluded)
339 : {
340 0 : this->excluded_tasks.erase(std::remove(this->excluded_tasks.begin(), this->excluded_tasks.end(), excluded),
341 0 : this->excluded_tasks.end());
342 :
343 0 : return *this;
344 : }
345 :
346 : Pipeline_builder::Stage_builder&
347 0 : Pipeline_builder::Stage_builder::remove_excluded_task(const runtime::Task& excluded)
348 : {
349 0 : return this->remove_excluded_task(&excluded);
350 : }
351 :
352 : const std::vector<runtime::Task*>
353 28 : Pipeline_builder::Stage_builder::get_excluded_tasks()
354 : {
355 28 : return this->excluded_tasks;
356 : }
357 :
358 : Pipeline_builder::Synchro_builder&
359 3 : Pipeline_builder::Synchro_builder::enable_active_waiting()
360 : {
361 3 : this->active_waiting = true;
362 3 : return *this;
363 : }
364 :
365 : Pipeline_builder::Synchro_builder&
366 14 : Pipeline_builder::Synchro_builder::disable_active_waiting()
367 : {
368 14 : this->active_waiting = false;
369 14 : return *this;
370 : }
371 :
372 : Pipeline_builder::Synchro_builder&
373 17 : Pipeline_builder::Synchro_builder::set_active_waiting(bool waiting)
374 : {
375 17 : return (waiting) ? this->enable_active_waiting() : this->disable_active_waiting();
376 : }
377 :
378 : const bool
379 19 : Pipeline_builder::Synchro_builder::is_active_waiting()
380 : {
381 19 : return this->active_waiting;
382 : }
383 :
384 : Pipeline_builder::Synchro_builder&
385 17 : Pipeline_builder::Synchro_builder::set_buffer_size(size_t buffer_size)
386 : {
387 17 : this->buffer_size = buffer_size;
388 17 : return *this;
389 : }
390 :
391 : const size_t
392 19 : Pipeline_builder::Synchro_builder::get_buffer_size()
393 : {
394 19 : return this->buffer_size;
395 : }
|