16 #ifndef dealii_array_view_h 17 #define dealii_array_view_h 19 #include <deal.II/base/config.h> 21 #include <deal.II/base/exceptions.h> 22 #include <deal.II/base/memory_space.h> 24 #include <deal.II/base/table.h> 25 #include <deal.II/base/tensor.h> 27 #include <deal.II/lac/lapack_full_matrix.h> 29 #include <type_traits> 32 DEAL_II_NAMESPACE_OPEN
76 template <
typename ElementType,
typename MemorySpaceType = MemorySpace::Host>
132 MemorySpaceType> &view);
149 const std::vector<
typename std::remove_cv<value_type>::type> &vector);
165 ArrayView(std::vector<
typename std::remove_cv<value_type>::type> &vector);
205 MemorySpaceType> &other_view)
const;
223 MemorySpaceType> &other_view)
const;
237 data() const noexcept;
299 namespace ArrayViewHelper
301 template <
typename MemorySpaceType>
303 is_in_correct_memory_space(
const void *
const ptr)
305 #ifndef DEAL_II_COMPILER_CUDA_AWARE 307 static_assert(std::is_same<MemorySpaceType, MemorySpace::Host>::value,
308 "If the compiler doesn't understand CUDA code, " 309 "the only possible memory space is 'MemorySpace::Host'!");
312 cudaPointerAttributes attributes;
313 const cudaError_t cuda_error = cudaPointerGetAttributes(&attributes, ptr);
314 if (cuda_error != cudaErrorInvalidValue)
317 if (std::is_same<MemorySpaceType, MemorySpace::Host>::value)
318 return attributes.memoryType == cudaMemoryTypeHost;
320 return attributes.memoryType == cudaMemoryTypeDevice;
326 return std::is_same<MemorySpaceType, MemorySpace::Host>::value;
335 template <
typename ElementType,
typename MemorySpaceType>
343 template <
typename ElementType,
typename MemorySpaceType>
346 const std::size_t n_elements)
347 : starting_element(starting_element)
348 , n_elements(n_elements)
352 internal::ArrayViewHelper::is_in_correct_memory_space<MemorySpaceType>(
354 ExcMessage(
"The memory space indicated by the template parameter " 355 "and the one derived from the pointer value do not match!"));
360 template <
typename ElementType,
typename MemorySpaceType>
363 const std::size_t n_elements)
365 *
this =
ArrayView(starting_element, n_elements);
370 template <
typename ElementType,
typename MemorySpaceType>
372 const ArrayView<
typename std::remove_cv<value_type>::type, MemorySpaceType>
374 : starting_element(view.starting_element)
375 , n_elements(view.n_elements)
380 template <
typename ElementType,
typename MemorySpaceType>
382 const std::vector<
typename std::remove_cv<value_type>::type> &vector)
395 static_assert(std::is_const<value_type>::value ==
true,
396 "This constructor may only be called if the ArrayView " 397 "object has a const value_type. In other words, you can " 398 "only create an ArrayView to const values from a const " 404 template <
typename ElementType,
typename MemorySpaceType>
406 std::vector<
typename std::remove_cv<value_type>::type> &vector)
413 template <
typename ElementType,
typename MemorySpaceType>
418 return (other_view.
data() == starting_element) &&
419 (other_view.
size() == n_elements);
424 template <
typename ElementType,
typename MemorySpaceType>
428 MemorySpaceType> &other_view)
const 430 return (other_view.data() == starting_element) &&
431 (other_view.size() == n_elements);
436 template <
typename ElementType,
typename MemorySpaceType>
441 return !(*
this == other_view);
446 template <
typename ElementType,
typename MemorySpaceType>
453 return starting_element;
458 template <
typename ElementType,
typename MemorySpaceType>
462 MemorySpaceType> &other_view)
const 464 return !(*
this == other_view);
469 template <
typename ElementType,
typename MemorySpaceType>
478 template <
typename ElementType,
typename MemorySpaceType>
482 return starting_element;
487 template <
typename ElementType,
typename MemorySpaceType>
491 return starting_element + n_elements;
496 template <
typename ElementType,
typename MemorySpaceType>
500 return starting_element;
505 template <
typename ElementType,
typename MemorySpaceType>
509 return starting_element + n_elements;
514 template <
typename ElementType,
typename MemorySpaceType>
520 (std::is_same<MemorySpaceType, MemorySpace::Host>::value),
522 "Accessing elements is only allowed if the data is stored in CPU memory!"));
524 return *(starting_element + i);
532 namespace ArrayViewHelper
539 template <
class Iterator>
541 is_contiguous(
const Iterator &first,
const Iterator &last)
543 const auto n = std::distance(first, last);
544 for (
typename std::decay<decltype(n)>::type i = 0; i < n; ++i)
545 if (std::addressof(*(std::next(first, i))) !=
546 std::next(std::addressof(*first), i))
564 is_contiguous(T *, T *)
590 template <
typename Iterator,
typename MemorySpaceType = MemorySpace::Host>
591 ArrayView<
typename std::remove_reference<
592 typename std::iterator_traits<Iterator>::reference>::type,
597 std::is_same<
typename std::iterator_traits<Iterator>::iterator_category,
598 typename std::random_access_iterator_tag>::value,
599 "The provided iterator should be a random access iterator.");
602 "The beginning of the array view should be before the end."));
603 Assert(internal::ArrayViewHelper::is_contiguous(begin, end),
604 ExcMessage(
"The provided range isn't contiguous in memory!"));
606 return ArrayView<
typename std::remove_reference<
607 typename std::iterator_traits<Iterator>::reference>::type,
608 MemorySpaceType>(std::addressof(*begin), end - begin);
622 template <
typename ElementType,
typename MemorySpaceType = MemorySpace::Host>
628 "The beginning of the array view should be before the end."));
644 template <
typename Number,
typename MemorySpaceType>
663 template <
typename Number,
typename MemorySpaceType>
688 template <
int rank,
int dim,
typename Number>
713 template <
int rank,
int dim,
typename Number>
738 template <
int rank,
int dim,
typename Number>
764 template <
int rank,
int dim,
typename Number>
786 template <
typename ElementType,
int N>
808 template <
typename ElementType>
831 template <
typename ElementType>
854 template <
typename ElementType>
877 template <
typename ElementType>
905 template <
typename ElementType>
908 const std::size_t starting_index,
909 const std::size_t size_of_view)
911 Assert(starting_index + size_of_view <= vector.size(),
912 ExcMessage(
"The starting index and size of the view you want to " 913 "create would lead to a view that extends beyond the end " 914 "of the given vector."));
939 template <
typename ElementType>
942 const std::size_t starting_index,
943 const std::size_t size_of_view)
945 Assert(starting_index + size_of_view <= vector.size(),
946 ExcMessage(
"The starting index and size of the view you want to " 947 "create would lead to a view that extends beyond the end " 948 "of the given vector."));
970 template <
typename ElementType>
997 template <
typename ElementType>
1021 template <
typename ElementType>
1046 template <
typename ElementType>
1071 template <
typename ElementType>
1096 template <
typename ElementType>
1126 template <
typename ElementType>
1131 const std::size_t size_of_view)
1135 Assert(starting_column + size_of_view <= table.
size()[1],
1136 ExcMessage(
"The starting index and size of the view you want to " 1137 "create would lead to a view that extends beyond the end " 1138 "of a column of the given table."));
1163 template <
typename ElementType>
1168 const std::size_t size_of_view)
1172 Assert(starting_column + size_of_view <= table.
size()[1],
1173 ExcMessage(
"The starting index and size of the view you want to " 1174 "create would lead to a view that extends beyond the end " 1175 "of a column of the given table."));
1192 template <
typename Container>
1194 make_const_array_view(
const Container &container)
1201 DEAL_II_NAMESPACE_CLOSE
ArrayView< ElementType > make_array_view(LAPACKFullMatrix< ElementType > &matrix)
ArrayView< const ElementType > make_array_view(const LAPACKFullMatrix< ElementType > &matrix)
ArrayView< Number, MemorySpaceType > make_array_view(ArrayView< Number, MemorySpaceType > &array_view)
ArrayView< const Number, MemorySpaceType > make_array_view(const ArrayView< Number, MemorySpaceType > &array_view)
ArrayView< ElementType > make_array_view(ElementType(&array)[N])
const_iterator cbegin() const
ArrayView< const Number > make_array_view(const Tensor< rank, dim, Number > &tensor)
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row, const typename Table< 2, ElementType >::size_type starting_column, const std::size_t size_of_view)
bool operator==(const ArrayView< const value_type, MemorySpaceType > &other_view) const
const std::conditional< std::is_const< VectorType >::value, const VectorType::value_type, VectorType::value_type >::type * const_iterator
ArrayView< Number > make_array_view(SymmetricTensor< rank, dim, Number > &tensor)
ArrayView< ElementType > make_array_view(Vector< ElementType > &vector)
static ::ExceptionBase & ExcMessage(std::string arg1)
value_type & operator[](const std::size_t i) const
void reinit(value_type *starting_element, const std::size_t n_elements)
std::conditional< std::is_const< VectorType >::value, const VectorType::value_type, VectorType::value_type >::type value_type
#define Assert(cond, exc)
#define AssertCuda(error_code)
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
value_type * data() const noexcept
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector, const std::size_t starting_index, const std::size_t size_of_view)
bool operator!=(const ArrayView< const value_type, MemorySpaceType > &other_view) const
ArrayView< const Number > make_array_view(const SymmetricTensor< rank, dim, Number > &tensor)
size_type size(const unsigned int i) const
ArrayView< const ElementType > make_array_view(const Vector< ElementType > &vector)
ArrayView< ElementType > make_array_view(std::vector< ElementType > &vector)
typename AlignedVector< T >::size_type size_type
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row)
ArrayView< ElementType, MemorySpaceType > make_array_view(ElementType *const begin, ElementType *const end)
value_type * starting_element
ArrayView< typename std::remove_reference< typename std::iterator_traits< Iterator >::reference >::type, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table, const typename Table< 2, ElementType >::size_type row, const typename Table< 2, ElementType >::size_type starting_column, const std::size_t size_of_view)
ArrayView< Number > make_array_view(Tensor< rank, dim, Number > &tensor)
const_iterator cend() const
ArrayView< const ElementType > make_array_view(const std::vector< ElementType > &vector)
ArrayView< const ElementType > make_array_view(const Table< 2, ElementType > &table)
ArrayView< ElementType > make_array_view(Table< 2, ElementType > &table)