Line data Source code
1 : #include <algorithm>
2 : #include <iterator>
3 : #include <sstream>
4 : #include <type_traits>
5 : #include <utility>
6 :
7 : #include "Runtime/Socket/Socket.hpp"
8 : #include "Tools/Exception/exception.hpp"
9 : #ifdef SPU_SHOW_DEPRECATED
10 : #include "Tools/Display/rang_format/rang_format.h"
11 : #ifdef SPU_STACKTRACE
12 : #include <cpptrace/cpptrace.hpp>
13 : #endif
14 : #endif
15 :
16 : namespace spu
17 : {
18 : namespace runtime
19 : {
20 : static std::unordered_map<std::type_index, std::string> type_to_string = {
21 : { typeid(int8_t), "int8" }, { typeid(uint8_t), "uint8" }, { typeid(int16_t), "int16" },
22 : { typeid(uint16_t), "uint16" }, { typeid(int32_t), "int32" }, { typeid(uint32_t), "uint32" },
23 : { typeid(int64_t), "int64" }, { typeid(uint64_t), "uint64" }, { typeid(float), "float32" },
24 : { typeid(double), "float64" }
25 : };
26 :
27 : static std::unordered_map<std::type_index, uint8_t> type_to_size = { { typeid(int8_t), 1 }, { typeid(uint8_t), 1 },
28 : { typeid(int16_t), 2 }, { typeid(uint16_t), 2 },
29 : { typeid(int32_t), 4 }, { typeid(uint32_t), 4 },
30 : { typeid(int64_t), 8 }, { typeid(uint64_t), 8 },
31 : { typeid(float), 4 }, { typeid(double), 8 } };
32 :
33 191820 : Socket::Socket(Task& task,
34 : const std::string& name,
35 : const std::type_index datatype,
36 : const std::pair<size_t, size_t> databytes_per_dim,
37 : const socket_t type,
38 : const bool fast,
39 191820 : void* dataptr)
40 191820 : : task(task)
41 191820 : , name(name)
42 191820 : , datatype(datatype)
43 191820 : , databytes(std::get<0>(databytes_per_dim) * std::get<1>(databytes_per_dim))
44 191820 : , fast(fast)
45 191820 : , dataptr(dataptr)
46 191820 : , rowsptr(nullptr)
47 191820 : , n_rows(std::get<0>(databytes_per_dim))
48 191820 : , start_row(0)
49 191820 : , bound_socket(nullptr)
50 383640 : , type(type)
51 : {
52 191820 : if (databytes % type_to_size[datatype] != 0)
53 : {
54 0 : std::stringstream message;
55 : message << "'databytes % type_to_size[datatype]' has to be equal to 0 ("
56 0 : << "'databytes' = " << databytes << ", "
57 0 : << "'type_to_size[datatype]' = " << type_to_size[datatype] << ", "
58 0 : << "'datatype' = " << type_to_string[datatype] << ").";
59 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
60 0 : }
61 :
62 191820 : this->rowsptr = new void*[this->n_rows];
63 191820 : }
64 :
65 9240 : Socket::Socket(Task& task,
66 : const std::string& name,
67 : const std::type_index datatype,
68 : const size_t databytes,
69 : const socket_t type,
70 : const bool fast,
71 9240 : void* dataptr)
72 9240 : : Socket(task, name, datatype, { 1, databytes }, type, fast, dataptr)
73 : {
74 9240 : }
75 :
76 376010 : Socket::~Socket()
77 : {
78 191820 : this->reset();
79 191820 : this->rowsptr -= this->start_row;
80 191820 : delete[] rowsptr;
81 376010 : }
82 :
83 : const std::string&
84 0 : Socket::get_name() const
85 : {
86 0 : return name;
87 : }
88 :
89 : const std::type_index&
90 185749 : Socket::get_datatype() const
91 : {
92 185749 : return datatype;
93 : }
94 :
95 : const std::string&
96 441 : Socket::get_datatype_string() const
97 : {
98 441 : return type_to_string[datatype];
99 : }
100 :
101 : uint8_t
102 1433 : Socket::get_datatype_size() const
103 : {
104 1433 : return type_to_size[datatype];
105 : }
106 :
107 : size_t
108 627590 : Socket::get_databytes() const
109 : {
110 627590 : return databytes;
111 : }
112 :
113 : size_t
114 621 : Socket::get_n_elmts() const
115 : {
116 621 : return get_databytes() / (size_t)get_datatype_size();
117 : }
118 :
119 : size_t
120 602048 : Socket::get_n_rows() const
121 : {
122 602048 : return this->n_rows;
123 : }
124 :
125 : void*
126 2938879 : Socket::_get_dataptr(const size_t start_col) const
127 : {
128 2938879 : uint8_t* ptr = (uint8_t*)dataptr;
129 2938879 : return (void*)(ptr + start_col);
130 : }
131 :
132 : void*
133 0 : Socket::get_dataptr(const size_t start_col) const
134 : {
135 : #ifdef SPU_SHOW_DEPRECATED
136 : std::clog << rang::tag::warning
137 : << "Deprecated: 'Socket::get_dataptr' should be replaced by 'Socket::get_dataptr<T>'." << std::endl;
138 : #ifdef SPU_STACKTRACE
139 : #ifdef SPU_COLORS
140 : bool enable_color = true;
141 : #else
142 : bool enable_color = false;
143 : #endif
144 : cpptrace::generate_trace().print(std::clog, enable_color);
145 : #endif
146 : #endif
147 0 : return this->_get_dataptr(start_col);
148 : }
149 :
150 : void*
151 : Socket::_get_dptr(const size_t start_col) const
152 : {
153 : return this->get_dataptr(start_col);
154 : }
155 :
156 : void*
157 : Socket::get_dptr(const size_t start_col) const
158 : {
159 : #ifdef SPU_SHOW_DEPRECATED
160 : std::clog << rang::tag::warning << "Deprecated: 'Socket::get_dptr' should be replaced by 'Socket::get_dptr<T>'."
161 : << std::endl;
162 : #ifdef SPU_STACKTRACE
163 : #ifdef SPU_COLORS
164 : bool enable_color = true;
165 : #else
166 : bool enable_color = false;
167 : #endif
168 : cpptrace::generate_trace().print(std::clog, enable_color);
169 : #endif
170 : #endif
171 : return this->_get_dptr(start_col);
172 : }
173 :
174 : void**
175 : Socket::_get_2d_dataptr(const size_t start_row, const size_t start_col)
176 : {
177 : assert(start_row < this->get_n_rows());
178 : const size_t n_cols = this->get_databytes() / this->get_n_rows();
179 : assert(start_col < n_cols);
180 :
181 : this->rowsptr -= this->start_row;
182 : uint8_t* dptr = (uint8_t*)get_dataptr() + start_col;
183 : for (size_t r = 0; r < this->get_n_rows(); r++)
184 : {
185 : this->rowsptr[r] = (void*)dptr;
186 : dptr += n_cols;
187 : }
188 :
189 : this->start_row = start_row;
190 : this->rowsptr += this->start_row;
191 :
192 : return this->rowsptr;
193 : }
194 :
195 : void**
196 : Socket::get_2d_dataptr(const size_t start_row, const size_t start_col)
197 : {
198 : #ifdef SPU_SHOW_DEPRECATED
199 : std::clog << rang::tag::warning
200 : << "Deprecated: 'Socket::get_2d_dataptr' should be replaced by 'Socket::get_2d_dataptr<T>'." << std::endl;
201 : #ifdef SPU_STACKTRACE
202 : #ifdef SPU_COLORS
203 : bool enable_color = true;
204 : #else
205 : bool enable_color = false;
206 : #endif
207 : cpptrace::generate_trace().print(std::clog, enable_color);
208 : #endif
209 : #endif
210 : return this->_get_2d_dataptr(start_row, start_col);
211 : }
212 :
213 : void**
214 : Socket::_get_2d_dptr(const size_t start_row, const size_t start_col)
215 : {
216 : return this->get_2d_dataptr(start_row, start_col);
217 : }
218 :
219 : void**
220 : Socket::get_2d_dptr(const size_t start_row, const size_t start_col)
221 : {
222 : #ifdef SPU_SHOW_DEPRECATED
223 : std::clog << rang::tag::warning
224 : << "Deprecated: 'Socket::get_2d_dptr' should be replaced by 'Socket::get_2d_dptr<T>'." << std::endl;
225 : #ifdef SPU_STACKTRACE
226 : #ifdef SPU_COLORS
227 : bool enable_color = true;
228 : #else
229 : bool enable_color = false;
230 : #endif
231 : cpptrace::generate_trace().print(std::clog, enable_color);
232 : #endif
233 : #endif
234 : return this->_get_2d_dptr(start_row, start_col);
235 : }
236 :
237 : template<typename T>
238 : T*
239 11144825 : Socket::get_dataptr(const size_t start_col) const
240 : {
241 : #ifndef SPU_FAST
242 11144825 : if (this->get_type() == socket_t::SIN && !std::is_const<T>::value)
243 : {
244 0 : std::stringstream message;
245 : message << "'This is an input socket and the 'T' template should be 'const' ("
246 : << "'T' = " << typeid(T).name() << ", "
247 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
248 0 : << "'name' = " << get_name() << ", "
249 0 : << "'task.name' = " << task.get_name() << ").";
250 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
251 0 : }
252 : #endif
253 :
254 11139165 : return static_cast<T*>(this->_get_dataptr(start_col * sizeof(T)));
255 : }
256 :
257 : template<typename T>
258 : T*
259 : Socket::get_dptr(const size_t start_col) const
260 : {
261 : return this->template get_dataptr<T>(start_col);
262 : }
263 :
264 : template<typename T>
265 : T**
266 : Socket::get_2d_dataptr(const size_t start_row, const size_t start_col)
267 : {
268 : #ifndef SPU_FAST
269 : if (this->get_type() == socket_t::SIN && !std::is_const<T>::value)
270 : {
271 : std::stringstream message;
272 : message << "'This is an input socket and the 'T' template should be 'const' ("
273 : << "'T' = " << typeid(T).name() << ", "
274 : << "'datatype' = " << type_to_string[this->datatype] << ", "
275 : << "'name' = " << get_name() << ", "
276 : << "'task.name' = " << task.get_name() << ").";
277 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
278 : }
279 : #endif
280 :
281 : return (T**)(this->_get_2d_dataptr(start_row, start_col * sizeof(T)));
282 : }
283 :
284 : template<typename T>
285 : T**
286 : Socket::get_2d_dptr(const size_t start_row, const size_t start_col)
287 : {
288 : return this->template get_2d_dataptr<T>(start_row, start_col);
289 : }
290 :
291 : bool
292 0 : Socket::is_fast() const
293 : {
294 : #ifndef SPU_FAST
295 0 : return fast;
296 : #else
297 : return true;
298 : #endif
299 : }
300 :
301 : Task&
302 89976 : Socket::get_task() const
303 : {
304 89976 : return this->task;
305 : }
306 :
307 : const std::vector<Socket*>&
308 116951 : Socket::get_bound_sockets() const
309 : {
310 116951 : return this->bound_sockets;
311 : }
312 :
313 : Socket&
314 51925 : Socket::get_bound_socket()
315 : {
316 51925 : if (this->bound_socket == nullptr)
317 : {
318 740 : std::stringstream message;
319 740 : message << "bound_socket can't be nullptr.";
320 740 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
321 740 : }
322 51185 : return *this->bound_socket;
323 : }
324 :
325 : const Socket&
326 : Socket::get_bound_socket() const
327 : {
328 : if (this->bound_socket == nullptr)
329 : {
330 : std::stringstream message;
331 : message << "bound_socket can't be nullptr.";
332 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
333 : }
334 : return *this->bound_socket;
335 : }
336 :
337 : socket_t
338 0 : Socket::get_type() const
339 : {
340 0 : return this->type;
341 : }
342 :
343 : void
344 200647 : Socket::set_fast(const bool fast)
345 : {
346 200647 : this->fast = fast;
347 200647 : }
348 :
349 : void
350 0 : Socket::_bind(Socket& s_out, const int priority)
351 : {
352 : #ifndef SPU_FAST
353 0 : if (!is_fast())
354 : {
355 0 : if (s_out.datatype != this->datatype)
356 : {
357 0 : std::stringstream message;
358 : message << "'s_out.datatype' has to be equal to 'datatype' ("
359 0 : << "'s_out.datatype' = " << type_to_string[s_out.datatype] << ", "
360 0 : << "'s_out.name' = " << s_out.get_name() << ", "
361 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
362 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
363 0 : << "'name' = " << get_name() << ", "
364 0 : << "'task.name' = " << task.get_name() << ").";
365 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
366 0 : }
367 :
368 0 : if (s_out.databytes != this->databytes)
369 : {
370 0 : std::stringstream message;
371 : message << "'s_out.databytes' has to be equal to 'databytes' ("
372 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
373 0 : << "'s_out.name' = " << s_out.get_name() << ", "
374 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
375 0 : << "'databytes' = " << this->databytes << ", "
376 0 : << "'name' = " << get_name() << ", "
377 0 : << "'task.name' = " << task.get_name() << ").";
378 :
379 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
380 0 : }
381 :
382 0 : if (s_out.dataptr == nullptr)
383 : {
384 0 : std::stringstream message;
385 0 : message << "'s_out.dataptr' can't be NULL.";
386 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
387 0 : }
388 : }
389 : #endif
390 :
391 0 : if (this->bound_socket == &s_out) this->unbind(s_out);
392 :
393 : #ifndef SPU_FAST
394 0 : if (this->bound_socket != nullptr && this->get_type() == socket_t::SIN)
395 : {
396 0 : std::stringstream message;
397 : message << "This socket is already connected ("
398 0 : << "'bound_socket->databytes' = " << this->bound_socket->databytes << ", "
399 0 : << "'bound_socket->name' = " << this->bound_socket->get_name() << ", "
400 0 : << "'bound_socket->task.name' = " << this->bound_socket->task.get_name() << ", "
401 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
402 0 : << "'s_out.name' = " << s_out.get_name() << ", "
403 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
404 0 : << "'databytes' = " << this->databytes << ", "
405 0 : << "'name' = " << get_name() << ", "
406 0 : << "'task.name' = " << task.get_name() << ").";
407 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
408 0 : }
409 : #endif
410 :
411 0 : this->bound_socket = &s_out;
412 :
413 : #ifndef SPU_FAST
414 0 : if (std::find(s_out.bound_sockets.begin(), s_out.bound_sockets.end(), this) != s_out.bound_sockets.end())
415 : {
416 0 : std::stringstream message;
417 : message << "It is not possible to bind the same socket twice ("
418 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
419 0 : << "'s_out.name' = " << s_out.get_name() << ", "
420 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
421 0 : << "'databytes' = " << this->databytes << ", "
422 0 : << "'name' = " << get_name() << ", "
423 0 : << "'task.name' = " << task.get_name() << ").";
424 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
425 0 : }
426 : #endif
427 :
428 0 : if ((size_t)priority > s_out.bound_sockets.size() || priority == -1)
429 0 : s_out.bound_sockets.push_back(this);
430 : else
431 0 : s_out.bound_sockets.insert(s_out.bound_sockets.begin() + priority, this);
432 0 : this->dataptr = s_out.dataptr;
433 0 : }
434 :
435 : void
436 : Socket::bind(Socket& s_out, const int priority)
437 : {
438 : #ifdef SPU_SHOW_DEPRECATED
439 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
440 : << std::endl;
441 : #ifdef SPU_STACKTRACE
442 : #ifdef SPU_COLORS
443 : bool enable_color = true;
444 : #else
445 : bool enable_color = false;
446 : #endif
447 : cpptrace::generate_trace().print(std::clog, enable_color);
448 : #endif
449 : #endif
450 : this->_bind(s_out, priority);
451 : }
452 :
453 : void
454 : Socket::operator()(Socket& s_out, const int priority)
455 : {
456 : #ifdef SPU_SHOW_DEPRECATED
457 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
458 : << std::endl;
459 : #ifdef SPU_STACKTRACE
460 : #ifdef SPU_COLORS
461 : bool enable_color = true;
462 : #else
463 : bool enable_color = false;
464 : #endif
465 : cpptrace::generate_trace().print(std::clog, enable_color);
466 : #endif
467 : #endif
468 : this->_bind(s_out, priority);
469 : }
470 :
471 : template<typename T>
472 : void
473 : Socket::operator=(const void* array)
474 : {
475 : #ifndef SPU_FAST
476 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
477 : #endif
478 : this->_bind(array);
479 : #ifndef SPU_FAST
480 : else
481 : {
482 : std::stringstream message;
483 : message << "Current socket have to be an input or forward socket ("
484 : << "'datatype' = " << type_to_string[this->datatype] << ", "
485 : << "'name' = " << get_name() << ", "
486 : << "'task.name' = " << task.get_name() << ", "
487 : << "'type' = "
488 : << (get_type() == socket_t::SIN ? "SIN"
489 : : get_type() == socket_t::SFWD ? "SFWD"
490 : : "SOUT")
491 : << ").";
492 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
493 : }
494 : #endif
495 : }
496 :
497 : template<typename T>
498 : void
499 : Socket::operator=(void* array)
500 : {
501 : #ifndef SPU_FAST
502 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
503 : #endif
504 : this->_bind(array);
505 : #ifndef SPU_FAST
506 : else
507 : {
508 : std::stringstream message;
509 : message << "Current socket have to be an input or forward socket ("
510 : << "'datatype' = " << type_to_string[this->datatype] << ", "
511 : << "'name' = " << get_name() << ", "
512 : << "'task.name' = " << task.get_name() << ", "
513 : << "'type' = "
514 : << (get_type() == socket_t::SIN ? "SIN"
515 : : get_type() == socket_t::SFWD ? "SFWD"
516 : : "SOUT")
517 : << ").";
518 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
519 : }
520 : #endif
521 : }
522 :
523 : template<typename T>
524 : void
525 : Socket::operator=(const T* array)
526 : {
527 : #ifndef SPU_FAST
528 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
529 : #endif
530 : this->_bind(array);
531 : #ifndef SPU_FAST
532 : else
533 : {
534 : std::stringstream message;
535 : message << "Current socket have to be an input or forward socket ("
536 : << "'datatype' = " << type_to_string[this->datatype] << ", "
537 : << "'name' = " << get_name() << ", "
538 : << "'task.name' = " << task.get_name() << ", "
539 : << "'type' = "
540 : << (get_type() == socket_t::SIN ? "SIN"
541 : : get_type() == socket_t::SFWD ? "SFWD"
542 : : "SOUT")
543 : << ").";
544 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
545 : }
546 : #endif
547 : }
548 :
549 : template<typename T>
550 : void
551 42 : Socket::operator=(T* array)
552 : {
553 : #ifndef SPU_FAST
554 42 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
555 : #endif
556 43 : this->_bind(array);
557 : #ifndef SPU_FAST
558 : else
559 : {
560 0 : std::stringstream message;
561 : message << "Current socket have to be an input or forward socket ("
562 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
563 0 : << "'name' = " << get_name() << ", "
564 0 : << "'task.name' = " << task.get_name() << ", "
565 : << "'type' = "
566 0 : << (get_type() == socket_t::SIN ? "SIN"
567 0 : : get_type() == socket_t::SFWD ? "SFWD"
568 : : "SOUT")
569 0 : << ").";
570 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
571 0 : }
572 : #endif
573 50 : }
574 :
575 : template<typename T, class A>
576 : void
577 : Socket::operator=(const std::vector<T, A>& vector)
578 : {
579 : #ifndef SPU_FAST
580 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
581 : #endif
582 : this->_bind(vector);
583 : #ifndef SPU_FAST
584 : else
585 : {
586 : std::stringstream message;
587 : message << "Current socket have to be an input or forward socket ("
588 : << "'datatype' = " << type_to_string[this->datatype] << ", "
589 : << "'name' = " << get_name() << ", "
590 : << "'task.name' = " << task.get_name() << ", "
591 : << "'type' = "
592 : << (get_type() == socket_t::SIN ? "SIN"
593 : : get_type() == socket_t::SFWD ? "SFWD"
594 : : "SOUT")
595 : << ").";
596 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
597 : }
598 : #endif
599 : }
600 :
601 : template<typename T, class A>
602 : void
603 : Socket::operator=(std::vector<T, A>& vector)
604 : {
605 : #ifndef SPU_FAST
606 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
607 : #endif
608 : this->_bind(vector);
609 : #ifndef SPU_FAST
610 : else
611 : {
612 : std::stringstream message;
613 : message << "Current socket have to be an input or forward socket ("
614 : << "'datatype' = " << type_to_string[this->datatype] << ", "
615 : << "'name' = " << get_name() << ", "
616 : << "'task.name' = " << task.get_name() << ", "
617 : << "'type' = "
618 : << (get_type() == socket_t::SIN ? "SIN"
619 : : get_type() == socket_t::SFWD ? "SFWD"
620 : : "SOUT")
621 : << ").";
622 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
623 : }
624 : #endif
625 : }
626 :
627 : void
628 0 : Socket::operator=(Socket& s)
629 : {
630 0 : if ((s.get_type() == socket_t::SOUT || s.get_type() == socket_t::SFWD) &&
631 0 : (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD))
632 0 : this->_bind(s);
633 0 : else if ((s.get_type() == socket_t::SIN || s.get_type() == socket_t::SFWD) &&
634 0 : (this->get_type() == socket_t::SOUT || this->get_type() == socket_t::SFWD))
635 0 : s._bind(*this);
636 : // Socket forward bind
637 0 : else if (s.get_type() == socket_t::SFWD && this->get_type() == socket_t::SFWD)
638 0 : this->_bind(s);
639 : #ifndef SPU_FAST
640 : else
641 : {
642 0 : std::stringstream message;
643 : message << "Binding of [output and input] or [forward and input] or [forward and forward] socket is required ("
644 0 : << "'s.datatype' = " << type_to_string[s.datatype] << ", "
645 0 : << "'s.name' = " << s.get_name() << ", "
646 0 : << "'s.task.name' = " << s.task.get_name() << ", "
647 : << "'s.type' = "
648 0 : << (s.get_type() == socket_t::SIN ? "SIN"
649 0 : : s.get_type() == socket_t::SFWD ? "SFWD"
650 : : "SOUT")
651 : << ", "
652 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
653 0 : << "'name' = " << get_name() << ", "
654 0 : << "'task.name' = " << task.get_name() << ", "
655 : << "'type' = "
656 0 : << (get_type() == socket_t::SIN ? "SIN"
657 0 : : get_type() == socket_t::SFWD ? "SFWD"
658 : : "SOUT")
659 0 : << ").";
660 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
661 0 : }
662 : #endif
663 0 : }
664 :
665 : void
666 : Socket::operator=(Task& t)
667 : {
668 : #ifndef SPU_FAST
669 : if (this->get_type() == socket_t::SOUT || this->get_type() == socket_t::SFWD)
670 : #endif
671 : t._bind(*this);
672 : #ifndef SPU_FAST
673 : else
674 : {
675 : std::stringstream message;
676 : message << "The current socket should be and output socket ("
677 : << "'datatype' = " << type_to_string[this->datatype] << ", "
678 : << "'name' = " << get_name() << ", "
679 : << "'task.name' = " << task.get_name() << ", "
680 : << "'type' = "
681 : << (get_type() == socket_t::SIN ? "SIN"
682 : : get_type() == socket_t::SFWD ? "SFWD"
683 : : "SOUT")
684 : << ").";
685 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
686 : }
687 : #endif
688 : }
689 :
690 : template<typename T, class A>
691 : void
692 : Socket::_bind(const std::vector<T, A>& vector)
693 : {
694 : this->_bind(const_cast<std::vector<T, A>&>(vector));
695 : }
696 :
697 : template<typename T, class A>
698 : void
699 : Socket::bind(const std::vector<T, A>& vector)
700 : {
701 : #ifdef SPU_SHOW_DEPRECATED
702 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
703 : << std::endl;
704 : #ifdef SPU_STACKTRACE
705 : #ifdef SPU_COLORS
706 : bool enable_color = true;
707 : #else
708 : bool enable_color = false;
709 : #endif
710 : cpptrace::generate_trace().print(std::clog, enable_color);
711 : #endif
712 : #endif
713 : this->_bind(vector);
714 : }
715 :
716 : template<typename T, class A>
717 : void
718 : Socket::_bind(std::vector<T, A>& vector)
719 : {
720 : #ifndef SPU_FAST
721 : if (is_fast())
722 : #endif
723 : this->dataptr = static_cast<void*>(vector.data());
724 : #ifndef SPU_FAST
725 : else
726 : {
727 : if (vector.size() != this->get_n_elmts())
728 : {
729 : std::stringstream message;
730 : message << "'vector.size()' has to be equal to 'get_n_elmts()' ('vector.size()' = " << vector.size()
731 : << ", 'get_n_elmts()' = " << get_n_elmts() << ", 'name' = " << get_name() << ", 'task.name' = "
732 : << task.get_name()
733 : // << ", 'task.module.name' = " << task.get_module_name()
734 : << ").";
735 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
736 : }
737 :
738 : this->_bind(vector.data());
739 : }
740 : #endif
741 : }
742 :
743 : template<typename T, class A>
744 : void
745 : Socket::bind(std::vector<T, A>& vector)
746 : {
747 : #ifdef SPU_SHOW_DEPRECATED
748 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
749 : << std::endl;
750 : #ifdef SPU_STACKTRACE
751 : #ifdef SPU_COLORS
752 : bool enable_color = true;
753 : #else
754 : bool enable_color = false;
755 : #endif
756 : cpptrace::generate_trace().print(std::clog, enable_color);
757 : #endif
758 : #endif
759 : this->_bind(vector);
760 : }
761 :
762 : template<typename T, class A>
763 : void
764 : Socket::operator()(std::vector<T, A>& vector)
765 : {
766 : #ifdef SPU_SHOW_DEPRECATED
767 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
768 : << std::endl;
769 : #ifdef SPU_STACKTRACE
770 : #ifdef SPU_COLORS
771 : bool enable_color = true;
772 : #else
773 : bool enable_color = false;
774 : #endif
775 : cpptrace::generate_trace().print(std::clog, enable_color);
776 : #endif
777 : #endif
778 : this->_bind(vector);
779 : }
780 :
781 : template<typename T>
782 : void
783 0 : Socket::_bind(const T* array)
784 : {
785 0 : this->_bind(const_cast<T*>(array));
786 0 : }
787 :
788 : template<typename T>
789 : void
790 0 : Socket::bind(const T* array)
791 : {
792 : #ifdef SPU_SHOW_DEPRECATED
793 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
794 : << std::endl;
795 : #ifdef SPU_STACKTRACE
796 : #ifdef SPU_COLORS
797 : bool enable_color = true;
798 : #else
799 : bool enable_color = false;
800 : #endif
801 : cpptrace::generate_trace().print(std::clog, enable_color);
802 : #endif
803 : #endif
804 0 : this->_bind(array);
805 0 : }
806 :
807 : template<typename T>
808 : void
809 0 : Socket::_bind(T* array)
810 : {
811 : #ifndef SPU_FAST
812 0 : if (is_fast())
813 : #endif
814 0 : this->dataptr = static_cast<void*>(array);
815 : #ifndef SPU_FAST
816 : else
817 : {
818 0 : if (type_to_string[typeid(T)] != type_to_string[this->datatype])
819 : {
820 0 : std::stringstream message;
821 0 : message << "'T' has to be equal to 'datatype' ('T' = " << type_to_string[typeid(T)]
822 0 : << ", 'datatype' = " << type_to_string[this->datatype] << ", 'socket.name' = " << get_name()
823 0 : << ", 'task.name' = " << task.get_name() << ").";
824 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
825 0 : }
826 :
827 0 : this->_bind(static_cast<void*>(array));
828 : }
829 : #endif
830 0 : }
831 :
832 : template<typename T>
833 : void
834 0 : Socket::bind(T* array)
835 : {
836 : #ifdef SPU_SHOW_DEPRECATED
837 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
838 : << std::endl;
839 : #ifdef SPU_STACKTRACE
840 : #ifdef SPU_COLORS
841 : bool enable_color = true;
842 : #else
843 : bool enable_color = false;
844 : #endif
845 : cpptrace::generate_trace().print(std::clog, enable_color);
846 : #endif
847 : #endif
848 0 : this->_bind(array);
849 0 : }
850 :
851 : template<typename T>
852 : void
853 : Socket::operator()(T* array)
854 : {
855 : #ifdef SPU_SHOW_DEPRECATED
856 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
857 : << std::endl;
858 : #ifdef SPU_STACKTRACE
859 : #ifdef SPU_COLORS
860 : bool enable_color = true;
861 : #else
862 : bool enable_color = false;
863 : #endif
864 : cpptrace::generate_trace().print(std::clog, enable_color);
865 : #endif
866 : #endif
867 : this->_bind(array);
868 : }
869 :
870 : void
871 933552 : Socket::_bind(void* dataptr)
872 : {
873 : #ifndef SPU_FAST
874 933552 : if (!is_fast())
875 : {
876 48 : if (dataptr == nullptr)
877 : {
878 0 : std::stringstream message;
879 0 : message << "'s.dataptr' can't be NULL.";
880 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
881 0 : }
882 48 : this->check_bound_socket();
883 : }
884 : #endif
885 932328 : this->dataptr = dataptr;
886 932328 : }
887 :
888 : void
889 : Socket::bind(void* dataptr)
890 : {
891 : #ifdef SPU_SHOW_DEPRECATED
892 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
893 : << std::endl;
894 : #ifdef SPU_STACKTRACE
895 : #ifdef SPU_COLORS
896 : bool enable_color = true;
897 : #else
898 : bool enable_color = false;
899 : #endif
900 : cpptrace::generate_trace().print(std::clog, enable_color);
901 : #endif
902 : #endif
903 : this->_bind(dataptr);
904 : }
905 :
906 : void
907 : Socket::operator()(void* dataptr)
908 : {
909 : #ifdef SPU_SHOW_DEPRECATED
910 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
911 : << std::endl;
912 : #ifdef SPU_STACKTRACE
913 : #ifdef SPU_COLORS
914 : bool enable_color = true;
915 : #else
916 : bool enable_color = false;
917 : #endif
918 : cpptrace::generate_trace().print(std::clog, enable_color);
919 : #endif
920 : #endif
921 : this->_bind(dataptr);
922 : }
923 :
924 : void
925 191820 : Socket::reset()
926 : {
927 191820 : if (this->bound_socket != nullptr) this->unbind(*this->bound_socket);
928 : // the backforward loop is required here because the 'unbind' method can remove elements in 'bound_sockets' array
929 216230 : for (int sid = (int)this->bound_sockets.size() - 1; sid >= 0; sid--)
930 24410 : this->bound_sockets[sid]->unbind(*this);
931 191820 : }
932 :
933 : size_t
934 0 : Socket::unbind(Socket& s_out)
935 : {
936 : #ifndef SPU_FAST
937 0 : if (this->bound_socket == nullptr)
938 : {
939 0 : std::stringstream message;
940 : message << "The current input socket can't be unbound because it is not bound to any output socket ("
941 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
942 0 : << "'s_out.name' = " << s_out.get_name() << ", "
943 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
944 0 : << "'databytes' = " << this->databytes << ", "
945 0 : << "'name' = " << get_name() << ", "
946 0 : << "'task.name' = " << task.get_name() << ").";
947 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
948 0 : }
949 :
950 0 : if (this->bound_socket != &s_out)
951 : {
952 0 : std::stringstream message;
953 : message << "This socket is connected to a different socket than 's_out' ("
954 0 : << "'bound_socket->databytes' = " << this->bound_socket->databytes << ", "
955 0 : << "'bound_socket->name' = " << this->bound_socket->get_name() << ", "
956 0 : << "'bound_socket->task.name' = " << this->bound_socket->task.get_name() << ", "
957 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
958 0 : << "'s_out.name' = " << s_out.get_name() << ", "
959 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
960 0 : << "'databytes' = " << this->databytes << ", "
961 0 : << "'name' = " << get_name() << ", "
962 0 : << "'task.name' = " << task.get_name() << ").";
963 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
964 0 : }
965 : #endif
966 :
967 0 : this->bound_socket = nullptr;
968 :
969 0 : size_t unbind_pos = 0;
970 0 : auto it = std::find(s_out.bound_sockets.begin(), s_out.bound_sockets.end(), this);
971 :
972 : #ifndef SPU_FAST
973 0 : if (it != s_out.bound_sockets.end())
974 : {
975 : #endif
976 0 : unbind_pos = (size_t)std::distance(s_out.bound_sockets.begin(), it);
977 0 : s_out.bound_sockets.erase(it);
978 : #ifndef SPU_FAST
979 : }
980 : else
981 : {
982 0 : std::stringstream message;
983 : message << "The 's_out' output socket is not bound to the current input socket ("
984 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
985 0 : << "'s_out.name' = " << s_out.get_name() << ", "
986 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
987 0 : << "'databytes' = " << this->databytes << ", "
988 0 : << "'name' = " << get_name() << ", "
989 0 : << "'task.name' = " << task.get_name() << ").";
990 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
991 0 : }
992 : #endif
993 :
994 0 : return unbind_pos;
995 : }
996 :
997 : void
998 : Socket::set_name(const std::string& name)
999 : {
1000 : if (name != this->get_name())
1001 : {
1002 : this->check_bound_socket();
1003 : this->name = name;
1004 : }
1005 : }
1006 :
1007 : void
1008 : Socket::set_datatype(const std::type_index datatype)
1009 : {
1010 : if (datatype != this->get_datatype())
1011 : {
1012 : this->check_bound_socket();
1013 : this->datatype = datatype;
1014 : }
1015 : }
1016 :
1017 : void
1018 205642 : Socket::set_databytes(const size_t databytes)
1019 : {
1020 205642 : if (databytes != this->get_databytes())
1021 : {
1022 205642 : this->check_bound_socket();
1023 205642 : this->databytes = databytes;
1024 : }
1025 205642 : }
1026 :
1027 : void
1028 129404 : Socket::set_dataptr(void* dataptr)
1029 : {
1030 129404 : if (dataptr != this->_get_dataptr())
1031 : {
1032 64750 : this->check_bound_socket();
1033 64750 : this->dataptr = dataptr;
1034 : }
1035 129404 : }
1036 :
1037 : void
1038 126074 : Socket::set_n_rows(const size_t n_rows)
1039 : {
1040 126074 : if (n_rows != this->get_n_rows())
1041 : {
1042 126074 : this->n_rows = n_rows;
1043 126074 : this->rowsptr -= this->start_row;
1044 126074 : delete[] this->rowsptr;
1045 :
1046 126074 : this->rowsptr = new void*[this->n_rows];
1047 126074 : this->start_row = 0;
1048 : }
1049 126074 : }
1050 :
1051 : void
1052 270442 : Socket::check_bound_socket()
1053 : {
1054 270442 : if (bound_sockets.size() != 0 || bound_socket != nullptr)
1055 : {
1056 0 : std::stringstream bound_sockets_str;
1057 0 : if (bound_sockets.size() != 0)
1058 : {
1059 0 : bound_sockets_str << ", 'bound_sockets' = [";
1060 :
1061 0 : for (size_t bs = 0; bs < bound_sockets.size(); bs++)
1062 : {
1063 : bound_sockets_str << "{"
1064 0 : << "'name' = " << bound_sockets[bs]->get_name() << ", "
1065 0 : << "'databytes' = " << bound_sockets[bs]->get_databytes() << ", "
1066 0 : << "'task.name' = " << bound_sockets[bs]->get_task().get_name() << "}";
1067 0 : if (bs < bound_sockets.size() - 1) bound_sockets_str << ", ";
1068 : }
1069 :
1070 0 : bound_sockets_str << "]";
1071 : }
1072 0 : else if (bound_socket != nullptr)
1073 : {
1074 0 : bound_sockets_str << ", 'bound_socket' = ";
1075 : bound_sockets_str << "{"
1076 0 : << "'name' = " << bound_socket->get_name() << ", "
1077 0 : << "'databytes' = " << bound_socket->get_databytes() << ", "
1078 0 : << "'task.name' = " << bound_socket->get_task().get_name() << "}";
1079 : }
1080 :
1081 0 : std::stringstream message;
1082 : message << "The current socket is already bound ("
1083 0 : << "'dataptr' = " << _get_dataptr() << ", "
1084 0 : << "'databytes' = " << get_databytes() << ", "
1085 0 : << "'datatype' = " << get_datatype_string() << ", "
1086 0 : << "'name' = " << get_name() << ", "
1087 0 : << "'task.name' = " << task.get_name() << bound_sockets_str.str() << ").";
1088 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1089 0 : }
1090 270442 : }
1091 :
1092 : }
1093 : }
|