Reference documentation for deal.II version Git 26229e5247 2020-04-07 14:28:34 +0200
\(\newcommand{\vcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\vcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
la_parallel_vector.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2011 - 2019 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_la_parallel_vector_h
17 #define dealii_la_parallel_vector_h
18 
19 #include <deal.II/base/config.h>
20 
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>
26 
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>
30 
31 #include <iomanip>
32 #include <memory>
33 
35 
36 // Forward declarations
37 #ifndef DOXYGEN
38 namespace LinearAlgebra
39 {
43  namespace distributed
44  {
45  template <typename>
46  class BlockVector;
47  }
48 
49  template <typename>
50  class ReadWriteVector;
51 } // namespace LinearAlgebra
52 
53 # ifdef DEAL_II_WITH_PETSC
54 namespace PETScWrappers
55 {
56  namespace MPI
57  {
58  class Vector;
59  }
60 } // namespace PETScWrappers
61 # endif
62 
63 # ifdef DEAL_II_WITH_TRILINOS
64 namespace TrilinosWrappers
65 {
66  namespace MPI
67  {
68  class Vector;
69  }
70 } // namespace TrilinosWrappers
71 # endif
72 #endif
73 
74 namespace LinearAlgebra
75 {
76  namespace distributed
77  {
225  template <typename Number, typename MemorySpace = MemorySpace::Host>
227  public Subscriptor
228  {
229  public:
230  using memory_space = MemorySpace;
231  using value_type = Number;
232  using pointer = value_type *;
233  using const_pointer = const value_type *;
234  using iterator = value_type *;
235  using const_iterator = const value_type *;
236  using reference = value_type &;
237  using const_reference = const value_type &;
238  using size_type = types::global_dof_index;
239  using real_type = typename numbers::NumberTraits<Number>::real_type;
240 
241  static_assert(
242  std::is_same<MemorySpace, ::MemorySpace::Host>::value ||
243  std::is_same<MemorySpace, ::MemorySpace::CUDA>::value,
244  "MemorySpace should be Host or CUDA");
245 
253  Vector();
254 
261  Vector(const Vector<Number, MemorySpace> &in_vector);
262 
267  Vector(const size_type size);
268 
285  Vector(const IndexSet &local_range,
286  const IndexSet &ghost_indices,
287  const MPI_Comm communicator);
288 
292  Vector(const IndexSet &local_range, const MPI_Comm communicator);
293 
300  Vector(
301  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
302 
306  virtual ~Vector() override;
307 
312  void
313  reinit(const size_type size, const bool omit_zeroing_entries = false);
314 
325  template <typename Number2>
326  void
327  reinit(const Vector<Number2, MemorySpace> &in_vector,
328  const bool omit_zeroing_entries = false);
329 
346  void
347  reinit(const IndexSet &local_range,
348  const IndexSet &ghost_indices,
349  const MPI_Comm communicator);
350 
354  void
355  reinit(const IndexSet &local_range, const MPI_Comm communicator);
356 
363  void
364  reinit(
365  const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner);
366 
382  void
384 
397  operator=(const Vector<Number, MemorySpace> &in_vector);
398 
410  template <typename Number2>
412  operator=(const Vector<Number2, MemorySpace> &in_vector);
413 
414 #ifdef DEAL_II_WITH_PETSC
415 
425  DEAL_II_DEPRECATED
427  operator=(const PETScWrappers::MPI::Vector &petsc_vec);
428 #endif
429 
430 #ifdef DEAL_II_WITH_TRILINOS
431 
442  DEAL_II_DEPRECATED
444  operator=(const TrilinosWrappers::MPI::Vector &trilinos_vec);
445 #endif
446 
447 
487  virtual void
488  compress(::VectorOperation::values operation) override;
489 
511  void
512  update_ghost_values() const;
513 
531  void
532  compress_start(
533  const unsigned int communication_channel = 0,
535 
551  void
552  compress_finish(::VectorOperation::values operation);
553 
571  void
572  update_ghost_values_start(
573  const unsigned int communication_channel = 0) const;
574 
575 
583  void
584  update_ghost_values_finish() const;
585 
594  void
595  zero_out_ghosts() const;
596 
608  bool
609  has_ghost_elements() const;
610 
625  template <typename Number2>
626  void
627  copy_locally_owned_data_from(const Vector<Number2, MemorySpace> &src);
628 
639  template <typename MemorySpace2>
640  void
641  import(const Vector<Number, MemorySpace2> &src,
642  VectorOperation::values operation);
643 
645 
650 
655  virtual void
656  reinit(const VectorSpaceVector<Number> &V,
657  const bool omit_zeroing_entries = false) override;
658 
663  operator*=(const Number factor) override;
664 
669  operator/=(const Number factor) override;
670 
675  operator+=(const VectorSpaceVector<Number> &V) override;
676 
681  operator-=(const VectorSpaceVector<Number> &V) override;
682 
694  virtual void
695  import(
697  VectorOperation::values operation,
698  std::shared_ptr<const CommunicationPatternBase> communication_pattern =
699  std::shared_ptr<const CommunicationPatternBase>()) override;
700 
704  virtual Number
705  operator*(const VectorSpaceVector<Number> &V) const override;
706 
710  virtual void
711  add(const Number a) override;
712 
716  virtual void
717  add(const Number a, const VectorSpaceVector<Number> &V) override;
718 
722  virtual void
723  add(const Number a,
724  const VectorSpaceVector<Number> &V,
725  const Number b,
726  const VectorSpaceVector<Number> &W) override;
727 
732  virtual void
733  add(const std::vector<size_type> &indices,
734  const std::vector<Number> & values);
735 
740  virtual void
741  sadd(const Number s,
742  const Number a,
743  const VectorSpaceVector<Number> &V) override;
744 
750  virtual void
751  scale(const VectorSpaceVector<Number> &scaling_factors) override;
752 
756  virtual void
757  equ(const Number a, const VectorSpaceVector<Number> &V) override;
758 
763  virtual real_type
764  l1_norm() const override;
765 
770  virtual real_type
771  l2_norm() const override;
772 
776  real_type
777  norm_sqr() const;
778 
783  virtual real_type
784  linfty_norm() const override;
785 
806  virtual Number
807  add_and_dot(const Number a,
808  const VectorSpaceVector<Number> &V,
809  const VectorSpaceVector<Number> &W) override;
810 
815  virtual size_type
816  size() const override;
817 
829  virtual ::IndexSet
830  locally_owned_elements() const override;
831 
835  virtual void
836  print(std::ostream & out,
837  const unsigned int precision = 3,
838  const bool scientific = true,
839  const bool across = true) const override;
840 
844  virtual std::size_t
845  memory_consumption() const override;
847 
852 
859  operator=(const Number s) override;
860 
865  template <typename OtherNumber>
866  void
867  add(const std::vector<size_type> & indices,
868  const ::Vector<OtherNumber> &values);
869 
874  template <typename OtherNumber>
875  void
876  add(const size_type n_elements,
877  const size_type * indices,
878  const OtherNumber *values);
879 
884  void
885  sadd(const Number s, const Vector<Number, MemorySpace> &V);
886 
892  DEAL_II_DEPRECATED
893  void
894  sadd(const Number s,
895  const Number a,
897  const Number b,
898  const Vector<Number, MemorySpace> &W);
899 
905  DEAL_II_DEPRECATED
906  void
907  equ(const Number a,
909  const Number b,
910  const Vector<Number, MemorySpace> &v);
911 
913 
914 
919 
924  size_type
925  local_size() const;
926 
934  DEAL_II_DEPRECATED
935  std::pair<size_type, size_type>
936  local_range() const;
937 
944  DEAL_II_DEPRECATED
945  bool
946  in_local_range(const size_type global_index) const;
947 
953  DEAL_II_DEPRECATED
954  size_type
955  n_ghost_entries() const;
956 
964  DEAL_II_DEPRECATED
965  const IndexSet &
966  ghost_elements() const;
967 
975  DEAL_II_DEPRECATED
976  bool
977  is_ghost_entry(const types::global_dof_index global_index) const;
978 
989  iterator
990  begin();
991 
999  const_iterator
1000  begin() const;
1001 
1009  iterator
1010  end();
1011 
1019  const_iterator
1020  end() const;
1021 
1031  Number
1032  operator()(const size_type global_index) const;
1033 
1043  Number &
1044  operator()(const size_type global_index);
1045 
1053  Number operator[](const size_type global_index) const;
1061  Number &operator[](const size_type global_index);
1062 
1071  Number
1072  local_element(const size_type local_index) const;
1073 
1082  Number &
1083  local_element(const size_type local_index);
1084 
1091  Number *
1092  get_values() const;
1093 
1111  template <typename OtherNumber>
1112  void
1113  extract_subvector_to(const std::vector<size_type> &indices,
1114  std::vector<OtherNumber> & values) const;
1115 
1143  template <typename ForwardIterator, typename OutputIterator>
1144  void
1145  extract_subvector_to(ForwardIterator indices_begin,
1146  const ForwardIterator indices_end,
1147  OutputIterator values_begin) const;
1153  virtual bool
1154  all_zero() const override;
1155 
1159  virtual Number
1160  mean_value() const override;
1161 
1166  real_type
1167  lp_norm(const real_type p) const;
1169 
1174 
1179  const MPI_Comm &
1180  get_mpi_communicator() const;
1181 
1188  const std::shared_ptr<const Utilities::MPI::Partitioner> &
1189  get_partitioner() const;
1190 
1200  bool
1201  partitioners_are_compatible(
1202  const Utilities::MPI::Partitioner &part) const;
1203 
1217  bool
1218  partitioners_are_globally_compatible(
1219  const Utilities::MPI::Partitioner &part) const;
1220 
1224  void
1225  set_ghost_state(const bool ghosted) const;
1226 
1228 
1234  DeclException0(ExcVectorTypeNotCompatible);
1235 
1241  DeclException0(ExcNotAllowedForCuda);
1242 
1246  DeclException3(ExcNonMatchingElements,
1247  Number,
1248  Number,
1249  unsigned int,
1250  << "Called compress(VectorOperation::insert), but"
1251  << " the element received from a remote processor, value "
1252  << std::setprecision(16) << arg1
1253  << ", does not match with the value "
1254  << std::setprecision(16) << arg2
1255  << " on the owner processor " << arg3);
1256 
1260  DeclException4(ExcAccessToNonLocalElement,
1261  size_type,
1262  size_type,
1263  size_type,
1264  size_type,
1265  << "You tried to access element " << arg1
1266  << " of a distributed vector, but this element is not "
1267  << "stored on the current processor. Note: The range of "
1268  << "locally owned elements is " << arg2 << " to " << arg3
1269  << ", and there are " << arg4 << " ghost elements "
1270  << "that this vector can access.");
1271 
1272  private:
1277  void
1278  add_local(const Number a, const VectorSpaceVector<Number> &V);
1279 
1284  void
1285  sadd_local(const Number s,
1286  const Number a,
1287  const VectorSpaceVector<Number> &V);
1288 
1292  template <typename Number2>
1293  Number
1294  inner_product_local(const Vector<Number2, MemorySpace> &V) const;
1295 
1299  real_type
1300  norm_sqr_local() const;
1301 
1305  Number
1306  mean_value_local() const;
1307 
1311  real_type
1312  l1_norm_local() const;
1313 
1317  real_type
1318  lp_norm_local(const real_type p) const;
1319 
1323  real_type
1324  linfty_norm_local() const;
1325 
1331  Number
1332  add_and_dot_local(const Number a,
1333  const Vector<Number, MemorySpace> &V,
1334  const Vector<Number, MemorySpace> &W);
1335 
1341  std::shared_ptr<const Utilities::MPI::Partitioner> partitioner;
1342 
1346  size_type allocated_size;
1347 
1351  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace> data;
1352 
1357  mutable std::shared_ptr<::parallel::internal::TBBPartitioner>
1359 
1365  mutable ::MemorySpace::MemorySpaceData<Number, MemorySpace>
1367 
1375  mutable bool vector_is_ghosted;
1376 
1377 #ifdef DEAL_II_WITH_MPI
1378 
1386  std::vector<MPI_Request> compress_requests;
1387 
1392  mutable std::vector<MPI_Request> update_ghost_values_requests;
1393 #endif
1394 
1400  mutable std::mutex mutex;
1401 
1406  void
1407  clear_mpi_requests();
1408 
1412  void
1413  resize_val(const size_type new_allocated_size);
1414 
1415  // Make all other vector types friends.
1416  template <typename Number2, typename MemorySpace2>
1417  friend class Vector;
1418 
1419  // Make BlockVector type friends.
1420  template <typename Number2>
1421  friend class BlockVector;
1422  };
1426  /*-------------------- Inline functions ---------------------------------*/
1427 
1428 #ifndef DOXYGEN
1429 
1430  namespace internal
1431  {
1432  template <typename Number, typename MemorySpace>
1433  struct Policy
1434  {
1435  static inline typename Vector<Number, MemorySpace>::iterator
1437  {
1438  return nullptr;
1439  }
1440 
1441  static inline typename Vector<Number, MemorySpace>::const_iterator
1442  begin(
1443  const ::MemorySpace::MemorySpaceData<Number, MemorySpace> &)
1444  {
1445  return nullptr;
1446  }
1447 
1448  static inline Number *
1449  get_values(
1451  {
1452  return nullptr;
1453  }
1454  };
1455 
1456 
1457 
1458  template <typename Number>
1459  struct Policy<Number, ::MemorySpace::Host>
1460  {
1461  static inline
1462  typename Vector<Number, ::MemorySpace::Host>::iterator
1463  begin(::MemorySpace::
1464  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1465  {
1466  return data.values.get();
1467  }
1468 
1469  static inline
1470  typename Vector<Number, ::MemorySpace::Host>::const_iterator
1471  begin(const ::MemorySpace::
1472  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1473  {
1474  return data.values.get();
1475  }
1476 
1477  static inline Number *
1478  get_values(::MemorySpace::
1479  MemorySpaceData<Number, ::MemorySpace::Host> &data)
1480  {
1481  return data.values.get();
1482  }
1483  };
1484 
1485 
1486 
1487  template <typename Number>
1488  struct Policy<Number, ::MemorySpace::CUDA>
1489  {
1490  static inline
1491  typename Vector<Number, ::MemorySpace::CUDA>::iterator
1492  begin(::MemorySpace::
1493  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1494  {
1495  return data.values_dev.get();
1496  }
1497 
1498  static inline
1499  typename Vector<Number, ::MemorySpace::CUDA>::const_iterator
1500  begin(const ::MemorySpace::
1501  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1502  {
1503  return data.values_dev.get();
1504  }
1505 
1506  static inline Number *
1507  get_values(::MemorySpace::
1508  MemorySpaceData<Number, ::MemorySpace::CUDA> &data)
1509  {
1510  return data.values_dev.get();
1511  }
1512  };
1513  } // namespace internal
1514 
1515 
1516  template <typename Number, typename MemorySpace>
1517  inline bool
1519  {
1520  return vector_is_ghosted;
1521  }
1522 
1523 
1524 
1525  template <typename Number, typename MemorySpace>
1526  inline typename Vector<Number, MemorySpace>::size_type
1528  {
1529  return partitioner->size();
1530  }
1531 
1532 
1533 
1534  template <typename Number, typename MemorySpace>
1535  inline typename Vector<Number, MemorySpace>::size_type
1537  {
1538  return partitioner->local_size();
1539  }
1540 
1541 
1542 
1543  template <typename Number, typename MemorySpace>
1544  inline std::pair<typename Vector<Number, MemorySpace>::size_type,
1545  typename Vector<Number, MemorySpace>::size_type>
1547  {
1548  return partitioner->local_range();
1549  }
1550 
1551 
1552 
1553  template <typename Number, typename MemorySpace>
1554  inline bool
1556  const size_type global_index) const
1557  {
1558  return partitioner->in_local_range(global_index);
1559  }
1560 
1561 
1562 
1563  template <typename Number, typename MemorySpace>
1564  inline IndexSet
1566  {
1567  IndexSet is(size());
1568 
1569  is.add_range(partitioner->local_range().first,
1570  partitioner->local_range().second);
1571 
1572  return is;
1573  }
1574 
1575 
1576 
1577  template <typename Number, typename MemorySpace>
1578  inline typename Vector<Number, MemorySpace>::size_type
1580  {
1581  return partitioner->n_ghost_indices();
1582  }
1583 
1584 
1585 
1586  template <typename Number, typename MemorySpace>
1587  inline const IndexSet &
1589  {
1590  return partitioner->ghost_indices();
1591  }
1592 
1593 
1594 
1595  template <typename Number, typename MemorySpace>
1596  inline bool
1598  const size_type global_index) const
1599  {
1600  return partitioner->is_ghost_entry(global_index);
1601  }
1602 
1603 
1604 
1605  template <typename Number, typename MemorySpace>
1606  inline typename Vector<Number, MemorySpace>::iterator
1608  {
1609  return internal::Policy<Number, MemorySpace>::begin(data);
1610  }
1611 
1612 
1613 
1614  template <typename Number, typename MemorySpace>
1615  inline typename Vector<Number, MemorySpace>::const_iterator
1617  {
1618  return internal::Policy<Number, MemorySpace>::begin(data);
1619  }
1620 
1621 
1622 
1623  template <typename Number, typename MemorySpace>
1624  inline typename Vector<Number, MemorySpace>::iterator
1626  {
1627  return internal::Policy<Number, MemorySpace>::begin(data) +
1628  partitioner->local_size();
1629  }
1630 
1631 
1632 
1633  template <typename Number, typename MemorySpace>
1634  inline typename Vector<Number, MemorySpace>::const_iterator
1636  {
1637  return internal::Policy<Number, MemorySpace>::begin(data) +
1638  partitioner->local_size();
1639  }
1640 
1641 
1642 
1643  template <typename Number, typename MemorySpace>
1644  inline Number
1645  Vector<Number, MemorySpace>::operator()(const size_type global_index) const
1646  {
1647  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1648  ExcMessage(
1649  "This function is only implemented for the Host memory space"));
1650  Assert(
1651  partitioner->in_local_range(global_index) ||
1652  partitioner->ghost_indices().is_element(global_index),
1653  ExcAccessToNonLocalElement(global_index,
1654  partitioner->local_range().first,
1655  partitioner->local_range().second,
1656  partitioner->ghost_indices().n_elements()));
1657  // do not allow reading a vector which is not in ghost mode
1658  Assert(partitioner->in_local_range(global_index) ||
1659  vector_is_ghosted == true,
1660  ExcMessage("You tried to read a ghost element of this vector, "
1661  "but it has not imported its ghost values."));
1662  return data.values[partitioner->global_to_local(global_index)];
1663  }
1664 
1665 
1666 
1667  template <typename Number, typename MemorySpace>
1668  inline Number &
1669  Vector<Number, MemorySpace>::operator()(const size_type global_index)
1670  {
1671  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1672  ExcMessage(
1673  "This function is only implemented for the Host memory space"));
1674  Assert(
1675  partitioner->in_local_range(global_index) ||
1676  partitioner->ghost_indices().is_element(global_index),
1677  ExcAccessToNonLocalElement(global_index,
1678  partitioner->local_range().first,
1679  partitioner->local_range().second,
1680  partitioner->ghost_indices().n_elements()));
1681  // we would like to prevent reading ghosts from a vector that does not
1682  // have them imported, but this is not possible because we might be in a
1683  // part of the code where the vector has enabled ghosts but is non-const
1684  // (then, the compiler picks this method according to the C++ rule book
1685  // even if a human would pick the const method when this subsequent use
1686  // is just a read)
1687  return data.values[partitioner->global_to_local(global_index)];
1688  }
1689 
1690 
1691 
1692  template <typename Number, typename MemorySpace>
1693  inline Number Vector<Number, MemorySpace>::
1694  operator[](const size_type global_index) const
1695  {
1696  return operator()(global_index);
1697  }
1698 
1699 
1700 
1701  template <typename Number, typename MemorySpace>
1702  inline Number &Vector<Number, MemorySpace>::
1703  operator[](const size_type global_index)
1704  {
1705  return operator()(global_index);
1706  }
1707 
1708 
1709 
1710  template <typename Number, typename MemorySpace>
1711  inline Number
1713  const size_type local_index) const
1714  {
1715  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1716  ExcMessage(
1717  "This function is only implemented for the Host memory space"));
1718  AssertIndexRange(local_index,
1719  partitioner->local_size() +
1720  partitioner->n_ghost_indices());
1721  // do not allow reading a vector which is not in ghost mode
1722  Assert(local_index < local_size() || vector_is_ghosted == true,
1723  ExcMessage("You tried to read a ghost element of this vector, "
1724  "but it has not imported its ghost values."));
1725 
1726  return data.values[local_index];
1727  }
1728 
1729 
1730 
1731  template <typename Number, typename MemorySpace>
1732  inline Number &
1733  Vector<Number, MemorySpace>::local_element(const size_type local_index)
1734  {
1735  Assert((std::is_same<MemorySpace, ::MemorySpace::Host>::value),
1736  ExcMessage(
1737  "This function is only implemented for the Host memory space"));
1738 
1739  AssertIndexRange(local_index,
1740  partitioner->local_size() +
1741  partitioner->n_ghost_indices());
1742 
1743  return data.values[local_index];
1744  }
1745 
1746 
1747 
1748  template <typename Number, typename MemorySpace>
1749  inline Number *
1751  {
1752  return internal::Policy<Number, MemorySpace>::get_values(data);
1753  }
1754 
1755 
1756 
1757  template <typename Number, typename MemorySpace>
1758  template <typename OtherNumber>
1759  inline void
1761  const std::vector<size_type> &indices,
1762  std::vector<OtherNumber> & values) const
1763  {
1764  for (size_type i = 0; i < indices.size(); ++i)
1765  values[i] = operator()(indices[i]);
1766  }
1767 
1768 
1769 
1770  template <typename Number, typename MemorySpace>
1771  template <typename ForwardIterator, typename OutputIterator>
1772  inline void
1774  ForwardIterator indices_begin,
1775  const ForwardIterator indices_end,
1776  OutputIterator values_begin) const
1777  {
1778  while (indices_begin != indices_end)
1779  {
1780  *values_begin = operator()(*indices_begin);
1781  indices_begin++;
1782  values_begin++;
1783  }
1784  }
1785 
1786 
1787 
1788  template <typename Number, typename MemorySpace>
1789  template <typename OtherNumber>
1790  inline void
1792  const std::vector<size_type> & indices,
1793  const ::Vector<OtherNumber> &values)
1794  {
1795  AssertDimension(indices.size(), values.size());
1796  for (size_type i = 0; i < indices.size(); ++i)
1797  {
1798  Assert(
1799  numbers::is_finite(values[i]),
1800  ExcMessage(
1801  "The given value is not finite but either infinite or Not A Number (NaN)"));
1802  this->operator()(indices[i]) += values(i);
1803  }
1804  }
1805 
1806 
1807 
1808  template <typename Number, typename MemorySpace>
1809  template <typename OtherNumber>
1810  inline void
1811  Vector<Number, MemorySpace>::add(const size_type n_elements,
1812  const size_type * indices,
1813  const OtherNumber *values)
1814  {
1815  for (size_type i = 0; i < n_elements; ++i, ++indices, ++values)
1816  {
1817  Assert(
1818  numbers::is_finite(*values),
1819  ExcMessage(
1820  "The given value is not finite but either infinite or Not A Number (NaN)"));
1821  this->operator()(*indices) += *values;
1822  }
1823  }
1824 
1825 
1826 
1827  template <typename Number, typename MemorySpace>
1828  inline const MPI_Comm &
1830  {
1831  return partitioner->get_mpi_communicator();
1832  }
1833 
1834 
1835 
1836  template <typename Number, typename MemorySpace>
1837  inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
1839  {
1840  return partitioner;
1841  }
1842 
1843 
1844 
1845  template <typename Number, typename MemorySpace>
1846  inline void
1847  Vector<Number, MemorySpace>::set_ghost_state(const bool ghosted) const
1848  {
1849  vector_is_ghosted = ghosted;
1850  }
1851 
1852 #endif
1853 
1854  } // namespace distributed
1855 } // namespace LinearAlgebra
1856 
1857 
1866 template <typename Number, typename MemorySpace>
1867 inline void
1870 {
1871  u.swap(v);
1872 }
1873 
1874 
1880 template <typename Number, typename MemorySpace>
1882  : std::false_type
1883 {};
1884 
1885 
1886 
1887 namespace internal
1888 {
1889  namespace LinearOperatorImplementation
1890  {
1891  template <typename>
1892  class ReinitHelper;
1893 
1898  template <typename Number>
1899  class ReinitHelper<LinearAlgebra::distributed::Vector<Number>>
1900  {
1901  public:
1902  template <typename Matrix>
1903  static void
1904  reinit_range_vector(const Matrix & matrix,
1906  bool omit_zeroing_entries)
1907  {
1908  matrix.initialize_dof_vector(v);
1909  if (!omit_zeroing_entries)
1910  v = Number();
1911  }
1912 
1913  template <typename Matrix>
1914  static void
1915  reinit_domain_vector(const Matrix & matrix,
1917  bool omit_zeroing_entries)
1918  {
1919  matrix.initialize_dof_vector(v);
1920  if (!omit_zeroing_entries)
1921  v = Number();
1922  }
1923  };
1924 
1925  } // namespace LinearOperatorImplementation
1926 } /* namespace internal */
1927 
1928 
1929 DEAL_II_NAMESPACE_CLOSE
1930 
1931 #endif
bool in_local_range(const size_type global_index) const
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1579
std::vector< MPI_Request > update_ghost_values_requests
std::shared_ptr< const Utilities::MPI::Partitioner > partitioner
#define AssertIndexRange(index, range)
Definition: exceptions.h:1649
__global__ void add_and_dot(Number *res, Number *v1, const Number *v2, const Number *v3, const Number a, const size_type N)
LinearAlgebra::distributed::Vector< Number > Vector
bool is_finite(const double x)
Definition: numbers.h:553
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)
Definition: exceptions.h:1419
#define DeclException0(Exception0)
Definition: exceptions.h:473
constexpr SymmetricTensor< rank_, dim, Number > operator*(const SymmetricTensor< rank_, dim, Number > &t, const Number &factor)
std::shared_ptr<::parallel::internal::TBBPartitioner > thread_loop_partitioner
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)
void swap(Vector< Number > &u, Vector< Number > &v)
Definition: vector.h:1390
unsigned int global_dof_index
Definition: types.h:77
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)
Definition: exceptions.h:587
Number operator()(const size_type global_index) const
virtual void add(const Number a) override
#define DeclException3(Exception3, type1, type2, type3, outsequence)
Definition: exceptions.h:564
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