Line data Source code
1 : #include <cmath>
2 : #include <sstream>
3 :
4 : #include "Module/Module.hpp"
5 : #include "Module/Stateless/Stateless.hpp"
6 : #include "Tools/Exception/exception.hpp"
7 : #include "Tools/Interface/Interface_reset.hpp"
8 :
9 : using namespace spu;
10 : using namespace spu::module;
11 :
12 1804 : Module::Module()
13 1804 : : n_frames(1)
14 1804 : , n_frames_per_wave(1)
15 1804 : , n_waves(1)
16 1804 : , n_frames_per_wave_rest(0)
17 1804 : , single_wave(false)
18 1804 : , name("Module")
19 3608 : , short_name("Module")
20 : {
21 1804 : }
22 :
23 : void
24 38548 : Module::deep_copy(const Module& m)
25 : {
26 38548 : this->tasks_with_nullptr.clear();
27 38548 : this->tasks.clear();
28 :
29 114525 : for (auto& t : m.tasks_with_nullptr)
30 : {
31 75977 : if (t == nullptr)
32 8998 : this->tasks_with_nullptr.push_back(nullptr);
33 : else
34 : {
35 66979 : auto t_new = std::shared_ptr<runtime::Task>(t->clone());
36 66979 : t_new->module = this;
37 66979 : this->tasks_with_nullptr.push_back(t_new);
38 66979 : this->tasks.push_back(std::move(t_new));
39 66979 : }
40 : }
41 38548 : }
42 :
43 : Module*
44 202 : Module::clone() const
45 : {
46 202 : throw tools::unimplemented_error(__FILE__, __LINE__, __func__);
47 : }
48 :
49 : void
50 43814 : Module::_set_n_frames(const size_t n_frames)
51 : {
52 43814 : if (n_frames == 0)
53 : {
54 0 : std::stringstream message;
55 0 : message << "'n_frames' has to be greater than 0 ('n_frames' = " << n_frames << ").";
56 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
57 0 : }
58 :
59 43814 : const auto old_n_frames = this->get_n_frames();
60 43814 : this->n_frames = n_frames;
61 43814 : this->n_frames_per_wave_rest = this->get_n_frames() % this->get_n_frames_per_wave();
62 43814 : this->n_waves = (size_t)std::ceil((float)this->get_n_frames() / (float)this->get_n_frames_per_wave());
63 123382 : for (auto& t : tasks)
64 79568 : t->update_n_frames((size_t)old_n_frames, (size_t)n_frames);
65 43814 : }
66 :
67 : void
68 9196 : Module::_set_n_frames_per_wave(const size_t n_frames_per_wave)
69 : {
70 9196 : if (n_frames_per_wave == 0)
71 : {
72 0 : std::stringstream message;
73 0 : message << "'n_frames_per_wave' has to be greater than 0 ('n_frames_per_wave' = " << n_frames_per_wave << ").";
74 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
75 0 : }
76 :
77 9196 : const auto old_n_frames_per_wave = this->get_n_frames_per_wave();
78 9196 : this->n_frames_per_wave = n_frames_per_wave;
79 9196 : this->n_frames_per_wave_rest = this->get_n_frames() % this->get_n_frames_per_wave();
80 9196 : this->n_waves = (size_t)std::ceil((float)this->get_n_frames() / (float)this->get_n_frames_per_wave());
81 27428 : for (auto& t : tasks)
82 18232 : t->update_n_frames_per_wave((size_t)old_n_frames_per_wave, (size_t)n_frames_per_wave);
83 9196 : }
84 :
85 : void
86 43937 : Module::set_n_frames(const size_t n_frames)
87 : {
88 43937 : if (this->get_n_frames() != n_frames) this->_set_n_frames(n_frames);
89 :
90 43937 : if (this->is_single_wave() && this->get_n_frames_per_wave() != n_frames) this->set_n_frames_per_wave(n_frames);
91 43937 : }
92 :
93 : void
94 9632 : Module::set_n_frames_per_wave(const size_t n_frames_per_wave)
95 : {
96 9632 : if (this->get_n_frames_per_wave() != n_frames_per_wave) this->_set_n_frames_per_wave(n_frames_per_wave);
97 :
98 9632 : if (this->is_single_wave() && this->get_n_frames() != n_frames_per_wave) this->set_n_frames(n_frames_per_wave);
99 9632 : }
100 :
101 : void
102 436 : Module::set_single_wave(const bool enable_single_wave)
103 : {
104 436 : this->single_wave = enable_single_wave;
105 436 : this->set_n_frames(this->n_frames);
106 436 : this->set_n_frames_per_wave(this->n_frames);
107 436 : }
108 :
109 : void
110 2275 : Module::set_name(const std::string& name)
111 : {
112 2275 : this->name = name;
113 2275 : }
114 :
115 : const std::string&
116 384 : Module::get_name() const
117 : {
118 384 : return this->name;
119 : }
120 :
121 : void
122 1967 : Module::set_short_name(const std::string& short_name)
123 : {
124 1967 : this->short_name = short_name;
125 1967 : }
126 :
127 : const std::string&
128 40 : Module::get_short_name() const
129 : {
130 40 : return this->short_name;
131 : }
132 :
133 : void
134 5107 : Module::set_custom_name(const std::string& custom_name)
135 : {
136 5107 : this->custom_name = custom_name;
137 5107 : }
138 :
139 : const std::string&
140 89585 : Module::get_custom_name() const
141 : {
142 89585 : return this->custom_name;
143 : }
144 :
145 : void
146 0 : Module::remove_custom_name()
147 : {
148 0 : this->custom_name = "";
149 0 : }
150 :
151 : runtime::Task&
152 3071 : Module::create_task(const std::string& name, const int id)
153 : {
154 :
155 3071 : auto it = find_if(this->tasks.begin(),
156 : this->tasks.end(),
157 1267 : [name](std::shared_ptr<runtime::Task> t) { return t->get_name() == name; });
158 :
159 3071 : if (it != this->tasks.end())
160 : {
161 0 : std::stringstream message;
162 0 : message << "runtime::Task '" << name << "' already exists.";
163 0 : throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
164 0 : }
165 :
166 3071 : auto t = std::make_shared<runtime::Task>(*this, name);
167 :
168 3071 : if (id < 0)
169 : {
170 2667 : tasks_with_nullptr.push_back(t);
171 : }
172 404 : else if (tasks_with_nullptr.size() > (size_t)id && tasks_with_nullptr[id] == nullptr)
173 : {
174 404 : tasks_with_nullptr[id] = t;
175 : }
176 : else
177 : {
178 0 : std::stringstream message;
179 0 : message << "Impossible to create the task ('task.name' = " << name << ", 'task.id' = " << id
180 0 : << ", 'tasks.size()' = " << tasks.size() << ", 'module.name' = " << this->get_name() << ").";
181 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
182 0 : }
183 :
184 3071 : tasks.push_back(std::move(t));
185 6142 : return *tasks.back();
186 3071 : }
187 :
188 : runtime::Task&
189 0 : Module::create_tsk(const std::string& name, const int id)
190 : {
191 0 : return this->create_task(name, id);
192 : }
193 :
194 : void
195 3071 : Module::create_codelet(runtime::Task& task,
196 : std::function<int(Module& m, runtime::Task& t, const size_t frame_id)> codelet)
197 : {
198 3071 : task.create_codelet(codelet);
199 3071 : }
200 :
201 : void
202 0 : Module::create_cdl(runtime::Task& task, std::function<int(Module& m, runtime::Task& t, const size_t frame_id)> codelet)
203 : {
204 0 : this->create_codelet(task, codelet);
205 0 : }
206 :
207 : size_t
208 611 : Module::create_socket_in(runtime::Task& task,
209 : const std::string& name,
210 : const size_t n_elmts,
211 : const std::type_index& datatype)
212 : {
213 611 : return task.create_2d_socket_in(name, this->n_frames, n_elmts, datatype);
214 : }
215 :
216 : size_t
217 0 : Module::create_socket_in(runtime::Task& task,
218 : const std::string& name,
219 : const size_t n_elmts,
220 : const runtime::datatype_t datatype)
221 : {
222 0 : return task.create_2d_socket_in(name, this->n_frames, n_elmts, datatype);
223 : }
224 :
225 : size_t
226 0 : Module::create_sck_in(runtime::Task& task,
227 : const std::string& name,
228 : const size_t n_elmts,
229 : const std::type_index& datatype)
230 : {
231 0 : return this->create_socket_in(task, name, n_elmts, datatype);
232 : }
233 :
234 : size_t
235 0 : Module::create_sck_in(runtime::Task& task,
236 : const std::string& name,
237 : const size_t n_elmts,
238 : const runtime::datatype_t datatype)
239 : {
240 0 : return this->create_socket_in(task, name, n_elmts, datatype);
241 : }
242 :
243 : size_t
244 606 : Module::create_socket_out(runtime::Task& task,
245 : const std::string& name,
246 : const size_t n_elmts,
247 : const std::type_index& datatype)
248 : {
249 606 : return task.create_2d_socket_out(name, this->n_frames, n_elmts, datatype);
250 : }
251 :
252 : size_t
253 0 : Module::create_socket_out(runtime::Task& task,
254 : const std::string& name,
255 : const size_t n_elmts,
256 : const runtime::datatype_t datatype)
257 : {
258 0 : return task.create_2d_socket_out(name, this->n_frames, n_elmts, datatype);
259 : }
260 :
261 : size_t
262 0 : Module::create_sck_out(runtime::Task& task,
263 : const std::string& name,
264 : const size_t n_elmts,
265 : const std::type_index& datatype)
266 : {
267 0 : return this->create_socket_out(task, name, n_elmts, datatype);
268 : }
269 :
270 : size_t
271 0 : Module::create_sck_out(runtime::Task& task,
272 : const std::string& name,
273 : const size_t n_elmts,
274 : const runtime::datatype_t datatype)
275 : {
276 0 : return this->create_socket_out(task, name, n_elmts, datatype);
277 : }
278 :
279 : size_t
280 0 : Module::create_socket_fwd(runtime::Task& task,
281 : const std::string& name,
282 : const size_t n_elmts,
283 : const std::type_index& datatype)
284 : {
285 0 : return task.create_2d_socket_fwd(name, this->n_frames, n_elmts, datatype);
286 : }
287 :
288 : size_t
289 0 : Module::create_socket_fwd(runtime::Task& task,
290 : const std::string& name,
291 : const size_t n_elmts,
292 : const runtime::datatype_t datatype)
293 : {
294 0 : return task.create_2d_socket_fwd(name, this->n_frames, n_elmts, datatype);
295 : }
296 :
297 : size_t
298 0 : Module::create_sck_fwd(runtime::Task& task,
299 : const std::string& name,
300 : const size_t n_elmts,
301 : const std::type_index& datatype)
302 : {
303 0 : return this->create_socket_fwd(task, name, n_elmts, datatype);
304 : }
305 :
306 : size_t
307 0 : Module::create_sck_fwd(runtime::Task& task,
308 : const std::string& name,
309 : const size_t n_elmts,
310 : const runtime::datatype_t datatype)
311 : {
312 0 : return this->create_socket_fwd(task, name, n_elmts, datatype);
313 : }
314 :
315 : size_t
316 0 : Module::create_2d_socket_in(runtime::Task& task,
317 : const std::string& name,
318 : const size_t n_rows,
319 : const size_t n_cols,
320 : const std::type_index& datatype)
321 : {
322 0 : return task.create_2d_socket_in(name, this->n_frames * n_rows, n_cols, datatype);
323 : }
324 :
325 : size_t
326 0 : Module::create_2d_socket_in(runtime::Task& task,
327 : const std::string& name,
328 : const size_t n_rows,
329 : const size_t n_cols,
330 : const runtime::datatype_t datatype)
331 : {
332 0 : return task.create_2d_socket_in(name, this->n_frames * n_rows, n_cols, datatype);
333 : }
334 :
335 : size_t
336 0 : Module::create_2d_sck_in(runtime::Task& task,
337 : const std::string& name,
338 : const size_t n_rows,
339 : const size_t n_cols,
340 : const std::type_index& datatype)
341 : {
342 0 : return this->create_2d_socket_in(task, name, n_rows, n_cols, datatype);
343 : }
344 :
345 : size_t
346 0 : Module::create_2d_sck_in(runtime::Task& task,
347 : const std::string& name,
348 : const size_t n_rows,
349 : const size_t n_cols,
350 : const runtime::datatype_t datatype)
351 : {
352 0 : return this->create_2d_socket_in(task, name, n_rows, n_cols, datatype);
353 : }
354 :
355 : size_t
356 0 : Module::create_2d_socket_out(runtime::Task& task,
357 : const std::string& name,
358 : const size_t n_rows,
359 : const size_t n_cols,
360 : const std::type_index& datatype)
361 : {
362 0 : return task.create_2d_socket_out(name, this->n_frames * n_rows, n_cols, datatype);
363 : }
364 :
365 : size_t
366 0 : Module::create_2d_socket_out(runtime::Task& task,
367 : const std::string& name,
368 : const size_t n_rows,
369 : const size_t n_cols,
370 : const runtime::datatype_t datatype)
371 : {
372 0 : return task.create_2d_socket_out(name, this->n_frames * n_rows, n_cols, datatype);
373 : }
374 :
375 : size_t
376 0 : Module::create_2d_sck_out(runtime::Task& task,
377 : const std::string& name,
378 : const size_t n_rows,
379 : const size_t n_cols,
380 : const std::type_index& datatype)
381 : {
382 0 : return this->create_2d_socket_out(task, name, n_rows, n_cols, datatype);
383 : }
384 :
385 : size_t
386 0 : Module::create_2d_sck_out(runtime::Task& task,
387 : const std::string& name,
388 : const size_t n_rows,
389 : const size_t n_cols,
390 : const runtime::datatype_t datatype)
391 : {
392 0 : return this->create_2d_socket_out(task, name, n_rows, n_cols, datatype);
393 : }
394 :
395 : size_t
396 0 : Module::create_2d_socket_fwd(runtime::Task& task,
397 : const std::string& name,
398 : const size_t n_rows,
399 : const size_t n_cols,
400 : const std::type_index& datatype)
401 : {
402 0 : return task.create_2d_socket_fwd(name, this->n_frames * n_rows, n_cols, datatype);
403 : }
404 :
405 : size_t
406 0 : Module::create_2d_socket_fwd(runtime::Task& task,
407 : const std::string& name,
408 : const size_t n_rows,
409 : const size_t n_cols,
410 : const runtime::datatype_t datatype)
411 : {
412 0 : return task.create_2d_socket_fwd(name, this->n_frames * n_rows, n_cols, datatype);
413 : }
414 :
415 : size_t
416 0 : Module::create_2d_sck_fwd(runtime::Task& task,
417 : const std::string& name,
418 : const size_t n_rows,
419 : const size_t n_cols,
420 : const std::type_index& datatype)
421 : {
422 0 : return this->create_2d_socket_fwd(task, name, n_rows, n_cols, datatype);
423 : }
424 :
425 : size_t
426 0 : Module::create_2d_sck_fwd(runtime::Task& task,
427 : const std::string& name,
428 : const size_t n_rows,
429 : const size_t n_cols,
430 : const runtime::datatype_t datatype)
431 : {
432 0 : return this->create_2d_socket_fwd(task, name, n_rows, n_cols, datatype);
433 : }
434 :
435 : void
436 0 : Module::register_timer(runtime::Task& task, const std::string& key)
437 : {
438 0 : task.register_timer(key);
439 0 : }
440 :
441 : void
442 0 : Module::set_fast(const bool fast)
443 : {
444 0 : for (auto& t : this->tasks)
445 0 : t->set_fast(fast);
446 0 : }
447 :
448 : void
449 0 : Module::create_reset_task()
450 : {
451 0 : auto iface = dynamic_cast<spu::tools::Interface_reset*>(this);
452 0 : if (iface == nullptr)
453 : {
454 0 : std::stringstream message;
455 0 : message << "This module does not inherits from the interface Interface_reset.";
456 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
457 0 : }
458 :
459 0 : auto& p = this->create_task("reset");
460 0 : this->create_codelet(p,
461 0 : [](Module& m, runtime::Task& t, const size_t frame_id) -> int
462 : {
463 0 : auto& iface = dynamic_cast<tools::Interface_reset&>(m);
464 0 : iface.reset();
465 0 : return 0;
466 : });
467 0 : }
468 :
469 : bool
470 3081 : Module::is_stateless() const
471 : {
472 3081 : return dynamic_cast<const spu::module::Stateless*>(this);
473 : }
474 :
475 : bool
476 0 : Module::is_stateful() const
477 : {
478 0 : return !this->is_stateless();
479 : }
480 :
481 : bool
482 3081 : Module::is_clonable() const
483 : {
484 3081 : if (this->is_stateless()) return true;
485 : try
486 : {
487 3028 : auto clone = this->clone();
488 2673 : delete clone;
489 2673 : return true;
490 : }
491 355 : catch (tools::unimplemented_error&)
492 : {
493 355 : return false;
494 355 : }
495 : }
|