16#ifndef dealii_la_parallel_vector_h
17#define dealii_la_parallel_vector_h
52 class ReadWriteVector;
55# ifdef DEAL_II_WITH_PETSC
65# ifdef DEAL_II_WITH_TRILINOS
247 template <
typename Number,
typename MemorySpace = MemorySpace::Host>
264 std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
265 std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
266 "MemorySpace should be Host or CUDA");
323 const std::shared_ptr<const Utilities::MPI::Partitioner> &
partitioner);
347 template <
typename Number2>
350 const bool omit_zeroing_entries =
false);
393 const std::shared_ptr<const Utilities::MPI::Partitioner> &
partitioner,
461 template <
typename Number2>
552 const unsigned int communication_channel = 0,
595 const unsigned int communication_channel = 0)
const;
660 template <
typename Number2>
674 template <
typename MemorySpace2>
692 const bool omit_zeroing_entries =
false)
override;
732 std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
733 communication_pattern = {})
override;
745 add(
const Number a)
override;
767 add(
const std::vector<size_type> &indices,
768 const std::vector<Number> &
values);
871 const unsigned int precision = 3,
872 const bool scientific =
true,
873 const bool across =
true)
const override;
899 template <
typename OtherNumber>
901 add(
const std::vector<size_type> & indices,
902 const ::Vector<OtherNumber> &
values);
908 template <
typename OtherNumber>
912 const OtherNumber *
values);
1085 template <
typename OtherNumber>
1088 std::vector<OtherNumber> &
values)
const;
1117 template <
typename ForwardIterator,
typename OutputIterator>
1120 const ForwardIterator indices_end,
1121 OutputIterator values_begin)
const;
1162 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1205 const std::vector<ArrayView<const Number>> &
1231 <<
"Called compress(VectorOperation::insert), but"
1232 <<
" the element received from a remote processor, value "
1233 << std::setprecision(16) << arg1
1234 <<
", does not match with the value "
1235 << std::setprecision(16) << arg2
1236 <<
" on the owner processor " << arg3);
1247 <<
"You tried to access element " << arg1
1248 <<
" of a distributed vector, but this element is not "
1249 <<
"stored on the current processor. Note: The range of "
1250 <<
"locally owned elements is [" << arg2 <<
"," << arg3
1251 <<
"], and there are " << arg4 <<
" ghost elements "
1252 <<
"that this vector can access."
1254 <<
"A common source for this kind of problem is that you "
1255 <<
"are passing a 'fully distributed' vector into a function "
1256 <<
"that needs read access to vector elements that correspond "
1257 <<
"to degrees of freedom on ghost cells (or at least to "
1258 <<
"'locally active' degrees of freedom that are not also "
1259 <<
"'locally owned'). You need to pass a vector that has these "
1260 <<
"elements as ghost entries.");
1282 template <
typename Number2>
1341 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
data;
1347 mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1354 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1366#ifdef DEAL_II_WITH_MPI
1413 template <
typename Number2,
typename MemorySpace2>
1417 template <
typename Number2>
1429 template <
typename Number,
typename MemorySpace>
1440 const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1445 static inline Number *
1455 template <
typename Number>
1460 begin(::MemorySpace::
1461 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1463 return data.values.get();
1468 begin(const ::MemorySpace::
1469 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1471 return data.values.get();
1474 static inline Number *
1475 get_values(::MemorySpace::
1476 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1478 return data.values.get();
1484 template <
typename Number>
1489 begin(::MemorySpace::
1490 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1492 return data.values_dev.get();
1497 begin(const ::MemorySpace::
1498 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1500 return data.values_dev.get();
1503 static inline Number *
1504 get_values(::MemorySpace::
1505 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1507 return data.values_dev.get();
1513 template <
typename Number,
typename MemorySpace>
1517 return vector_is_ghosted;
1522 template <
typename Number,
typename MemorySpace>
1526 return partitioner->size();
1531 template <
typename Number,
typename MemorySpace>
1535 return locally_owned_size();
1540 template <
typename Number,
typename MemorySpace>
1544 return partitioner->locally_owned_size();
1549 template <
typename Number,
typename MemorySpace>
1559 template <
typename Number,
typename MemorySpace>
1565 is.add_range(partitioner->local_range().first,
1566 partitioner->local_range().second);
1573 template <
typename Number,
typename MemorySpace>
1582 template <
typename Number,
typename MemorySpace>
1591 template <
typename Number,
typename MemorySpace>
1596 partitioner->locally_owned_size();
1601 template <
typename Number,
typename MemorySpace>
1606 partitioner->locally_owned_size();
1611 template <
typename Number,
typename MemorySpace>
1612 const std::vector<ArrayView<const Number>> &
1615 return data.values_sm;
1620 template <
typename Number,
typename MemorySpace>
1624 Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1626 "This function is only implemented for the Host memory space"));
1631 partitioner->local_range().first,
1632 partitioner->local_range().second - 1,
1633 partitioner->ghost_indices().n_elements()));
1636 vector_is_ghosted ==
true,
1637 ExcMessage(
"You tried to read a ghost element of this vector, "
1638 "but it has not imported its ghost values."));
1639 return data.values[partitioner->global_to_local(
global_index)];
1644 template <
typename Number,
typename MemorySpace>
1648 Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1650 "This function is only implemented for the Host memory space"));
1655 partitioner->local_range().first,
1656 partitioner->local_range().second - 1,
1657 partitioner->ghost_indices().n_elements()));
1664 return data.values[partitioner->global_to_local(
global_index)];
1669 template <
typename Number,
typename MemorySpace>
1678 template <
typename Number,
typename MemorySpace>
1687 template <
typename Number,
typename MemorySpace>
1692 Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1694 "This function is only implemented for the Host memory space"));
1696 partitioner->locally_owned_size() +
1697 partitioner->n_ghost_indices());
1699 Assert(local_index < locally_owned_size() || vector_is_ghosted ==
true,
1700 ExcMessage(
"You tried to read a ghost element of this vector, "
1701 "but it has not imported its ghost values."));
1703 return data.values[local_index];
1708 template <
typename Number,
typename MemorySpace>
1712 Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1714 "This function is only implemented for the Host memory space"));
1717 partitioner->locally_owned_size() +
1718 partitioner->n_ghost_indices());
1720 return data.values[local_index];
1725 template <
typename Number,
typename MemorySpace>
1729 return internal::Policy<Number, MemorySpace>::get_values(data);
1734 template <
typename Number,
typename MemorySpace>
1735 template <
typename OtherNumber>
1738 const std::vector<size_type> &indices,
1739 std::vector<OtherNumber> &
values)
const
1741 for (
size_type i = 0; i < indices.size(); ++i)
1742 values[i] =
operator()(indices[i]);
1747 template <
typename Number,
typename MemorySpace>
1748 template <
typename ForwardIterator,
typename OutputIterator>
1751 ForwardIterator indices_begin,
1752 const ForwardIterator indices_end,
1753 OutputIterator values_begin)
const
1755 while (indices_begin != indices_end)
1757 *values_begin = operator()(*indices_begin);
1765 template <
typename Number,
typename MemorySpace>
1766 template <
typename OtherNumber>
1769 const std::vector<size_type> & indices,
1770 const ::Vector<OtherNumber> &
values)
1773 for (
size_type i = 0; i < indices.size(); ++i)
1778 "The given value is not finite but either infinite or Not A Number (NaN)"));
1779 this->operator()(indices[i]) +=
values(i);
1785 template <
typename Number,
typename MemorySpace>
1786 template <
typename OtherNumber>
1790 const OtherNumber *
values)
1797 "The given value is not finite but either infinite or Not A Number (NaN)"));
1798 this->operator()(*indices) += *
values;
1804 template <
typename Number,
typename MemorySpace>
1808 return partitioner->get_mpi_communicator();
1813 template <
typename Number,
typename MemorySpace>
1814 inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1822 template <
typename Number,
typename MemorySpace>
1826 vector_is_ghosted = ghosted;
1842template <
typename Number,
typename MemorySpace>
1854template <
typename Number,
typename MemorySpace>
1863 namespace LinearOperatorImplementation
1872 template <
typename Number>
1878 template <
typename T>
1879 struct has_get_mpi_communicator
1885 template <
typename U>
1886 static decltype(std::declval<U>().get_mpi_communicator())
1891 !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1896 template <
typename T>
1897 struct has_locally_owned_domain_indices
1903 template <
typename U>
1904 static decltype(std::declval<U>().locally_owned_domain_indices())
1909 !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1914 template <
typename T>
1915 struct has_locally_owned_range_indices
1921 template <
typename U>
1922 static decltype(std::declval<U>().locally_owned_range_indices())
1927 !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1932 template <
typename T>
1933 struct has_initialize_dof_vector
1939 template <
typename U>
1940 static decltype(std::declval<U>().initialize_dof_vector(
1946 !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
1950 template <
typename MatrixType,
1951 typename std::enable_if<
1952 has_get_mpi_communicator<MatrixType>::value &&
1953 has_locally_owned_domain_indices<MatrixType>::value,
1954 MatrixType>::type * =
nullptr>
1960 vec.
reinit(mat.locally_owned_domain_indices(),
1961 mat.get_mpi_communicator());
1966 typename MatrixType,
1967 typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1968 MatrixType>::type * =
nullptr>
1972 bool omit_zeroing_entries)
1974 mat.initialize_dof_vector(vec);
1975 if (!omit_zeroing_entries)
1980 template <
typename MatrixType,
1981 typename std::enable_if<
1982 has_get_mpi_communicator<MatrixType>::value &&
1983 has_locally_owned_range_indices<MatrixType>::value,
1984 MatrixType>::type * =
nullptr>
1990 vec.
reinit(mat.locally_owned_range_indices(),
1991 mat.get_mpi_communicator());
1996 typename MatrixType,
1997 typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1998 MatrixType>::type * =
nullptr>
2002 bool omit_zeroing_entries)
2004 mat.initialize_dof_vector(vec);
2005 if (!omit_zeroing_entries)
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v)
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DEPRECATED_EARLY
#define DEAL_II_NAMESPACE_CLOSE
#define DeclException0(Exception0)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
Number & operator()(const size_type global_index)
void zero_out_ghost_values() const
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
Number mean_value_local() const
virtual real_type l1_norm() const override
void resize_val(const size_type new_allocated_size, const MPI_Comm &comm_sm=MPI_COMM_SELF)
bool partitioners_are_compatible(const Utilities::MPI::Partitioner &part) const
virtual Vector< Number, MemorySpace > & operator*=(const Number factor) override
bool has_ghost_elements() const
void reinit(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner, const MPI_Comm &comm_sm=MPI_COMM_SELF)
const value_type & const_reference
Number local_element(const size_type local_index) const
Number add_and_dot_local(const Number a, const Vector< Number, MemorySpace > &V, const Vector< Number, MemorySpace > &W)
real_type linfty_norm_local() const
virtual void add(const Number a, const VectorSpaceVector< Number > &V, const Number b, const VectorSpaceVector< Number > &W) override
Number * get_values() const
void update_ghost_values() const
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > import_data
void swap(Vector< Number, MemorySpace > &v)
real_type l1_norm_local() const
virtual real_type linfty_norm() const override
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > data
types::global_dof_index size_type
Vector(const IndexSet &local_range, const IndexSet &ghost_indices, const MPI_Comm &communicator)
const value_type * const_iterator
typename numbers::NumberTraits< Number >::real_type real_type
const_iterator end() const
Vector(const size_type size)
size_type locally_owned_size() const
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
void add(const size_type n_elements, const size_type *indices, const OtherNumber *values)
virtual void equ(const Number a, const VectorSpaceVector< Number > &V) override
void sadd(const Number s, const Vector< Number, MemorySpace > &V)
Vector(const IndexSet &local_range, const MPI_Comm &communicator)
Vector< Number, MemorySpace > & operator=(const Vector< Number, MemorySpace > &in_vector)
real_type norm_sqr_local() const
virtual std::size_t memory_consumption() const override
const value_type * const_iterator
void clear_mpi_requests()
static decltype(std::declval< U >().locally_owned_domain_indices()) detect(const U &)
static ::ExceptionBase & ExcVectorTypeNotCompatible()
Number operator[](const size_type global_index) const
virtual bool all_zero() const override
Vector(const Vector< Number, MemorySpace > &in_vector)
virtual Number mean_value() const override
void set_ghost_state(const bool ghosted) const
static ::ExceptionBase & ExcNonMatchingElements(Number arg1, Number arg2, unsigned int arg3)
virtual Vector< Number, MemorySpace > & operator=(const Number s) override
void reinit(const IndexSet &local_range, const IndexSet &ghost_indices, const MPI_Comm &communicator)
void add(const std::vector< size_type > &indices, const ::Vector< OtherNumber > &values)
virtual void reinit(const VectorSpaceVector< Number > &V, const bool omit_zeroing_entries=false) override
Number & operator[](const size_type global_index)
virtual Number operator*(const VectorSpaceVector< Number > &V) const override
const value_type * const_pointer
static ::ExceptionBase & ExcNotAllowedForCuda()
virtual void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
virtual void compress(::VectorOperation::values operation) override
void reinit(const Vector< Number2, MemorySpace > &in_vector, const bool omit_zeroing_entries=false)
real_type lp_norm(const real_type p) const
bool partitioners_are_globally_compatible(const Utilities::MPI::Partitioner &part) const
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
static decltype(std::declval< U >().locally_owned_range_indices()) detect(const U &)
virtual size_type size() const override
virtual ~Vector() override
virtual Vector< Number, MemorySpace > & operator-=(const VectorSpaceVector< Number > &V) override
void add_local(const Number a, const VectorSpaceVector< Number > &V)
static decltype(std::declval< U >().get_mpi_communicator()) detect(const U &)
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
virtual void sadd(const Number s, const Number a, const VectorSpaceVector< Number > &V) override
void compress_start(const unsigned int communication_channel=0, ::VectorOperation::values operation=VectorOperation::add)
const MPI_Comm & get_mpi_communicator() const
virtual void scale(const VectorSpaceVector< Number > &scaling_factors) override
virtual void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const override
void update_ghost_values_finish() const
const std::vector< ArrayView< const Number > > & shared_vector_data() const
void update_ghost_values_start(const unsigned int communication_channel=0) const
void copy_locally_owned_data_from(const Vector< Number2, MemorySpace > &src)
Vector< Number, MemorySpace > & operator=(const Vector< Number2, MemorySpace > &in_vector)
virtual void add(const Number a, const VectorSpaceVector< Number > &V) override
size_type local_size() const
virtual Vector< Number, MemorySpace > & operator/=(const Number factor) override
virtual void add(const Number a) override
void zero_out_ghosts() const
const value_type * const_iterator
Number operator()(const size_type global_index) const
virtual Vector< Number, MemorySpace > & operator+=(const VectorSpaceVector< Number > &V) override
real_type lp_norm_local(const real_type p) const
void reinit(const types::global_dof_index local_size, const types::global_dof_index ghost_size, const MPI_Comm &comm, const MPI_Comm &comm_sm=MPI_COMM_SELF)
void sadd_local(const Number s, const Number a, const VectorSpaceVector< Number > &V)
void reinit(const IndexSet &local_range, const MPI_Comm &communicator)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
static decltype(std::declval< U >().initialize_dof_vector(std::declval< LinearAlgebra::distributed::Vector< Number > & >())) detect(const U &)
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
void compress_finish(::VectorOperation::values operation)
std::vector< MPI_Request > update_ghost_values_requests
const_iterator begin() const
std::vector< MPI_Request > compress_requests
bool in_local_range(const size_type global_index) const
void extract_subvector_to(ForwardIterator indices_begin, const ForwardIterator indices_end, OutputIterator values_begin) const
Number inner_product_local(const Vector< Number2, MemorySpace > &V) const
Number & local_element(const size_type local_index)
real_type norm_sqr() const
virtual Number add_and_dot(const Number a, const VectorSpaceVector< Number > &V, const VectorSpaceVector< Number > &W) override
virtual real_type l2_norm() const override
Vector(const std::shared_ptr< const Utilities::MPI::Partitioner > &partitioner)
virtual ::IndexSet locally_owned_elements() const override
types::global_dof_index size_type
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
VectorType::value_type * begin(VectorType &V)
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
bool is_finite(const double x)
unsigned int global_dof_index
*braid_SplitCommworld & comm