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 
1671  void norm1 (const Kokkos::View<mag_type*, device_type>& norms) const;
1672 
1686  template <typename T>
1687  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1688  norm1 (const Kokkos::View<T*, device_type>& norms) const
1689  {
1690  const size_t numNorms = norms.dimension_0 ();
1691  Kokkos::View<mag_type*, device_type> tmpNorms ("MV::norm1 tmp", numNorms);
1692  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1693  this->norm1 (tmpNorms);
1694  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
1695  // and T differ? We would need a test for this, but only the
1696  // Sacado and Stokhos packages are likely to care about this use
1697  // case. It could also come up with Kokkos::complex ->
1698  // std::complex conversion.
1699  Kokkos::deep_copy (norms, tmpNorms);
1700  }
1701 
1702 
1708  void norm1 (const Teuchos::ArrayView<mag_type>& norms) const;
1709 
1722  template <typename T>
1723  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1724  norm1 (const Teuchos::ArrayView<T>& norms) const
1725  {
1726  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1727  const size_type sz = norms.size ();
1728  Teuchos::Array<mag_type> theNorms (sz);
1729  this->norm1 (theNorms);
1730  for (size_type i = 0; i < sz; ++i) {
1731  // If T and mag_type differ, this does an implicit conversion.
1732  norms[i] = theNorms[i];
1733  }
1734  }
1735 
1748  void norm2 (const Kokkos::View<mag_type*, device_type>& norms) const;
1749 
1761  template<typename T>
1762  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1763  norm2 (const Kokkos::View<T*, device_type>& norms) const
1764  {
1765  const size_t numNorms = norms.dimension_0 ();
1766  Kokkos::View<mag_type*, device_type> theNorms ("MV::norm2 tmp", numNorms);
1767  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1768  this->norm2 (theNorms);
1769  // FIXME (mfh 14 Jul 2014) Does this actually work if mag_type
1770  // and T differ? We would need a test for this, but only the
1771  // Sacado and Stokhos packages are likely to care about this use
1772  // case. This could also come up with Kokkos::complex ->
1773  // std::complex conversion.
1774  Kokkos::deep_copy (norms, theNorms);
1775  }
1776 
1783  void norm2 (const Teuchos::ArrayView<mag_type>& norms) const;
1784 
1797  template <typename T>
1798  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1799  norm2 (const Teuchos::ArrayView<T>& norms) const
1800  {
1801  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1802  const size_type sz = norms.size ();
1803  Teuchos::Array<mag_type> theNorms (sz);
1804  this->norm2 (theNorms);
1805  for (size_type i = 0; i < sz; ++i) {
1806  // If T and mag_type differ, this does an implicit conversion.
1807  norms[i] = theNorms[i];
1808  }
1809  }
1810 
1817  void normInf (const Kokkos::View<mag_type*, device_type>& norms) const;
1818 
1830  template<typename T>
1831  typename std::enable_if< ! (std::is_same<mag_type, T>::value), void >::type
1832  normInf (const Kokkos::View<T*, device_type>& norms) const
1833  {
1834  const size_t numNorms = norms.dimension_0 ();
1835  Kokkos::View<mag_type*, device_type> theNorms ("MV::normInf tmp", numNorms);
1836  // Call overload that takes a Kokkos::View<mag_type*, device_type>.
1837  this->normInf (theNorms);
1838  // FIXME (mfh 15 Jul 2014) Does this actually work if mag_type
1839  // and T differ? We would need a test for this, but only the
1840  // Sacado and Stokhos packages are likely to care about this use
1841  // case. This could also come up with Kokkos::complex ->
1842  // std::complex conversion.
1843  Kokkos::deep_copy (norms, theNorms);
1844  }
1845 
1851  void normInf (const Teuchos::ArrayView<mag_type>& norms) const;
1852 
1865  template <typename T>
1866  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1867  normInf (const Teuchos::ArrayView<T>& norms) const
1868  {
1869  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1870  const size_type sz = norms.size ();
1871  Teuchos::Array<mag_type> theNorms (sz);
1872  this->norm2 (theNorms);
1873  for (size_type i = 0; i < sz; ++i) {
1874  // If T and mag_type differ, this does an implicit conversion.
1875  norms[i] = theNorms[i];
1876  }
1877  }
1878 
1885  void TPETRA_DEPRECATED
1887  const Teuchos::ArrayView<mag_type>& norms) const;
1888 
1905  template <typename T>
1906  typename std::enable_if< ! (std::is_same<mag_type,T>::value), void >::type
1907  TPETRA_DEPRECATED
1909  const Teuchos::ArrayView<T>& norms) const
1910  {
1911  typedef typename Teuchos::ArrayView<T>::size_type size_type;
1912  const size_type sz = norms.size ();
1913  Teuchos::Array<mag_type> theNorms (sz);
1914  this->normWeighted (weights, theNorms);
1915  for (size_type i = 0; i < sz; ++i) {
1916  // If T and mag_type differ, this does an implicit conversion.
1917  norms[i] = theNorms[i];
1918  }
1919  }
1920 
1925  void meanValue (const Teuchos::ArrayView<impl_scalar_type>& means) const;
1926 
1927  template <typename T>
1928  typename std::enable_if<! std::is_same<impl_scalar_type, T>::value, void>::type
1929  meanValue (const Teuchos::ArrayView<T>& means) const
1930  {
1931  typedef typename Teuchos::Array<T>::size_type size_type;
1932  const size_type numMeans = means.size ();
1933 
1934  Teuchos::Array<impl_scalar_type> theMeans (numMeans);
1935  this->meanValue (theMeans ());
1936  for (size_type k = 0; k < numMeans; ++k) {
1937  means[k] = static_cast<T> (theMeans[k]);
1938  }
1939  }
1940 
1946  void
1947  multiply (Teuchos::ETransp transA,
1948  Teuchos::ETransp transB,
1949  const Scalar& alpha,
1952  const Scalar& beta);
1953 
1974  void
1975  elementWiseMultiply (Scalar scalarAB,
1978  Scalar scalarThis);
1980 
1982 
1984  size_t getNumVectors() const;
1985 
1987  size_t getLocalLength() const;
1988 
1990  global_size_t getGlobalLength() const;
1991 
1997  size_t getStride() const;
1998 
2002  bool isConstantStride() const;
2003 
2005 
2007 
2008 
2010  virtual std::string description() const;
2011 
2040  virtual void
2041  describe (Teuchos::FancyOStream& out,
2042  const Teuchos::EVerbosityLevel verbLevel =
2043  Teuchos::Describable::verbLevel_default) const;
2045 
2059  virtual void
2060  removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
2061 
2072  void setCopyOrView (const Teuchos::DataAccess copyOrView) {
2073  TEUCHOS_TEST_FOR_EXCEPTION(
2074  copyOrView == Teuchos::Copy, std::invalid_argument,
2075  "Tpetra::MultiVector::setCopyOrView: The Kokkos refactor version of "
2076  "MultiVector _only_ implements view semantics. You may not call this "
2077  "method with copyOrView = Teuchos::Copy. The only valid argument is "
2078  "Teuchos::View.");
2079  }
2080 
2091  Teuchos::DataAccess getCopyOrView () const {
2092  return Teuchos::View;
2093  }
2094 
2109  void
2111 
2112  protected:
2113  template <class DS, class DL, class DG, class DN, const bool dstClassic,
2114  class SS, class SL, class SG, class SN, const bool srcClassic>
2115  friend void
2118 
2125  mutable dual_view_type view_;
2126 
2156  mutable dual_view_type origView_;
2157 
2170  Teuchos::Array<size_t> whichVectors_;
2171 
2173 
2174 
2176  enum EWhichNorm {
2177  NORM_ONE, //<! Use the one-norm
2178  NORM_TWO, //<! Use the two-norm
2179  NORM_INF //<! Use the infinity-norm
2180  };
2181 
2189  void
2190  normImpl (const Kokkos::View<mag_type*, device_type>& norms,
2191  const EWhichNorm whichNorm) const;
2192 
2194 
2196 
2203  std::string
2204  descriptionImpl (const std::string& className) const;
2205 
2212  std::string
2213  localDescribeToString (const Teuchos::EVerbosityLevel vl) const;
2214 
2228  void
2229  describeImpl (Teuchos::FancyOStream& out,
2230  const std::string& className,
2231  const Teuchos::EVerbosityLevel verbLevel =
2232  Teuchos::Describable::verbLevel_default) const;
2233 
2234  // Return true if and only if VectorIndex is a valid column index.
2235  bool vectorIndexOutOfRange (const size_t VectorIndex) const;
2236 
2241  template <class T>
2242  Teuchos::ArrayRCP<T>
2243  getSubArrayRCP (Teuchos::ArrayRCP<T> arr, size_t j) const;
2244 
2246  size_t getOrigNumLocalRows () const;
2247 
2249  size_t getOrigNumLocalCols () const;
2250 
2252 
2254 
2259  virtual bool
2260  checkSizes (const SrcDistObject& sourceObj);
2261 
2263  virtual size_t constantNumberOfPackets () const;
2264 
2266  virtual bool useNewInterface () { return true; }
2267 
2268  virtual void
2269  copyAndPermuteNew (const SrcDistObject& sourceObj,
2270  const size_t numSameIDs,
2271  const Kokkos::DualView<const local_ordinal_type*, device_type>& permuteToLIDs,
2272  const Kokkos::DualView<const local_ordinal_type*, device_type>& permuteFromLIDs);
2273 
2274  virtual void
2275  packAndPrepareNew (const SrcDistObject& sourceObj,
2276  const Kokkos::DualView<const local_ordinal_type*, device_type>& exportLIDs,
2277  Kokkos::DualView<impl_scalar_type*, device_type>& exports,
2278  const Kokkos::DualView<size_t*, device_type>& /* numPacketsPerLID */,
2279  size_t& constantNumPackets,
2280  Distributor& /* distor */);
2281 
2282  virtual void
2283  unpackAndCombineNew (const Kokkos::DualView<const LocalOrdinal*, device_type>& importLIDs,
2284  const Kokkos::DualView<const impl_scalar_type*, device_type>& imports,
2285  const Kokkos::DualView<const size_t*, device_type>& /* numPacketsPerLID */,
2286  const size_t constantNumPackets,
2287  Distributor& /* distor */,
2288  const CombineMode CM);
2290  }; // class MultiVector
2291 
2292  namespace Details {
2293 
2294  template<class DstMultiVectorType,
2295  class SrcMultiVectorType>
2296  Teuchos::RCP<typename MultiVectorCloner<DstMultiVectorType, SrcMultiVectorType>::dst_mv_type>
2297  MultiVectorCloner<DstMultiVectorType, SrcMultiVectorType>::
2298  clone (const src_mv_type& X,
2299  const Teuchos::RCP<typename dst_mv_type::node_type>& node2)
2300  {
2301  using Teuchos::RCP;
2302  typedef typename src_mv_type::map_type src_map_type;
2303  typedef typename dst_mv_type::map_type dst_map_type;
2304  typedef typename dst_mv_type::node_type dst_node_type;
2305  typedef typename dst_mv_type::dual_view_type dst_dual_view_type;
2306 
2307  // Clone X's Map to have the new Node type.
2308  RCP<const src_map_type> map1 = X.getMap ();
2309  RCP<const dst_map_type> map2 = map1.is_null () ?
2310  Teuchos::null : map1->template clone<dst_node_type> (node2);
2311 
2312  const size_t lclNumRows = X.getLocalLength ();
2313  const size_t numCols = X.getNumVectors ();
2314  dst_dual_view_type Y_view ("MV::dual_view", lclNumRows, numCols);
2315 
2316  RCP<dst_mv_type> Y (new dst_mv_type (map2, Y_view));
2317  // Let deep_copy do the work for us, to avoid code duplication.
2318  ::Tpetra::deep_copy (Y, X);
2319  return Y ;
2320  }
2321 
2322  } // namespace Details
2323 
2326  template <class ST, class LO, class GO, class NT, const bool classic>
2327  void
2330  {
2331  // NOTE (mfh 11 Sep 2014) We can't implement deep_copy with
2332  // shallow-copy operator=, because that would invalidate existing
2333  // views of dst!
2334  dst.assign (src);
2335  }
2336 
2337  // Implementation of the most generic version of MultiVector deep_copy.
2338  template <class DS, class DL, class DG, class DN, const bool dstClassic,
2339  class SS, class SL, class SG, class SN, const bool srcClassic>
2340  void
2343  {
2344  typedef typename DN::device_type DD;
2345  //typedef typename SN::device_type SD;
2346 
2347  TEUCHOS_TEST_FOR_EXCEPTION(
2348  dst.getGlobalLength () != src.getGlobalLength () ||
2349  dst.getNumVectors () != src.getNumVectors (), std::invalid_argument,
2350  "Tpetra::deep_copy: Global dimensions of the two Tpetra::MultiVector "
2351  "objects do not match. src has dimensions [" << src.getGlobalLength ()
2352  << "," << src.getNumVectors () << "], and dst has dimensions ["
2353  << dst.getGlobalLength () << "," << dst.getNumVectors () << "].");
2354 
2355  // FIXME (mfh 28 Jul 2014) Don't throw; just set a local error flag.
2356  TEUCHOS_TEST_FOR_EXCEPTION(
2357  dst.getLocalLength () != src.getLocalLength (), std::invalid_argument,
2358  "Tpetra::deep_copy: The local row counts of the two Tpetra::MultiVector "
2359  "objects do not match. src has " << src.getLocalLength () << " row(s) "
2360  << " and dst has " << dst.getLocalLength () << " row(s).");
2361 
2362  if (src.isConstantStride () && dst.isConstantStride ()) {
2365 
2366  // If we need sync to device, then host has the most recent version.
2367  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2368 
2369  if (! useHostVersion) {
2370  // Device memory has the most recent version of src.
2371  dst.template modify<DES> (); // We are about to modify dst on device.
2372  // Copy from src to dst on device.
2373  Details::localDeepCopyConstStride (dst.template getLocalView<DES> (),
2374  src.template getLocalView<typename SN::device_type> ());
2375  dst.template sync<HES> (); // Sync dst from device to host.
2376  }
2377  else { // Host memory has the most recent version of src.
2378  dst.template modify<HES> (); // We are about to modify dst on host.
2379  // Copy from src to dst on host.
2380  Details::localDeepCopyConstStride (dst.template getLocalView<Kokkos::HostSpace> (),
2381  src.template getLocalView<Kokkos::HostSpace> ());
2382  dst.template sync<DES> (); // Sync dst from host to device.
2383  }
2384  }
2385  else {
2386  typedef Kokkos::DualView<SL*, DD> whichvecs_type;
2387  typedef typename whichvecs_type::t_dev::execution_space DES;
2388  typedef typename whichvecs_type::t_host::execution_space HES;
2389 
2390  if (dst.isConstantStride ()) {
2391  const SL numWhichVecs = static_cast<SL> (src.whichVectors_.size ());
2392  const std::string whichVecsLabel ("MV::deep_copy::whichVecs");
2393 
2394  // We can't sync src, since it is only an input argument.
2395  // Thus, we have to use the most recently modified version of
2396  // src, which could be either the device or host version.
2397  //
2398  // If we need sync to device, then host has the most recent version.
2399  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2400 
2401  if (! useHostVersion) { // Copy from the device version of src.
2402  // whichVecs tells the kernel which vectors (columns) of src
2403  // to copy. Fill whichVecs on the host, and sync to device.
2404  whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2405  whichVecs.template modify<HES> ();
2406  for (SL i = 0; i < numWhichVecs; ++i) {
2407  whichVecs.h_view(i) = static_cast<SL> (src.whichVectors_[i]);
2408  }
2409  // Sync the host version of whichVecs to the device.
2410  whichVecs.template sync<DES> ();
2411 
2412  // Mark the device version of dst's DualView as modified.
2413  dst.template modify<DES> ();
2414  // Copy from the selected vectors of src to dst, on the device.
2415  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2416  src.template getLocalView<typename SN::device_type> (),
2417  dst.isConstantStride (),
2418  src.isConstantStride (),
2419  whichVecs.d_view,
2420  whichVecs.d_view);
2421  // Sync dst's DualView to the host. This is cheaper than
2422  // repeating the above copy from src to dst on the host.
2423  dst.template sync<HES> ();
2424  }
2425  else { // host version of src was the most recently modified
2426  // Copy from the host version of src.
2427  //
2428  // whichVecs tells the kernel which vectors (columns) of src
2429  // to copy. Fill whichVecs on the host, and use it there.
2430  typedef Kokkos::View<SL*, HES> the_whichvecs_type;
2431  the_whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2432  for (SL i = 0; i < numWhichVecs; ++i) {
2433  whichVecs(i) = static_cast<SL> (src.whichVectors_[i]);
2434  }
2435  // Copy from the selected vectors of src to dst, on the
2436  // host. The function ignores the first instance of
2437  // 'whichVecs' in this case.
2438  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2439  src.template getLocalView<Kokkos::HostSpace> (),
2440  dst.isConstantStride (),
2441  src.isConstantStride (),
2442  whichVecs, whichVecs);
2443  // Sync dst back to the device, since we only copied on the host.
2444  dst.template sync<DES> ();
2445  }
2446  }
2447  else { // dst is NOT constant stride
2448  if (src.isConstantStride ()) {
2449 
2450  // If we need sync to device, then host has the most recent version.
2451  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2452 
2453  if (! useHostVersion) { // Copy from the device version of src.
2454  // whichVecs tells the kernel which vectors (columns) of dst
2455  // to copy. Fill whichVecs on the host, and sync to device.
2456  typedef Kokkos::DualView<DL*, DES> the_whichvecs_type;
2457  const std::string whichVecsLabel ("MV::deep_copy::whichVecs");
2458  const DL numWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2459  the_whichvecs_type whichVecs (whichVecsLabel, numWhichVecs);
2460  whichVecs.template modify<HES> ();
2461  for (DL i = 0; i < numWhichVecs; ++i) {
2462  whichVecs.h_view(i) = dst.whichVectors_[i];
2463  }
2464  // Sync the host version of whichVecs to the device.
2465  whichVecs.template sync<DES> ();
2466 
2467  // Copy src to the selected vectors of dst, on the device.
2468  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2469  src.template getLocalView<typename SN::device_type> (),
2470  dst.isConstantStride (),
2471  src.isConstantStride (),
2472  whichVecs.d_view,
2473  whichVecs.d_view);
2474  // We can't sync src and repeat the above copy on the
2475  // host, so sync dst back to the host.
2476  //
2477  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2478  // don't actually belong to dst's view.
2479  dst.template sync<HES> ();
2480  }
2481  else { // host version of src was the most recently modified
2482  // Copy from the host version of src.
2483  //
2484  // whichVecs tells the kernel which vectors (columns) of src
2485  // to copy. Fill whichVecs on the host, and use it there.
2486  typedef Kokkos::View<DL*, HES> the_whichvecs_type;
2487  const DL numWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2488  the_whichvecs_type whichVecs ("MV::deep_copy::whichVecs", numWhichVecs);
2489  for (DL i = 0; i < numWhichVecs; ++i) {
2490  whichVecs(i) = static_cast<DL> (dst.whichVectors_[i]);
2491  }
2492  // Copy from src to the selected vectors of dst, on the host.
2493  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2494  src.template getLocalView<Kokkos::HostSpace> (),
2495  dst.isConstantStride (),
2496  src.isConstantStride (),
2497  whichVecs, whichVecs);
2498  // Sync dst back to the device, since we only copied on the host.
2499  //
2500  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2501  // don't actually belong to dst's view.
2502  dst.template sync<DES> ();
2503  }
2504  }
2505  else { // neither src nor dst have constant stride
2506 
2507  // If we need sync to device, then host has the most recent version.
2508  const bool useHostVersion = src.template need_sync<typename SN::device_type> ();
2509 
2510  if (! useHostVersion) { // Copy from the device version of src.
2511  // whichVectorsDst tells the kernel which columns of dst
2512  // to copy. Fill it on the host, and sync to device.
2513  const DL dstNumWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2514  Kokkos::DualView<DL*, DES> whichVecsDst ("MV::deep_copy::whichVecsDst",
2515  dstNumWhichVecs);
2516  whichVecsDst.template modify<HES> ();
2517  for (DL i = 0; i < dstNumWhichVecs; ++i) {
2518  whichVecsDst.h_view(i) = static_cast<DL> (dst.whichVectors_[i]);
2519  }
2520  // Sync the host version of whichVecsDst to the device.
2521  whichVecsDst.template sync<DES> ();
2522 
2523  // whichVectorsSrc tells the kernel which vectors
2524  // (columns) of src to copy. Fill it on the host, and
2525  // sync to device. Use the destination MultiVector's
2526  // LocalOrdinal type here.
2527  const DL srcNumWhichVecs = static_cast<DL> (src.whichVectors_.size ());
2528  Kokkos::DualView<DL*, DES> whichVecsSrc ("MV::deep_copy::whichVecsSrc",
2529  srcNumWhichVecs);
2530  whichVecsSrc.template modify<HES> ();
2531  for (DL i = 0; i < srcNumWhichVecs; ++i) {
2532  whichVecsSrc.h_view(i) = static_cast<DL> (src.whichVectors_[i]);
2533  }
2534  // Sync the host version of whichVecsSrc to the device.
2535  whichVecsSrc.template sync<DES> ();
2536 
2537  // Copy from the selected vectors of src to the selected
2538  // vectors of dst, on the device.
2539  Details::localDeepCopy (dst.template getLocalView<typename DN::device_type> (),
2540  src.template getLocalView<typename SN::device_type> (),
2541  dst.isConstantStride (),
2542  src.isConstantStride (),
2543  whichVecsDst.d_view,
2544  whichVecsSrc.d_view);
2545  }
2546  else {
2547  const DL dstNumWhichVecs = static_cast<DL> (dst.whichVectors_.size ());
2548  Kokkos::View<DL*, HES> whichVectorsDst ("dstWhichVecs", dstNumWhichVecs);
2549  for (DL i = 0; i < dstNumWhichVecs; ++i) {
2550  whichVectorsDst(i) = dst.whichVectors_[i];
2551  }
2552 
2553  // Use the destination MultiVector's LocalOrdinal type here.
2554  const DL srcNumWhichVecs = static_cast<DL> (src.whichVectors_.size ());
2555  Kokkos::View<DL*, HES> whichVectorsSrc ("srcWhichVecs", srcNumWhichVecs);
2556  for (DL i = 0; i < srcNumWhichVecs; ++i) {
2557  whichVectorsSrc(i) = src.whichVectors_[i];
2558  }
2559 
2560  // Copy from the selected vectors of src to the selected
2561  // vectors of dst, on the host.
2562  Details::localDeepCopy (dst.template getLocalView<Kokkos::HostSpace> (),
2563  src.template getLocalView<Kokkos::HostSpace> (),
2564  dst.isConstantStride (),
2565  src.isConstantStride (),
2566  whichVectorsDst, whichVectorsSrc);
2567  // We can't sync src and repeat the above copy on the
2568  // host, so sync dst back to the host.
2569  //
2570  // FIXME (mfh 29 Jul 2014) This may overwrite columns that
2571  // don't actually belong to dst's view.
2572  dst.template sync<HES> ();
2573  }
2574  }
2575  }
2576  }
2577  }
2578 } // namespace Tpetra
2579 
2580 
2581 namespace Teuchos {
2582 
2583  // Give Teuchos::TypeNameTraits<Tpetra::MultiVector<...> > a
2584  // human-readable definition.
2585  template<class SC, class LO, class GO, class NT, const bool classic>
2586  class TypeNameTraits<Tpetra::MultiVector<SC, LO, GO, NT, classic> > {
2587  public:
2588  static std::string name () {
2589  return std::string ("Tpetra::MultiVector<") +
2590  TypeNameTraits<SC>::name () + "," +
2591  TypeNameTraits<LO>::name () + "," +
2592  TypeNameTraits<GO>::name () + "," +
2593  TypeNameTraits<NT>::name () + ">";
2594  }
2595 
2596  static std::string
2597  concreteName (const Tpetra::MultiVector<SC, LO, GO, NT, classic>&) {
2598  return name ();
2599  }
2600  };
2601 } // namespace Teuchos
2602 
2603 #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.
Declarations for 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.
Describes a parallel distribution of objects 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.