16 #ifndef dealii_la_parallel_vector_h 17 #define dealii_la_parallel_vector_h 19 #include <deal.II/base/config.h> 21 #include <deal.II/base/memory_space.h> 22 #include <deal.II/base/mpi.h> 23 #include <deal.II/base/numbers.h> 24 #include <deal.II/base/partitioner.h> 25 #include <deal.II/base/thread_management.h> 27 #include <deal.II/lac/vector_operation.h> 28 #include <deal.II/lac/vector_space_vector.h> 29 #include <deal.II/lac/vector_type_traits.h> 34 DEAL_II_NAMESPACE_OPEN
51 #ifdef DEAL_II_WITH_PETSC 61 #ifdef DEAL_II_WITH_TRILINOS 222 template <
typename Number,
typename MemorySpace = MemorySpace::Host>
228 using value_type = Number;
229 using pointer = value_type *;
230 using const_pointer =
const value_type *;
231 using iterator = value_type *;
232 using const_iterator =
const value_type *;
233 using reference = value_type &;
234 using const_reference =
const value_type &;
239 std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
240 std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
241 "MemorySpace should be Host or CUDA");
261 Vector(
const size_type size);
281 const MPI_Comm communicator);
295 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
300 virtual ~
Vector()
override;
307 reinit(
const size_type size,
const bool omit_zeroing_entries =
false);
319 template <
typename Number2>
322 const bool omit_zeroing_entries =
false);
343 const MPI_Comm communicator);
349 reinit(
const IndexSet &local_range,
const MPI_Comm communicator);
359 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
404 template <
typename Number2>
408 #ifdef DEAL_II_WITH_PETSC 424 #ifdef DEAL_II_WITH_TRILINOS 506 update_ghost_values()
const;
524 const unsigned int communication_channel = 0,
560 update_ghost_values_start(
561 const unsigned int communication_channel = 0)
const;
572 update_ghost_values_finish()
const;
583 zero_out_ghosts()
const;
597 has_ghost_elements()
const;
613 template <
typename Number2>
630 const bool omit_zeroing_entries =
false)
override;
636 operator*=(
const Number factor)
override;
642 operator/=(
const Number factor)
override;
671 std::shared_ptr<const CommunicationPatternBase> communication_pattern =
672 std::shared_ptr<const CommunicationPatternBase>())
override;
684 add(
const Number a)
override;
706 add(
const std::vector<size_type> &indices,
707 const std::vector<Number> & values);
737 l1_norm()
const override;
744 l2_norm()
const override;
757 linfty_norm()
const override;
789 size()
const override;
803 locally_owned_elements()
const override;
809 print(std::ostream & out,
810 const unsigned int precision = 3,
811 const bool scientific =
true,
812 const bool across =
true)
const override;
818 memory_consumption()
const override;
832 operator=(
const Number s)
override;
838 template <
typename OtherNumber>
840 add(
const std::vector<size_type> & indices,
841 const ::Vector<OtherNumber> &values);
847 template <
typename OtherNumber>
849 add(
const size_type n_elements,
850 const size_type * indices,
851 const OtherNumber *values);
908 std::pair<size_type, size_type>
919 in_local_range(
const size_type global_index)
const;
928 n_ghost_entries()
const;
939 ghost_elements()
const;
1005 operator()(
const size_type global_index)
const;
1017 operator()(
const size_type global_index);
1026 Number operator[](
const size_type global_index)
const;
1034 Number &operator[](
const size_type global_index);
1045 local_element(
const size_type local_index)
const;
1056 local_element(
const size_type local_index);
1084 template <
typename OtherNumber>
1086 extract_subvector_to(
const std::vector<size_type> &indices,
1087 std::vector<OtherNumber> & values)
const;
1116 template <
typename ForwardIterator,
typename OutputIterator>
1118 extract_subvector_to(ForwardIterator indices_begin,
1119 const ForwardIterator indices_end,
1120 OutputIterator values_begin)
const;
1127 all_zero()
const override;
1133 mean_value()
const override;
1140 lp_norm(
const real_type p)
const;
1153 get_mpi_communicator()
const;
1161 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1162 get_partitioner()
const;
1174 partitioners_are_compatible(
1191 partitioners_are_globally_compatible(
1198 set_ghost_state(
const bool ghosted)
const;
1223 <<
"Called compress(VectorOperation::insert), but" 1224 <<
" the element received from a remote processor, value " 1225 << std::setprecision(16) << arg1
1226 <<
", does not match with the value " 1227 << std::setprecision(16) << arg2
1228 <<
" on the owner processor " << arg3);
1238 <<
"You tried to access element " << arg1
1239 <<
" of a distributed vector, but this element is not " 1240 <<
"stored on the current processor. Note: The range of " 1241 <<
"locally owned elements is " << arg2 <<
" to " << arg3
1242 <<
", and there are " << arg4 <<
" ghost elements " 1243 <<
"that this vector can access.");
1258 sadd_local(
const Number s,
1265 template <
typename Number2>
1273 norm_sqr_local()
const;
1279 mean_value_local()
const;
1285 l1_norm_local()
const;
1291 lp_norm_local(
const real_type p)
const;
1297 linfty_norm_local()
const;
1305 add_and_dot_local(
const Number a,
1324 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
data;
1330 mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1338 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1350 #ifdef DEAL_II_WITH_MPI 1380 clear_mpi_requests();
1386 resize_val(
const size_type new_allocated_size);
1391 template <
typename Number2,
typename MemorySpace2>
1397 template <
typename Number2>
1409 template <
typename Number,
typename MemorySpace>
1412 static inline typename Vector<Number, MemorySpace>::iterator
1418 static inline typename Vector<Number, MemorySpace>::const_iterator
1420 const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1425 static inline Number *
1435 template <
typename Number>
1439 typename Vector<Number, ::MemorySpace::Host>::iterator
1441 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1443 return data.values.get();
1447 typename Vector<Number, ::MemorySpace::Host>::const_iterator
1448 begin(const ::MemorySpace::
1449 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1451 return data.values.get();
1454 static inline Number *
1456 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1458 return data.values.get();
1464 template <
typename Number>
1468 typename Vector<Number, ::MemorySpace::CUDA>::iterator
1470 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1472 return data.values_dev.get();
1476 typename Vector<Number, ::MemorySpace::CUDA>::const_iterator
1477 begin(const ::MemorySpace::
1478 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1480 return data.values_dev.get();
1483 static inline Number *
1485 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1487 return data.values_dev.get();
1493 template <
typename Number,
typename MemorySpace>
1497 return vector_is_ghosted;
1502 template <
typename Number,
typename MemorySpace>
1503 inline typename Vector<Number, MemorySpace>::size_type
1506 return partitioner->size();
1511 template <
typename Number,
typename MemorySpace>
1512 inline typename Vector<Number, MemorySpace>::size_type
1515 return partitioner->local_size();
1520 template <
typename Number,
typename MemorySpace>
1521 inline std::pair<typename Vector<Number, MemorySpace>::size_type,
1522 typename Vector<Number, MemorySpace>::size_type>
1525 return partitioner->local_range();
1530 template <
typename Number,
typename MemorySpace>
1533 const size_type global_index)
const 1535 return partitioner->in_local_range(global_index);
1540 template <
typename Number,
typename MemorySpace>
1546 is.add_range(partitioner->local_range().first,
1547 partitioner->local_range().second);
1554 template <
typename Number,
typename MemorySpace>
1555 inline typename Vector<Number, MemorySpace>::size_type
1558 return partitioner->n_ghost_indices();
1563 template <
typename Number,
typename MemorySpace>
1567 return partitioner->ghost_indices();
1572 template <
typename Number,
typename MemorySpace>
1575 const size_type global_index)
const 1577 return partitioner->is_ghost_entry(global_index);
1582 template <
typename Number,
typename MemorySpace>
1583 inline typename Vector<Number, MemorySpace>::iterator
1586 return internal::Policy<Number, MemorySpace>::begin(data);
1591 template <
typename Number,
typename MemorySpace>
1592 inline typename Vector<Number, MemorySpace>::const_iterator
1595 return internal::Policy<Number, MemorySpace>::begin(data);
1600 template <
typename Number,
typename MemorySpace>
1601 inline typename Vector<Number, MemorySpace>::iterator
1604 return internal::Policy<Number, MemorySpace>::begin(data) +
1605 partitioner->local_size();
1610 template <
typename Number,
typename MemorySpace>
1611 inline typename Vector<Number, MemorySpace>::const_iterator
1614 return internal::Policy<Number, MemorySpace>::begin(data) +
1615 partitioner->local_size();
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"));
1628 partitioner->in_local_range(global_index) ||
1629 partitioner->ghost_indices().is_element(global_index),
1630 ExcAccessToNonLocalElement(global_index,
1631 partitioner->local_range().first,
1632 partitioner->local_range().second,
1633 partitioner->ghost_indices().n_elements()));
1635 Assert(partitioner->in_local_range(global_index) ||
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"));
1652 partitioner->in_local_range(global_index) ||
1653 partitioner->ghost_indices().is_element(global_index),
1654 ExcAccessToNonLocalElement(global_index,
1655 partitioner->local_range().first,
1656 partitioner->local_range().second,
1657 partitioner->ghost_indices().n_elements()));
1664 return data.values[partitioner->global_to_local(global_index)];
1669 template <
typename Number,
typename MemorySpace>
1671 operator[](
const size_type global_index)
const 1673 return operator()(global_index);
1678 template <
typename Number,
typename MemorySpace>
1682 return operator()(global_index);
1687 template <
typename Number,
typename MemorySpace>
1690 const size_type local_index)
const 1692 Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1694 "This function is only implemented for the Host memory space"));
1696 partitioner->local_size() +
1697 partitioner->n_ghost_indices());
1699 Assert(local_index < local_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->local_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>
1789 const size_type * indices,
1790 const OtherNumber *values)
1792 for (size_type i = 0; i < n_elements; ++i, ++indices, ++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>
1805 inline const MPI_Comm &
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;
1843 template <
typename Number,
typename MemorySpace>
1857 template <
typename Number,
typename MemorySpace>
1866 namespace LinearOperatorImplementation
1875 template <
typename Number>
1879 template <
typename Matrix>
1881 reinit_range_vector(
const Matrix & matrix,
1883 bool omit_zeroing_entries)
1885 matrix.initialize_dof_vector(v);
1886 if (!omit_zeroing_entries)
1890 template <
typename Matrix>
1892 reinit_domain_vector(
const Matrix & matrix,
1894 bool omit_zeroing_entries)
1896 matrix.initialize_dof_vector(v);
1897 if (!omit_zeroing_entries)
1906 DEAL_II_NAMESPACE_CLOSE
size_type local_size() const
bool in_local_range(const size_type global_index) const
#define AssertDimension(dim1, dim2)
std::vector< MPI_Request > update_ghost_values_requests
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
#define AssertIndexRange(index, range)
__global__ void add_and_dot(Number *res, Number *v1, const Number *v2, const Number *v3, const Number a, const size_type N)
Number * get_values() const
SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
LinearAlgebra::distributed::Vector< Number > Vector
bool is_finite(const double x)
bool is_ghost_entry(const types::global_dof_index global_index) const
__global__ void scale(Number *val, const Number *V_val, const size_type N)
Number local_element(const size_type local_index) const
void set_ghost_state(const bool ghosted) const
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
#define DeclException0(Exception0)
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
size_type n_ghost_entries() const
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > import_data
__global__ void equ(Number *val, const Number a, const Number *V_val, const size_type N)
mutable ::MemorySpace::MemorySpaceData< Number, MemorySpace > data
__global__ void sadd(const Number s, Number *val, const Number a, const Number *V_val, const size_type N)
bool has_ghost_elements() const
void swap(Vector< Number > &u, Vector< Number > &v)
unsigned int global_dof_index
virtual ::IndexSet locally_owned_elements() const override
virtual size_type size() const override
std::pair< size_type, size_type > local_range() const
void swap(Vector< Number, MemorySpace > &v)
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Number operator()(const size_type global_index) const
virtual void add(const Number a) override
#define DeclException3(Exception3, type1, type2, type3, outsequence)
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v)
const MPI_Comm & get_mpi_communicator() const
std::vector< MPI_Request > compress_requests
const IndexSet & ghost_elements() const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number operator[](const size_type global_index) const