FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
container.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
10#include <kernel/util/memory_pool.hpp>
11#include <kernel/lafem/base.hpp>
12#include <kernel/util/type_traits.hpp>
13#include <kernel/util/random.hpp>
14#include <kernel/util/pack.hpp>
15
16
17#include <vector>
18#include <limits>
19#include <cmath>
20#include <typeinfo>
21#include <string>
22#include <type_traits>
23#include <cstdlib>
24#include <stdint.h>
25
26namespace FEAT
27{
31 namespace LAFEM
32 {
47 {
48 private:
49 CompressionModes elements_compression, indices_compression;
50 FEAT::Real tolerance;
51 public:
57#ifdef FEAT_HAVE_ZLIB
58 explicit SerialConfig() :
59 elements_compression(CompressionModes::elements_zlib),
60 indices_compression(CompressionModes::indices_zlib),
61 tolerance(FEAT::Real(-1.))
62#else
63 explicit SerialConfig() :
64 elements_compression(CompressionModes::elements_off),
65 indices_compression(CompressionModes::indices_off),
66 tolerance(FEAT::Real(-1.))
67#endif
68 {
69 }
82 explicit SerialConfig(bool zlib_compression, bool zfp_compression, FEAT::Real tol = FEAT::Real(-1.))
83 {
86 if(zlib_compression)
87 {
90 }
91 if(zfp_compression)
92 {
93 set_tolerance(tol);
95 }
96 }
97
105 {
107 switch(temp)
108 {
110 break;
112#ifdef FEAT_HAVE_ZLIB
113 break;
114#else
115 XABORTM("Zlib compression was enabled for elements, but zlib bibliography was not loaded. Please configure FEAT with -zlib flag!");
116#endif
118#ifdef FEAT_HAVE_ZFP
119 XASSERTM(tolerance > FEAT::Real(0.), "tolerance ist smaller or equall 0 while zfp is enabled!");
120 break;
121#else
122 XABORTM("Zfp compression was enabled for elements, but zfp bibliography was not loaded. Please configure FEAT with -zfp flag!");
123#endif
124 default:
125 XABORTM("No legal CompressionModes was given");
126 }
127 elements_compression = temp;
128 }
136 {
137 CompressionModes temp = comp & CompressionModes::indices_mask;
138 switch(temp)
139 {
141 break;
143#ifdef FEAT_HAVE_ZLIB
144 break;
145#else
146 XABORTM("Zlib compression was enabled for indices, but zlib bibliography was not loaded. Please configure FEAT with -zlib flag!");
147#endif
148 default:
149 XABORTM("No legal CompressionModes was given");
150 }
151 indices_compression = temp;
152 }
153
161 {
162 if(elements_compression == CompressionModes::elements_zfp)
163 {
164 XASSERTM(tol > FEAT::Real(0.), "Zfp enabled, but tolerance is smaller or equal to 0!");
165 }
166 tolerance = tol;
167 }
175 {
176 return elements_compression;
177 }
178
186 {
187 return indices_compression;
188 }
189
197 {
198 return tolerance;
199 }
200
201 }; //class SerialConfig
202
203
218 template <typename DT_, typename IT_>
220 {
221 template <typename DT2_, typename IT2_>
222 friend class Container;
223
224 protected:
226 std::vector<DT_*> _elements;
228 std::vector<IT_*> _indices;
230 std::vector<Index> _elements_size;
232 std::vector<Index> _indices_size;
234 std::vector<Index> _scalar_index;
236 std::vector<DT_> _scalar_dt;
239
240 void _copy_content(const Container & other, bool full)
241 {
242 // avoid self-copy
243 if(this == &other)
244 return;
245
246 XASSERTM(_elements.size() == other.get_elements().size(), "Container size mismatch!");
247 XASSERTM(_indices.size() == other.get_indices().size(), "Container size mismatch!");
248 XASSERTM(_scalar_index.size() == other.get_scalar_index().size(), "Container size mismatch!");
249 XASSERTM(_scalar_dt.size() == other.get_scalar_dt().size(), "Container size mismatch!");
250
251 if (full)
252 {
253 this->_scalar_index.assign(other._scalar_index.begin(), other._scalar_index.end());
254 this->_scalar_dt.assign(other._scalar_dt.begin(), other._scalar_dt.end());
255
256 for (Index i(0) ; i < _indices.size() ; ++i)
257 {
258 XASSERTM(_indices_size.at(i) == other.get_indices_size().at(i), "Container size mismatch!");
259 MemoryPool::copy(_indices.at(i), other.get_indices().at(i), _indices_size.at(i));
260 }
261 }
262
263 for (Index i(0) ; i < _elements.size() ; ++i)
264 {
265 XASSERTM(_elements_size.at(i) == other.get_elements_size().at(i), "Container size mismatch!");
266 MemoryPool::copy(_elements.at(i), other.get_elements().at(i), _elements_size.at(i));
267 }
268
269 }
270
279 template <typename DT2_, typename IT2_>
280 void assign(const Container<DT2_, IT2_> & other)
281 {
282 XASSERTM(!other._foreign_memory, "assign/convert is forbidden with foreign memory source objects.");
283 if (!this->_foreign_memory)
284 {
285 for (Index i(0) ; i < this->_elements.size() ; ++i)
286 MemoryPool::release_memory(this->_elements.at(i));
287 for (Index i(0) ; i < this->_indices.size() ; ++i)
288 MemoryPool::release_memory(this->_indices.at(i));
289 }
290
291 this->_foreign_memory = false;
292
293 this->_elements.clear();
294 this->_indices.clear();
295 this->_elements_size.clear();
296 this->_indices_size.clear();
297 this->_scalar_index.clear();
298 this->_scalar_dt.clear();
299
300 this->_elements_size.assign(other.get_elements_size().begin(), other.get_elements_size().end());
301 this->_indices_size.assign(other.get_indices_size().begin(), other.get_indices_size().end());
302 this->_scalar_index.assign(other.get_scalar_index().begin(), other.get_scalar_index().end());
303 if constexpr (std::is_same<DT_, DT2_>::value)
304 {
305 this->_scalar_dt.assign(other.get_scalar_dt().begin(), other.get_scalar_dt().end());
306
307 }
308 else
309 {
310 for(auto t : other.get_scalar_dt())
311 {
312 this->_scalar_dt.push_back(DT_(t));
313 }
314 }
315
316 if constexpr (std::is_same<DT_, DT2_>::value)
317 {
318 this->_elements.assign(other.get_elements().begin(), other.get_elements().end());
319
320 for (Index i(0) ; i < this->_elements.size() ; ++i)
321 MemoryPool::increase_memory(this->_elements.at(i));
322 }
323 else
324 {
325 for (Index i(0) ; i < this->_elements_size.size() ; ++i)
326 {
327 const Index tsize(this->_elements_size.at(i));
328 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(tsize));
329 MemoryPool::convert(this->_elements.at(i), other.get_elements().at(i), tsize);
330 }
331 }
332
333 if constexpr (std::is_same<IT_, IT2_>::value)
334 {
335 this->_indices.assign(other.get_indices().begin(), other.get_indices().end());
336
337 for (Index i(0) ; i < this->_indices.size() ; ++i)
338 MemoryPool::increase_memory(this->_indices.at(i));
339 }
340 else
341 {
342 for (Index i(0) ; i < this->_indices_size.size() ; ++i)
343 {
344 const Index tsize(this->_indices_size.at(i));
345 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(tsize));
346 MemoryPool::convert(this->_indices.at(i), other.get_indices().at(i), tsize);
347 }
348 }
349 }
350
360 template <typename DT2_ = DT_, typename IT2_ = IT_>
361 std::uint64_t _serialized_size(const LAFEM::SerialConfig& config = LAFEM::SerialConfig()) const
362 {
364 tc.assign(*this);
365
366 std::uint64_t gsize(4 * sizeof(std::uint64_t)); //raw array size + magic number + type_index DT_ + type_index IT_
367 gsize += 7 * sizeof(std::uint64_t); // size of all seven stl containers
368 gsize += 2 * tc._elements_size.size() * sizeof(std::uint64_t); // _elements_size contents + _elements_arrays bytesize
369 gsize += 2 * tc._indices_size.size() * sizeof(std::uint64_t); // _indices_size contents + _indizes_arrays bytesize
370 gsize += tc._scalar_index.size() * sizeof(std::uint64_t); // _scalar_index contents
371 gsize += tc._scalar_dt.size() * sizeof(DT2_); // _scalar_dt contents
372
373 CompressionModes compress = config.get_elements_compression() | config.get_indices_compression();
374 Pack::Type compression_type_elements = Pack::deduct_type<DT2_>();
375 Pack::Type compression_type_index = Pack::deduct_type<IT2_>();
376 if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zfp) // If zfp is used for elements
377 {
378 compression_type_elements = compression_type_elements | Pack::Type::Mask_P;
379 }
380 else if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zlib) //If zlib is used and zfp is not used elements
381 {
382 compression_type_elements = compression_type_elements | Pack::Type::Mask_Z;
383 }
384 if((compress & CompressionModes::indices_mask) == CompressionModes::indices_zlib) // If zlib is used for indices
385 compression_type_index = compression_type_index | Pack::Type::Mask_Z;
386
387
388 FEAT::Real tolerance = config.get_tolerance();
389
390 for (Index i(0) ; i < tc._elements_size.size() ; ++i)
391 {
392 gsize += Pack::estimate_size(tc._elements_size.at(i), compression_type_elements, (double)tolerance); // upper_bound for (compressed) elements
393 }
394
395 for (Index i(0) ; i < tc._indices_size.size() ; ++i)
396 {
397 gsize += Pack::estimate_size(tc._indices_size.at(i), compression_type_index); // upper_bound for (compressed) indizes
398 }
399 gsize += 16; //padding for datatype alignment mismatch
400
401 return gsize;
402 }
403
443 template <typename DT2_ = DT_, typename IT2_ = IT_>
444 std::vector<char> _serialize(FileMode mode, const SerialConfig& config = SerialConfig()) const
445 {
446 std::uint64_t raw_size = 0u;
447 FEAT::Real tolerance = config.get_tolerance();
448
449 CompressionModes compress = config.get_elements_compression() | config.get_indices_compression();
450 Pack::Type compression_type_elements = Pack::deduct_type<DT2_>();
451 Pack::Type compression_type_index = Pack::deduct_type<IT2_>();
452 if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zfp) // If zfp is used for elements
453 {
454 compression_type_elements = compression_type_elements | Pack::Type::Mask_P;
455 }
456 else if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zlib) //If zlib is used and zfp is not used elements
457 {
458 compression_type_elements = compression_type_elements | Pack::Type::Mask_Z;
459 }
460 if((compress & CompressionModes::indices_mask) == CompressionModes::indices_zlib) // If zlib is used for indices
461 compression_type_index = compression_type_index | Pack::Type::Mask_Z;
462
464 tc.assign(*this);
465
466 std::uint64_t gsize = this->template _serialized_size<DT2_, IT2_>(config);
467
468 std::vector<char> result((size_t(gsize)));
469 char * array(result.data());
470 std::uint64_t * uiarray(reinterpret_cast<std::uint64_t *>(array));
471 DT2_ * dtarray(reinterpret_cast<DT2_ *>(array));
472 IT2_ * itarray(reinterpret_cast<IT2_ *>(array));
473
475 #if defined(FEAT_COMPILER_CLANG)
476 std::uint64_t magic = (std::uint64_t)static_cast<__underlying_type(FileMode)>(mode);
477 #else
478 std::uint64_t magic = (std::uint64_t)static_cast<typename std::underlying_type<FileMode>::type>(mode);
479 #endif
480 uiarray[0] = gsize; //we will overwrite this at the end with the finalized data...
481 uiarray[1] = magic;
482 uiarray[2] = Type::Traits<DT_>::feature_hash();
483 uiarray[3] = Type::Traits<IT_>::feature_hash();
484 uiarray[4] = tc._elements.size();
485 uiarray[5] = tc._indices.size();
486 uiarray[6] = tc._elements_size.size();
487 uiarray[7] = tc._indices_size.size();
488 uiarray[8] = tc._scalar_index.size();
489 uiarray[9] = tc._scalar_dt.size();
490 uiarray[10] = (std::uint64_t)compress;
491 raw_size += 11 * (std::uint64_t)sizeof(std::uint64_t);
492
493 Index global_i(11); // count how many elements of std::uint64_t have been inserted so far
494 Index local_elements(0); // count where elements array bytesize starts
495 Index local_index(0); // same for index...
496
497 for (Index i(0) ; i < tc._elements_size.size() ; ++i)
498 {
499 uiarray[i + global_i] = tc._elements_size.at(i);
500 }
501 global_i += Index(tc._elements_size.size());
502 local_elements = global_i;
503 for (Index i(0) ; i < tc._elements_size.size() ; ++i)
504 {
505 uiarray[i + global_i] = (std::uint64_t)0u; //placeholder, until we calculate the real data...
506 }
507 global_i += Index(tc._elements_size.size());
508 raw_size += 2 * std::uint64_t(tc._elements_size.size()) * std::uint64_t(sizeof(std::uint64_t));
509
510 for (Index i(0) ; i < tc._indices_size.size() ; ++i)
511 {
512 uiarray[i + global_i] = tc._indices_size.at(i);
513 }
514 global_i += Index(tc._indices_size.size());
515 local_index = global_i;
516 for (Index i(0) ; i < tc._indices_size.size() ; ++i)
517 {
518 uiarray[i + global_i] = 0;
519 }
520 global_i += Index(tc._indices_size.size());
521 raw_size += 2 * std::uint64_t(tc._indices_size.size()) * std::uint64_t(sizeof(std::uint64_t));
522
523 for (Index i(0) ; i < tc._scalar_index.size() ; ++i)
524 {
525 uiarray[i + global_i] = tc._scalar_index.at(i);
526 }
527 global_i += Index(tc._scalar_index.size());
528 raw_size += std::uint64_t(tc._scalar_index.size()) * std::uint64_t(sizeof(std::uint64_t));
529
530 global_i = Index((global_i * sizeof(std::uint64_t) + sizeof(DT2_) - 1u) / sizeof(DT2_)); // now counting how many DT2 have been inserted so far
531
532 for (Index i(0) ; i < tc._scalar_dt.size() ; ++i)
533 {
534 dtarray[i + global_i] = tc._scalar_dt.at(i);
535 }
536 global_i += Index(tc._scalar_dt.size());
537 raw_size += std::uint64_t(tc._scalar_dt.size()) * std::uint64_t(sizeof(DT2_));
538
540 {
541 global_i = Index((global_i * sizeof(DT2_) + sizeof(char) - 1u) / sizeof(char)); // now counting how many bytes/chars have been inserted so far
542 for (Index i(0) ; i < tc._elements.size() ; ++i)
543 {
544 char* dest = &result[global_i];
545 std::size_t est_buff_size = Pack::estimate_size(tc._elements_size.at(i), compression_type_elements, (double)tolerance);
546 std::size_t real_size = Pack::encode<DT2_>(dest, tc._elements.at(i), est_buff_size, tc._elements_size.at(i), compression_type_elements, false, (double)tolerance);
547 XASSERTM(real_size != 0u, "could not encode elements");
548 uiarray[i + local_elements] = (std::uint64_t)real_size; //save used memory for compressed array
549 global_i += (Index)real_size; //go forward the number of bytes(chars)
550 raw_size += (std::uint64_t)real_size * (std::uint64_t)sizeof(char);
551 }
552 global_i = Index((global_i * sizeof(char) + sizeof(DT2_) - 1u) / sizeof(DT2_)); // go back to DT2_ indexing
553 }
554 else
555 {
556 for (Index i(0) ; i < tc._elements.size() ; ++i)
557 {
558 std::memcpy(&dtarray[global_i], tc._elements.at(i), tc._elements_size.at(i) * sizeof(DT2_));
559 uiarray[i + local_elements] = (std::uint64_t) tc._elements_size.at(i) * sizeof(DT2_);
560 global_i += tc._elements_size.at(i);
561 raw_size += (std::uint64_t) tc._elements_size.at(i) * sizeof(DT2_);
562 }
563 }
564 if((compress & CompressionModes::indices_mask) != CompressionModes::indices_off)
565 {
566 global_i = Index((global_i * sizeof(DT2_) + sizeof(char) - 1u) / sizeof(char)); // now counting how many bytes/chars have been inserted so far
567 for (Index i(0) ; i < tc._indices.size() ; ++i)
568 {
569 char* dest = &result[global_i];
570 std::size_t est_buff_size = Pack::estimate_size(tc._indices_size.at(i), compression_type_index);
571 std::size_t real_size = Pack::encode<IT2_>(dest, tc._indices.at(i), est_buff_size, tc._indices_size.at(i), compression_type_index, false);
572 XASSERTM(real_size != 0u, "could not encode indices");
573 uiarray[i + local_index] = (std::uint64_t) real_size;
574 global_i += Index(real_size);
575 raw_size += std::uint64_t(real_size) * std::uint64_t(sizeof(char));
576 }
577 }
578 else
579 {
580 global_i = Index((global_i * sizeof(DT2_) + sizeof(IT2_) - 1u) / sizeof(IT2_)); // now counting IT2_ elements
581 for (Index i(0) ; i < tc._indices.size() ; ++i)
582 {
583 std::memcpy(&itarray[global_i], tc._indices.at(i), tc._indices_size.at(i) * sizeof(IT2_));
584 uiarray[i + local_index] = (std::uint64_t) tc._indices_size.at(i) * sizeof(IT2_);
585 global_i += tc._indices_size.at(i);
586 raw_size += (std::uint64_t) tc._indices_size.at(i) * sizeof(IT2_);
587 }
588 }
589 uiarray[0] = raw_size + 16u; //padding
590 //std::cout << "Compressed size is: " << uiarray[0] << "\n";
591
592 result.resize(std::size_t(uiarray[0]));
593 return result;
594 }
595
608 template <typename DT2_ = DT_, typename IT2_ = IT_>
609 void _serialize(FileMode mode, std::ostream & file, const SerialConfig& config = SerialConfig()) const
610 {
611 auto temp(this->template _serialize<DT2_, IT2_>(mode, config));
612 file.write(temp.data(), long(temp.size()));
613 if (!file.good())
614 XABORTM("Error in _serialize - file ostream is not good anymore!");
615 }
616
625 template <typename DT2_ = DT_, typename IT2_ = IT_>
626 void _deserialize(FileMode mode, std::vector<char> & input)
627 {
628 this->clear();
630 tc.clear();
631
632 char * array(input.data());
633 std::uint64_t * uiarray(reinterpret_cast<std::uint64_t *>(array));
634 DT2_ * dtarray(reinterpret_cast<DT2_ *>(array));
635 IT2_ * itarray(reinterpret_cast<IT2_ *>(array));
636
638#if defined(FEAT_COMPILER_CLANG)
639 std::uint64_t magic = (std::uint64_t)static_cast<__underlying_type(FileMode)>(mode);
640#else
641 std::uint64_t magic = (std::uint64_t)static_cast<typename std::underlying_type<FileMode>::type>(mode);
642#endif
643 XASSERTM(magic == uiarray[1], "_deserialize: given FileMode incompatible with given array!");
644
645 //ensure that we have the same integral/floating type configuration, that was used when storing the serialized data
652
653 if (sizeof(DT_) > Type::Helper::extract_type_size(uiarray[2]))
654 std::cerr<<"Warning: You are reading a container floating point in higher precision then it was saved before!\n";
655
656 if (sizeof(IT_) > Type::Helper::extract_type_size(uiarray[3]))
657 std::cerr<<"Warning: You are reading a container integral type in higher precision then it was saved before!\n";
658
659 CompressionModes compress = (CompressionModes)uiarray[10];
660 //test whether system has right third_party software loaded:
661#ifndef FEAT_HAVE_ZLIB
663 "Data was compressed with ZLIB! To read in data, please configure FEAT with zlib enabled.\n For more information see FEAT documentation.");
664 XASSERTM((compress & CompressionModes::indices_mask) != CompressionModes::indices_zlib,
665 "Data was compressed with ZLIB! To read in data, please configure FEAT with zlib enabled.\n For more information see FEAT documentation.");
666#endif
667#ifndef FEAT_HAVE_ZFP
669 "Data was compressed with zfp! To read in data, please configure FEAT with zfp enabled.\n For more information see FEAT documentation.");
670#endif
671 std::vector<std::uint64_t> elements_bytes(uiarray[6]); //temp arrays to keep track of bytessize of compressed arrays
672 std::vector<std::uint64_t> indices_bytes(uiarray[7]);
673 Index global_i(11);
674 for (std::uint64_t i(0) ; i < uiarray[6] ; ++i)
675 {
676 tc._elements_size.push_back(Index(uiarray[i + global_i]));
677 }
678 global_i += Index(uiarray[6]);
679 for (std::uint64_t i(0) ; i < uiarray[6] ; ++i)
680 {
681 elements_bytes[i] = uiarray[i + global_i];
682 }
683 global_i += Index(uiarray[6]);
684
685 for (std::uint64_t i(0) ; i < uiarray[7] ; ++i)
686 {
687 tc._indices_size.push_back(Index(uiarray[i + global_i]));
688 }
689 global_i += Index(uiarray[7]);
690 for (std::uint64_t i(0) ; i < uiarray[7] ; ++i)
691 {
692 indices_bytes[i] = uiarray[i + global_i];
693 }
694 global_i += Index(uiarray[7]);
695
696 for (std::uint64_t i(0) ; i < uiarray[8] ; ++i)
697 {
698 tc._scalar_index.push_back(Index(uiarray[i + global_i]));
699 }
700 global_i += Index(uiarray[8]);
701
702 global_i = Index((global_i * sizeof(std::uint64_t) + sizeof(DT2_) - 1u) / sizeof(DT2_));
703 for (std::uint64_t i(0) ; i < uiarray[9] ; ++i)
704 {
705 tc._scalar_dt.push_back(dtarray[i + global_i]);
706 }
707 global_i += Index(uiarray[9]);
708
709 Pack::Type compression_type_elements = Pack::deduct_type<DT2_>();
710 Pack::Type compression_type_index = Pack::deduct_type<IT2_>();
711 if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zfp)// If zfp is used
712 {
713 compression_type_elements = compression_type_elements | Pack::Type::Mask_P;
714 }
715 else if((compress & CompressionModes::elements_mask) == CompressionModes::elements_zlib) //If zlib is loaded and zfp is not used
716 {
717 compression_type_elements = compression_type_elements | Pack::Type::Mask_Z;
718 }
719 if((compress & CompressionModes::indices_mask) == CompressionModes::indices_zlib)
720 {
721 compression_type_index = compression_type_index | Pack::Type::Mask_Z;
722 }
723
725 {
726 global_i = Index((global_i * sizeof(DT2_) + sizeof(char) - 1u) / sizeof(char));
727 for(Index i(0); i < Index(uiarray[4]); ++i)
728 {
729 tc._elements.push_back(MemoryPool::template allocate_memory<DT2_>(tc._elements_size.at(i)));
730 if(0u == Pack::decode(tc._elements.at(i), &array[global_i], (std::size_t) tc._elements_size.at(i), (std::size_t) elements_bytes[i], compression_type_elements, false))
731 XABORTM("Cannot decode compressed elements array");
732 global_i += (Index)elements_bytes[i];
733 }
734 global_i = Index((global_i * sizeof(char) + sizeof(DT2_) - 1u) / sizeof(DT2_));
735 }
736 else
737 {
738 for (Index i(0) ; i < Index(uiarray[4]) ; ++i)
739 {
740 tc._elements.push_back(MemoryPool::template allocate_memory<DT2_>(tc._elements_size.at(i)));
741 MemoryPool::template copy<DT2_>(tc._elements.at(i), &dtarray[global_i], tc._elements_size.at(i));
742 global_i += tc._elements_size.at(i);
743 }
744 }
745
746 if((compress & CompressionModes::indices_mask) != CompressionModes::indices_off)
747 {
748 global_i = Index((global_i * sizeof(DT2_) + sizeof(char) - 1u) / sizeof(char));
749 for (Index i(0) ; i < Index(uiarray[5]) ; ++i)
750 {
751 tc._indices.push_back(MemoryPool::template allocate_memory<IT2_>(tc._indices_size.at(i)));
752 if(0u == Pack::decode(tc._indices.at(i), &array[global_i], (std::size_t) tc._indices_size.at(i), (std::size_t) indices_bytes[i], compression_type_index, false))
753 XABORTM("Cannot decode compressed indice array");
754 global_i += (Index)indices_bytes[i];
755 }
756 }
757 else
758 {
759 global_i = Index((global_i * sizeof(DT2_) + sizeof(IT2_) - 1u) / sizeof(IT2_));
760 for (Index i(0) ; i < Index(uiarray[5]) ; ++i)
761 {
762 tc._indices.push_back(MemoryPool::template allocate_memory<IT2_>(tc._indices_size.at(i)));
763 MemoryPool::template copy<IT2_>(tc._indices.at(i), &itarray[global_i], tc._indices_size.at(i));
764 global_i += tc._indices_size.at(i);
765 }
766 }
767
768 this->assign(tc);
769 }
770
779 template <typename DT2_ = DT_, typename IT2_ = IT_>
780 void _deserialize(FileMode mode, std::istream & file)
781 {
782 std::uint64_t tsize;
783 file.read((char *)&tsize, (long)(sizeof(std::uint64_t)));
784 std::vector<char> temp((size_t(tsize)));
785 file.seekg(-(long)sizeof(std::uint64_t), file.cur);
786 file.read(temp.data(), (long)(tsize));
787 if (!file.good())
788 XABORTM("Error in _deserialize - file istream is not good anymore!");
789 this->template _deserialize<DT2_, IT2_>(mode, temp);
790 }
791
792 public:
800 explicit Container(Index size_in) :
801 _foreign_memory(false)
802 {
803 _scalar_index.push_back(size_in);
804 }
805
811 virtual ~Container()
812 {
813 if(! _foreign_memory)
814 {
815 for (Index i(0) ; i < _elements.size() ; ++i)
817 for (Index i(0) ; i < _indices.size() ; ++i)
819 }
820 }
821
830 _elements(std::move(other._elements)),
831 _indices(std::move(other._indices)),
833 _indices_size(std::move(other._indices_size)),
834 _scalar_index(std::move(other._scalar_index)),
835 _scalar_dt(std::move(other._scalar_dt)),
837 {
838 other._elements.clear();
839 other._indices.clear();
840 other._elements_size.clear();
841 other._indices_size.clear();
842 other._scalar_index.clear();
843 other._scalar_dt.clear();
844 }
845
851 void format(DT_ value = DT_(0))
852 {
853 for (Index i(0) ; i < _elements.size() ; ++i)
855 }
856
864 void format(Random & rng, DT_ min, DT_ max)
865 {
866 for (Index e(0) ; e < _elements.size() ; ++e)
867 {
868 MemoryPool::set_memory(rng, min, max, this->_elements.at(e), this->_elements_size.at(e));
869 }
870 }
871
875 virtual void clear()
876 {
877 if (! _foreign_memory)
878 {
879 for (Index i(0) ; i < _elements.size() ; ++i)
880 MemoryPool::release_memory(this->_elements.at(i));
881 for (Index i(0) ; i < _indices.size() ; ++i)
882 MemoryPool::release_memory(this->_indices.at(i));
883 }
884
885 this->_elements.clear();
886 this->_indices.clear();
887 this->_elements_size.clear();
888 this->_indices_size.clear();
889 this->_scalar_index.clear();
890 this->_scalar_dt.clear();
891 this->_foreign_memory = false;
892 }
893
902 void clone(const Container & other, CloneMode clone_mode = CloneMode::Weak)
903 {
904 if (this == &other)
905 {
906 XABORTM("Trying to self-clone a lafem container!");
907 }
908
909 XASSERTM(other._foreign_memory == false || clone_mode == CloneMode::Deep, "Must use deep cloning with ranged based source containers");
910
911 this->clear();
912
913 this->_scalar_index.assign(other._scalar_index.begin(), other._scalar_index.end());
914 this->_scalar_dt.assign(other._scalar_dt.begin(), other._scalar_dt.end());
915 this->_elements_size.assign(other._elements_size.begin(), other._elements_size.end());
916 this->_indices_size.assign(other._indices_size.begin(), other._indices_size.end());
917
918
919 if (clone_mode == CloneMode::Deep || clone_mode == CloneMode::Allocate)
920 {
921 for (Index i(0) ; i < other._indices.size() ; ++i)
922 {
923 this->_indices.push_back(MemoryPool::template allocate_memory<IT_>(this->_indices_size.at(i)));
924 if (clone_mode == CloneMode::Deep)
925 MemoryPool::template copy<IT_>(this->_indices.at(i), other._indices.at(i), this->_indices_size.at(i));
926 }
927
928 for (Index i(0) ; i < other._elements.size() ; ++i)
929 {
930 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(this->_elements_size.at(i)));
931 if (clone_mode == CloneMode::Deep)
932 MemoryPool::template copy<DT_>(this->_elements.at(i), other._elements.at(i), this->_elements_size.at(i));
933 }
934
935 return;
936 }
937 else
938 {
939 this->_indices.assign(other._indices.begin(), other._indices.end());
940 for (Index i(0) ; i < this->_indices.size() ; ++i)
941 MemoryPool::increase_memory(this->_indices.at(i));
942 }
943
944 if(clone_mode == CloneMode::Shallow)
945 {
946 this->_elements.assign(other._elements.begin(), other._elements.end());
947 for (Index i(0) ; i < this->_elements.size() ; ++i)
948 MemoryPool::increase_memory(this->_elements.at(i));
949
950 return;
951 }
952 else if(clone_mode == CloneMode::Layout)
953 {
954 for (Index i(0) ; i < other._elements.size() ; ++i)
955 {
956 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(this->_elements_size.at(i)));
957 }
958
959 return;
960 }
961 else if(clone_mode == CloneMode::Weak)
962 {
963 for (Index i(0) ; i < other._elements.size() ; ++i)
964 {
965 this->_elements.push_back(MemoryPool::template allocate_memory<DT_>(this->_elements_size.at(i)));
966 MemoryPool::template copy<DT_>(this->_elements.at(i), other._elements.at(i), this->_elements_size.at(i));
967 }
968
969 return;
970 }
971 }
972
974 template <typename DT2_, typename IT2_>
975 void clone(const Container<DT2_, IT2_> & other, CloneMode clone_mode = CloneMode::Weak)
976 {
977 Container t(other.size());
978 t.assign(other);
979 clone(t, clone_mode);
980 }
981
989 void move(Container && other)
990 {
991 if (this == &other)
992 return;
993
994 if (!this->_foreign_memory)
995 {
996 for (Index i(0) ; i < this->_elements.size() ; ++i)
997 MemoryPool::release_memory(this->_elements.at(i));
998 for (Index i(0) ; i < this->_indices.size() ; ++i)
999 MemoryPool::release_memory(this->_indices.at(i));
1000 }
1001
1002 this->_elements = std::move(other._elements);
1003 this->_indices = std::move(other._indices);
1004 this->_elements_size = std::move(other._elements_size);
1005 this->_indices_size = std::move(other._indices_size);
1006 this->_scalar_index = std::move(other._scalar_index);
1007 this->_scalar_dt = std::move(other._scalar_dt);
1008
1009 other._elements.clear();
1010 other._indices.clear();
1011 other._elements_size.clear();
1012 other._indices_size.clear();
1013
1014 this->_foreign_memory = other._foreign_memory;
1015 }
1016
1018 std::uint64_t get_checkpoint_size(const LAFEM::SerialConfig& config)
1019 {
1020 return this->template _serialized_size<>(config);
1021 }
1022
1024 void restore_from_checkpoint_data(std::vector<char> & data)
1025 {
1026 this->template _deserialize<>(FileMode::fm_binary, data);
1027 }
1028
1030 std::uint64_t set_checkpoint_data(std::vector<char>& data, const LAFEM::SerialConfig& config)
1031 {
1032 auto buffer = this->template _serialize<>(FileMode::fm_binary, config);
1033 data.insert(std::end(data), std::begin(buffer), std::end(buffer));
1034 return std::uint64_t(buffer.size());
1035 }
1036
1042 std::size_t bytes() const
1043 {
1044 std::size_t tbytes(0);
1045
1046 for (Index i(0) ; i < _elements_size.size() ; ++i)
1047 {
1048 tbytes += std::size_t(_elements_size.at(i) * sizeof(DT_));
1049 }
1050
1051 for (Index i(0) ; i < _indices_size.size() ; ++i)
1052 {
1053 tbytes += std::size_t(_indices_size.at(i) * sizeof(IT_));
1054 }
1055
1056 tbytes += std::size_t(_scalar_index.size() * sizeof(Index));
1057 tbytes += std::size_t(_scalar_dt.size() * sizeof(DT_));
1058
1059 return tbytes;
1060 }
1061
1062
1068 const std::vector<DT_*> & get_elements() const
1069 {
1070 return _elements;
1071 }
1072
1078 const std::vector<IT_*> & get_indices() const
1079 {
1080 return _indices;
1081 }
1082
1088 const std::vector<Index> & get_elements_size() const
1089 {
1090 return _elements_size;
1091 }
1092
1098 const std::vector<Index> & get_indices_size() const
1099 {
1100 return _indices_size;
1101 }
1102
1108 const std::vector<Index> & get_scalar_index() const
1109 {
1110 return _scalar_index;
1111 }
1112
1118 const std::vector<DT_> & get_scalar_dt() const
1119 {
1120 return _scalar_dt;
1121 }
1122
1135 template <Perspective = Perspective::native>
1136 Index size() const
1137 {
1138 if (_scalar_index.size() > 0)
1139 return _scalar_index.at(0);
1140 else
1141 return Index(0);
1142 }
1143
1154 template <Perspective = Perspective::native>
1156 {
1157 return this->size();
1158 }
1159
1165 bool empty() const
1166 {
1167 return (this->size() == Index(0));
1168 }
1169
1175 static String name()
1176 {
1177 return "Container";
1178 }
1179 };
1180 } // namespace LAFEM
1181} // namespace FEAT
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Container base class.
Definition: container.hpp:220
void _deserialize(FileMode mode, std::istream &file)
Deserialization of complete container entity with possible decompression.
Definition: container.hpp:780
Container(Index size_in)
Constructor.
Definition: container.hpp:800
const std::vector< IT_ * > & get_indices() const
Returns a list of all Index arrays.
Definition: container.hpp:1078
std::size_t bytes() const
Returns the total amount of bytes allocated.
Definition: container.hpp:1042
Container(Container &&other)
Move Constructor.
Definition: container.hpp:829
bool _foreign_memory
do we use memory that we did not allocate, nor are we allowed to free it - this mostly holds true,...
Definition: container.hpp:238
std::vector< char > _serialize(FileMode mode, const SerialConfig &config=SerialConfig()) const
Serialization of complete container entity(with options of lossless and lossy compression of data arr...
Definition: container.hpp:444
std::vector< DT_ * > _elements
List of pointers to all datatype dependent arrays.
Definition: container.hpp:226
Index used_elements() const
Returns the number of effective stored elements.
Definition: container.hpp:1155
const std::vector< DT_ > & get_scalar_dt() const
Returns a list of all scalar values with datatype dt.
Definition: container.hpp:1118
const std::vector< Index > & get_indices_size() const
Returns a list of all Index array sizes.
Definition: container.hpp:1098
bool empty() const
Checks whether the container is empty.
Definition: container.hpp:1165
const std::vector< Index > & get_elements_size() const
Returns a list of all data array sizes.
Definition: container.hpp:1088
std::uint64_t get_checkpoint_size(const LAFEM::SerialConfig &config)
Calculate size.
Definition: container.hpp:1018
const std::vector< DT_ * > & get_elements() const
Returns a list of all data arrays.
Definition: container.hpp:1068
std::vector< Index > _elements_size
List of corresponding datatype array sizes.
Definition: container.hpp:230
std::uint64_t _serialized_size(const LAFEM::SerialConfig &config=LAFEM::SerialConfig()) const
Calculation of the serialized size with optional compression of complete container entity.
Definition: container.hpp:361
Index size() const
Returns the containers size.
Definition: container.hpp:1136
void clone(const Container< DT2_, IT2_ > &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Definition: container.hpp:975
void assign(const Container< DT2_, IT2_ > &other)
Assignment operation.
Definition: container.hpp:280
static String name()
Returns a descriptive string.
Definition: container.hpp:1175
void restore_from_checkpoint_data(std::vector< char > &data)
Extract object from checkpoint.
Definition: container.hpp:1024
std::vector< IT_ * > _indices
List of pointers to all IT_ dependent arrays.
Definition: container.hpp:228
std::uint64_t set_checkpoint_data(std::vector< char > &data, const LAFEM::SerialConfig &config)
Definition: container.hpp:1030
void format(Random &rng, DT_ min, DT_ max)
Reset all elements of the container to random values.
Definition: container.hpp:864
virtual ~Container()
Destructor.
Definition: container.hpp:811
void clone(const Container &other, CloneMode clone_mode=CloneMode::Weak)
Clone operation.
Definition: container.hpp:902
const std::vector< Index > & get_scalar_index() const
Returns a list of all scalar values with datatype index.
Definition: container.hpp:1108
void move(Container &&other)
Assignment move operation.
Definition: container.hpp:989
virtual void clear()
Free all allocated arrays.
Definition: container.hpp:875
void _serialize(FileMode mode, std::ostream &file, const SerialConfig &config=SerialConfig()) const
Serialization of complete container entity(with options of lossless and lossy compression of data arr...
Definition: container.hpp:609
std::vector< Index > _indices_size
List of corresponding IT_ array sizes.
Definition: container.hpp:232
std::vector< DT_ > _scalar_dt
List of scalars with datatype DT_.
Definition: container.hpp:236
void _deserialize(FileMode mode, std::vector< char > &input)
Deserialization of complete container entity with possible decompression.
Definition: container.hpp:626
void format(DT_ value=DT_(0))
Reset all elements of the container to a given value or zero if missing.
Definition: container.hpp:851
std::vector< Index > _scalar_index
List of scalars with datatype index.
Definition: container.hpp:234
Config class for serialize parameter.
Definition: container.hpp:47
void set_tolerance(FEAT::Real tol)
method for setting tolerance
Definition: container.hpp:160
SerialConfig()
Default Constructor.
Definition: container.hpp:63
CompressionModes get_elements_compression() const
method for getting elements_compression
Definition: container.hpp:174
FEAT::Real get_tolerance() const
method for getting tolerance
Definition: container.hpp:196
SerialConfig(bool zlib_compression, bool zfp_compression, FEAT::Real tol=FEAT::Real(-1.))
Constructor.
Definition: container.hpp:82
void set_indices_compression(CompressionModes comp)
method for setting indices_compression
Definition: container.hpp:135
void set_elements_compression(CompressionModes comp)
method for setting elements_compression
Definition: container.hpp:104
CompressionModes get_indices_compression() const
method for getting indices_compression
Definition: container.hpp:185
static void copy(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void convert(DT_ *dest, const DT_ *src, const Index count)
Copy memory area from src to dest.
static void set_memory(DT_ *address, const DT_ val, const Index count=1)
set memory to specific value
static void release_memory(void *address)
release memory or decrease reference counter
static void increase_memory(void *address)
increase memory counter
Pseudo-Random Number Generator.
Definition: random.hpp:54
String class implementation.
Definition: string.hpp:46
LAFEM common type definitions.
CompressionModes
Definition: base.hpp:95
std::size_t estimate_size(const std::size_t count, const Pack::Type type, const double tolerance)
Computes the estimated (upper bound) pack buffer size for an array.
Definition: pack.cpp:543
Type
bitmask for zfp header
Definition: pack.hpp:81
std::size_t decode(T_ *dst, void *buf, const std::size_t count, const std::size_t buf_size, const Pack::Type pack_type, bool swap_bytes)
Decodes an array from a packed buffer.
Definition: pack.cpp:680
FEAT namespace.
Definition: adjactor.hpp:12
double Real
Real data type.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.
static bool extract_signedness(uint64_t feature_hash)
extracts sign feature from a given types feature hash
Definition: type_traits.hpp:51
static bool extract_intness(uint64_t feature_hash)
extracts integral feature from a given types feature hash
Definition: type_traits.hpp:39
static bool extract_floatness(uint64_t feature_hash)
extracts floating point feature from a given types feature hash
Definition: type_traits.hpp:45
static size_t extract_type_size(uint64_t feature_hash)
extracts sizeof datatype from a given types feature hash
Definition: type_traits.hpp:33
basic Type Traits struct
Definition: type_traits.hpp:73