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 210612 : 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 210612 : void* dataptr)
40 210612 : : task(task)
41 210612 : , name(name)
42 210612 : , datatype(datatype)
43 210612 : , databytes(std::get<0>(databytes_per_dim) * std::get<1>(databytes_per_dim))
44 210612 : , fast(fast)
45 210612 : , dataptr(dataptr)
46 210612 : , rowsptr(nullptr)
47 210612 : , n_rows(std::get<0>(databytes_per_dim))
48 210612 : , start_row(0)
49 210612 : , bound_socket(nullptr)
50 421224 : , type(type)
51 : {
52 210612 : 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 210612 : this->rowsptr = new void*[this->n_rows];
63 210612 : }
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 412771 : Socket::~Socket()
77 : {
78 210612 : this->reset();
79 210612 : this->rowsptr -= this->start_row;
80 210612 : delete[] rowsptr;
81 412771 : }
82 :
83 : const std::string&
84 0 : Socket::get_name() const
85 : {
86 0 : return name;
87 : }
88 :
89 : const std::type_index&
90 203777 : Socket::get_datatype() const
91 : {
92 203777 : return datatype;
93 : }
94 :
95 : const std::string&
96 439 : Socket::get_datatype_string() const
97 : {
98 439 : return type_to_string[datatype];
99 : }
100 :
101 : uint8_t
102 1664 : Socket::get_datatype_size() const
103 : {
104 1664 : return type_to_size[datatype];
105 : }
106 :
107 : size_t
108 659528 : Socket::get_databytes() const
109 : {
110 659528 : return databytes;
111 : }
112 :
113 : size_t
114 856 : Socket::get_n_elmts() const
115 : {
116 856 : return get_databytes() / (size_t)get_datatype_size();
117 : }
118 :
119 : size_t
120 648422 : Socket::get_n_rows() const
121 : {
122 648422 : return this->n_rows;
123 : }
124 :
125 : void*
126 2008139 : Socket::_get_dataptr(const size_t start_col) const
127 : {
128 2008139 : uint8_t* ptr = (uint8_t*)dataptr;
129 2008139 : return (void*)(ptr + start_col);
130 : }
131 :
132 : void*
133 107297 : 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 107297 : 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 10559467 : Socket::get_dataptr(const size_t start_col) const
240 : {
241 : #ifndef SPU_FAST
242 10559467 : 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 10497835 : 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 : Socket::buffer&
292 : Socket::get_out_buffer()
293 : {
294 : return this->out_buffer;
295 : }
296 :
297 : bool
298 0 : Socket::is_fast() const
299 : {
300 : #ifndef SPU_FAST
301 0 : return fast;
302 : #else
303 : return true;
304 : #endif
305 : }
306 :
307 : Task&
308 0 : Socket::get_task() const
309 : {
310 0 : return this->task;
311 : }
312 :
313 : const std::vector<Socket*>&
314 202585 : Socket::get_bound_sockets() const
315 : {
316 202585 : return this->bound_sockets;
317 : }
318 :
319 : Socket&
320 55467 : Socket::get_bound_socket()
321 : {
322 55467 : if (this->bound_socket == nullptr)
323 : {
324 740 : std::stringstream message;
325 740 : message << "bound_socket can't be nullptr.";
326 740 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
327 740 : }
328 54727 : return *this->bound_socket;
329 : }
330 :
331 : const Socket&
332 : Socket::get_bound_socket() const
333 : {
334 : if (this->bound_socket == nullptr)
335 : {
336 : std::stringstream message;
337 : message << "bound_socket can't be nullptr.";
338 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
339 : }
340 : return *this->bound_socket;
341 : }
342 :
343 : socket_t
344 0 : Socket::get_type() const
345 : {
346 0 : return this->type;
347 : }
348 :
349 : void
350 224466 : Socket::set_fast(const bool fast)
351 : {
352 224466 : this->fast = fast;
353 224466 : }
354 :
355 : void
356 0 : Socket::_bind(Socket& s_out, const int priority)
357 : {
358 : #ifndef SPU_FAST
359 0 : if (!is_fast())
360 : {
361 0 : if (s_out.datatype != this->datatype)
362 : {
363 0 : std::stringstream message;
364 : message << "'s_out.datatype' has to be equal to 'datatype' ("
365 0 : << "'s_out.datatype' = " << type_to_string[s_out.datatype] << ", "
366 0 : << "'s_out.name' = " << s_out.get_name() << ", "
367 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
368 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
369 0 : << "'name' = " << get_name() << ", "
370 0 : << "'task.name' = " << task.get_name() << ").";
371 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
372 0 : }
373 :
374 0 : if (s_out.databytes != this->databytes)
375 : {
376 0 : std::stringstream message;
377 : message << "'s_out.databytes' has to be equal to 'databytes' ("
378 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
379 0 : << "'s_out.name' = " << s_out.get_name() << ", "
380 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
381 0 : << "'databytes' = " << this->databytes << ", "
382 0 : << "'name' = " << get_name() << ", "
383 0 : << "'task.name' = " << task.get_name() << ").";
384 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
385 0 : }
386 :
387 0 : if (s_out.get_task().is_outbuffers_allocated() && s_out.dataptr == nullptr)
388 : {
389 0 : std::stringstream message;
390 : message << "'s_out.dataptr' can't be NULL ("
391 0 : << "'s_out.name' = " << s_out.get_name() << ", "
392 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ","
393 0 : << "'name' = " << get_name() << ", "
394 0 : << "'task.name' = " << task.get_name() << ").";
395 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
396 0 : }
397 : }
398 : #endif
399 :
400 0 : if (this->bound_socket == &s_out) this->unbind(s_out);
401 :
402 : #ifndef SPU_FAST
403 0 : if (this->bound_socket != nullptr && this->get_type() == socket_t::SIN)
404 : {
405 0 : std::stringstream message;
406 : message << "This socket is already connected ("
407 0 : << "'bound_socket->databytes' = " << this->bound_socket->databytes << ", "
408 0 : << "'bound_socket->name' = " << this->bound_socket->get_name() << ", "
409 0 : << "'bound_socket->task.name' = " << this->bound_socket->task.get_name() << ", "
410 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
411 0 : << "'s_out.name' = " << s_out.get_name() << ", "
412 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
413 0 : << "'databytes' = " << this->databytes << ", "
414 0 : << "'name' = " << get_name() << ", "
415 0 : << "'task.name' = " << task.get_name() << ").";
416 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
417 0 : }
418 : #endif
419 :
420 0 : this->bound_socket = &s_out;
421 :
422 : #ifndef SPU_FAST
423 0 : if (std::find(s_out.bound_sockets.begin(), s_out.bound_sockets.end(), this) != s_out.bound_sockets.end())
424 : {
425 0 : std::stringstream message;
426 : message << "It is not possible to bind the same socket twice ("
427 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
428 0 : << "'s_out.name' = " << s_out.get_name() << ", "
429 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
430 0 : << "'databytes' = " << this->databytes << ", "
431 0 : << "'name' = " << get_name() << ", "
432 0 : << "'task.name' = " << task.get_name() << ").";
433 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
434 0 : }
435 : #endif
436 :
437 0 : if ((size_t)priority > s_out.bound_sockets.size() || priority == -1)
438 0 : s_out.bound_sockets.push_back(this);
439 : else
440 0 : s_out.bound_sockets.insert(s_out.bound_sockets.begin() + priority, this);
441 0 : this->dataptr = s_out.dataptr;
442 0 : }
443 :
444 : void
445 : Socket::bind(Socket& s_out, const int priority)
446 : {
447 : #ifdef SPU_SHOW_DEPRECATED
448 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
449 : << std::endl;
450 : #ifdef SPU_STACKTRACE
451 : #ifdef SPU_COLORS
452 : bool enable_color = true;
453 : #else
454 : bool enable_color = false;
455 : #endif
456 : cpptrace::generate_trace().print(std::clog, enable_color);
457 : #endif
458 : #endif
459 : this->_bind(s_out, priority);
460 : }
461 :
462 : void
463 : Socket::operator()(Socket& s_out, const int priority)
464 : {
465 : #ifdef SPU_SHOW_DEPRECATED
466 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
467 : << std::endl;
468 : #ifdef SPU_STACKTRACE
469 : #ifdef SPU_COLORS
470 : bool enable_color = true;
471 : #else
472 : bool enable_color = false;
473 : #endif
474 : cpptrace::generate_trace().print(std::clog, enable_color);
475 : #endif
476 : #endif
477 : this->_bind(s_out, priority);
478 : }
479 :
480 : template<typename T>
481 : void
482 : Socket::operator=(const void* array)
483 : {
484 : #ifndef SPU_FAST
485 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
486 : #endif
487 : this->_bind(array);
488 : #ifndef SPU_FAST
489 : else
490 : {
491 : std::stringstream message;
492 : message << "Current socket have to be an input or forward socket ("
493 : << "'datatype' = " << type_to_string[this->datatype] << ", "
494 : << "'name' = " << get_name() << ", "
495 : << "'task.name' = " << task.get_name() << ", "
496 : << "'type' = "
497 : << (get_type() == socket_t::SIN ? "SIN"
498 : : get_type() == socket_t::SFWD ? "SFWD"
499 : : "SOUT")
500 : << ").";
501 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
502 : }
503 : #endif
504 : }
505 :
506 : template<typename T>
507 : void
508 : Socket::operator=(void* array)
509 : {
510 : #ifndef SPU_FAST
511 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
512 : #endif
513 : this->_bind(array);
514 : #ifndef SPU_FAST
515 : else
516 : {
517 : std::stringstream message;
518 : message << "Current socket have to be an input or forward socket ("
519 : << "'datatype' = " << type_to_string[this->datatype] << ", "
520 : << "'name' = " << get_name() << ", "
521 : << "'task.name' = " << task.get_name() << ", "
522 : << "'type' = "
523 : << (get_type() == socket_t::SIN ? "SIN"
524 : : get_type() == socket_t::SFWD ? "SFWD"
525 : : "SOUT")
526 : << ").";
527 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
528 : }
529 : #endif
530 : }
531 :
532 : template<typename T>
533 : void
534 : Socket::operator=(const T* array)
535 : {
536 : #ifndef SPU_FAST
537 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
538 : #endif
539 : this->_bind(array);
540 : #ifndef SPU_FAST
541 : else
542 : {
543 : std::stringstream message;
544 : message << "Current socket have to be an input or forward socket ("
545 : << "'datatype' = " << type_to_string[this->datatype] << ", "
546 : << "'name' = " << get_name() << ", "
547 : << "'task.name' = " << task.get_name() << ", "
548 : << "'type' = "
549 : << (get_type() == socket_t::SIN ? "SIN"
550 : : get_type() == socket_t::SFWD ? "SFWD"
551 : : "SOUT")
552 : << ").";
553 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
554 : }
555 : #endif
556 : }
557 :
558 : template<typename T>
559 : void
560 41 : Socket::operator=(T* array)
561 : {
562 : #ifndef SPU_FAST
563 41 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
564 : #endif
565 41 : this->_bind(array);
566 : #ifndef SPU_FAST
567 : else
568 : {
569 0 : std::stringstream message;
570 : message << "Current socket have to be an input or forward socket ("
571 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
572 0 : << "'name' = " << get_name() << ", "
573 0 : << "'task.name' = " << task.get_name() << ", "
574 : << "'type' = "
575 0 : << (get_type() == socket_t::SIN ? "SIN"
576 0 : : get_type() == socket_t::SFWD ? "SFWD"
577 : : "SOUT")
578 0 : << ").";
579 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
580 0 : }
581 : #endif
582 50 : }
583 :
584 : template<typename T, class A>
585 : void
586 : Socket::operator=(const std::vector<T, A>& vector)
587 : {
588 : #ifndef SPU_FAST
589 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
590 : #endif
591 : this->_bind(vector);
592 : #ifndef SPU_FAST
593 : else
594 : {
595 : std::stringstream message;
596 : message << "Current socket have to be an input or forward socket ("
597 : << "'datatype' = " << type_to_string[this->datatype] << ", "
598 : << "'name' = " << get_name() << ", "
599 : << "'task.name' = " << task.get_name() << ", "
600 : << "'type' = "
601 : << (get_type() == socket_t::SIN ? "SIN"
602 : : get_type() == socket_t::SFWD ? "SFWD"
603 : : "SOUT")
604 : << ").";
605 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
606 : }
607 : #endif
608 : }
609 :
610 : template<typename T, class A>
611 : void
612 : Socket::operator=(std::vector<T, A>& vector)
613 : {
614 : #ifndef SPU_FAST
615 : if (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD)
616 : #endif
617 : this->_bind(vector);
618 : #ifndef SPU_FAST
619 : else
620 : {
621 : std::stringstream message;
622 : message << "Current socket have to be an input or forward socket ("
623 : << "'datatype' = " << type_to_string[this->datatype] << ", "
624 : << "'name' = " << get_name() << ", "
625 : << "'task.name' = " << task.get_name() << ", "
626 : << "'type' = "
627 : << (get_type() == socket_t::SIN ? "SIN"
628 : : get_type() == socket_t::SFWD ? "SFWD"
629 : : "SOUT")
630 : << ").";
631 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
632 : }
633 : #endif
634 : }
635 :
636 : void
637 0 : Socket::operator=(Socket& s)
638 : {
639 0 : if ((s.get_type() == socket_t::SOUT || s.get_type() == socket_t::SFWD) &&
640 0 : (this->get_type() == socket_t::SIN || this->get_type() == socket_t::SFWD))
641 0 : this->_bind(s);
642 0 : else if ((s.get_type() == socket_t::SIN || s.get_type() == socket_t::SFWD) &&
643 0 : (this->get_type() == socket_t::SOUT || this->get_type() == socket_t::SFWD))
644 0 : s._bind(*this);
645 : // Socket forward bind
646 0 : else if (s.get_type() == socket_t::SFWD && this->get_type() == socket_t::SFWD)
647 0 : this->_bind(s);
648 : #ifndef SPU_FAST
649 : else
650 : {
651 0 : std::stringstream message;
652 : message << "Binding of [output and input] or [forward and input] or [forward and forward] socket is required ("
653 0 : << "'s.datatype' = " << type_to_string[s.datatype] << ", "
654 0 : << "'s.name' = " << s.get_name() << ", "
655 0 : << "'s.task.name' = " << s.task.get_name() << ", "
656 : << "'s.type' = "
657 0 : << (s.get_type() == socket_t::SIN ? "SIN"
658 0 : : s.get_type() == socket_t::SFWD ? "SFWD"
659 : : "SOUT")
660 : << ", "
661 0 : << "'datatype' = " << type_to_string[this->datatype] << ", "
662 0 : << "'name' = " << get_name() << ", "
663 0 : << "'task.name' = " << task.get_name() << ", "
664 : << "'type' = "
665 0 : << (get_type() == socket_t::SIN ? "SIN"
666 0 : : get_type() == socket_t::SFWD ? "SFWD"
667 : : "SOUT")
668 0 : << ").";
669 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
670 0 : }
671 : #endif
672 0 : }
673 :
674 : void
675 : Socket::operator=(Task& t)
676 : {
677 : #ifndef SPU_FAST
678 : if (this->get_type() == socket_t::SOUT || this->get_type() == socket_t::SFWD)
679 : #endif
680 : t._bind(*this);
681 : #ifndef SPU_FAST
682 : else
683 : {
684 : std::stringstream message;
685 : message << "The current socket should be and output socket ("
686 : << "'datatype' = " << type_to_string[this->datatype] << ", "
687 : << "'name' = " << get_name() << ", "
688 : << "'task.name' = " << task.get_name() << ", "
689 : << "'type' = "
690 : << (get_type() == socket_t::SIN ? "SIN"
691 : : get_type() == socket_t::SFWD ? "SFWD"
692 : : "SOUT")
693 : << ").";
694 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
695 : }
696 : #endif
697 : }
698 :
699 : template<typename T, class A>
700 : void
701 : Socket::_bind(const std::vector<T, A>& vector)
702 : {
703 : this->_bind(const_cast<std::vector<T, A>&>(vector));
704 : }
705 :
706 : template<typename T, class A>
707 : void
708 : Socket::bind(const std::vector<T, A>& vector)
709 : {
710 : #ifdef SPU_SHOW_DEPRECATED
711 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
712 : << std::endl;
713 : #ifdef SPU_STACKTRACE
714 : #ifdef SPU_COLORS
715 : bool enable_color = true;
716 : #else
717 : bool enable_color = false;
718 : #endif
719 : cpptrace::generate_trace().print(std::clog, enable_color);
720 : #endif
721 : #endif
722 : this->_bind(vector);
723 : }
724 :
725 : template<typename T, class A>
726 : void
727 : Socket::_bind(std::vector<T, A>& vector)
728 : {
729 : #ifndef SPU_FAST
730 : if (is_fast())
731 : #endif
732 : this->dataptr = static_cast<void*>(vector.data());
733 : #ifndef SPU_FAST
734 : else
735 : {
736 : if (vector.size() != this->get_n_elmts())
737 : {
738 : std::stringstream message;
739 : message << "'vector.size()' has to be equal to 'get_n_elmts()' ('vector.size()' = " << vector.size()
740 : << ", 'get_n_elmts()' = " << get_n_elmts() << ", 'name' = " << get_name() << ", 'task.name' = "
741 : << task.get_name()
742 : // << ", 'task.module.name' = " << task.get_module_name()
743 : << ").";
744 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
745 : }
746 :
747 : this->_bind(vector.data());
748 : }
749 : #endif
750 : }
751 :
752 : template<typename T, class A>
753 : void
754 : Socket::bind(std::vector<T, A>& vector)
755 : {
756 : #ifdef SPU_SHOW_DEPRECATED
757 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
758 : << std::endl;
759 : #ifdef SPU_STACKTRACE
760 : #ifdef SPU_COLORS
761 : bool enable_color = true;
762 : #else
763 : bool enable_color = false;
764 : #endif
765 : cpptrace::generate_trace().print(std::clog, enable_color);
766 : #endif
767 : #endif
768 : this->_bind(vector);
769 : }
770 :
771 : template<typename T, class A>
772 : void
773 : Socket::operator()(std::vector<T, A>& vector)
774 : {
775 : #ifdef SPU_SHOW_DEPRECATED
776 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
777 : << std::endl;
778 : #ifdef SPU_STACKTRACE
779 : #ifdef SPU_COLORS
780 : bool enable_color = true;
781 : #else
782 : bool enable_color = false;
783 : #endif
784 : cpptrace::generate_trace().print(std::clog, enable_color);
785 : #endif
786 : #endif
787 : this->_bind(vector);
788 : }
789 :
790 : template<typename T>
791 : void
792 0 : Socket::_bind(const T* array)
793 : {
794 0 : this->_bind(const_cast<T*>(array));
795 0 : }
796 :
797 : template<typename T>
798 : void
799 0 : Socket::bind(const T* array)
800 : {
801 : #ifdef SPU_SHOW_DEPRECATED
802 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
803 : << std::endl;
804 : #ifdef SPU_STACKTRACE
805 : #ifdef SPU_COLORS
806 : bool enable_color = true;
807 : #else
808 : bool enable_color = false;
809 : #endif
810 : cpptrace::generate_trace().print(std::clog, enable_color);
811 : #endif
812 : #endif
813 0 : this->_bind(array);
814 0 : }
815 :
816 : template<typename T>
817 : void
818 0 : Socket::_bind(T* array)
819 : {
820 : #ifndef SPU_FAST
821 0 : if (is_fast())
822 : #endif
823 0 : this->dataptr = static_cast<void*>(array);
824 : #ifndef SPU_FAST
825 : else
826 : {
827 0 : if (type_to_string[typeid(T)] != type_to_string[this->datatype])
828 : {
829 0 : std::stringstream message;
830 0 : message << "'T' has to be equal to 'datatype' ('T' = " << type_to_string[typeid(T)]
831 0 : << ", 'datatype' = " << type_to_string[this->datatype] << ", 'socket.name' = " << get_name()
832 0 : << ", 'task.name' = " << task.get_name() << ").";
833 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
834 0 : }
835 :
836 0 : this->_bind(static_cast<void*>(array));
837 : }
838 : #endif
839 0 : }
840 :
841 : template<typename T>
842 : void
843 0 : Socket::bind(T* array)
844 : {
845 : #ifdef SPU_SHOW_DEPRECATED
846 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
847 : << std::endl;
848 : #ifdef SPU_STACKTRACE
849 : #ifdef SPU_COLORS
850 : bool enable_color = true;
851 : #else
852 : bool enable_color = false;
853 : #endif
854 : cpptrace::generate_trace().print(std::clog, enable_color);
855 : #endif
856 : #endif
857 0 : this->_bind(array);
858 0 : }
859 :
860 : template<typename T>
861 : void
862 : Socket::operator()(T* array)
863 : {
864 : #ifdef SPU_SHOW_DEPRECATED
865 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
866 : << std::endl;
867 : #ifdef SPU_STACKTRACE
868 : #ifdef SPU_COLORS
869 : bool enable_color = true;
870 : #else
871 : bool enable_color = false;
872 : #endif
873 : cpptrace::generate_trace().print(std::clog, enable_color);
874 : #endif
875 : #endif
876 : this->_bind(array);
877 : }
878 :
879 : void
880 931569 : Socket::_bind(void* dataptr)
881 : {
882 : #ifndef SPU_FAST
883 931569 : if (!is_fast())
884 : {
885 43 : if (dataptr == nullptr)
886 : {
887 0 : std::stringstream message;
888 0 : message << "'s.dataptr' can't be NULL.";
889 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
890 0 : }
891 43 : this->check_bound_socket();
892 : }
893 : #endif
894 927768 : this->dataptr = dataptr;
895 927768 : }
896 :
897 : void
898 : Socket::bind(void* dataptr)
899 : {
900 : #ifdef SPU_SHOW_DEPRECATED
901 : std::clog << rang::tag::warning << "Deprecated: 'Socket::bind()' should be replaced by 'Socket::operator='."
902 : << std::endl;
903 : #ifdef SPU_STACKTRACE
904 : #ifdef SPU_COLORS
905 : bool enable_color = true;
906 : #else
907 : bool enable_color = false;
908 : #endif
909 : cpptrace::generate_trace().print(std::clog, enable_color);
910 : #endif
911 : #endif
912 : this->_bind(dataptr);
913 : }
914 :
915 : void
916 : Socket::operator()(void* dataptr)
917 : {
918 : #ifdef SPU_SHOW_DEPRECATED
919 : std::clog << rang::tag::warning << "Deprecated: 'Socket::operator()' should be replaced by 'Socket::operator='."
920 : << std::endl;
921 : #ifdef SPU_STACKTRACE
922 : #ifdef SPU_COLORS
923 : bool enable_color = true;
924 : #else
925 : bool enable_color = false;
926 : #endif
927 : cpptrace::generate_trace().print(std::clog, enable_color);
928 : #endif
929 : #endif
930 : this->_bind(dataptr);
931 : }
932 :
933 : void
934 210612 : Socket::reset()
935 : {
936 210612 : if (this->bound_socket != nullptr) this->unbind(*this->bound_socket);
937 : // the backforward loop is required here because the 'unbind' method can remove elements in 'bound_sockets' array
938 237044 : for (int sid = (int)this->bound_sockets.size() - 1; sid >= 0; sid--)
939 26432 : this->bound_sockets[sid]->unbind(*this);
940 210612 : }
941 :
942 : size_t
943 0 : Socket::unbind(Socket& s_out)
944 : {
945 : #ifndef SPU_FAST
946 0 : if (this->bound_socket == nullptr)
947 : {
948 0 : std::stringstream message;
949 : message << "The current input socket can't be unbound because it is not bound to any output socket ("
950 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
951 0 : << "'s_out.name' = " << s_out.get_name() << ", "
952 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
953 0 : << "'databytes' = " << this->databytes << ", "
954 0 : << "'name' = " << get_name() << ", "
955 0 : << "'task.name' = " << task.get_name() << ").";
956 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
957 0 : }
958 :
959 0 : if (this->bound_socket != &s_out)
960 : {
961 0 : std::stringstream message;
962 : message << "This socket is connected to a different socket than 's_out' ("
963 0 : << "'bound_socket->databytes' = " << this->bound_socket->databytes << ", "
964 0 : << "'bound_socket->name' = " << this->bound_socket->get_name() << ", "
965 0 : << "'bound_socket->task.name' = " << this->bound_socket->task.get_name() << ", "
966 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
967 0 : << "'s_out.name' = " << s_out.get_name() << ", "
968 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
969 0 : << "'databytes' = " << this->databytes << ", "
970 0 : << "'name' = " << get_name() << ", "
971 0 : << "'task.name' = " << task.get_name() << ").";
972 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
973 0 : }
974 : #endif
975 :
976 0 : this->bound_socket = nullptr;
977 :
978 0 : size_t unbind_pos = 0;
979 0 : auto it = std::find(s_out.bound_sockets.begin(), s_out.bound_sockets.end(), this);
980 :
981 : #ifndef SPU_FAST
982 0 : if (it != s_out.bound_sockets.end())
983 : {
984 : #endif
985 0 : unbind_pos = (size_t)std::distance(s_out.bound_sockets.begin(), it);
986 0 : s_out.bound_sockets.erase(it);
987 : #ifndef SPU_FAST
988 : }
989 : else
990 : {
991 0 : std::stringstream message;
992 : message << "The 's_out' output socket is not bound to the current input socket ("
993 0 : << "'s_out.databytes' = " << s_out.databytes << ", "
994 0 : << "'s_out.name' = " << s_out.get_name() << ", "
995 0 : << "'s_out.task.name' = " << s_out.task.get_name() << ", "
996 0 : << "'databytes' = " << this->databytes << ", "
997 0 : << "'name' = " << get_name() << ", "
998 0 : << "'task.name' = " << task.get_name() << ").";
999 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1000 0 : }
1001 : #endif
1002 :
1003 0 : return unbind_pos;
1004 : }
1005 :
1006 : void
1007 37312 : Socket::_allocate_buffer()
1008 : {
1009 37312 : out_buffer.resize(this->databytes);
1010 37312 : this->dataptr = out_buffer.data();
1011 37312 : }
1012 :
1013 : void
1014 37312 : Socket::allocate_buffer()
1015 : {
1016 : #ifndef SPU_FAST
1017 37312 : if (this->dataptr != nullptr)
1018 : {
1019 0 : std::stringstream message;
1020 : message << "The current socket is already allocated ("
1021 0 : << ", 'name' = " << get_name() << ", 'task.name' = " << task.get_name() << ").";
1022 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1023 0 : }
1024 :
1025 37312 : if (this->get_type() == socket_t::SIN)
1026 : {
1027 0 : std::stringstream message;
1028 : message << "The current socket is an input socket and can't be allocated ("
1029 0 : << "'name' = " << get_name() << ", "
1030 0 : << "'task.name' = " << task.get_name() << ").";
1031 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1032 0 : }
1033 :
1034 37312 : if (this->get_type() == socket_t::SFWD)
1035 : {
1036 0 : std::stringstream message;
1037 : message << "The current socket is a forward socket and can't be allocated ("
1038 0 : << "'name' = " << get_name() << ", "
1039 0 : << "'task.name' = " << task.get_name() << ").";
1040 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1041 0 : }
1042 : #endif
1043 :
1044 37312 : _allocate_buffer();
1045 37312 : }
1046 :
1047 : void
1048 32625 : Socket::deallocate_buffer()
1049 : {
1050 : #ifndef SPU_FAST
1051 32625 : if (this->dataptr == nullptr)
1052 : {
1053 0 : std::stringstream message;
1054 : message << "The current socket is already deallocated ("
1055 0 : << "'name' = " << get_name() << ", "
1056 0 : << "'task.name' = " << task.get_name() << ").";
1057 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1058 0 : }
1059 :
1060 32625 : if (this->get_type() == socket_t::SIN)
1061 : {
1062 0 : std::stringstream message;
1063 : message << "The current socket is an input socket and can't be deallocated ("
1064 0 : << "'name' = " << get_name() << ", "
1065 0 : << "'task.name' = " << task.get_name() << ").";
1066 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1067 0 : }
1068 :
1069 32625 : if (this->get_type() == socket_t::SFWD)
1070 : {
1071 0 : std::stringstream message;
1072 : message << "The current socket is a forward socket and can't be deallocated ("
1073 0 : << "'name' = " << get_name() << ", "
1074 0 : << "'task.name' = " << task.get_name() << ").";
1075 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1076 0 : }
1077 : #endif
1078 :
1079 32625 : out_buffer.clear();
1080 32625 : this->dataptr = nullptr;
1081 32625 : }
1082 :
1083 : void
1084 : Socket::set_name(const std::string& name)
1085 : {
1086 : if (name != this->get_name())
1087 : {
1088 : this->check_bound_socket();
1089 : this->name = name;
1090 : }
1091 : }
1092 :
1093 : void
1094 : Socket::set_datatype(const std::type_index datatype)
1095 : {
1096 : if (datatype != this->get_datatype())
1097 : {
1098 : this->check_bound_socket();
1099 : this->datatype = datatype;
1100 : }
1101 : }
1102 :
1103 : void
1104 214100 : Socket::set_databytes(const size_t databytes)
1105 : {
1106 214100 : if (databytes != this->get_databytes())
1107 : {
1108 214100 : this->check_bound_socket();
1109 214100 : this->databytes = databytes;
1110 : }
1111 214100 : }
1112 :
1113 : void
1114 161222 : Socket::set_dataptr(void* dataptr)
1115 : {
1116 161222 : if (dataptr != this->_get_dataptr())
1117 : {
1118 119771 : this->dataptr = dataptr;
1119 : }
1120 161222 : }
1121 :
1122 : void
1123 131292 : Socket::set_n_rows(const size_t n_rows)
1124 : {
1125 131292 : if (n_rows != this->get_n_rows())
1126 : {
1127 131292 : this->n_rows = n_rows;
1128 131292 : this->rowsptr -= this->start_row;
1129 131292 : delete[] this->rowsptr;
1130 :
1131 131292 : this->rowsptr = new void*[this->n_rows];
1132 131292 : this->start_row = 0;
1133 : }
1134 131292 : }
1135 :
1136 : void
1137 214148 : Socket::check_bound_socket()
1138 : {
1139 214148 : if (bound_sockets.size() != 0 || bound_socket != nullptr)
1140 : {
1141 0 : std::stringstream bound_sockets_str;
1142 0 : if (bound_sockets.size() != 0)
1143 : {
1144 0 : bound_sockets_str << ", 'bound_sockets' = [";
1145 :
1146 0 : for (size_t bs = 0; bs < bound_sockets.size(); bs++)
1147 : {
1148 : bound_sockets_str << "{"
1149 0 : << "'name' = " << bound_sockets[bs]->get_name() << ", "
1150 0 : << "'databytes' = " << bound_sockets[bs]->get_databytes() << ", "
1151 0 : << "'task.name' = " << bound_sockets[bs]->get_task().get_name() << "}";
1152 0 : if (bs < bound_sockets.size() - 1) bound_sockets_str << ", ";
1153 : }
1154 :
1155 0 : bound_sockets_str << "]";
1156 : }
1157 0 : else if (bound_socket != nullptr)
1158 : {
1159 0 : bound_sockets_str << ", 'bound_socket' = ";
1160 : bound_sockets_str << "{"
1161 0 : << "'name' = " << bound_socket->get_name() << ", "
1162 0 : << "'databytes' = " << bound_socket->get_databytes() << ", "
1163 0 : << "'task.name' = " << bound_socket->get_task().get_name() << "}";
1164 : }
1165 :
1166 0 : std::stringstream message;
1167 : message << "The current socket is already bound ("
1168 0 : << "'dataptr' = " << _get_dataptr() << ", "
1169 0 : << "'databytes' = " << get_databytes() << ", "
1170 0 : << "'datatype' = " << get_datatype_string() << ", "
1171 0 : << "'name' = " << get_name() << ", "
1172 0 : << "'task.name' = " << task.get_name() << bound_sockets_str.str() << ").";
1173 0 : throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
1174 0 : }
1175 214149 : }
1176 :
1177 : void
1178 51842 : Socket::resize_out_buffer(size_t new_data_bytes)
1179 : {
1180 51842 : out_buffer.resize(new_data_bytes);
1181 51842 : this->dataptr = ((void*)out_buffer.data());
1182 51842 : }
1183 :
1184 : }
1185 : }
|