Tpetra parallel linear algebra  Version of the Day
Tpetra_MultiVector_decl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_MULTIVECTOR_DECL_HPP
43 #define TPETRA_MULTIVECTOR_DECL_HPP
44 
47 
49 #include "Tpetra_Vector_fwd.hpp"
51 #include "Tpetra_DistObject.hpp"
52 #include "Tpetra_Map_fwd.hpp"
54 #include "Kokkos_DualView.hpp"
55 #include "Teuchos_BLAS_types.hpp"
56 #include "Teuchos_DataAccess.hpp"
57 #include "Teuchos_Range1D.hpp"
58 #include "Kokkos_ArithTraits.hpp"
59 #include "Kokkos_InnerProductSpaceTraits.hpp"
60 #include "Tpetra_KokkosRefactor_Details_MultiVectorLocalDeepCopy.hpp"
61 #include "Tpetra_Access.hpp"
62 #include <type_traits>
63 
64 #ifdef HAVE_TPETRACORE_TEUCHOSNUMERICS
65 #ifndef DOXYGEN_SHOULD_SKIP_THIS
66 namespace Teuchos {
67  template<class OrdinalType, class ScalarType>
68  class SerialDenseMatrix; // forward declaration
69 }
70 #endif // DOXYGEN_SHOULD_SKIP_THIS
71 #endif // HAVE_TPETRACORE_TEUCHOSNUMERICS
72 
73 
74 namespace Tpetra {
75 
76 
97  template <class DS, class DL, class DG, class DN,
98  class SS, class SL, class SG, class SN>
99  void
101  const MultiVector<SS, SL, SG, SN>& src);
102 
103 #ifdef HAVE_TPETRACORE_TEUCHOSNUMERICS
110  template <class ST, class LO, class GO, class NT>
111  void
113  const Teuchos::SerialDenseMatrix<int, ST>& src);
114 
121  template <class ST, class LO, class GO, class NT>
122  void
123  deep_copy (Teuchos::SerialDenseMatrix<int, ST>& dst,
124  const MultiVector<ST, LO, GO, NT>& src);
125 #endif // HAVE_TPETRACORE_TEUCHOSNUMERICS
126 
134  template <class ST, class LO, class GO, class NT>
137 
147  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
148  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
150  const size_t numVectors);
151 
152  // WARNING NOT FOR USERS
153  // This means we don't need to make MultiVector a friend of
154  // Vector or of itself (with different template parameters).
155  template<class SC, class LO, class GO, class NT>
156  Teuchos::ArrayView<const size_t>
157  getMultiVectorWhichVectors (const MultiVector<SC, LO, GO, NT>& X);
158 
378  template <class Scalar,
379  class LocalOrdinal,
380  class GlobalOrdinal,
381  class Node>
382  class MultiVector :
383  public DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node>
384  {
385  public:
387 
388 
390  using scalar_type = Scalar;
407  typename Kokkos::Details::ArithTraits<Scalar>::val_type;
408 
418  using node_type = typename map_type::node_type;
419 
425  using dot_type =
426  typename Kokkos::Details::InnerProductSpaceTraits<impl_scalar_type>::dot_type;
427 
434  using mag_type = typename Kokkos::ArithTraits<impl_scalar_type>::mag_type;
435 
440  using execution_space = typename device_type::execution_space;
441 
464  using dual_view_type = Kokkos::DualView<impl_scalar_type**,
465  Kokkos::LayoutLeft,
466  device_type>;
467 
469 
471 
473  MultiVector ();
474 
481  MultiVector (const Teuchos::RCP<const map_type>& map,
482  const size_t numVecs,
483  const bool zeroOut = true);
484 
496  const Teuchos::DataAccess copyOrView);
497 
513  MultiVector (const Teuchos::RCP<const map_type>& map,
514  const Teuchos::ArrayView<const Scalar>& A,
515  const size_t LDA,
516  const size_t NumVectors);
517 
531  MultiVector (const Teuchos::RCP<const map_type>& map,
532  const Teuchos::ArrayView<const Teuchos::ArrayView<const Scalar> >&ArrayOfPtrs,
533  const size_t NumVectors);
534 
547  MultiVector (const Teuchos::RCP<const map_type>& map,
548  const dual_view_type& view);
549 
588  MultiVector (const Teuchos::RCP<const map_type>& map,
589  const typename dual_view_type::t_dev& d_view);
590 
613  MultiVector (const Teuchos::RCP<const map_type>& map,
614  const dual_view_type& view,
615  const dual_view_type& origView);
616 
617  protected:
618 
624  const size_t j);
625 
626  public:
627 
645  MultiVector (const Teuchos::RCP<const map_type>& map,
646  const dual_view_type& view,
647  const Teuchos::ArrayView<const size_t>& whichVectors);
648 
676  MultiVector (const Teuchos::RCP<const map_type>& map,
677  const dual_view_type& view,
678  const dual_view_type& origView,
679  const Teuchos::ArrayView<const size_t>& whichVectors);
680 
742  const Teuchos::RCP<const map_type>& subMap,
743  const local_ordinal_type rowOffset = 0);
744 
752  const map_type& subMap,
753  const size_t offset = 0);
754 
764 
767 
775 
779 
789  virtual ~MultiVector () = default;
790 
793 
795 
797 
798  protected:
803  static const bool useAtomicUpdatesByDefault =
804 #ifdef KOKKOS_ENABLE_SERIAL
805  ! std::is_same<execution_space, Kokkos::Serial>::value;
806 #else
807  true;
808 #endif // KOKKOS_ENABLE_SERIAL
809 
810  public:
840  void
841  replaceGlobalValue (const GlobalOrdinal gblRow,
842  const size_t col,
843  const impl_scalar_type& value);
844 
877  template<typename T>
878  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
879  replaceGlobalValue (GlobalOrdinal globalRow,
880  size_t col,
881  const T& value)
882  {
883  replaceGlobalValue (globalRow, col, static_cast<impl_scalar_type> (value));
884  }
885 
910  void
911  sumIntoGlobalValue (const GlobalOrdinal gblRow,
912  const size_t col,
913  const impl_scalar_type& value,
914  const bool atomic = useAtomicUpdatesByDefault);
915 
944  template<typename T>
945  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
946  sumIntoGlobalValue (const GlobalOrdinal gblRow,
947  const size_t col,
948  const T& val,
949  const bool atomic = useAtomicUpdatesByDefault)
950  {
951  sumIntoGlobalValue (gblRow, col, static_cast<impl_scalar_type> (val), atomic);
952  }
953 
983  void
984  replaceLocalValue (const LocalOrdinal lclRow,
985  const size_t col,
986  const impl_scalar_type& value);
987 
1021  template<typename T>
1022  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
1023  replaceLocalValue (const LocalOrdinal lclRow,
1024  const size_t col,
1025  const T& val)
1026  {
1027  replaceLocalValue (lclRow, col, static_cast<impl_scalar_type> (val));
1028  }
1029 
1054  void
1055  sumIntoLocalValue (const LocalOrdinal lclRow,
1056  const size_t col,
1057  const impl_scalar_type& val,
1058  const bool atomic = useAtomicUpdatesByDefault);
1059 
1086  template<typename T>
1087  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
1088  sumIntoLocalValue (const LocalOrdinal lclRow,
1089  const size_t col,
1090  const T& val,
1091  const bool atomic = useAtomicUpdatesByDefault)
1092  {
1093  sumIntoLocalValue (lclRow, col, static_cast<impl_scalar_type> (val), atomic);
1094  }
1095 
1097  void putScalar (const Scalar& value);
1098 
1107  template<typename T>
1108  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
1109  putScalar (const T& value)
1110  {
1111  putScalar (static_cast<impl_scalar_type> (value));
1112  }
1113 
1126  void randomize();
1127 
1141  void randomize (const Scalar& minVal, const Scalar& maxVal);
1142 
1208  void replaceMap (const Teuchos::RCP<const map_type>& map);
1209 
1216  void reduce();
1217 
1219 
1245 
1246 
1248  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1249  subCopy (const Teuchos::Range1D& colRng) const;
1250 
1252  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1253  subCopy (const Teuchos::ArrayView<const size_t>& cols) const;
1254 
1256  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1257  subView (const Teuchos::Range1D& colRng) const;
1258 
1260  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1261  subView (const Teuchos::ArrayView<const size_t>& cols) const;
1262 
1264  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1265  subViewNonConst (const Teuchos::Range1D& colRng);
1266 
1268  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1269  subViewNonConst (const Teuchos::ArrayView<const size_t>& cols);
1270 
1333  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1334  offsetView (const Teuchos::RCP<const map_type>& subMap,
1335  const size_t offset) const;
1336 
1354  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1355  offsetViewNonConst (const Teuchos::RCP<const map_type>& subMap,
1356  const size_t offset);
1357 
1359  Teuchos::RCP<const Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1360  getVector (const size_t j) const;
1361 
1363  Teuchos::RCP<Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
1364  getVectorNonConst (const size_t j);
1365 
1367  Teuchos::ArrayRCP<const Scalar> getData (size_t j) const;
1368 
1370  Teuchos::ArrayRCP<Scalar> getDataNonConst (size_t j);
1371 
1379  void
1380  get1dCopy (const Teuchos::ArrayView<Scalar>& A,
1381  const size_t LDA) const;
1382 
1389  void
1390  get2dCopy (const Teuchos::ArrayView<const Teuchos::ArrayView<Scalar> >& ArrayOfPtrs) const;
1391 
1397  Teuchos::ArrayRCP<const Scalar> get1dView () const;
1398 
1400  Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > get2dView () const;
1401 
1407  Teuchos::ArrayRCP<Scalar> get1dViewNonConst ();
1408 
1410  Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > get2dViewNonConst ();
1411 
1414  typename dual_view_type::t_host::const_type getLocalViewHost(Access::ReadOnlyStruct) const;
1415 
1418  typename dual_view_type::t_host getLocalViewHost(Access::ReadWriteStruct);
1419 
1422  typename dual_view_type::t_host getLocalViewHost(Access::OverwriteAllStruct);
1423 
1426  typename dual_view_type::t_dev::const_type getLocalViewDevice(Access::ReadOnlyStruct) const;
1427 
1430  typename dual_view_type::t_dev getLocalViewDevice(Access::ReadWriteStruct);
1431 
1434  typename dual_view_type::t_dev getLocalViewDevice(Access::OverwriteAllStruct);
1435 
1436 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
1438  //TPETRA_DEPRECATED
1439  void clear_sync_state ();
1440 
1459  template<class TargetDeviceType>
1460  //TPETRA_DEPRECATED
1461  void sync () {
1462  view_.template sync<TargetDeviceType> ();
1463  }
1464 
1466  //TPETRA_DEPRECATED
1467  void sync_host ();
1468 
1470  //TPETRA_DEPRECATED
1471  void sync_device ();
1472 #endif // TPETRA_ENABLE_DEPRECATED_CODE
1473 
1475  template<class TargetDeviceType>
1476  bool need_sync () const {
1477  return view_.template need_sync<TargetDeviceType> ();
1478  }
1479 
1481  bool need_sync_host () const;
1482 
1484  bool need_sync_device () const;
1485 
1486 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
1487 
1493  template<class TargetDeviceType>
1494  //TPETRA_DEPRECATED
1495  void modify () {
1496  view_.template modify<TargetDeviceType> ();
1497  }
1498 
1500  //TPETRA_DEPRECATED
1501  void modify_device ();
1502 
1504  //TPETRA_DEPRECATED
1505  void modify_host ();
1506 #endif // TPETRA_ENABLE_DEPRECATED_CODE
1507 
1536  template<class TargetDeviceType>
1537  typename std::remove_reference<decltype(std::declval<dual_view_type>().template view<TargetDeviceType>())>::type::const_type
1538  getLocalView (Access::ReadOnlyStruct) const
1539  {
1540  bool returnDevice = true;
1541  {
1542  auto tmp = view_.template view<TargetDeviceType>();
1543  if (tmp == this->view_.view_host()) returnDevice = false;
1544  }
1545  if (returnDevice)
1546  {
1547  //returning dual_view_type::t_dev::const_type
1548  if(owningView_.h_view.use_count() > owningView_.d_view.use_count()) {
1549  const bool debug = Details::Behavior::debug();
1550  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1551  " device while a host view is alive";
1552  if (debug) {
1553  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1554  << ": " << msg << std::endl;
1555  }
1556  throw std::runtime_error(msg);
1557  }
1558  owningView_.sync_device();
1559  }
1560  else
1561  {
1562  //returning dual_view_type::t_host::const_type
1563  if(owningView_.d_view.use_count() > owningView_.h_view.use_count()) {
1564  const bool debug = Details::Behavior::debug();
1565  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1566  " host while a device view is alive";
1567  if (debug) {
1568  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1569  << ": " << msg << std::endl;
1570  }
1571  throw std::runtime_error(msg);
1572  }
1573  owningView_.sync_host();
1574  }
1575  return view_.template view<TargetDeviceType>();
1576  }
1577 
1578  template<class TargetDeviceType>
1579  typename std::remove_reference<decltype(std::declval<dual_view_type>().template view<TargetDeviceType>())>::type
1580  getLocalView (Access::ReadWriteStruct)
1581  {
1582  bool returnDevice = true;
1583  {
1584  auto tmp = view_.template view<TargetDeviceType>();
1585  if (tmp == this->view_.view_host()) returnDevice = false;
1586  }
1587  if (returnDevice)
1588  {
1589  //returning dual_view_type::t_dev::type
1590  if(owningView_.h_view.use_count() > owningView_.d_view.use_count()) {
1591  const bool debug = Details::Behavior::debug();
1592  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1593  " device while a host view is alive";
1594  if (debug) {
1595  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1596  << ": " << msg << std::endl;
1597  }
1598  throw std::runtime_error(msg);
1599  }
1600  owningView_.sync_device();
1601  owningView_.modify_device();
1602  }
1603  else
1604  {
1605  //returning dual_view_type::t_host::type
1606  if(owningView_.d_view.use_count() > owningView_.h_view.use_count()) {
1607  const bool debug = Details::Behavior::debug();
1608  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1609  " host while a device view is alive";
1610  if (debug) {
1611  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1612  << ": " << msg << std::endl;
1613  }
1614  throw std::runtime_error(msg);
1615  }
1616  owningView_.sync_host();
1617  owningView_.modify_host();
1618  }
1619  return view_.template view<TargetDeviceType>();
1620  }
1621 
1622  template<class TargetDeviceType>
1623  typename std::remove_reference<decltype(std::declval<dual_view_type>().template view<TargetDeviceType>())>::type
1624  getLocalView (Access::OverwriteAllStruct)
1625  {
1626  if (owningView_.h_view != view_.h_view) {
1627  // view_ is a subview of owningView_; for safety, need to use ReadWrite
1628  return getLocalView<TargetDeviceType>(Access::ReadWrite);
1629  }
1630  bool returnDevice = true;
1631  {
1632  auto tmp = view_.template view<TargetDeviceType>();
1633  if (tmp == this->view_.view_host()) returnDevice = false;
1634  }
1635  if (returnDevice)
1636  {
1637  //returning dual_view_type::t_dev::type
1638  if(owningView_.h_view.use_count() > owningView_.d_view.use_count()) {
1639  const bool debug = Details::Behavior::debug();
1640  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1641  " device while a host view is alive";
1642  if (debug) {
1643  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1644  << ": " << msg << std::endl;
1645  }
1646  throw std::runtime_error(msg);
1647  }
1648  owningView_.clear_sync_state();
1649  owningView_.modify_device();
1650  }
1651  else
1652  {
1653  //returning dual_view_type::t_host::type
1654  if(owningView_.d_view.use_count() > owningView_.h_view.use_count()) {
1655  const bool debug = Details::Behavior::debug();
1656  const char msg[] = "Tpetra::MultiVector: Cannot access data on "
1657  " host while a device view is alive";
1658  if (debug) {
1659  std::cout << "Rank " << this->getMap()->getComm()->getRank()
1660  << ": " << msg << std::endl;
1661  }
1662  throw std::runtime_error(msg);
1663  }
1664  owningView_.clear_sync_state();
1665  owningView_.modify_host();
1666  }
1667  return view_.template view<TargetDeviceType>();
1668  }
1669 
1670 
1671 #ifdef TPETRA_ENABLE_DEPRECATED_CODE
1702  template<class TargetDeviceType>
1703  //TPETRA_DEPRECATED
1704  typename std::remove_reference<decltype(std::declval<dual_view_type>().template view<TargetDeviceType>())>::type
1705  getLocalView () const
1706  {
1707  return view_.template view<TargetDeviceType>();
1708  }
1709 
1711  //TPETRA_DEPRECATED
1712  typename dual_view_type::t_host getLocalViewHost () const;
1713 
1715  //TPETRA_DEPRECATED
1716  typename dual_view_type::t_dev getLocalViewDevice () const;
1717 #endif
1718 
1720 
1722 
1736  void
1737  dot (const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A,
1738  const Teuchos::ArrayView<dot_type>& dots) const;
1739 
1751  template <typename T>
1752  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1754  const Teuchos::ArrayView<T> &dots) const
1755  {
1756  const size_t sz = static_cast<size_t> (dots.size ());
1757  Teuchos::Array<dot_type> dts (sz);
1758  this->dot (A, dts);
1759  for (size_t i = 0; i < sz; ++i) {
1760  // If T and dot_type differ, this does an implicit conversion.
1761  dots[i] = dts[i];
1762  }
1763  }
1764 
1766  template <typename T>
1767  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1769  std::vector<T>& dots) const
1770  {
1771  const size_t sz = dots.size ();
1772  Teuchos::Array<dot_type> dts (sz);
1773  this->dot (A, dts);
1774  for (size_t i = 0; i < sz; ++i) {
1775  // If T and dot_type differ, this does an implicit conversion.
1776  dots[i] = dts[i];
1777  }
1778  }
1779 
1797  void
1799  const Kokkos::View<dot_type*, Kokkos::HostSpace>& norms) const;
1800 
1801  template<class ViewType>
1802  void
1803  dot (typename std::enable_if<std::is_same<typename ViewType::value_type,dot_type>::value &&
1804  std::is_same<typename ViewType::memory_space,typename device_type::memory_space>::value,
1806  const ViewType& dots) const {
1807  const Kokkos::View<dot_type*, Kokkos::HostSpace> h_dots("Tpetra::Dots",dots.extent(0));
1808  this->dot (A, h_dots);
1809  Kokkos::deep_copy(dots,h_dots);
1810  }
1811 
1824  template <typename T>
1825  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1827  const Kokkos::View<T*, device_type>& dots) const
1828  {
1829  const size_t numDots = dots.extent (0);
1830  Kokkos::View<dot_type*, device_type> dts ("MV::dot tmp", numDots);
1831  // Call overload that takes a Kokkos::View<dot_type*, device_type>.
1832  this->dot (A, dts);
1833  // FIXME (mfh 14 Jul 2014) Does this actually work if dot_type
1834  // and T differ? We would need a test for this, but only the
1835  // Sacado and Stokhos packages are likely to care about this use
1836  // case. It could also come up for Kokkos::complex ->
1837  // std::complex conversions, but those two implementations
1838  // should generally be bitwise compatible.
1839  // CT: no this can't possible work .....
1840  Kokkos::deep_copy (dots, dts);
1841  }
1842 
1845 
1848 
1856  void scale (const Scalar& alpha);
1857 
1866  void scale (const Teuchos::ArrayView<const Scalar>& alpha);
1867 
1876  void scale (const Kokkos::View<const impl_scalar_type*, device_type>& alpha);
1877 
1886  void
1887  scale (const Scalar& alpha,
1889 
1896  void
1897  update (const Scalar& alpha,
1899  const Scalar& beta);
1900 
1907  void
1908  update (const Scalar& alpha,
1910  const Scalar& beta,
1912  const Scalar& gamma);
1913 
1925  void
1926  norm1 (const Kokkos::View<mag_type*, Kokkos::HostSpace>& norms) const;
1927 
1928  template<class ViewType>
1929  typename std::enable_if<std::is_same<typename ViewType::value_type,mag_type>::value &&
1930  std::is_same<typename ViewType::memory_space,typename device_type::memory_space>::value>::type
1931  norm1 (const ViewType& norms) const {
1932  // FIXME (mfh 11 Apr 2019) The enable_ifs make it useless for
1933  // this method to be templated. (It only exists in case
1934  // HostSpace = device_type::memory_space.)
1935  using host_norms_view_type = Kokkos::View<mag_type*, Kokkos::HostSpace>;
1936  host_norms_view_type h_norms ("Tpetra::MV::h_norms", norms.extent (0));
1937  this->norm1 (h_norms);
1938  Kokkos::deep_copy (norms, h_norms);
1939  }
1940 
1956  template <typename T>
1957  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1958  norm1 (const Kokkos::View<T*, device_type>& norms) const
1959  {
1960  const size_t numNorms = norms.extent (0);
1961  Kokkos::View<mag_type*, device_type> tmpNorms ("MV::norm1 tmp", numNorms);
1962  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1963  this->norm1 (tmpNorms);
1964  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
1965  // and T differ? We would need a test for this, but only the
1966  // Sacado and Stokhos packages are likely to care about this use
1967  // case. It could also come up with Kokkos::complex ->
1968  // std::complex conversion.
1969  Kokkos::deep_copy (norms, tmpNorms);
1970  }
1971 
1975  void norm1 (const Teuchos::ArrayView<mag_type>& norms) const;
1976 
1991  template <typename T>
1992  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1993  norm1 (const Teuchos::ArrayView<T>& norms) const
1994  {
1995  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1996  const size_type sz = norms.size ();
1997  Teuchos::Array<mag_type> theNorms (sz);
1998  this->norm1 (theNorms);
1999  for (size_type i = 0; i < sz; ++i) {
2000  // If T and mag_type differ, this does an implicit conversion.
2001  norms[i] = theNorms[i];
2002  }
2003  }
2004 
2017  void
2018  norm2 (const Kokkos::View<mag_type*, Kokkos::HostSpace>& norms) const;
2019 
2020  template<class ViewType>
2021  typename std::enable_if<std::is_same<typename ViewType::value_type,mag_type>::value &&
2022  std::is_same<typename ViewType::memory_space,typename device_type::memory_space>::value>::type
2023  norm2 (const ViewType& norms) const {
2024  // FIXME (mfh 11 Apr 2019) The enable_ifs make it useless for
2025  // this method to be templated. (It only exists in case
2026  // HostSpace = device_type::memory_space.)
2027  using host_norms_view_type = Kokkos::View<mag_type*, Kokkos::HostSpace>;
2028  host_norms_view_type h_norms ("Tpetra::MV::h_norms", norms.extent (0));
2029  this->norm2 (h_norms);
2030  Kokkos::deep_copy (norms, h_norms);
2031  }
2032 
2046  template<typename T>
2047  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
2048  norm2 (const Kokkos::View<T*, device_type>& norms) const
2049  {
2050  const size_t numNorms = norms.extent (0);
2051  Kokkos::View<mag_type*, device_type> theNorms ("MV::norm2 tmp", numNorms);
2052  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
2053  this->norm2 (theNorms);
2054  // FIXME (mfh 14 Jul 2014) Does this actually work if mag_type
2055  // and T differ? We would need a test for this, but only the
2056  // Sacado and Stokhos packages are likely to care about this use
2057  // case. This could also come up with Kokkos::complex ->
2058  // std::complex conversion.
2059  Kokkos::deep_copy (norms, theNorms);
2060  }
2061 
2065  void norm2 (const Teuchos::ArrayView<mag_type>& norms) const;
2066 
2081  template <typename T>
2082  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
2083  norm2 (const Teuchos::ArrayView<T>& norms) const
2084  {
2085  typedef typename Teuchos::ArrayView<T>::size_type size_type;
2086  const size_type sz = norms.size ();
2087  Teuchos::Array<mag_type> theNorms (sz);
2088  this->norm2 (theNorms);
2089  for (size_type i = 0; i < sz; ++i) {
2090  // If T and mag_type differ, this does an implicit conversion.
2091  norms[i] = theNorms[i];
2092  }
2093  }
2094 
2101  void normInf (const Kokkos::View<mag_type*, Kokkos::HostSpace>& norms) const;
2102 
2103  template<class ViewType>
2104  typename std::enable_if<std::is_same<typename ViewType::value_type,mag_type>::value &&
2105  std::is_same<typename ViewType::memory_space,typename device_type::memory_space>::value>::type
2106  normInf (const ViewType& norms) const {
2107  // FIXME (mfh 11 Apr 2019) The enable_ifs make it useless for
2108  // this method to be templated. (It only exists in case
2109  // HostSpace = device_type::memory_space.)
2110  using host_norms_view_type = Kokkos::View<mag_type*, Kokkos::HostSpace>;
2111  host_norms_view_type h_norms ("Tpetra::MV::h_norms", norms.extent (0));
2112  this->normInf (h_norms);
2113  Kokkos::deep_copy (norms, h_norms);
2114  }
2115 
2129  template<typename T>
2130  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
2131  normInf (const Kokkos::View<T*, device_type>& norms) const
2132  {
2133  const size_t numNorms = norms.extent (0);
2134  Kokkos::View<mag_type*, device_type> theNorms ("MV::normInf tmp", numNorms);
2135  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
2136  this->normInf (theNorms);
2137  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
2138  // and T differ? We would need a test for this, but only the
2139  // Sacado and Stokhos packages are likely to care about this use
2140  // case. This could also come up with Kokkos::complex ->
2141  // std::complex conversion.
2142  Kokkos::deep_copy (norms, theNorms);
2143  }
2144 
2149  void normInf (const Teuchos::ArrayView<mag_type>& norms) const;
2150 
2166  template <typename T>
2167  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
2168  normInf (const Teuchos::ArrayView<T>& norms) const
2169  {
2170  typedef typename Teuchos::ArrayView<T>::size_type size_type;
2171  const size_type sz = norms.size ();
2172  Teuchos::Array<mag_type> theNorms (sz);
2173  this->norm2 (theNorms);
2174  for (size_type i = 0; i < sz; ++i) {
2175  // If T and mag_type differ, this does an implicit conversion.
2176  norms[i] = theNorms[i];
2177  }
2178  }
2179 
2180 
2185  void meanValue (const Teuchos::ArrayView<impl_scalar_type>& means) const;
2186 
2187  template <typename T>
2188  typename std::enable_if<! std::is_same<impl_scalar_type, T>::value, void>::type
2189  meanValue (const Teuchos::ArrayView<T>& means) const
2190  {
2191  typedef typename Teuchos::Array<T>::size_type size_type;
2192  const size_type numMeans = means.size ();
2193 
2194  Teuchos::Array<impl_scalar_type> theMeans (numMeans);
2195  this->meanValue (theMeans ());
2196  for (size_type k = 0; k < numMeans; ++k) {
2197  means[k] = static_cast<T> (theMeans[k]);
2198  }
2199  }
2200 
2206  void
2207  multiply (Teuchos::ETransp transA,
2208  Teuchos::ETransp transB,
2209  const Scalar& alpha,
2210  const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A,
2211  const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& B,
2212  const Scalar& beta);
2213 
2234  void
2235  elementWiseMultiply (Scalar scalarAB,
2236  const Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A,
2237  const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& B,
2238  Scalar scalarThis);
2240 
2242 
2244  size_t getNumVectors() const;
2245 
2247  size_t getLocalLength() const;
2248 
2251 
2257  size_t getStride() const;
2258 
2262  bool isConstantStride() const;
2263 
2267  bool aliases(const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& other) const;
2268 
2270 
2272 
2273 
2275  virtual std::string description() const;
2276 
2305  virtual void
2306  describe (Teuchos::FancyOStream& out,
2307  const Teuchos::EVerbosityLevel verbLevel =
2308  Teuchos::Describable::verbLevel_default) const;
2310 
2324  virtual void
2325  removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
2326 
2337  void setCopyOrView (const Teuchos::DataAccess copyOrView) {
2338  TEUCHOS_TEST_FOR_EXCEPTION(
2339  copyOrView == Teuchos::Copy, std::invalid_argument,
2340  "Tpetra::MultiVector::setCopyOrView: The Kokkos refactor version of "
2341  "MultiVector _only_ implements view semantics. You may not call this "
2342  "method with copyOrView = Teuchos::Copy. The only valid argument is "
2343  "Teuchos::View.");
2344  }
2345 
2349  // This method ONLY exists for the circa 2014 "Kokkos refactor"
2350  // effort. It ALWAYS returns Teuchos::View.
2354  Teuchos::DataAccess getCopyOrView () const {
2355  return Teuchos::View;
2356  }
2357 
2372  void
2374 
2377  template <class T>
2378  Teuchos::RCP<MultiVector<T, LocalOrdinal, GlobalOrdinal, Node> >
2379  convert () const;
2380 
2381 
2382  // \brief Checks to see if the local length, number of vectors and size of Scalar type match
2391 
2392  private:
2394  using base_type = DistObject<scalar_type, local_ordinal_type,
2396 
2397  protected:
2398  template <class DS, class DL, class DG, class DN,
2399  class SS, class SL, class SG, class SN>
2400  friend void
2402  const MultiVector<SS, SL, SG, SN>& src);
2403 
2411 
2442 
2446 
2459  Teuchos::Array<size_t> whichVectors_;
2460 
2461  template<class SC, class LO, class GO, class NT>
2462  friend ::Teuchos::ArrayView<const size_t> getMultiVectorWhichVectors (const ::Tpetra::MultiVector<SC, LO, GO, NT>& X);
2463 
2465 
2467 
2474  std::string
2475  descriptionImpl (const std::string& className) const;
2476 
2483  std::string
2484  localDescribeToString (const Teuchos::EVerbosityLevel vl) const;
2485 
2499  void
2500  describeImpl (Teuchos::FancyOStream& out,
2501  const std::string& className,
2502  const Teuchos::EVerbosityLevel verbLevel =
2503  Teuchos::Describable::verbLevel_default) const;
2504 
2505  // Return true if and only if VectorIndex is a valid column index.
2506  bool vectorIndexOutOfRange (const size_t VectorIndex) const;
2507 
2512  template <class T>
2513  Teuchos::ArrayRCP<T>
2514  getSubArrayRCP (Teuchos::ArrayRCP<T> arr, size_t j) const;
2515 
2517  size_t getOrigNumLocalRows () const;
2518 
2520  size_t getOrigNumLocalCols () const;
2521 
2523 
2525 
2531  typename DistObject<scalar_type,
2535 
2540  virtual bool
2541  checkSizes (const SrcDistObject& sourceObj);
2542 
2544  virtual size_t constantNumberOfPackets () const;
2545 
2546  virtual void
2548  (const SrcDistObject& sourceObj,
2549  const size_t numSameIDs,
2550  const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteToLIDs,
2551  const Kokkos::DualView<const local_ordinal_type*, buffer_device_type>& permuteFromLIDs,
2552  const CombineMode CM);
2553 
2554  virtual void
2555  packAndPrepare
2556  (const SrcDistObject& sourceObj,
2557  const Kokkos::DualView<
2558  const local_ordinal_type*,
2559  buffer_device_type>& exportLIDs,
2560  Kokkos::DualView<
2562  buffer_device_type>& exports,
2563  Kokkos::DualView<
2564  size_t*,
2565  buffer_device_type> /* numPacketsPerLID */,
2566  size_t& constantNumPackets);
2567 
2568  virtual void
2569  unpackAndCombine
2570  (const Kokkos::DualView<
2571  const local_ordinal_type*,
2572  buffer_device_type>& importLIDs,
2573  Kokkos::DualView<
2575  buffer_device_type> imports,
2576  Kokkos::DualView<
2577  size_t*,
2578  buffer_device_type> /* numPacketsPerLID */,
2579  const size_t constantNumPackets,
2580  const CombineMode CM);
2581 
2582  private:
2583 
2584  // If comm buffers can be aliased to the data view, use this
2585  // implementation.
2586  template<class NO=Node>
2587  typename std::enable_if<std::is_same<typename Tpetra::Details::DefaultTypes::CommBufferMemorySpace<typename NO::execution_space>::type,
2588  typename NO::device_type::memory_space>::value, bool>::type
2589  reallocImportsIfNeededImpl (const size_t newSize,
2590  const bool verbose,
2591  const std::string* prefix,
2592  const bool areRemoteLIDsContiguous,
2593  const CombineMode CM);
2594 
2595  // If comm buffers cannot be aliased to the data view, use this
2596  // implementation. (Just calls DistObject::reallocImportsIfNeeded.)
2597  template<class NO=Node>
2598  typename std::enable_if<!std::is_same<typename Tpetra::Details::DefaultTypes::CommBufferMemorySpace<typename NO::execution_space>::type,
2599  typename NO::device_type::memory_space>::value, bool>::type
2600  reallocImportsIfNeededImpl (const size_t newSize,
2601  const bool verbose,
2602  const std::string* prefix,
2603  const bool areRemoteLIDsContiguous,
2604  const CombineMode CM);
2605  protected:
2606 
2607  virtual bool
2608  reallocImportsIfNeeded (const size_t newSize,
2609  const bool verbose,
2610  const std::string* prefix,
2611  const bool areRemoteLIDsContiguous=false,
2612  const CombineMode CM=INSERT);
2613 
2614 
2615  public:
2616  bool importsAreAliased();
2617 
2618  protected:
2619  Kokkos::DualView<impl_scalar_type*, buffer_device_type> unaliased_imports_;
2620 
2622  }; // class MultiVector
2623 
2624  template<class SC, class LO, class GO, class NT>
2625  Teuchos::ArrayView<const size_t>
2626  getMultiVectorWhichVectors (const MultiVector<SC, LO, GO, NT>& X)
2627  {
2628  return X.whichVectors_ ();
2629  }
2630 
2631 
2634  template <class ST, class LO, class GO, class NT>
2635  void
2637  const MultiVector<ST, LO, GO, NT>& src)
2638  {
2639  // NOTE (mfh 11 Sep 2014) We can't implement deep_copy with
2640  // shallow-copy operator=, because that would invalidate existing
2641  // views of dst!
2642  dst.assign (src);
2643  }
2644 
2645  // Implementation of the most generic version of MultiVector deep_copy.
2646  template <class DS, class DL, class DG, class DN,
2647  class SS, class SL, class SG, class SN>
2648  void
2650  const MultiVector<SS, SL, SG, SN>& src)
2651  {
2652  using ::Tpetra::getMultiVectorWhichVectors;
2653 
2654  TEUCHOS_TEST_FOR_EXCEPTION(
2655  dst.getGlobalLength () != src.getGlobalLength () ||
2656  dst.getNumVectors () != src.getNumVectors (), std::invalid_argument,
2657  "Tpetra::deep_copy: Global dimensions of the two Tpetra::MultiVector "
2658  "objects do not match. src has dimensions [" << src.getGlobalLength ()
2659  << "," << src.getNumVectors () << "], and dst has dimensions ["
2660  << dst.getGlobalLength () << "," << dst.getNumVectors () << "].");
2661 
2662  // FIXME (mfh 28 Jul 2014) Don't throw; just set a local error flag.
2663  TEUCHOS_TEST_FOR_EXCEPTION(
2664  dst.getLocalLength () != src.getLocalLength (), std::invalid_argument,
2665  "Tpetra::deep_copy: The local row counts of the two Tpetra::MultiVector "
2666  "objects do not match. src has " << src.getLocalLength () << " row(s) "
2667  << " and dst has " << dst.getLocalLength () << " row(s).");
2668 
2669  const bool srcMostUpToDateOnDevice = ! src.need_sync_device ();
2670 
2671  if (src.isConstantStride () && dst.isConstantStride ()) {
2672  if (srcMostUpToDateOnDevice) {
2674  dst.getLocalViewDevice (Access::OverwriteAll),
2675  src.getLocalViewDevice (Access::ReadOnly));
2676  }
2677  else {
2679  dst.getLocalViewDevice (Access::OverwriteAll),
2680  src.getLocalViewHost (Access::ReadOnly));
2681  }
2682  }
2683  else {
2684  auto dstWhichVecs = getMultiVectorWhichVectors (dst);
2685  auto srcWhichVecs = getMultiVectorWhichVectors (src);
2686 
2687  if (srcMostUpToDateOnDevice) {
2688  Details::localDeepCopy (dst.getLocalViewDevice (Access::OverwriteAll),
2689  src.getLocalViewDevice (Access::ReadOnly),
2690  dst.isConstantStride (),
2691  src.isConstantStride (),
2692  dstWhichVecs,
2693  srcWhichVecs);
2694  }
2695  else {
2696  Details::localDeepCopy (dst.getLocalViewDevice (Access::OverwriteAll),
2697  src.getLocalViewHost (Access::ReadOnly),
2698  dst.isConstantStride (),
2699  src.isConstantStride (),
2700  dstWhichVecs,
2701  srcWhichVecs);
2702  }
2703  }
2704  }
2705 } // namespace Tpetra
2706 
2707 
2708 namespace Teuchos {
2709 
2710  // Give Teuchos::TypeNameTraits<Tpetra::MultiVector<...> > a
2711  // human-readable definition.
2712  template<class SC, class LO, class GO, class NT>
2713  class TypeNameTraits<Tpetra::MultiVector<SC, LO, GO, NT> > {
2714  public:
2715  static std::string name () {
2716  return std::string ("Tpetra::MultiVector<") +
2717  TypeNameTraits<SC>::name () + "," +
2718  TypeNameTraits<LO>::name () + "," +
2719  TypeNameTraits<GO>::name () + "," +
2720  TypeNameTraits<NT>::name () + ">";
2721  }
2722 
2723  static std::string
2724  concreteName (const Tpetra::MultiVector<SC, LO, GO, NT>&) {
2725  return name ();
2726  }
2727  };
2728 } // namespace Teuchos
2729 
2730 #endif // TPETRA_MULTIVECTOR_DECL_HPP
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Forward declaration of Tpetra::FEMultiVector.
Forward declaration of Tpetra::Map.
Forward declaration of Tpetra::MultiVector.
Forward declaration of Tpetra::Vector.
static bool debug()
Whether Tpetra is in debug mode.
Base class for distributed Tpetra objects that support data redistribution.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
A parallel distribution of indices over processes.
Node node_type
Legacy typedef that will go away at some point.
GlobalOrdinal global_ordinal_type
The type of global indices.
LocalOrdinal local_ordinal_type
The type of local indices.
typename Node::device_type device_type
This class' Kokkos::Device specialization.
One or more distributed dense vectors.
typename map_type::global_ordinal_type global_ordinal_type
The type of global indices that this class uses.
void reciprocal(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Put element-wise reciprocal values of input Multi-vector in target, this(i,j) = 1/A(i,...
dual_view_type origView_
The "original view" of the MultiVector's data.
void normInf(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the infinity-norm of each vector (column), storing the result in a host View.
void get1dCopy(const Teuchos::ArrayView< Scalar > &A, const size_t LDA) const
Fill the given array with a copy of this multivector's local values.
size_t getStride() const
Stride between columns in the multivector.
virtual size_t constantNumberOfPackets() const
Number of packets to send per LID.
typename map_type::node_type node_type
Legacy thing that you should not use any more.
virtual std::string description() const
A simple one-line description of this object.
std::enable_if<! std::is_same< T, impl_scalar_type >::value &&std::is_convertible< T, impl_scalar_type >::value, void >::type sumIntoLocalValue(const LocalOrdinal lclRow, const size_t col, const T &val, const bool atomic=useAtomicUpdatesByDefault)
Like the above sumIntoLocalValue, but only enabled if T differs from impl_scalar_type.
void reduce()
Sum values of a locally replicated multivector across all processes.
void randomize()
Set all values in the multivector to pseudorandom numbers.
virtual void removeEmptyProcessesInPlace(const Teuchos::RCP< const map_type > &newMap)
Remove processes owning zero rows from the Map and their communicator.
typename map_type::local_ordinal_type local_ordinal_type
The type of local indices that this class uses.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subView(const Teuchos::Range1D &colRng) const
Return a const MultiVector with const views of selected columns.
void dot(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Teuchos::ArrayView< dot_type > &dots) const
Compute the dot product of each corresponding pair of vectors (columns) in A and B.
void describeImpl(Teuchos::FancyOStream &out, const std::string &className, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of describe() for this class, and its subclass Vector.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > offsetView(const Teuchos::RCP< const map_type > &subMap, const size_t offset) const
Return a const view of a subset of rows.
MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > & operator=(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &)=default
Copy assigment (shallow copy).
Teuchos::ArrayRCP< Scalar > get1dViewNonConst()
Nonconst persisting (1-D) view of this multivector's local values.
void assign(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &src)
Copy the contents of src into *this (deep copy).
Teuchos::RCP< Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVectorNonConst(const size_t j)
Return a Vector which is a nonconst view of column j.
void meanValue(const Teuchos::ArrayView< impl_scalar_type > &means) const
Compute mean (average) value of each column.
std::string descriptionImpl(const std::string &className) const
Implementation of description() for this class, and its subclass Vector.
void multiply(Teuchos::ETransp transA, Teuchos::ETransp transB, const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, const Scalar &beta)
Matrix-matrix multiplication: this = beta*this + alpha*op(A)*op(B).
bool need_sync_device() const
Whether this MultiVector needs synchronization to the device.
virtual void copyAndPermute(const SrcDistObject &sourceObj, const size_t numSameIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteToLIDs, const Kokkos::DualView< const local_ordinal_type *, buffer_device_type > &permuteFromLIDs, const CombineMode CM)
Perform copies and permutations that are local to the calling (MPI) process.
MultiVector(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const map_type &subMap, const size_t offset=0)
"Offset view" constructor, that takes the new Map as a const Map& rather than by RCP.
void replaceLocalValue(const LocalOrdinal lclRow, const size_t col, const impl_scalar_type &value)
Replace value in host memory, using local (row) index.
void swap(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &mv)
Swap contents of mv with contents of *this.
size_t getLocalLength() const
Local number of rows on the calling process.
std::enable_if<! std::is_same< T, impl_scalar_type >::value &&std::is_convertible< T, impl_scalar_type >::value, void >::type sumIntoGlobalValue(const GlobalOrdinal gblRow, const size_t col, const T &val, const bool atomic=useAtomicUpdatesByDefault)
Like the above sumIntoGlobalValue, but only enabled if T differs from impl_scalar_type.
typename DistObject< scalar_type, local_ordinal_type, global_ordinal_type, node_type >::buffer_device_type buffer_device_type
Kokkos::Device specialization for communication buffers.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subCopy(const Teuchos::Range1D &colRng) const
Return a MultiVector with copies of selected columns.
typename Kokkos::Details::InnerProductSpaceTraits< impl_scalar_type >::dot_type dot_type
Type of an inner ("dot") product result.
Teuchos::ArrayRCP< const Scalar > getData(size_t j) const
Const view of the local values in a particular vector of this multivector.
bool need_sync_host() const
Whether this MultiVector needs synchronization to the host.
Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(const size_t j) const
Return a Vector which is a const view of column j.
Scalar scalar_type
The type of each entry in the MultiVector.
bool need_sync() const
Whether this MultiVector needs synchronization to the given space.
void norm2(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the two-norm of each vector (column), storing the result in a host View.
std::remove_reference< decltype(std::declval< dual_view_type >).template view< TargetDeviceType >))>::type::const_type getLocalView(Access::ReadOnlyStruct) const
Return a view of the local data on a specific device, with the given access mode. The return type is ...
typename Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
global_size_t getGlobalLength() const
Global number of rows in the multivector.
Teuchos::ArrayRCP< const Scalar > get1dView() const
Const persisting (1-D) view of this multivector's local values.
Teuchos::ArrayRCP< T > getSubArrayRCP(Teuchos::ArrayRCP< T > arr, size_t j) const
Persisting view of j-th column in the given ArrayRCP.
void replaceGlobalValue(const GlobalOrdinal gblRow, const size_t col, const impl_scalar_type &value)
Replace value in host memory, using global row index.
Kokkos::DualView< impl_scalar_type **, Kokkos::LayoutLeft, device_type > dual_view_type
Kokkos::DualView specialization used by this class.
virtual bool reallocImportsIfNeeded(const size_t newSize, const bool verbose, const std::string *prefix, const bool areRemoteLIDsContiguous=false, const CombineMode CM=INSERT)
Reallocate imports_ if needed.
typename map_type::device_type device_type
This class' preferred Kokkos device type.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with the given verbosity level to a FancyOStream.
void elementWiseMultiply(Scalar scalarAB, const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B, Scalar scalarThis)
Multiply a Vector A elementwise by a MultiVector B.
void setCopyOrView(const Teuchos::DataAccess copyOrView)
Set whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
size_t getNumVectors() const
Number of columns in the multivector.
dual_view_type owningView_
The true original DualView - it owns the memory of this MultiVector, and was not constructed as a sub...
void sumIntoLocalValue(const LocalOrdinal lclRow, const size_t col, const impl_scalar_type &val, const bool atomic=useAtomicUpdatesByDefault)
Update (+=) a value in host memory, using local row index.
void replaceMap(const Teuchos::RCP< const map_type > &map)
Replace the underlying Map in place.
Teuchos::DataAccess getCopyOrView() const
Get whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
std::enable_if<! std::is_same< T, impl_scalar_type >::value &&std::is_convertible< T, impl_scalar_type >::value, void >::type replaceLocalValue(const LocalOrdinal lclRow, const size_t col, const T &val)
Like the above replaceLocalValue, but only enabled if T differs from impl_scalar_type.
virtual bool checkSizes(const SrcDistObject &sourceObj)
Whether data redistribution between sourceObj and this object is legal.
Teuchos::RCP< MultiVector< T, LocalOrdinal, GlobalOrdinal, Node > > convert() const
Return another MultiVector with the same entries, but converted to a different Scalar type T.
MultiVector()
Default constructor: makes a MultiVector with no rows or columns.
dual_view_type::t_dev::const_type getLocalViewDevice(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on device. This requires that th...
typename device_type::execution_space execution_space
Type of the (new) Kokkos execution space.
void abs(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Put element-wise absolute values of input Multi-vector in target: A = abs(this)
void norm1(const Kokkos::View< mag_type *, Kokkos::HostSpace > &norms) const
Compute the one-norm of each vector (column), storing the result in a host view.
void get2dCopy(const Teuchos::ArrayView< const Teuchos::ArrayView< Scalar > > &ArrayOfPtrs) const
Fill the given array with a copy of this multivector's local values.
void sumIntoGlobalValue(const GlobalOrdinal gblRow, const size_t col, const impl_scalar_type &value, const bool atomic=useAtomicUpdatesByDefault)
Update (+=) a value in host memory, using global row index.
bool aliases(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &other) const
Whether this multivector's memory might alias other. This is conservative: if either this or other is...
dual_view_type::t_host::const_type getLocalViewHost(Access::ReadOnlyStruct) const
Return a read-only, up-to-date view of this MultiVector's local data on host. This requires that ther...
std::enable_if<! std::is_same< T, impl_scalar_type >::value &&std::is_convertible< T, impl_scalar_type >::value, void >::type replaceGlobalValue(GlobalOrdinal globalRow, size_t col, const T &value)
Like the above replaceGlobalValue, but only enabled if T differs from impl_scalar_type.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > subViewNonConst(const Teuchos::Range1D &colRng)
Return a MultiVector with views of selected columns.
MultiVector(MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &&)=default
Move constructor (shallow move).
Teuchos::Array< size_t > whichVectors_
Indices of columns this multivector is viewing.
Teuchos::ArrayRCP< Scalar > getDataNonConst(size_t j)
View of the local values in a particular vector of this multivector.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
typename Kokkos::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
std::enable_if<! std::is_same< T, impl_scalar_type >::value &&std::is_convertible< T, impl_scalar_type >::value, void >::type putScalar(const T &value)
Set all values in the multivector with the given value.
size_t getOrigNumLocalCols() const
"Original" number of columns in the (local) data.
MultiVector(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, const Teuchos::RCP< const map_type > &subMap, const local_ordinal_type rowOffset=0)
"Offset view" constructor; make a view of a contiguous subset of rows on each process.
Teuchos::ArrayRCP< Teuchos::ArrayRCP< Scalar > > get2dViewNonConst()
Return non-const persisting pointers to values.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > offsetViewNonConst(const Teuchos::RCP< const map_type > &subMap, const size_t offset)
Return a nonconst view of a subset of rows.
std::string localDescribeToString(const Teuchos::EVerbosityLevel vl) const
Print the calling process' verbose describe() information to the returned string.
bool isSameSize(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &vec) const
size_t getOrigNumLocalRows() const
"Original" number of rows in the (local) data.
MultiVector(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &)=default
Copy constructor (shallow copy).
Teuchos::ArrayRCP< Teuchos::ArrayRCP< const Scalar > > get2dView() const
Return const persisting pointers to values.
virtual ~MultiVector()=default
Destructor (virtual for memory safety of derived classes).
dual_view_type view_
The Kokkos::DualView containing the MultiVector's data.
static const bool useAtomicUpdatesByDefault
Whether sumIntoLocalValue and sumIntoGlobalValue should use atomic updates by default.
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)
Update: this = beta*this + alpha*A.
Abstract base class for objects that can be the source of an Import or Export operation.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > createMultiVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, const size_t numVectors)
Nonmember MultiVector "constructor": Create a MultiVector from a given Map.
void localDeepCopyConstStride(const DstViewType &dst, const SrcViewType &src)
Implementation of Tpetra::MultiVector deep copy of local data, for when both the source and destinati...
void localDeepCopy(const DstViewType &dst, const SrcViewType &src, const bool dstConstStride, const bool srcConstStride, const DstWhichVecsType &dstWhichVecs, const SrcWhichVecsType &srcWhichVecs)
Implementation of Tpetra::MultiVector deep copy of local data.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
void deep_copy(MultiVector< ST, LO, GO, NT > &dst, const MultiVector< ST, LO, GO, NT > &src)
Specialization of deep_copy for MultiVector objects with the same template parameters.
size_t global_size_t
Global size_t object.
MultiVector< ST, LO, GO, NT > createCopy(const MultiVector< ST, LO, GO, NT > &src)
Return a deep copy of the given MultiVector.
CombineMode
Rule for combining data in an Import or Export.
@ INSERT
Insert new values that don't currently exist.