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 
53 
54 #include "Tpetra_DistObject.hpp"
55 #include "Tpetra_Map_decl.hpp"
56 #include "Kokkos_DualView.hpp"
57 #include "Teuchos_BLAS_types.hpp"
58 #include "Teuchos_DataAccess.hpp"
59 #include "Teuchos_Range1D.hpp"
60 #include "Kokkos_ArithTraits.hpp"
61 #include "Kokkos_InnerProductSpaceTraits.hpp"
62 #include "Tpetra_KokkosRefactor_Details_MultiVectorLocalDeepCopy.hpp"
63 #include <type_traits>
64 
65 namespace Tpetra {
66 
67 #ifndef DOXYGEN_SHOULD_SKIP_THIS
68  // forward declaration of Map
69  template<class LO, class GO, class N> class Map;
70 
71  // forward declaration of Vector, needed to prevent circular inclusions
72  template<class S, class LO, class GO, class N, const bool classic> class Vector;
73 
74  // forward declaration of MultiVector (declared later in this file)
75  template<class S, class LO, class GO, class N, const bool classic> class MultiVector;
76 #endif // DOXYGEN_SHOULD_SKIP_THIS
77 
78  namespace Details {
104  template<class DstMultiVectorType, class SrcMultiVectorType>
106  typedef DstMultiVectorType dst_mv_type;
107  typedef SrcMultiVectorType src_mv_type;
108 
109  static Teuchos::RCP<dst_mv_type>
110  clone (const src_mv_type& X,
111  const Teuchos::RCP<typename dst_mv_type::node_type>& node2);
112  };
113 
114  } // namespace Details
115 
136  template <class DS, class DL, class DG, class DN, const bool dstClassic,
137  class SS, class SL, class SG, class SN, const bool srcClassic>
138  void
141 
149  template <class ST, class LO, class GO, class NT, const bool classic = NT::classic>
152 
162  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, const bool classic = Node::classic>
163  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
164  createMultiVector (const Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >& map,
165  const size_t numVectors);
166 
386  template <class Scalar = ::Tpetra::Details::DefaultTypes::scalar_type,
388  class GlobalOrdinal = ::Tpetra::Details::DefaultTypes::global_ordinal_type,
390  const bool classic = Node::classic>
391  class MultiVector :
392  public DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node>
393  {
394  static_assert (! classic, "The 'classic' version of Tpetra was deprecated long ago, and has been removed.");
395 
396  public:
398 
399 
402  typedef Scalar scalar_type;
418  typedef typename Kokkos::Details::ArithTraits<Scalar>::val_type impl_scalar_type;
420  typedef LocalOrdinal local_ordinal_type;
422  typedef GlobalOrdinal global_ordinal_type;
424  typedef Node node_type;
425 
427  typedef typename Node::device_type device_type;
428 
429  private:
432 
433  public:
439  typedef typename Kokkos::Details::InnerProductSpaceTraits<impl_scalar_type>::dot_type dot_type;
440 
447  typedef typename Kokkos::Details::ArithTraits<impl_scalar_type>::mag_type mag_type;
448 
455  typedef typename Node::execution_space execution_space;
456 
479  typedef Kokkos::DualView<impl_scalar_type**, Kokkos::LayoutLeft,
480  typename execution_space::execution_space> dual_view_type;
481 
484 
486 
488 
490  MultiVector ();
491 
498  MultiVector (const Teuchos::RCP<const map_type>& map,
499  const size_t numVecs,
500  const bool zeroOut = true);
501 
504 
514  const Teuchos::DataAccess copyOrView);
515 
531  MultiVector (const Teuchos::RCP<const map_type>& map,
532  const Teuchos::ArrayView<const Scalar>& A,
533  const size_t LDA,
534  const size_t NumVectors);
535 
549  MultiVector (const Teuchos::RCP<const map_type>& map,
550  const Teuchos::ArrayView<const Teuchos::ArrayView<const Scalar> >&ArrayOfPtrs,
551  const size_t NumVectors);
552 
565  MultiVector (const Teuchos::RCP<const map_type>& map,
566  const dual_view_type& view);
567 
606  MultiVector (const Teuchos::RCP<const map_type>& map,
607  const typename dual_view_type::t_dev& d_view);
608 
631  MultiVector (const Teuchos::RCP<const map_type>& map,
632  const dual_view_type& view,
633  const dual_view_type& origView);
634 
652  MultiVector (const Teuchos::RCP<const map_type>& map,
653  const dual_view_type& view,
654  const Teuchos::ArrayView<const size_t>& whichVectors);
655 
683  MultiVector (const Teuchos::RCP<const map_type>& map,
684  const dual_view_type& view,
685  const dual_view_type& origView,
686  const Teuchos::ArrayView<const size_t>& whichVectors);
687 
747  const map_type& subMap,
748  const size_t offset = 0);
749 
758  template <class Node2>
759  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> >
760  clone (const Teuchos::RCP<Node2>& node2) const;
761 
763  virtual ~MultiVector ();
764 
766 
768 
769  protected:
774  static const bool useAtomicUpdatesByDefault =
775 #ifdef KOKKOS_HAVE_SERIAL
776  ! std::is_same<execution_space, Kokkos::Serial>::value;
777 #else
778  true;
779 #endif // KOKKOS_HAVE_SERIAL
780 
781  public:
810  void
811  replaceGlobalValue (const GlobalOrdinal gblRow,
812  const size_t col,
813  const impl_scalar_type& value) const;
814 
847  template<typename T>
848  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
849  replaceGlobalValue (GlobalOrdinal globalRow,
850  size_t col,
851  const T& value) const
852  {
853  replaceGlobalValue (globalRow, col, static_cast<impl_scalar_type> (value));
854  }
855 
879  void
880  sumIntoGlobalValue (const GlobalOrdinal gblRow,
881  const size_t col,
882  const impl_scalar_type& value,
883  const bool atomic = useAtomicUpdatesByDefault) const;
884 
912  template<typename T>
913  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
914  sumIntoGlobalValue (const GlobalOrdinal gblRow,
915  const size_t col,
916  const T& val,
917  const bool atomic = useAtomicUpdatesByDefault) const
918  {
919  sumIntoGlobalValue (gblRow, col, static_cast<impl_scalar_type> (val), atomic);
920  }
921 
950  void
951  replaceLocalValue (const LocalOrdinal lclRow,
952  const size_t col,
953  const impl_scalar_type& value) const;
954 
987  template<typename T>
988  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
989  replaceLocalValue (const LocalOrdinal lclRow,
990  const size_t col,
991  const T& val) const
992  {
993  replaceLocalValue (lclRow, col, static_cast<impl_scalar_type> (val));
994  }
995 
1019  void
1020  sumIntoLocalValue (const LocalOrdinal lclRow,
1021  const size_t col,
1022  const impl_scalar_type& val,
1023  const bool atomic = useAtomicUpdatesByDefault) const;
1024 
1050  template<typename T>
1051  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
1052  sumIntoLocalValue (const LocalOrdinal lclRow,
1053  const size_t col,
1054  const T& val,
1055  const bool atomic = useAtomicUpdatesByDefault) const
1056  {
1057  sumIntoLocalValue (lclRow, col, static_cast<impl_scalar_type> (val), atomic);
1058  }
1059 
1061  void putScalar (const Scalar& value);
1062 
1071  template<typename T>
1072  typename std::enable_if<! std::is_same<T, impl_scalar_type>::value && std::is_convertible<T, impl_scalar_type>::value, void>::type
1073  putScalar (const T& value)
1074  {
1075  putScalar (static_cast<impl_scalar_type> (value));
1076  }
1077 
1090  void randomize();
1091 
1105  void randomize (const Scalar& minVal, const Scalar& maxVal);
1106 
1172  void replaceMap (const Teuchos::RCP<const map_type>& map);
1173 
1180  void reduce();
1181 
1185 
1187 
1213 
1214 
1216  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1217  subCopy (const Teuchos::Range1D& colRng) const;
1218 
1220  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1221  subCopy (const Teuchos::ArrayView<const size_t>& cols) const;
1222 
1224  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1225  subView (const Teuchos::Range1D& colRng) const;
1226 
1228  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1229  subView (const Teuchos::ArrayView<const size_t>& cols) const;
1230 
1232  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1233  subViewNonConst (const Teuchos::Range1D& colRng);
1234 
1236  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1237  subViewNonConst (const Teuchos::ArrayView<const size_t>& cols);
1238 
1301  Teuchos::RCP<const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1302  offsetView (const Teuchos::RCP<const map_type>& subMap,
1303  const size_t offset) const;
1304 
1322  Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1323  offsetViewNonConst (const Teuchos::RCP<const map_type>& subMap,
1324  const size_t offset);
1325 
1327  Teuchos::RCP<const Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1328  getVector (const size_t j) const;
1329 
1331  Teuchos::RCP<Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node, classic> >
1332  getVectorNonConst (const size_t j);
1333 
1335  Teuchos::ArrayRCP<const Scalar> getData (size_t j) const;
1336 
1338  Teuchos::ArrayRCP<Scalar> getDataNonConst (size_t j);
1339 
1347  void
1348  get1dCopy (const Teuchos::ArrayView<Scalar>& A,
1349  const size_t LDA) const;
1350 
1357  void
1358  get2dCopy (const Teuchos::ArrayView<const Teuchos::ArrayView<Scalar> >& ArrayOfPtrs) const;
1359 
1365  Teuchos::ArrayRCP<const Scalar> get1dView () const;
1366 
1368  Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > get2dView () const;
1369 
1375  Teuchos::ArrayRCP<Scalar> get1dViewNonConst ();
1376 
1378  Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > get2dViewNonConst ();
1379 
1394  dual_view_type getDualView () const;
1395 
1414  template<class TargetDeviceType>
1415  void sync () {
1416  getDualView ().template sync<TargetDeviceType> ();
1417  }
1418 
1420  template<class TargetDeviceType>
1421  bool need_sync () const {
1422  return getDualView ().template need_sync<TargetDeviceType> ();
1423  }
1424 
1430  template<class TargetDeviceType>
1431  void modify () {
1432  getDualView ().template modify<TargetDeviceType> ();
1433  }
1434 
1466  template<class TargetDeviceType>
1467  typename Kokkos::Impl::if_c<
1468  std::is_same<
1469  typename device_type::memory_space,
1470  typename TargetDeviceType::memory_space>::value,
1471  typename dual_view_type::t_dev,
1472  typename dual_view_type::t_host>::type
1473  getLocalView () const {
1474  return getDualView ().template view<TargetDeviceType> ();
1475  }
1476 
1478 
1480 
1494  void
1496  const Teuchos::ArrayView<dot_type>& dots) const;
1497 
1509  template <typename T>
1510  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1512  const Teuchos::ArrayView<T> &dots) const
1513  {
1514  const size_t sz = static_cast<size_t> (dots.size ());
1515  Teuchos::Array<dot_type> dts (sz);
1516  this->dot (A, dts);
1517  for (size_t i = 0; i < sz; ++i) {
1518  // If T and dot_type differ, this does an implicit conversion.
1519  dots[i] = dts[i];
1520  }
1521  }
1522 
1524  template <typename T>
1525  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1527  std::vector<T>& dots) const
1528  {
1529  const size_t sz = dots.size ();
1530  Teuchos::Array<dot_type> dts (sz);
1531  this->dot (A, dts);
1532  for (size_t i = 0; i < sz; ++i) {
1533  // If T and dot_type differ, this does an implicit conversion.
1534  dots[i] = dts[i];
1535  }
1536  }
1537 
1555  void
1557  const Kokkos::View<dot_type*, device_type>& dots) const;
1558 
1571  template <typename T>
1572  typename std::enable_if< ! (std::is_same<dot_type, T>::value), void >::type
1574  const Kokkos::View<T*, device_type>& dots) const
1575  {
1576  const size_t numDots = dots.dimension_0 ();
1577  Kokkos::View<dot_type*, device_type> dts ("MV::dot tmp", numDots);
1578  // Call overload that takes a Kokkos::View<dot_type*, device_type>.
1579  this->dot (A, dts);
1580  // FIXME (mfh 14 Jul 2014) Does this actually work if dot_type
1581  // and T differ? We would need a test for this, but only the
1582  // Sacado and Stokhos packages are likely to care about this use
1583  // case. It could also come up for Kokkos::complex ->
1584  // std::complex conversions, but those two implementations
1585  // should generally be bitwise compatible.
1586  Kokkos::deep_copy (dots, dts);
1587  }
1588 
1591 
1594 
1602  void scale (const Scalar& alpha);
1603 
1612  void scale (const Teuchos::ArrayView<const Scalar>& alpha);
1613 
1622  void scale (const Kokkos::View<const impl_scalar_type*, device_type>& alpha);
1623 
1632  void
1633  scale (const Scalar& alpha,
1635 
1642  void
1643  update (const Scalar& alpha,
1645  const Scalar& beta);
1646 
1653  void
1654  update (const Scalar& alpha,
1656  const Scalar& beta,
1658  const Scalar& gamma);
1659 
1677  void norm1 (const Kokkos::View<mag_type*, device_type>& norms) const;
1678 
1694  template <typename T>
1695  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1696  norm1 (const Kokkos::View<T*, device_type>& norms) const
1697  {
1698  const size_t numNorms = norms.dimension_0 ();
1699  Kokkos::View<mag_type*, device_type> tmpNorms ("MV::norm1 tmp", numNorms);
1700  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1701  this->norm1 (tmpNorms);
1702  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
1703  // and T differ? We would need a test for this, but only the
1704  // Sacado and Stokhos packages are likely to care about this use
1705  // case. It could also come up with Kokkos::complex ->
1706  // std::complex conversion.
1707  Kokkos::deep_copy (norms, tmpNorms);
1708  }
1709 
1713  void norm1 (const Teuchos::ArrayView<mag_type>& norms) const;
1714 
1729  template <typename T>
1730  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1731  norm1 (const Teuchos::ArrayView<T>& norms) const
1732  {
1733  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1734  const size_type sz = norms.size ();
1735  Teuchos::Array<mag_type> theNorms (sz);
1736  this->norm1 (theNorms);
1737  for (size_type i = 0; i < sz; ++i) {
1738  // If T and mag_type differ, this does an implicit conversion.
1739  norms[i] = theNorms[i];
1740  }
1741  }
1742 
1761  void norm2 (const Kokkos::View<mag_type*, device_type>& norms) const;
1762 
1776  template<typename T>
1777  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1778  norm2 (const Kokkos::View<T*, device_type>& norms) const
1779  {
1780  const size_t numNorms = norms.dimension_0 ();
1781  Kokkos::View<mag_type*, device_type> theNorms ("MV::norm2 tmp", numNorms);
1782  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1783  this->norm2 (theNorms);
1784  // FIXME (mfh 14 Jul 2014) Does this actually work if mag_type
1785  // and T differ? We would need a test for this, but only the
1786  // Sacado and Stokhos packages are likely to care about this use
1787  // case. This could also come up with Kokkos::complex ->
1788  // std::complex conversion.
1789  Kokkos::deep_copy (norms, theNorms);
1790  }
1791 
1795  void norm2 (const Teuchos::ArrayView<mag_type>& norms) const;
1796 
1811  template <typename T>
1812  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1813  norm2 (const Teuchos::ArrayView<T>& norms) const
1814  {
1815  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1816  const size_type sz = norms.size ();
1817  Teuchos::Array<mag_type> theNorms (sz);
1818  this->norm2 (theNorms);
1819  for (size_type i = 0; i < sz; ++i) {
1820  // If T and mag_type differ, this does an implicit conversion.
1821  norms[i] = theNorms[i];
1822  }
1823  }
1824 
1837  void normInf (const Kokkos::View<mag_type*, device_type>& norms) const;
1838 
1852  template<typename T>
1853  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1854  normInf (const Kokkos::View<T*, device_type>& norms) const
1855  {
1856  const size_t numNorms = norms.dimension_0 ();
1857  Kokkos::View<mag_type*, device_type> theNorms ("MV::normInf tmp", numNorms);
1858  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1859  this->normInf (theNorms);
1860  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
1861  // and T differ? We would need a test for this, but only the
1862  // Sacado and Stokhos packages are likely to care about this use
1863  // case. This could also come up with Kokkos::complex ->
1864  // std::complex conversion.
1865  Kokkos::deep_copy (norms, theNorms);
1866  }
1867 
1872  void normInf (const Teuchos::ArrayView<mag_type>& norms) const;
1873 
1889  template <typename T>
1890  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1891  normInf (const Teuchos::ArrayView<T>& norms) const
1892  {
1893  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1894  const size_type sz = norms.size ();
1895  Teuchos::Array<mag_type> theNorms (sz);
1896  this->norm2 (theNorms);
1897  for (size_type i = 0; i < sz; ++i) {
1898  // If T and mag_type differ, this does an implicit conversion.
1899  norms[i] = theNorms[i];
1900  }
1901  }
1902 
1909  void TPETRA_DEPRECATED
1911  const Teuchos::ArrayView<mag_type>& norms) const;
1912 
1929  template <typename T>
1930  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1931  TPETRA_DEPRECATED
1933  const Teuchos::ArrayView<T>& norms) const
1934  {
1935  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1936  const size_type sz = norms.size ();
1937  Teuchos::Array<mag_type> theNorms (sz);
1938  this->normWeighted (weights, theNorms);
1939  for (size_type i = 0; i < sz; ++i) {
1940  // If T and mag_type differ, this does an implicit conversion.
1941  norms[i] = theNorms[i];
1942  }
1943  }
1944 
1949  void meanValue (const Teuchos::ArrayView<impl_scalar_type>& means) const;
1950 
1951  template <typename T>
1952  typename std::enable_if<! std::is_same<impl_scalar_type, T>::value, void>::type
1953  meanValue (const Teuchos::ArrayView<T>& means) const
1954  {
1955  typedef typename Teuchos::Array<T>::size_type size_type;
1956  const size_type numMeans = means.size ();
1957 
1958  Teuchos::Array<impl_scalar_type> theMeans (numMeans);
1959  this->meanValue (theMeans ());
1960  for (size_type k = 0; k < numMeans; ++k) {
1961  means[k] = static_cast<T> (theMeans[k]);
1962  }
1963  }
1964 
1970  void
1971  multiply (Teuchos::ETransp transA,
1972  Teuchos::ETransp transB,
1973  const Scalar& alpha,
1976  const Scalar& beta);
1977 
1998  void
1999  elementWiseMultiply (Scalar scalarAB,
2002  Scalar scalarThis);
2004 
2006 
2008  size_t getNumVectors() const;
2009 
2011  size_t getLocalLength() const;
2012 
2014  global_size_t getGlobalLength() const;
2015 
2021  size_t getStride() const;
2022 
2026  bool isConstantStride() const;
2027 
2029 
2031 
2032 
2034  virtual std::string description() const;
2035 
2064  virtual void
2065  describe (Teuchos::FancyOStream& out,
2066  const Teuchos::EVerbosityLevel verbLevel =
2067  Teuchos::Describable::verbLevel_default) const;
2069 
2083  virtual void
2084  removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
2085 
2096  void setCopyOrView (const Teuchos::DataAccess copyOrView) {
2097  TEUCHOS_TEST_FOR_EXCEPTION(
2098  copyOrView == Teuchos::Copy, std::invalid_argument,
2099  "Tpetra::MultiVector::setCopyOrView: The Kokkos refactor version of "
2100  "MultiVector _only_ implements view semantics. You may not call this "
2101  "method with copyOrView = Teuchos::Copy. The only valid argument is "
2102  "Teuchos::View.");
2103  }
2104 
2115  Teuchos::DataAccess getCopyOrView () const {
2116  return Teuchos::View;
2117  }
2118 
2133  void
2135 
2136  protected:
2137  template <class DS, class DL, class DG, class DN, const bool dstClassic,
2138  class SS, class SL, class SG, class SN, const bool srcClassic>
2139  friend void
2142 
2149  mutable dual_view_type view_;
2150 
2180  mutable dual_view_type origView_;
2181 
2194  Teuchos::Array<size_t> whichVectors_;
2195 
2197 
2198 
2200  enum EWhichNorm {
2201  NORM_ONE, //<! Use the one-norm
2202  NORM_TWO, //<! Use the two-norm
2203  NORM_INF //<! Use the infinity-norm
2204  };
2205 
2213  void
2214  normImpl (const Kokkos::View<mag_type*, device_type>& norms,
2215  const EWhichNorm whichNorm) const;
2216 
2218 
2220 
2227  std::string
2228  descriptionImpl (const std::string& className) const;
2229 
2236  std::string
2237  localDescribeToString (const Teuchos::EVerbosityLevel vl) const;
2238 
2252  void
2253  describeImpl (Teuchos::FancyOStream& out,
2254  const std::string& className,
2255  const Teuchos::EVerbosityLevel verbLevel =
2256  Teuchos::Describable::verbLevel_default) const;
2257 
2258  // Return true if and only if VectorIndex is a valid column index.
2259  bool vectorIndexOutOfRange (const size_t VectorIndex) const;
2260 
2265  template <class T>
2266  Teuchos::ArrayRCP<T>
2267  getSubArrayRCP (Teuchos::ArrayRCP<T> arr, size_t j) const;
2268 
2270  size_t getOrigNumLocalRows () const;
2271 
2273  size_t getOrigNumLocalCols () const;
2274 
2276 
2278 
2283  virtual bool
2284  checkSizes (const SrcDistObject& sourceObj);
2285 
2287  virtual size_t constantNumberOfPackets () const;
2288 
2290  virtual bool useNewInterface () { return true; }
2291 
2292  virtual void
2293  copyAndPermuteNew (const SrcDistObject& sourceObj,
2294  const size_t numSameIDs,
2295  const Kokkos::DualView<const local_ordinal_type*, device_type>& permuteToLIDs,
2296  const Kokkos::DualView<const local_ordinal_type*, device_type>& permuteFromLIDs);
2297 
2298  virtual void
2299  packAndPrepareNew (const SrcDistObject& sourceObj,
2300  const Kokkos::DualView<const local_ordinal_type*, device_type>& exportLIDs,
2301  Kokkos::DualView<impl_scalar_type*, device_type>& exports,
2302  const Kokkos::DualView<size_t*, device_type>& /* numPacketsPerLID */,
2303  size_t& constantNumPackets,
2304  Distributor& /* distor */);
2305 
2306  virtual void
2307  unpackAndCombineNew (const Kokkos::DualView<const LocalOrdinal*, device_type>& importLIDs,
2308  const Kokkos::DualView<const impl_scalar_type*, device_type>& imports,
2309  const Kokkos::DualView<const size_t*, device_type>& /* numPacketsPerLID */,
2310  const size_t constantNumPackets,
2311  Distributor& /* distor */,
2312  const CombineMode CM);
2314  }; // class MultiVector
2315 
2316  namespace Details {
2317 
2318  template<class DstMultiVectorType,
2319  class SrcMultiVectorType>
2320  Teuchos::RCP<typename MultiVectorCloner<DstMultiVectorType, SrcMultiVectorType>::dst_mv_type>
2321  MultiVectorCloner<DstMultiVectorType, SrcMultiVectorType>::
2322  clone (const src_mv_type& X,
2323  const Teuchos::RCP<typename dst_mv_type::node_type>& node2)
2324  {
2325  using Teuchos::RCP;
2326  typedef typename src_mv_type::map_type src_map_type;
2327  typedef typename dst_mv_type::map_type dst_map_type;
2328  typedef typename dst_mv_type::node_type dst_node_type;
2329  typedef typename dst_mv_type::dual_view_type dst_dual_view_type;
2330 
2331  // Clone X's Map to have the new Node type.
2332  RCP<const src_map_type> map1 = X.getMap ();
2333  RCP<const dst_map_type> map2 = map1.is_null () ?
2334  Teuchos::null : map1->template clone<dst_node_type> (node2);
2335 
2336  const size_t lclNumRows = X.getLocalLength ();
2337  const size_t numCols = X.getNumVectors ();
2338  dst_dual_view_type Y_view ("MV::dual_view", lclNumRows, numCols);
2339 
2340  RCP<dst_mv_type> Y (new dst_mv_type (map2, Y_view));
2341  // Let deep_copy do the work for us, to avoid code duplication.
2342  ::Tpetra::deep_copy (Y, X);
2343  return Y ;
2344  }
2345 
2346  } // namespace Details
2347 
2350  template <class ST, class LO, class GO, class NT, const bool classic>
2351  void
2354  {
2355  // NOTE (mfh 11 Sep 2014) We can't implement deep_copy with
2356  // shallow-copy operator=, because that would invalidate existing
2357  // views of dst!
2358  dst.assign (src);
2359  }
2360 
2361  // Implementation of the most generic version of MultiVector deep_copy.
2362  template <class DS, class DL, class DG, class DN, const bool dstClassic,
2363  class SS, class SL, class SG, class SN, const bool srcClassic>
2364  void
2367  {
2368  typedef typename DN::device_type DD;
2369  //typedef typename SN::device_type SD;
2370 
2371  TEUCHOS_TEST_FOR_EXCEPTION(
2372  dst.getGlobalLength () != src.getGlobalLength () ||
2373  dst.getNumVectors () != src.getNumVectors (), std::invalid_argument,
2374  "Tpetra::deep_copy: Global dimensions of the two Tpetra::MultiVector "
2375  "objects do not match. src has dimensions [" << src.getGlobalLength ()
2376  << "," << src.getNumVectors () << "], and dst has dimensions ["
2377  << dst.getGlobalLength () << "," << dst.getNumVectors () << "].");
2378 
2379  // FIXME (mfh 28 Jul 2014) Don't throw; just set a local error flag.
2380  TEUCHOS_TEST_FOR_EXCEPTION(
2381  dst.getLocalLength () != src.getLocalLength (), std::invalid_argument,
2382  "Tpetra::deep_copy: The local row counts of the two Tpetra::MultiVector "
2383  "objects do not match. src has " << src.getLocalLength () << " row(s) "
2384  << " and dst has " << dst.getLocalLength () << " row(s).");
2385 
2386  if (src.isConstantStride () && dst.isConstantStride ()) {
2389 
2390  // If we need sync to device, then host has the most recent version.
2391  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2392 
2393  if (! useHostVersion) {
2394  // Device memory has the most recent version of src.
2395  dst.template modify<DES> (); // We are about to modify dst on device.
2396  // Copy from src to dst on device.
2397  Details::localDeepCopyConstStride (dst.template getLocalView<DES> (),
2398  src.template getLocalView<typename SN::device_type> ());
2399  dst.template sync<HES> (); // Sync dst from device to host.
2400  }
2401  else { // Host memory has the most recent version of src.
2402  dst.template modify<HES> (); // We are about to modify dst on host.
2403  // Copy from src to dst on host.
2404  Details::localDeepCopyConstStride (dst.template getLocalView<Kokkos::HostSpace> (),
2405  src.template getLocalView<Kokkos::HostSpace> ());
2406  dst.template sync<DES> (); // Sync dst from host to device.
2407  }
2408  }
2409  else {
2410  typedef Kokkos::DualView<SL*, DD> whichvecs_type;
2411  typedef typename whichvecs_type::t_dev::execution_space DES;
2412  typedef typename whichvecs_type::t_host::execution_space HES;
2413 
2414  if (dst.isConstantStride ()) {
2415  const SL numWhichVecs = static_cast<SL> (src.whichVectors_.size ());
2416  const std::string whichVecsLabel ("MV::deep_copy::whichVecs");
2417 
2418  // We can't sync src, since it is only an input argument.
2419  // Thus, we have to use the most recently modified version of
2420  // src, which could be either the device or host version.
2421  //
2422  // If we need sync to device, then host has the most recent version.
2423  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2424 
2425  if (! useHostVersion) { // Copy from the device version of src.
2426  // whichVecs tells the kernel which vectors (columns) of src
2427  // to copy. Fill whichVecs on the host, and sync to device.
2428  whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2429  whichVecs.template modify<HES> ();
2430  for (SL i = 0; i < numWhichVecs; ++i) {
2431  whichVecs.h_view(i) = static_cast<SL> (src.whichVectors_[i]);
2432  }
2433  // Sync the host version of whichVecs to the device.
2434  whichVecs.template sync<DES> ();
2435 
2436  // Mark the device version of dst's DualView as modified.
2437  dst.template modify<DES> ();
2438  // Copy from the selected vectors of src to dst, on the device.
2439  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2440  src.template getLocalView<typename SN::device_type> (),
2441  dst.isConstantStride (),
2442  src.isConstantStride (),
2443  whichVecs.d_view,
2444  whichVecs.d_view);
2445  // Sync dst's DualView to the host. This is cheaper than
2446  // repeating the above copy from src to dst on the host.
2447  dst.template sync<HES> ();
2448  }
2449  else { // host version of src was the most recently modified
2450  // Copy from the host version of src.
2451  //
2452  // whichVecs tells the kernel which vectors (columns) of src
2453  // to copy. Fill whichVecs on the host, and use it there.
2454  typedef Kokkos::View<SL*, HES> the_whichvecs_type;
2455  the_whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2456  for (SL i = 0; i < numWhichVecs; ++i) {
2457  whichVecs(i) = static_cast<SL> (src.whichVectors_[i]);
2458  }
2459  // Copy from the selected vectors of src to dst, on the
2460  // host. The function ignores the first instance of
2461  // 'whichVecs' in this case.
2462  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2463  src.template getLocalView<Kokkos::HostSpace> (),
2464  dst.isConstantStride (),
2465  src.isConstantStride (),
2466  whichVecs, whichVecs);
2467  // Sync dst back to the device, since we only copied on the host.
2468  dst.template sync<DES> ();
2469  }
2470  }
2471  else { // dst is NOT constant stride
2472  if (src.isConstantStride ()) {
2473 
2474  // If we need sync to device, then host has the most recent version.
2475  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2476 
2477  if (! useHostVersion) { // Copy from the device version of src.
2478  // whichVecs tells the kernel which vectors (columns) of dst
2479  // to copy. Fill whichVecs on the host, and sync to device.
2480  typedef Kokkos::DualView<DL*, DES> the_whichvecs_type;
2481  const std::string whichVecsLabel ("MV::deep_copy::whichVecs");
2482  const DL numWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2483  the_whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2484  whichVecs.template modify<HES> ();
2485  for (DL i = 0; i < numWhichVecs; ++i) {
2486  whichVecs.h_view(i) = dst.whichVectors_[i];
2487  }
2488  // Sync the host version of whichVecs to the device.
2489  whichVecs.template sync<DES> ();
2490 
2491  // Copy src to the selected vectors of dst, on the device.
2492  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2493  src.template getLocalView<typename SN::device_type> (),
2494  dst.isConstantStride (),
2495  src.isConstantStride (),
2496  whichVecs.d_view,
2497  whichVecs.d_view);
2498  // We can't sync src and repeat the above copy on the
2499  // host, so sync dst back to the host.
2500  //
2501  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2502  // don't actually belong to dst's view.
2503  dst.template sync<HES> ();
2504  }
2505  else { // host version of src was the most recently modified
2506  // Copy from the host version of src.
2507  //
2508  // whichVecs tells the kernel which vectors (columns) of src
2509  // to copy. Fill whichVecs on the host, and use it there.
2510  typedef Kokkos::View<DL*, HES> the_whichvecs_type;
2511  const DL numWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2512  the_whichvecs_type whichVecs ("MV::deep_copy::whichVecs", numWhichVecs);
2513  for (DL i = 0; i < numWhichVecs; ++i) {
2514  whichVecs(i) = static_cast<DL> (dst.whichVectors_[i]);
2515  }
2516  // Copy from src to the selected vectors of dst, on the host.
2517  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2518  src.template getLocalView<Kokkos::HostSpace> (),
2519  dst.isConstantStride (),
2520  src.isConstantStride (),
2521  whichVecs, whichVecs);
2522  // Sync dst back to the device, since we only copied on the host.
2523  //
2524  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2525  // don't actually belong to dst's view.
2526  dst.template sync<DES> ();
2527  }
2528  }
2529  else { // neither src nor dst have constant stride
2530 
2531  // If we need sync to device, then host has the most recent version.
2532  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2533 
2534  if (! useHostVersion) { // Copy from the device version of src.
2535  // whichVectorsDst tells the kernel which columns of dst
2536  // to copy. Fill it on the host, and sync to device.
2537  const DL dstNumWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2538  Kokkos::DualView<DL*, DES> whichVecsDst ("MV::deep_copy::whichVecsDst",
2539  dstNumWhichVecs);
2540  whichVecsDst.template modify<HES> ();
2541  for (DL i = 0; i < dstNumWhichVecs; ++i) {
2542  whichVecsDst.h_view(i) = static_cast<DL> (dst.whichVectors_[i]);
2543  }
2544  // Sync the host version of whichVecsDst to the device.
2545  whichVecsDst.template sync<DES> ();
2546 
2547  // whichVectorsSrc tells the kernel which vectors
2548  // (columns) of src to copy. Fill it on the host, and
2549  // sync to device. Use the destination MultiVector's
2550  // LocalOrdinal type here.
2551  const DL srcNumWhichVecs = static_cast<DL> (src.whichVectors_.size ());
2552  Kokkos::DualView<DL*, DES> whichVecsSrc ("MV::deep_copy::whichVecsSrc",
2553  srcNumWhichVecs);
2554  whichVecsSrc.template modify<HES> ();
2555  for (DL i = 0; i < srcNumWhichVecs; ++i) {
2556  whichVecsSrc.h_view(i) = static_cast<DL> (src.whichVectors_[i]);
2557  }
2558  // Sync the host version of whichVecsSrc to the device.
2559  whichVecsSrc.template sync<DES> ();
2560 
2561  // Copy from the selected vectors of src to the selected
2562  // vectors of dst, on the device.
2563  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2564  src.template getLocalView<typename SN::device_type> (),
2565  dst.isConstantStride (),
2566  src.isConstantStride (),
2567  whichVecsDst.d_view,
2568  whichVecsSrc.d_view);
2569  }
2570  else {
2571  const DL dstNumWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2572  Kokkos::View<DL*, HES> whichVectorsDst ("dstWhichVecs", dstNumWhichVecs);
2573  for (DL i = 0; i < dstNumWhichVecs; ++i) {
2574  whichVectorsDst(i) = dst.whichVectors_[i];
2575  }
2576 
2577  // Use the destination MultiVector's LocalOrdinal type here.
2578  const DL srcNumWhichVecs = static_cast<DL> (src.whichVectors_.size ());
2579  Kokkos::View<DL*, HES> whichVectorsSrc ("srcWhichVecs", srcNumWhichVecs);
2580  for (DL i = 0; i < srcNumWhichVecs; ++i) {
2581  whichVectorsSrc(i) = src.whichVectors_[i];
2582  }
2583 
2584  // Copy from the selected vectors of src to the selected
2585  // vectors of dst, on the host.
2586  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2587  src.template getLocalView<Kokkos::HostSpace> (),
2588  dst.isConstantStride (),
2589  src.isConstantStride (),
2590  whichVectorsDst, whichVectorsSrc);
2591  // We can't sync src and repeat the above copy on the
2592  // host, so sync dst back to the host.
2593  //
2594  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2595  // don't actually belong to dst's view.
2596  dst.template sync<HES> ();
2597  }
2598  }
2599  }
2600  }
2601  }
2602 } // namespace Tpetra
2603 
2604 
2605 namespace Teuchos {
2606 
2607  // Give Teuchos::TypeNameTraits<Tpetra::MultiVector<...> > a
2608  // human-readable definition.
2609  template<class SC, class LO, class GO, class NT, const bool classic>
2610  class TypeNameTraits<Tpetra::MultiVector<SC, LO, GO, NT, classic> > {
2611  public:
2612  static std::string name () {
2613  return std::string ("Tpetra::MultiVector<") +
2614  TypeNameTraits<SC>::name () + "," +
2615  TypeNameTraits<LO>::name () + "," +
2616  TypeNameTraits<GO>::name () + "," +
2617  TypeNameTraits<NT>::name () + ">";
2618  }
2619 
2620  static std::string
2621  concreteName (const Tpetra::MultiVector<SC, LO, GO, NT, classic>&) {
2622  return name ();
2623  }
2624  };
2625 } // namespace Teuchos
2626 
2627 #endif // TPETRA_MULTIVECTOR_DECL_HPP
Node node_type
This class&#39; fourth template parameter; the Kokkos Node type.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void sync()
Update data on device or host only if data in the other space has been marked as modified.
MultiVector< ST, LO, GO, NT, classic > createCopy(const MultiVector< ST, LO, GO, NT, classic > &src)
Return a deep copy of the given MultiVector.
Kokkos::Impl::if_c< std::is_same< typename device_type::memory_space, typename TargetDeviceType::memory_space >::value, typename dual_view_type::t_dev, typename dual_view_type::t_host >::type getLocalView() const
Return a view of the local data on a specific device.
KokkosClassic::DefaultNode::DefaultNodeType node_type
Default value of Node template parameter.
void setCopyOrView(const Teuchos::DataAccess copyOrView)
Set whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
Teuchos::Array< size_t > whichVectors_
Indices of columns this multivector is viewing.
One or more distributed dense vectors.
void deep_copy(MultiVector< ST, LO, GO, NT, classic > &dst, const MultiVector< ST, LO, GO, NT, classic > &src)
Specialization of deep_copy for MultiVector objects with the same template parameters.
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
Node::device_type device_type
The Kokkos device type.
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.
void removeEmptyProcessesInPlace(Teuchos::RCP< DistObjectType > &input, const Teuchos::RCP< const Map< typename DistObjectType::local_ordinal_type, typename DistObjectType::global_ordinal_type, typename DistObjectType::node_type > > &newMap)
Remove processes which contain no elements in this object&#39;s Map.
Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The type of the Map specialization used by this class.
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) const
Like the above sumIntoGlobalValue, but only enabled if T differs from impl_scalar_type.
dual_view_type view_
The Kokkos::DualView containing the MultiVector&#39;s data.
Kokkos::Details::InnerProductSpaceTraits< impl_scalar_type >::dot_type dot_type
Type of an inner ("dot") product result.
int local_ordinal_type
Default value of LocalOrdinal template parameter.
virtual bool useNewInterface()
Whether this class implements the old or new interface of DistObject.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > 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 modify()
Mark data as modified on the given device TargetDeviceType.
Implementation details of Tpetra.
size_t global_size_t
Global size_t object.
Declaration of the Tpetra::Map class and related nonmember constructors.
Scalar scalar_type
This class&#39; first template parameter; the type of each entry in the MultiVector.
bool isConstantStride() const
Whether this multivector has constant stride between columns.
size_t getLocalLength() const
Local number of rows on the calling process.
Node::execution_space execution_space
Type of the (new) Kokkos execution space.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
global_size_t getGlobalLength() const
Global number of rows in the multivector.
Abstract base class for objects that can be the source of an Import or Export operation.
double scalar_type
Default value of Scalar template parameter.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
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) const
Like the above sumIntoLocalValue, but only enabled if T differs from impl_scalar_type.
Implementation of Tpetra::MultiVector::clone().
Kokkos::Details::ArithTraits< impl_scalar_type >::mag_type mag_type
Type of a norm result.
Kokkos::DualView< impl_scalar_type **, Kokkos::LayoutLeft, typename execution_space::execution_space > dual_view_type
Kokkos::DualView specialization used by this class.
A parallel distribution of indices over processes.
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) const
Like the above replaceGlobalValue, but only enabled if T differs from impl_scalar_type.
size_t getNumVectors() const
Number of columns in the multivector.
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) const
Like the above replaceLocalValue, but only enabled if T differs from impl_scalar_type.
A distributed dense vector.
void assign(const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > &src)
Copy the contents of src into *this (deep copy).
LocalOrdinal local_ordinal_type
This class&#39; second template parameter; the type of local indices.
bool need_sync() const
Whether this MultiVector needs synchronization to the given space.
EWhichNorm
Input argument for normImpl() (which see).
Teuchos::DataAccess getCopyOrView() const
Get whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
Base class for distributed Tpetra objects that support data redistribution.
GlobalOrdinal global_ordinal_type
This class&#39; third template parameter; the type of global indices.
dual_view_type origView_
The "original view" of the MultiVector&#39;s data.