Tpetra Matrix/Vector Services Version of the Day
Tpetra_MultiVector_decl.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 
00042 #ifndef TPETRA_MULTIVECTOR_DECL_HPP
00043 #define TPETRA_MULTIVECTOR_DECL_HPP
00044 
00045 #include <Teuchos_DataAccess.hpp>
00046 #include <Teuchos_Range1D.hpp>
00047 #include "Tpetra_ConfigDefs.hpp"
00048 #if TPETRA_USE_KOKKOS_DISTOBJECT
00049 #include "Tpetra_DistObjectKA.hpp"
00050 #else
00051 #include "Tpetra_DistObject.hpp"
00052 #endif
00053 #include "Tpetra_ViewAccepter.hpp"
00054 #include <Kokkos_MultiVector.hpp>
00055 #include <Teuchos_BLAS_types.hpp>
00056 
00057 namespace KokkosClassic {
00058 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00059   // forward declaration of DefaultArithmetic
00060   template<class KokkosMultiVectorType>
00061   class DefaultArithmetic;
00062 #endif // DOXYGEN_SHOULD_SKIP_THIS
00063 } // namespace KokkosClassic
00064 
00065 namespace Tpetra {
00066 
00067 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00068   // forward declaration of Vector, needed to prevent circular inclusions
00069   template<class S, class LO, class GO, class N> class Vector;
00070 
00071   // forward declaration of Map
00072   template<class LO, class GO, class N> class Map;
00073 #endif // DOXYGEN_SHOULD_SKIP_THIS
00074 
00075 
00076   namespace Details {
00085     template<class MultiVectorType>
00086     struct CreateMultiVectorFromView {
00087       typedef typename MultiVectorType::scalar_type scalar_type;
00088       typedef typename MultiVectorType::local_ordinal_type local_ordinal_type;
00089       typedef typename MultiVectorType::global_ordinal_type global_ordinal_type;
00090       typedef typename MultiVectorType::node_type node_type;
00091       typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type;
00092 
00093       static Teuchos::RCP<MultiVectorType>
00094       create (const Teuchos::RCP<const map_type>& map,
00095               const Teuchos::ArrayRCP<scalar_type>& view,
00096               const size_t LDA,
00097               const size_t numVectors);
00098     };
00099   } // namespace Details
00100 
00101 
00331   template<class Scalar=double,
00332            class LocalOrdinal=int,
00333            class GlobalOrdinal=LocalOrdinal,
00334            class Node=KokkosClassic::DefaultNode::DefaultNodeType>
00335   class MultiVector :
00336 #if TPETRA_USE_KOKKOS_DISTOBJECT
00337     public DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node>
00338 #else
00339     public DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node>
00340 #endif
00341   {
00342   public:
00344 
00345 
00347     typedef Scalar scalar_type;
00349     typedef LocalOrdinal local_ordinal_type;
00351     typedef GlobalOrdinal global_ordinal_type;
00353     typedef Node node_type;
00355 
00359     typedef Scalar dot_type;
00360 
00361 #if TPETRA_USE_KOKKOS_DISTOBJECT
00362     typedef DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO;
00363     typedef typename DO::device_type device_type;
00364 #else
00365     typedef DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO;
00366 #endif
00367 
00369 
00370 
00371 
00373     MultiVector ();
00374 
00381     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00382                  size_t NumVectors,
00383                  bool zeroOut=true);
00384 
00390     MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &source);
00391 
00409     MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source,
00410                  const Teuchos::DataAccess copyOrView);
00411 
00427     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00428                  const Teuchos::ArrayView<const Scalar>& A,
00429                  size_t LDA,
00430                  size_t NumVectors);
00431 
00445     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00446                  const Teuchos::ArrayView<const Teuchos::ArrayView<const Scalar> >&ArrayOfPtrs,
00447                  size_t NumVectors);
00448 
00459     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00460                  const Teuchos::ArrayRCP<Scalar>& data,
00461                  const size_t LDA,
00462                  const size_t numVectors);
00463 
00465     template <class Node2>
00466     Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> >
00467     clone(const Teuchos::RCP<Node2> &node2) const;
00468 
00470     virtual ~MultiVector();
00471 
00473 
00474 
00475 
00484     void
00485     replaceGlobalValue (GlobalOrdinal globalRow,
00486                         size_t vectorIndex,
00487                         const Scalar &value);
00488 
00497     void
00498     sumIntoGlobalValue (GlobalOrdinal globalRow,
00499                         size_t vectorIndex,
00500                         const Scalar &value);
00501 
00510     void
00511     replaceLocalValue (LocalOrdinal myRow,
00512                        size_t vectorIndex,
00513                        const Scalar &value);
00514 
00523     void
00524     sumIntoLocalValue (LocalOrdinal myRow,
00525                        size_t vectorIndex,
00526                        const Scalar &value);
00527 
00529     void putScalar (const Scalar &value);
00530 
00546     void randomize();
00547 
00613     void replaceMap (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map);
00614 
00621     void reduce();
00622 
00643     MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>&
00644     operator= (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source);
00645 
00647 
00662 
00663 
00668     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00669     subCopy (const Teuchos::Range1D &colRng) const;
00670 
00672     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00673     subCopy (const Teuchos::ArrayView<const size_t> &cols) const;
00674 
00679     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00680     subView (const Teuchos::Range1D &colRng) const;
00681 
00683     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00684     subView (const Teuchos::ArrayView<const size_t> &cols) const;
00685 
00690     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00691     subViewNonConst (const Teuchos::Range1D &colRng);
00692 
00694     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00695     subViewNonConst (const Teuchos::ArrayView<const size_t> &cols);
00696 
00759     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00760     offsetView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& subMap,
00761                 size_t offset) const;
00762 
00780     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00781     offsetViewNonConst (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &subMap,
00782                         size_t offset);
00783 
00785     Teuchos::RCP<const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00786     getVector (size_t j) const;
00787 
00789     Teuchos::RCP<Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00790     getVectorNonConst (size_t j);
00791 
00793     Teuchos::ArrayRCP<const Scalar> getData(size_t j) const;
00794 
00796     Teuchos::ArrayRCP<Scalar> getDataNonConst(size_t j);
00797 
00804     void get1dCopy (Teuchos::ArrayView<Scalar> A, size_t LDA) const;
00805 
00811     void get2dCopy (Teuchos::ArrayView<const Teuchos::ArrayView<Scalar> > ArrayOfPtrs) const;
00812 
00818     Teuchos::ArrayRCP<const Scalar> get1dView() const;
00819 
00821     Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > get2dView() const;
00822 
00828     Teuchos::ArrayRCP<Scalar> get1dViewNonConst();
00829 
00831     Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > get2dViewNonConst();
00832 
00837     KokkosClassic::MultiVector<Scalar,Node> getLocalMV () const;
00838 
00849     TEUCHOS_DEPRECATED
00850     KokkosClassic::MultiVector<Scalar,Node>& getLocalMVNonConst ();
00851 
00853 
00854 
00855 
00869     void
00870     dot (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00871          const Teuchos::ArrayView<Scalar>& dots) const;
00872 
00874     void abs(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A);
00875 
00877     void reciprocal(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A);
00878 
00886     void scale (const Scalar &alpha);
00887 
00896     void scale (Teuchos::ArrayView<const Scalar> alpha);
00897 
00906     void
00907     scale (const Scalar& alpha,
00908            const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A);
00909 
00916     void
00917     update (const Scalar& alpha,
00918             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00919             const Scalar& beta);
00920 
00927     void
00928     update (const Scalar& alpha,
00929             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00930             const Scalar& beta,
00931             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
00932             const Scalar& gamma);
00933 
00939     void norm1(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const;
00940 
00947     void norm2(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const;
00948 
00954     void normInf (const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const;
00955 
00958     void
00959     normWeighted (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& weights,
00960                   const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const;
00961 
00964     void meanValue (const Teuchos::ArrayView<Scalar>& means) const;
00965 
00971     void
00972     multiply (Teuchos::ETransp transA,
00973               Teuchos::ETransp transB,
00974               const Scalar& alpha,
00975               const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00976               const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
00977               const Scalar& beta);
00978 
00999     void
01000     elementWiseMultiply (Scalar scalarAB,
01001                          const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
01002                          const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
01003                          Scalar scalarThis);
01005 
01006 
01007 
01009     size_t getNumVectors() const;
01010 
01012     size_t getLocalLength() const;
01013 
01015     global_size_t getGlobalLength() const;
01016 
01022     size_t getStride() const;
01023 
01027     bool isConstantStride() const;
01028 
01030 
01032 
01033 
01035     virtual std::string description() const;
01036 
01065     virtual void
01066     describe (Teuchos::FancyOStream& out,
01067               const Teuchos::EVerbosityLevel verbLevel =
01068               Teuchos::Describable::verbLevel_default) const;
01070 
01084     virtual void
01085     removeEmptyProcessesInPlace (const Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >& newMap);
01086 
01092     void setCopyOrView (const Teuchos::DataAccess copyOrView) {
01093       hasViewSemantics_ = (copyOrView == Teuchos::View);
01094     }
01095 
01101     Teuchos::DataAccess getCopyOrView () const {
01102       return hasViewSemantics_ ? Teuchos::View : Teuchos::Copy;
01103     }
01104 
01105   protected:
01106     // template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01107     // friend MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
01108     // createCopy (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node >& src);
01109 
01110     typedef KokkosClassic::MultiVector<Scalar,Node> KMV;
01111     typedef KokkosClassic::DefaultArithmetic<KMV>   MVT;
01112 
01114     KMV lclMV_;
01115 
01128     Array<size_t> whichVectors_;
01129 
01141     bool hasViewSemantics_;
01142 
01144 
01145 
01146     // Implementation detail of the nonmember "constructor" function
01147     // createMultiVectorFromView.  Please consider this function
01148     // DEPRECATED.
01149     template <class MultiVectorType>
01150     friend struct Details::CreateMultiVectorFromView;
01151 
01163     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01164                  const Teuchos::ArrayRCP<Scalar>& view,
01165                  size_t LDA,
01166                  size_t NumVectors,
01167                  EPrivateHostViewConstructor /* dummy */);
01168 
01169     bool vectorIndexOutOfRange (size_t VectorIndex) const;
01170 
01176     template <class T>
01177     ArrayRCP<T> getSubArrayRCP(ArrayRCP<T> arr, size_t j) const;
01178 
01182     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01183                  Teuchos::ArrayRCP<Scalar> data,
01184                  size_t LDA,
01185                  Teuchos::ArrayView<const size_t> whichVectors,
01186                  EPrivateComputeViewConstructor /* dummy */);
01187 
01191     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01192                  Teuchos::ArrayRCP<Scalar> data,
01193                  size_t LDA,
01194                  size_t NumVectors,
01195                  EPrivateComputeViewConstructor /* dummy */);
01196 
01204     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01205                  const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector,
01206                  EPrivateComputeViewConstructor /* dummy */);
01207 
01215     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01216                  const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector,
01217                  Teuchos::ArrayView<const size_t> whichVectors,
01218                  EPrivateComputeViewConstructor /* dummy */);
01219 
01221 
01222 
01223 
01228     virtual bool
01229     checkSizes (const SrcDistObject& sourceObj);
01230 
01232     virtual size_t constantNumberOfPackets () const;
01233 
01234 #if TPETRA_USE_KOKKOS_DISTOBJECT
01235     virtual void
01236     copyAndPermute (
01237       const SrcDistObject& sourceObj,
01238       size_t numSameIDs,
01239       const Kokkos::View<const LocalOrdinal*, device_type> &permuteToLIDs,
01240       const Kokkos::View<const LocalOrdinal*, device_type> &permuteFromLIDs);
01241 
01242     virtual void
01243     packAndPrepare (
01244       const SrcDistObject& sourceObj,
01245       const Kokkos::View<const LocalOrdinal*, device_type> &exportLIDs,
01246       Kokkos::View<Scalar*, device_type> &exports,
01247       const Kokkos::View<size_t*, device_type> &numPacketsPerLID,
01248       size_t& constantNumPackets,
01249       Distributor &distor);
01250 
01251     virtual void
01252     unpackAndCombine (
01253       const Kokkos::View<const LocalOrdinal*, device_type> &importLIDs,
01254       const Kokkos::View<const Scalar*, device_type> &imports,
01255       const Kokkos::View<size_t*, device_type> &numPacketsPerLID,
01256       size_t constantNumPackets,
01257       Distributor &distor,
01258       CombineMode CM);
01259 #else
01260     virtual void
01261     copyAndPermute (const SrcDistObject& sourceObj,
01262                     size_t numSameIDs,
01263                     const ArrayView<const LocalOrdinal>& permuteToLIDs,
01264                     const ArrayView<const LocalOrdinal>& permuteFromLIDs);
01265 
01266     virtual void
01267     packAndPrepare (const SrcDistObject& sourceObj,
01268                     const ArrayView<const LocalOrdinal>& exportLIDs,
01269                     Array<Scalar>& exports,
01270                     const ArrayView<size_t>& numExportPacketsPerLID,
01271                     size_t& constantNumPackets,
01272                     Distributor& distor);
01273 
01274     virtual void
01275     unpackAndCombine (const ArrayView<const LocalOrdinal>& importLIDs,
01276                       const ArrayView<const Scalar>& imports,
01277                       const ArrayView<size_t>& numPacketsPerLID,
01278                       size_t constantNumPackets,
01279                       Distributor& distor,
01280                       CombineMode CM);
01281 #endif
01282 
01283     void createViews () const;
01284     void createViewsNonConst (KokkosClassic::ReadWriteOption rwo);
01285     void releaseViews () const;
01286 
01288     mutable ArrayRCP<Scalar> ncview_;
01289 
01291     mutable ArrayRCP<const Scalar> cview_;
01292 
01294 
01295 #if TPETRA_USE_KOKKOS_DISTOBJECT
01296 
01297     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged>
01298     getKokkosView() const {
01299       Teuchos::ArrayRCP<const Scalar> buff = MVT::getValues (lclMV_);
01300       Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> v(
01301         buff.getRawPtr(), buff.size());
01302       return v;
01303     }
01304     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged>
01305     getKokkosViewNonConst() {
01306       Teuchos::ArrayRCP<Scalar> buff = MVT::getValuesNonConst (lclMV_);
01307       Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> v(
01308         buff.getRawPtr(), buff.size());
01309       return v;
01310     }
01311 
01312 #endif
01313   };
01314 
01315 
01335   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01336   MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>
01337   createCopy (const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& src);
01338 
01339 
01360   template <class DS, class DL, class DG, class DN,
01361             class SS, class SL, class SG, class SN>
01362   void
01363   deep_copy (MultiVector<DS,DL,DG,DN>& dst,
01364              const MultiVector<SS,SL,SG,SN>& src);
01365 
01366   namespace Details {
01392     template<class DstMultiVecType, class SrcMultiVecType>
01393     struct MultiVectorCloner {
01394       typedef DstMultiVecType dst_mv_type;
01395       typedef SrcMultiVecType src_mv_type;
01396 
01397       static Teuchos::RCP<dst_mv_type>
01398       clone (const src_mv_type& X,
01399              const Teuchos::RCP<typename dst_mv_type::node_type>& node2);
01400     };
01401 
01402     // Partial specialization of MultiVectorCloner for when the source
01403     // and destination MultiVector types have the same Scalar type,
01404     // but all their other template parameters might be different.
01405     template<class ScalarType,
01406              class DstLocalOrdinalType, class DstGlobalOrdinalType, class DstNodeType,
01407              class SrcLocalOrdinalType, class SrcGlobalOrdinalType, class SrcNodeType>
01408     struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType>,
01409                               ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> >
01410     {
01411       typedef ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType> dst_mv_type;
01412       typedef ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> src_mv_type;
01413 
01414       static Teuchos::RCP<dst_mv_type>
01415       clone (const src_mv_type& X,
01416              const Teuchos::RCP<typename src_mv_type::node_type>& node2)
01417       {
01418         using Teuchos::ArrayRCP;
01419         using Teuchos::RCP;
01420         using Teuchos::rcp;
01421         typedef typename src_mv_type::map_type src_map_type;
01422         typedef typename dst_mv_type::map_type dst_map_type;
01423         typedef typename dst_mv_type::node_type dst_node_type;
01424 
01425         // Clone X's Map to have the new Node type.
01426         RCP<const src_map_type> map1 = X.getMap ();
01427         RCP<const dst_map_type> map2 = map1.is_null () ?
01428           Teuchos::null : map1->template clone<dst_node_type> (node2);
01429 
01430         const size_t lclNumRows = X.getLocalLength ();
01431         const size_t numCols = X.getNumVectors ();
01432         const size_t LDA = lclNumRows;
01433 
01434         // Get a host deep copy of X's data.
01435         ArrayRCP<ScalarType> data1 (LDA * numCols);
01436         X.get1dCopy (data1 (), LDA);
01437 
01438         // Create the destination MultiVector.  This might do another
01439         // deep copy; I'm not really worried about that.  clone()
01440         // doesn't have to be super fast; it just can't be too slow.
01441         return rcp (new dst_mv_type (map2, data1 (), LDA, numCols));
01442       }
01443     };
01444 
01445     // Partial specialization of MultiVectorCloner for when the source
01446     // and destination MultiVector types are the same.
01447     template<class ScalarType, class LocalOrdinalType, class GlobalOrdinalType, class NodeType>
01448     struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType>,
01449                               ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> >
01450     {
01451       typedef ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> dst_mv_type;
01452       typedef dst_mv_type src_mv_type;
01453 
01454       static Teuchos::RCP<dst_mv_type>
01455       clone (const src_mv_type& X, const Teuchos::RCP<NodeType>& )
01456       {
01457         // Create a deep copy.
01458         RCP<dst_mv_type> X_clone = rcp (new dst_mv_type (X, Teuchos::Copy));
01459         // Set the cloned MultiVector to have the same copy-or-view
01460         // semantics as the input MultiVector X.
01461         X_clone->setCopyOrView (X.getCopyOrView ());
01462 
01463         return X_clone;
01464       }
01465     };
01466 
01467     template<class MultiVectorType>
01468     Teuchos::RCP<MultiVectorType>
01469     CreateMultiVectorFromView<MultiVectorType>::
01470     create (const Teuchos::RCP<const map_type>& map,
01471             const Teuchos::ArrayRCP<scalar_type>& view,
01472             const size_t LDA,
01473             const size_t numVectors)
01474     {
01475       using Teuchos::rcp;
01476       typedef Tpetra::details::ViewAccepter<node_type> VAN;
01477 
01478       // This uses a protected MultiVector constructor, but this
01479       // nonmember function was declared a friend of MultiVector.
01480       //
01481       // The ViewAccepter expression will fail to compile for
01482       // unsupported Kokkos Node types.
01483       return rcp (new MultiVectorType (map, VAN::template acceptView<scalar_type> (view),
01484                                        LDA, numVectors, HOST_VIEW_CONSTRUCTOR));
01485     }
01486   } // namespace Details
01487 
01488 
01489   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01490   template <class Node2>
01491   Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> >
01492   MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
01493   clone (const Teuchos::RCP<Node2>& node2) const
01494   {
01495     typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> dst_mv_type;
01496     typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> src_mv_type;
01497     typedef Details::MultiVectorCloner<dst_mv_type, src_mv_type> cloner_type;
01498     return cloner_type::clone (*this, node2);
01499   }
01500 
01501 
01510   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01511   Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
01512   createMultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01513                      const size_t numVectors)
01514   {
01515     using Teuchos::rcp;
01516     typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
01517 
01518     const bool initToZero = true;
01519     return rcp (new MV (map, numVectors, initToZero));
01520   }
01521 
01522 } // namespace Tpetra
01523 
01524 // Include KokkosRefactor partial specialization if enabled
01525 #if defined(TPETRA_HAVE_KOKKOS_REFACTOR)
01526 #include "Tpetra_KokkosRefactor_MultiVector_decl.hpp"
01527 #endif
01528 
01529 // Define createMultiVectorFromView after the above include, so that
01530 // the function can pick up the partial specialization of
01531 // CreateMultiVectorFromView.
01532 
01533 namespace Tpetra {
01534 
01560   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01561   Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
01562   createMultiVectorFromView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01563                              const Teuchos::ArrayRCP<Scalar>& view,
01564                              const size_t LDA,
01565                              const size_t numVectors)
01566   {
01567     typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> mv_type;
01568     typedef Details::CreateMultiVectorFromView<mv_type> impl_type;
01569     return impl_type::create (map, view, LDA, numVectors);
01570   }
01571 
01572 } // namespace Tpetra
01573 
01574 #endif // TPETRA_MULTIVECTOR_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines