Reference documentation for deal.II version Git 03f4796af1 2021-03-01 10:26:03 -0500
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
aligned_vector.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_aligned_vector_h
18 #define dealii_aligned_vector_h
19 
20 #include <deal.II/base/config.h>
21 
24 #include <deal.II/base/parallel.h>
25 #include <deal.II/base/utilities.h>
26 
27 // boost::serialization::make_array used to be in array.hpp, but was
28 // moved to a different file in BOOST 1.64
29 #include <boost/version.hpp>
30 #if BOOST_VERSION >= 106400
31 # include <boost/serialization/array_wrapper.hpp>
32 #else
33 # include <boost/serialization/array.hpp>
34 #endif
35 #include <boost/serialization/split_member.hpp>
36 
37 #include <cstring>
38 #include <type_traits>
39 
40 
41 
43 
44 
60 template <class T>
62 {
63 public:
68  using value_type = T;
69  using pointer = value_type *;
70  using const_pointer = const value_type *;
71  using iterator = value_type *;
72  using const_iterator = const value_type *;
73  using reference = value_type &;
74  using const_reference = const value_type &;
75  using size_type = std::size_t;
76 
80  AlignedVector();
81 
88  explicit AlignedVector(const size_type size, const T &init = T());
89 
94 
100  AlignedVector(const AlignedVector<T> &vec);
101 
106  AlignedVector(AlignedVector<T> &&vec) noexcept;
107 
113  AlignedVector &
114  operator=(const AlignedVector<T> &vec);
115 
119  AlignedVector &
120  operator=(AlignedVector<T> &&vec) noexcept;
121 
130  void
131  resize_fast(const size_type size);
132 
145  void
146  resize(const size_type size_in);
147 
163  void
164  resize(const size_type size_in, const T &init);
165 
174  void
175  reserve(const size_type size_alloc);
176 
181  void
182  clear();
183 
189  void
190  push_back(const T in_data);
191 
195  reference
196  back();
197 
202  back() const;
203 
208  template <typename ForwardIterator>
209  void
210  insert_back(ForwardIterator begin, ForwardIterator end);
211 
221  void
222  fill();
223 
232  void
233  fill(const T &element);
234 
238  void
239  swap(AlignedVector<T> &vec);
240 
244  bool
245  empty() const;
246 
250  size_type
251  size() const;
252 
257  size_type
258  capacity() const;
259 
263  reference operator[](const size_type index);
264 
268  const_reference operator[](const size_type index) const;
269 
273  pointer
274  data();
275 
280  data() const;
281 
285  iterator
286  begin();
287 
291  iterator
292  end();
293 
298  begin() const;
299 
304  end() const;
305 
311  size_type
312  memory_consumption() const;
313 
319  template <class Archive>
320  void
321  save(Archive &ar, const unsigned int version) const;
322 
328  template <class Archive>
329  void
330  load(Archive &ar, const unsigned int version);
331 
332 #ifdef DOXYGEN
333 
338  template <class Archive>
339  void
340  serialize(Archive &archive, const unsigned int version);
341 #else
342  // This macro defines the serialize() method that is compatible with
343  // the templated save() and load() method that have been implemented.
344  BOOST_SERIALIZATION_SPLIT_MEMBER()
345 #endif
346 
347 private:
352 
357 
362 };
363 
364 
365 // ------------------------------- inline functions --------------------------
366 
372 namespace internal
373 {
389  template <typename T>
391  {
392  static const std::size_t minimum_parallel_grain_size =
393  160000 / sizeof(T) + 1;
394 
395  public:
405  AlignedVectorCopy(const T *const source_begin,
406  const T *const source_end,
407  T *const destination)
408  : source_(source_begin)
409  , destination_(destination)
410  {
411  Assert(source_end >= source_begin, ExcInternalError());
412  Assert(source_end == source_begin || destination != nullptr,
413  ExcInternalError());
414  const std::size_t size = source_end - source_begin;
415  if (size < minimum_parallel_grain_size)
416  AlignedVectorCopy::apply_to_subrange(0, size);
417  else
418  apply_parallel(0, size, minimum_parallel_grain_size);
419  }
420 
425  virtual void
426  apply_to_subrange(const std::size_t begin,
427  const std::size_t end) const override
428  {
429  if (end == begin)
430  return;
431 
432  // for classes trivial assignment can use memcpy. cast element to
433  // (void*) to silence compiler warning for virtual classes (they will
434  // never arrive here because they are non-trivial).
435 
436  if (std::is_trivial<T>::value == true)
437  std::memcpy(static_cast<void *>(destination_ + begin),
438  static_cast<const void *>(source_ + begin),
439  (end - begin) * sizeof(T));
440  else
441  for (std::size_t i = begin; i < end; ++i)
442  new (&destination_[i]) T(source_[i]);
443  }
444 
445  private:
446  const T *const source_;
447  T *const destination_;
448  };
449 
450 
456  template <typename T>
458  {
459  static const std::size_t minimum_parallel_grain_size =
460  160000 / sizeof(T) + 1;
461 
462  public:
472  AlignedVectorMove(T *const source_begin,
473  T *const source_end,
474  T *const destination)
475  : source_(source_begin)
476  , destination_(destination)
477  {
478  Assert(source_end >= source_begin, ExcInternalError());
479  Assert(source_end == source_begin || destination != nullptr,
480  ExcInternalError());
481  const std::size_t size = source_end - source_begin;
482  if (size < minimum_parallel_grain_size)
483  AlignedVectorMove::apply_to_subrange(0, size);
484  else
485  apply_parallel(0, size, minimum_parallel_grain_size);
486  }
487 
492  virtual void
493  apply_to_subrange(const std::size_t begin,
494  const std::size_t end) const override
495  {
496  if (end == begin)
497  return;
498 
499  // for classes trivial assignment can use memcpy. cast element to
500  // (void*) to silence compiler warning for virtual classes (they will
501  // never arrive here because they are non-trivial).
502 
503  if (std::is_trivial<T>::value == true)
504  std::memcpy(static_cast<void *>(destination_ + begin),
505  static_cast<void *>(source_ + begin),
506  (end - begin) * sizeof(T));
507  else
508  for (std::size_t i = begin; i < end; ++i)
509  {
510  // initialize memory (copy construct by placement new), and
511  // destruct the source
512  new (&destination_[i]) T(std::move(source_[i]));
513  source_[i].~T();
514  }
515  }
516 
517  private:
518  T *const source_;
519  T *const destination_;
520  };
521 
522 
534  template <typename T, bool initialize_memory>
536  {
537  static const std::size_t minimum_parallel_grain_size =
538  160000 / sizeof(T) + 1;
539 
540  public:
545  AlignedVectorSet(const std::size_t size,
546  const T & element,
547  T *const destination)
548  : element_(element)
549  , destination_(destination)
550  , trivial_element(false)
551  {
552  if (size == 0)
553  return;
554  Assert(destination != nullptr, ExcInternalError());
555 
556  // do not use memcmp for long double because on some systems it does not
557  // completely fill its memory and may lead to false positives in
558  // e.g. valgrind
559  if (std::is_trivial<T>::value == true &&
560  std::is_same<T, long double>::value == false)
561  {
562  const unsigned char zero[sizeof(T)] = {};
563  // cast element to (void*) to silence compiler warning for virtual
564  // classes (they will never arrive here because they are
565  // non-trivial).
566  if (std::memcmp(zero,
567  static_cast<const void *>(&element),
568  sizeof(T)) == 0)
569  trivial_element = true;
570  }
571  if (size < minimum_parallel_grain_size)
572  AlignedVectorSet::apply_to_subrange(0, size);
573  else
574  apply_parallel(0, size, minimum_parallel_grain_size);
575  }
576 
580  virtual void
581  apply_to_subrange(const std::size_t begin,
582  const std::size_t end) const override
583  {
584  // for classes with trivial assignment of zero can use memset. cast
585  // element to (void*) to silence compiler warning for virtual
586  // classes (they will never arrive here because they are
587  // non-trivial).
588  if (std::is_trivial<T>::value == true && trivial_element)
589  std::memset(static_cast<void *>(destination_ + begin),
590  0,
591  (end - begin) * sizeof(T));
592  else
593  copy_construct_or_assign(
594  begin, end, std::integral_constant<bool, initialize_memory>());
595  }
596 
597  private:
598  const T & element_;
599  mutable T *destination_;
601 
602  // copy assignment operation
603  void
604  copy_construct_or_assign(const std::size_t begin,
605  const std::size_t end,
606  std::integral_constant<bool, false>) const
607  {
608  for (std::size_t i = begin; i < end; ++i)
609  destination_[i] = element_;
610  }
611 
612  // copy constructor (memory initialization)
613  void
614  copy_construct_or_assign(const std::size_t begin,
615  const std::size_t end,
616  std::integral_constant<bool, true>) const
617  {
618  for (std::size_t i = begin; i < end; ++i)
619  new (&destination_[i]) T(element_);
620  }
621  };
622 
623 
624 
636  template <typename T, bool initialize_memory>
639  {
640  static const std::size_t minimum_parallel_grain_size =
641  160000 / sizeof(T) + 1;
642 
643  public:
648  AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
649  : destination_(destination)
650  {
651  if (size == 0)
652  return;
653  Assert(destination != nullptr, ExcInternalError());
654 
655  if (size < minimum_parallel_grain_size)
656  AlignedVectorDefaultInitialize::apply_to_subrange(0, size);
657  else
658  apply_parallel(0, size, minimum_parallel_grain_size);
659  }
660 
664  virtual void
665  apply_to_subrange(const std::size_t begin,
666  const std::size_t end) const override
667  {
668  // for classes with trivial assignment of zero can use memset. cast
669  // element to (void*) to silence compiler warning for virtual
670  // classes (they will never arrive here because they are
671  // non-trivial).
672  if (std::is_trivial<T>::value == true)
673  std::memset(static_cast<void *>(destination_ + begin),
674  0,
675  (end - begin) * sizeof(T));
676  else
677  default_construct_or_assign(
678  begin, end, std::integral_constant<bool, initialize_memory>());
679  }
680 
681  private:
682  mutable T *destination_;
683 
684  // copy assignment operation
685  void
687  const std::size_t end,
688  std::integral_constant<bool, false>) const
689  {
690  for (std::size_t i = begin; i < end; ++i)
691  destination_[i] = std::move(T());
692  }
693 
694  // copy constructor (memory initialization)
695  void
697  const std::size_t end,
698  std::integral_constant<bool, true>) const
699  {
700  for (std::size_t i = begin; i < end; ++i)
701  new (&destination_[i]) T;
702  }
703  };
704 
705 } // end of namespace internal
706 
707 
708 #ifndef DOXYGEN
709 
710 
711 template <class T>
713  : data_begin(nullptr)
714  , data_end(nullptr)
715  , allocated_end(nullptr)
716 {}
717 
718 
719 
720 template <class T>
721 inline AlignedVector<T>::AlignedVector(const size_type size, const T &init)
722  : data_begin(nullptr)
723  , data_end(nullptr)
724  , allocated_end(nullptr)
725 {
726  if (size > 0)
727  resize(size, init);
728 }
729 
730 
731 
732 template <class T>
734 {
735  clear();
736 }
737 
738 
739 
740 template <class T>
742  : data_begin(nullptr)
743  , data_end(nullptr)
744  , allocated_end(nullptr)
745 {
746  // copy the data from vec
747  reserve(vec.data_end - vec.data_begin);
749  internal::AlignedVectorCopy<T>(vec.data_begin, vec.data_end, data_begin);
750 }
751 
752 
753 
754 template <class T>
756  : data_begin(vec.data_begin)
757  , data_end(vec.data_end)
758  , allocated_end(vec.allocated_end)
759 {
760  vec.data_begin = nullptr;
761  vec.data_end = nullptr;
762  vec.allocated_end = nullptr;
763 }
764 
765 
766 
767 template <class T>
768 inline AlignedVector<T> &
770 {
771  resize(0);
772  resize_fast(vec.data_end - vec.data_begin);
773  internal::AlignedVectorCopy<T>(vec.data_begin, vec.data_end, data_begin);
774  return *this;
775 }
776 
777 
778 
779 template <class T>
780 inline AlignedVector<T> &
782 {
783  clear();
784 
785  data_begin = vec.data_begin;
786  data_end = vec.data_end;
787  allocated_end = vec.allocated_end;
788 
789  vec.data_begin = nullptr;
790  vec.data_end = nullptr;
791  vec.allocated_end = nullptr;
792 
793  return *this;
794 }
795 
796 
797 
798 template <class T>
799 inline void
801 {
802  const size_type old_size = size();
803  if (std::is_trivial<T>::value == false && size_in < old_size)
804  {
805  // call destructor on fields that are released. doing it backward
806  // releases the elements in reverse order as compared to how they were
807  // created
808  while (data_end != data_begin + size_in)
809  (--data_end)->~T();
810  }
811  reserve(size_in);
812  data_end = data_begin + size_in;
813 
814  // need to still set the values in case the class is non-trivial because
815  // virtual classes etc. need to run their (default) constructor
816  if (std::is_trivial<T>::value == false && size_in > old_size)
818  size_in - old_size, data_begin + old_size);
819 }
820 
821 
822 
823 template <class T>
824 inline void
825 AlignedVector<T>::resize(const size_type size_in)
826 {
827  const size_type old_size = size();
828  if (std::is_trivial<T>::value == false && size_in < old_size)
829  {
830  // call destructor on fields that are released. doing it backward
831  // releases the elements in reverse order as compared to how they were
832  // created
833  while (data_end != data_begin + size_in)
834  (--data_end)->~T();
835  }
836  reserve(size_in);
837  data_end = data_begin + size_in;
838 
839  // finally set the desired init values
840  if (size_in > old_size)
842  size_in - old_size, data_begin + old_size);
843 }
844 
845 
846 
847 template <class T>
848 inline void
849 AlignedVector<T>::resize(const size_type size_in, const T &init)
850 {
851  const size_type old_size = size();
852  if (std::is_trivial<T>::value == false && size_in < old_size)
853  {
854  // call destructor on fields that are released. doing it backward
855  // releases the elements in reverse order as compared to how they were
856  // created
857  while (data_end != data_begin + size_in)
858  (--data_end)->~T();
859  }
860  reserve(size_in);
861  data_end = data_begin + size_in;
862 
863  // finally set the desired init values
864  if (size_in > old_size)
865  ::internal::AlignedVectorSet<T, true>(size_in - old_size,
866  init,
867  data_begin + old_size);
868 }
869 
870 
871 
872 template <class T>
873 inline void
874 AlignedVector<T>::reserve(const size_type size_alloc)
875 {
876  const size_type old_size = data_end - data_begin;
877  const size_type allocated_size = allocated_end - data_begin;
878  if (size_alloc > allocated_size)
879  {
880  // if we continuously increase the size of the vector, we might be
881  // reallocating a lot of times. therefore, try to increase the size more
882  // aggressively
883  size_type new_size = size_alloc;
884  if (size_alloc < (2 * allocated_size))
885  new_size = 2 * allocated_size;
886 
887  const size_type size_actual_allocate = new_size * sizeof(T);
888 
889  // allocate and align along 64-byte boundaries (this is enough for all
890  // levels of vectorization currently supported by deal.II)
891  T *new_data;
892  Utilities::System::posix_memalign(reinterpret_cast<void **>(&new_data),
893  64,
894  size_actual_allocate);
895 
896  // copy data in case there was some content before and release the old
897  // memory with the function corresponding to the one used for allocating
898  std::swap(data_begin, new_data);
899  data_end = data_begin + old_size;
900  allocated_end = data_begin + new_size;
901  if (data_end != data_begin)
902  {
904  new_data + old_size,
905  data_begin);
906  free(new_data);
907  }
908  else
909  Assert(new_data == nullptr, ExcInternalError());
910  }
911  else if (size_alloc == 0)
912  clear();
913 }
914 
915 
916 
917 template <class T>
918 inline void
920 {
921  if (data_begin != nullptr)
922  {
923  if (std::is_trivial<T>::value == false)
924  while (data_end != data_begin)
925  (--data_end)->~T();
926 
927  free(data_begin);
928  }
929  data_begin = nullptr;
930  data_end = nullptr;
931  allocated_end = nullptr;
932 }
933 
934 
935 
936 template <class T>
937 inline void
938 AlignedVector<T>::push_back(const T in_data)
939 {
941  if (data_end == allocated_end)
942  reserve(std::max(2 * capacity(), static_cast<size_type>(16)));
943  if (std::is_trivial<T>::value == false)
944  new (data_end++) T(in_data);
945  else
946  *data_end++ = in_data;
947 }
948 
949 
950 
951 template <class T>
952 inline typename AlignedVector<T>::reference
954 {
955  AssertIndexRange(0, size());
956  T *field = data_end - 1;
957  return *field;
958 }
959 
960 
961 
962 template <class T>
963 inline typename AlignedVector<T>::const_reference
965 {
966  AssertIndexRange(0, size());
967  const T *field = data_end - 1;
968  return *field;
969 }
970 
971 
972 
973 template <class T>
974 template <typename ForwardIterator>
975 inline void
976 AlignedVector<T>::insert_back(ForwardIterator begin, ForwardIterator end)
977 {
978  const unsigned int old_size = size();
979  reserve(old_size + (end - begin));
980  for (; begin != end; ++begin, ++data_end)
981  {
982  if (std::is_trivial<T>::value == false)
983  new (data_end) T;
984  *data_end = *begin;
985  }
986 }
987 
988 
989 
990 template <class T>
991 inline void
993 {
995  data_begin);
996 }
997 
998 
999 
1000 template <class T>
1001 inline void
1003 {
1005 }
1006 
1007 
1008 
1009 template <class T>
1010 inline void
1012 {
1013  std::swap(data_begin, vec.data_begin);
1014  std::swap(data_end, vec.data_end);
1015  std::swap(allocated_end, vec.allocated_end);
1016 }
1017 
1018 
1019 
1020 template <class T>
1021 inline bool
1023 {
1024  return data_end == data_begin;
1025 }
1026 
1027 
1028 
1029 template <class T>
1030 inline typename AlignedVector<T>::size_type
1031 AlignedVector<T>::size() const
1032 {
1033  return data_end - data_begin;
1034 }
1035 
1036 
1037 
1038 template <class T>
1039 inline typename AlignedVector<T>::size_type
1041 {
1042  return allocated_end - data_begin;
1043 }
1044 
1045 
1046 
1047 template <class T>
1049  operator[](const size_type index)
1050 {
1051  AssertIndexRange(index, size());
1052  return data_begin[index];
1053 }
1054 
1055 
1056 
1057 template <class T>
1059  operator[](const size_type index) const
1060 {
1061  AssertIndexRange(index, size());
1062  return data_begin[index];
1063 }
1064 
1065 
1066 
1067 template <typename T>
1068 inline typename AlignedVector<T>::pointer
1070 {
1071  return data_begin;
1072 }
1073 
1074 
1075 
1076 template <typename T>
1077 inline typename AlignedVector<T>::const_pointer
1078 AlignedVector<T>::data() const
1079 {
1080  return data_begin;
1081 }
1082 
1083 
1084 
1085 template <class T>
1086 inline typename AlignedVector<T>::iterator
1088 {
1089  return data_begin;
1090 }
1091 
1092 
1093 
1094 template <class T>
1095 inline typename AlignedVector<T>::iterator
1097 {
1098  return data_end;
1099 }
1100 
1101 
1102 
1103 template <class T>
1104 inline typename AlignedVector<T>::const_iterator
1106 {
1107  return data_begin;
1108 }
1109 
1110 
1111 
1112 template <class T>
1113 inline typename AlignedVector<T>::const_iterator
1114 AlignedVector<T>::end() const
1115 {
1116  return data_end;
1117 }
1118 
1119 
1120 
1121 template <class T>
1122 template <class Archive>
1123 inline void
1124 AlignedVector<T>::save(Archive &ar, const unsigned int) const
1125 {
1126  size_type vec_size(size());
1127  ar & vec_size;
1128  if (vec_size > 0)
1129  ar &boost::serialization::make_array(data_begin, vec_size);
1130 }
1131 
1132 
1133 
1134 template <class T>
1135 template <class Archive>
1136 inline void
1137 AlignedVector<T>::load(Archive &ar, const unsigned int)
1138 {
1139  size_type vec_size = 0;
1140  ar & vec_size;
1141 
1142  if (vec_size > 0)
1143  {
1144  reserve(vec_size);
1145  ar &boost::serialization::make_array(data_begin, vec_size);
1146  data_end = data_begin + vec_size;
1147  }
1148 }
1149 
1150 
1151 
1152 template <class T>
1153 inline typename AlignedVector<T>::size_type
1155 {
1156  size_type memory = sizeof(*this);
1157  for (const T *t = data_begin; t != data_end; ++t)
1158  memory += ::MemoryConsumption::memory_consumption(*t);
1159  memory += sizeof(T) * (allocated_end - data_end);
1160  return memory;
1161 }
1162 
1163 
1164 #endif // ifndef DOXYGEN
1165 
1166 
1172 template <class T>
1173 bool
1175 {
1176  if (lhs.size() != rhs.size())
1177  return false;
1178  for (typename AlignedVector<T>::const_iterator lit = lhs.begin(),
1179  rit = rhs.begin();
1180  lit != lhs.end();
1181  ++lit, ++rit)
1182  if (*lit != *rit)
1183  return false;
1184  return true;
1185 }
1186 
1187 
1188 
1194 template <class T>
1195 bool
1197 {
1198  return !(operator==(lhs, rhs));
1199 }
1200 
1201 
1203 
1204 #endif
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
void posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
Definition: utilities.cc:1050
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
value_type * pointer
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
#define AssertIndexRange(index, range)
Definition: exceptions.h:1691
pointer data()
void load(Archive &ar, const unsigned int version)
AlignedVector & operator=(const AlignedVector< T > &vec)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
void reserve(const size_type size_alloc)
void push_back(const T in_data)
void resize(const size_type size_in)
value_type * iterator
reference operator[](const size_type index)
void serialize(Archive &archive, const unsigned int version)
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
static const char T
#define Assert(cond, exc)
Definition: exceptions.h:1466
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:394
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
void insert_back(ForwardIterator begin, ForwardIterator end)
const value_type * const_iterator
size_type memory_consumption() const
value_type & reference
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
void swap(AlignedVector< T > &vec)
void resize_fast(const size_type size)
void swap(MemorySpaceData< Number, MemorySpace > &, MemorySpaceData< Number, MemorySpace > &)
void save(Archive &ar, const unsigned int version) const
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
iterator end()
AlignedVectorMove(T *const source_begin, T *const source_end, T *const destination)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:393
AlignedVectorCopy(const T *const source_begin, const T *const source_end, T *const destination)
iterator begin()
AlignedVectorSet(const std::size_t size, const T &element, T *const destination)
size_type size() const
unsigned int minimum_parallel_grain_size
Definition: parallel.cc:34
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
static const types::blas_int zero
void free(T *&pointer)
Definition: cuda.h:97
const value_type * const_pointer
bool empty() const
const value_type & const_reference
T max(const T &t, const MPI_Comm &mpi_communicator)
size_type capacity() const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
reference back()
static ::ExceptionBase & ExcInternalError()