16 #ifndef dealii_la_parallel_vector_h 17 #define dealii_la_parallel_vector_h 50 class ReadWriteVector;
53 # ifdef DEAL_II_WITH_PETSC 63 # ifdef DEAL_II_WITH_TRILINOS 225 template <
typename Number,
typename MemorySpace = MemorySpace::Host>
244 "MemorySpace should be Host or CUDA");
287 const MPI_Comm communicator);
301 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
306 virtual ~
Vector()
override;
325 template <
typename Number2>
328 const bool omit_zeroing_entries =
false);
349 const MPI_Comm communicator);
365 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
410 template <
typename Number2>
480 update_ghost_values()
const;
501 const unsigned int communication_channel = 0,
543 update_ghost_values_start(
544 const unsigned int communication_channel = 0)
const;
555 update_ghost_values_finish()
const;
566 zero_out_ghosts()
const;
580 has_ghost_elements()
const;
596 template <
typename Number2>
610 template <
typename MemorySpace2>
628 const bool omit_zeroing_entries =
false)
override;
634 operator*=(
const Number factor)
override;
640 operator/=(
const Number factor)
override;
669 std::shared_ptr<const CommunicationPatternBase> communication_pattern =
670 std::shared_ptr<const CommunicationPatternBase>())
override;
682 add(
const Number a)
override;
704 add(
const std::vector<size_type> &indices,
705 const std::vector<Number> & values);
787 size()
const override;
801 locally_owned_elements()
const override;
807 print(std::ostream & out,
808 const unsigned int precision = 3,
809 const bool scientific =
true,
810 const bool across =
true)
const override;
830 operator=(
const Number s)
override;
836 template <
typename OtherNumber>
838 add(
const std::vector<size_type> & indices,
839 const ::Vector<OtherNumber> &values);
845 template <
typename OtherNumber>
849 const OtherNumber *values);
973 local_element(
const size_type local_index)
const;
984 local_element(
const size_type local_index);
1012 template <
typename OtherNumber>
1014 extract_subvector_to(
const std::vector<size_type> &indices,
1015 std::vector<OtherNumber> & values)
const;
1044 template <
typename ForwardIterator,
typename OutputIterator>
1046 extract_subvector_to(ForwardIterator indices_begin,
1047 const ForwardIterator indices_end,
1048 OutputIterator values_begin)
const;
1055 all_zero()
const override;
1061 mean_value()
const override;
1081 get_mpi_communicator()
const;
1089 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1090 get_partitioner()
const;
1102 partitioners_are_compatible(
1119 partitioners_are_globally_compatible(
1126 set_ghost_state(
const bool ghosted)
const;
1151 <<
"Called compress(VectorOperation::insert), but" 1152 <<
" the element received from a remote processor, value " 1153 << std::setprecision(16) << arg1
1154 <<
", does not match with the value " 1155 << std::setprecision(16) << arg2
1156 <<
" on the owner processor " << arg3);
1166 <<
"You tried to access element " << arg1
1167 <<
" of a distributed vector, but this element is not " 1168 <<
"stored on the current processor. Note: The range of " 1169 <<
"locally owned elements is " << arg2 <<
" to " << arg3
1170 <<
", and there are " << arg4 <<
" ghost elements " 1171 <<
"that this vector can access.");
1186 sadd_local(
const Number s,
1193 template <
typename Number2>
1201 norm_sqr_local()
const;
1207 mean_value_local()
const;
1213 l1_norm_local()
const;
1225 linfty_norm_local()
const;
1233 add_and_dot_local(
const Number a,
1252 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
data;
1258 mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1266 mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1278 #ifdef DEAL_II_WITH_MPI 1308 clear_mpi_requests();
1314 resize_val(
const size_type new_allocated_size);
1317 template <
typename Number2,
typename MemorySpace2>
1321 template <
typename Number2>
1333 template <
typename Number,
typename MemorySpace>
1344 const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1349 static inline Number *
1359 template <
typename Number>
1365 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1367 return data.values.get();
1372 begin(const ::MemorySpace::
1373 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1375 return data.values.get();
1378 static inline Number *
1380 MemorySpaceData<Number, ::MemorySpace::Host> &data)
1382 return data.values.get();
1388 template <
typename Number>
1394 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1396 return data.values_dev.get();
1401 begin(const ::MemorySpace::
1402 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1404 return data.values_dev.get();
1407 static inline Number *
1409 MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1411 return data.values_dev.get();
1417 template <
typename Number,
typename MemorySpace>
1421 return vector_is_ghosted;
1426 template <
typename Number,
typename MemorySpace>
1430 return partitioner->size();
1435 template <
typename Number,
typename MemorySpace>
1439 return partitioner->local_size();
1444 template <
typename Number,
typename MemorySpace>
1449 return partitioner->in_local_range(global_index);
1454 template <
typename Number,
typename MemorySpace>
1460 is.add_range(partitioner->local_range().first,
1461 partitioner->local_range().second);
1468 template <
typename Number,
typename MemorySpace>
1477 template <
typename Number,
typename MemorySpace>
1486 template <
typename Number,
typename MemorySpace>
1491 partitioner->local_size();
1496 template <
typename Number,
typename MemorySpace>
1501 partitioner->local_size();
1506 template <
typename Number,
typename MemorySpace>
1512 "This function is only implemented for the Host memory space"));
1514 partitioner->in_local_range(global_index) ||
1515 partitioner->ghost_indices().is_element(global_index),
1516 ExcAccessToNonLocalElement(global_index,
1517 partitioner->local_range().first,
1518 partitioner->local_range().second,
1519 partitioner->ghost_indices().n_elements()));
1521 Assert(partitioner->in_local_range(global_index) ||
1522 vector_is_ghosted ==
true,
1523 ExcMessage(
"You tried to read a ghost element of this vector, " 1524 "but it has not imported its ghost values."));
1525 return data.values[partitioner->global_to_local(global_index)];
1530 template <
typename Number,
typename MemorySpace>
1536 "This function is only implemented for the Host memory space"));
1538 partitioner->in_local_range(global_index) ||
1539 partitioner->ghost_indices().is_element(global_index),
1540 ExcAccessToNonLocalElement(global_index,
1541 partitioner->local_range().first,
1542 partitioner->local_range().second,
1543 partitioner->ghost_indices().n_elements()));
1550 return data.values[partitioner->global_to_local(global_index)];
1555 template <
typename Number,
typename MemorySpace>
1559 return operator()(global_index);
1564 template <
typename Number,
typename MemorySpace>
1568 return operator()(global_index);
1573 template <
typename Number,
typename MemorySpace>
1580 "This function is only implemented for the Host memory space"));
1582 partitioner->local_size() +
1583 partitioner->n_ghost_indices());
1585 Assert(local_index < local_size() || vector_is_ghosted ==
true,
1586 ExcMessage(
"You tried to read a ghost element of this vector, " 1587 "but it has not imported its ghost values."));
1589 return data.values[local_index];
1594 template <
typename Number,
typename MemorySpace>
1600 "This function is only implemented for the Host memory space"));
1603 partitioner->local_size() +
1604 partitioner->n_ghost_indices());
1606 return data.values[local_index];
1611 template <
typename Number,
typename MemorySpace>
1615 return internal::Policy<Number, MemorySpace>::get_values(data);
1620 template <
typename Number,
typename MemorySpace>
1621 template <
typename OtherNumber>
1624 const std::vector<size_type> &indices,
1625 std::vector<OtherNumber> & values)
const 1627 for (
size_type i = 0; i < indices.size(); ++i)
1628 values[i] =
operator()(indices[i]);
1633 template <
typename Number,
typename MemorySpace>
1634 template <
typename ForwardIterator,
typename OutputIterator>
1637 ForwardIterator indices_begin,
1638 const ForwardIterator indices_end,
1639 OutputIterator values_begin)
const 1641 while (indices_begin != indices_end)
1643 *values_begin = operator()(*indices_begin);
1651 template <
typename Number,
typename MemorySpace>
1652 template <
typename OtherNumber>
1655 const std::vector<size_type> & indices,
1656 const ::Vector<OtherNumber> &values)
1659 for (
size_type i = 0; i < indices.size(); ++i)
1664 "The given value is not finite but either infinite or Not A Number (NaN)"));
1665 this->operator()(indices[i]) += values(i);
1671 template <
typename Number,
typename MemorySpace>
1672 template <
typename OtherNumber>
1676 const OtherNumber *values)
1678 for (
size_type i = 0; i < n_elements; ++i, ++indices, ++values)
1683 "The given value is not finite but either infinite or Not A Number (NaN)"));
1684 this->operator()(*indices) += *values;
1690 template <
typename Number,
typename MemorySpace>
1691 inline const MPI_Comm &
1694 return partitioner->get_mpi_communicator();
1699 template <
typename Number,
typename MemorySpace>
1700 inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1708 template <
typename Number,
typename MemorySpace>
1712 vector_is_ghosted = ghosted;
1729 template <
typename Number,
typename MemorySpace>
1743 template <
typename Number,
typename MemorySpace>
1752 namespace LinearOperatorImplementation
1761 template <
typename Number>
1767 template <
typename T>
1768 struct has_get_mpi_communicator
1774 template <
typename U>
1775 static decltype(std::declval<U>().get_mpi_communicator())
1780 !std::is_same<bool, decltype(detect(std::declval<T>()))>::
value;
1785 template <
typename T>
1786 struct has_locally_owned_domain_indices
1792 template <
typename U>
1793 static decltype(std::declval<U>().locally_owned_domain_indices())
1798 !std::is_same<bool, decltype(detect(std::declval<T>()))>::
value;
1803 template <
typename T>
1804 struct has_locally_owned_range_indices
1810 template <
typename U>
1811 static decltype(std::declval<U>().locally_owned_range_indices())
1816 !std::is_same<bool, decltype(detect(std::declval<T>()))>::
value;
1821 template <
typename T>
1822 struct has_initialize_dof_vector
1828 template <
typename U>
1829 static decltype(std::declval<U>().initialize_dof_vector(
1835 !std::is_same<bool, decltype(detect(std::declval<T>()))>::
value;
1839 template <
typename MatrixType,
1840 typename std::enable_if<
1843 MatrixType>::type * =
nullptr>
1849 vec.
reinit(mat.locally_owned_domain_indices(),
1850 mat.get_mpi_communicator());
1855 typename MatrixType,
1857 MatrixType>::type * =
nullptr>
1861 bool omit_zeroing_entries)
1863 mat.initialize_dof_vector(vec);
1864 if (!omit_zeroing_entries)
1869 template <
typename MatrixType,
1870 typename std::enable_if<
1873 MatrixType>::type * =
nullptr>
1879 vec.
reinit(mat.locally_owned_range_indices(),
1880 mat.get_mpi_communicator());
1885 typename MatrixType,
1886 typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
1887 MatrixType>::type * =
nullptr>
1891 bool omit_zeroing_entries)
1893 mat.initialize_dof_vector(vec);
1894 if (!omit_zeroing_entries)
size_type local_size() const
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
bool in_local_range(const size_type global_index) const
#define AssertDimension(dim1, dim2)
std::vector< MPI_Request > update_ghost_values_requests
std::vector< value_type > l2_norm(const typename ::Triangulation< dim, spacedim >::cell_iterator &parent, const value_type parent_value)
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
void reinit(const size_type size, const bool omit_zeroing_entries=false)
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
const value_type & const_reference
bool is_finite(const double x)
Number local_element(const size_type local_index) const
void set_ghost_state(const bool ghosted) const
static ::ExceptionBase & ExcMessage(std::string arg1)
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
std::string compress(const std::string &input)
#define Assert(cond, exc)
static void reinit_range_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool)
const value_type * const_pointer
Number linfty_norm(const Tensor< 2, dim, Number > &t)
#define DeclException0(Exception0)
void swap(LinearAlgebra::distributed::Vector< Number, MemorySpace > &u, LinearAlgebra::distributed::Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_CLOSE
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
VectorType::value_type * end(VectorType &V)
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)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
bool has_ghost_elements() const
typename numbers::NumberTraits< Number >::real_type real_type
unsigned int global_dof_index
virtual ::IndexSet locally_owned_elements() const override
virtual size_type size() const override
const value_type * const_iterator
void swap(Vector< Number, MemorySpace > &v)
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_partitioner() const
static void reinit_domain_vector(MatrixType &mat, LinearAlgebra::distributed::Vector< Number > &vec, bool omit_zeroing_entries)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Number l1_norm(const Tensor< 2, dim, Number > &t)
Number operator()(const size_type global_index) const
virtual void add(const Number a) override
TrilinosWrappers::types::int_type global_index(const Epetra_BlockMap &map, const ::types::global_dof_index i)
#define DeclException3(Exception3, type1, type2, type3, outsequence)
std::enable_if< std::is_floating_point< T >::value &&std::is_floating_point< U >::value, typename ProductType< std::complex< T >, std::complex< U > >::type >::type operator*(const std::complex< T > &left, const std::complex< U > &right)
const MPI_Comm & get_mpi_communicator() const
std::vector< MPI_Request > compress_requests
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< OtherNumber > &values) const
Number operator[](const size_type global_index) const
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)