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;
275 value_type &operator[](const std::
size_t i) const;
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