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 
00352   template<class Scalar=double,
00353            class LocalOrdinal=int,
00354            class GlobalOrdinal=LocalOrdinal,
00355            class Node=KokkosClassic::DefaultNode::DefaultNodeType>
00356   class MultiVector :
00357 #if TPETRA_USE_KOKKOS_DISTOBJECT
00358     public DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node>
00359 #else
00360     public DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node>
00361 #endif
00362   {
00363   public:
00365 
00366 
00368     typedef Scalar scalar_type;
00370     typedef LocalOrdinal local_ordinal_type;
00372     typedef GlobalOrdinal global_ordinal_type;
00374     typedef Node node_type;
00376 
00380     typedef Scalar dot_type;
00381 
00382 #if TPETRA_USE_KOKKOS_DISTOBJECT
00383     typedef DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO;
00384     typedef typename DO::device_type device_type;
00385 #else
00386     typedef DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO;
00387 #endif
00388 
00390 
00391 
00392 
00394     MultiVector ();
00395 
00402     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00403                  size_t NumVectors,
00404                  bool zeroOut=true);
00405 
00411     MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &source);
00412 
00430     MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source,
00431                  const Teuchos::DataAccess copyOrView);
00432 
00448     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00449                  const Teuchos::ArrayView<const Scalar>& A,
00450                  size_t LDA,
00451                  size_t NumVectors);
00452 
00466     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00467                  const Teuchos::ArrayView<const Teuchos::ArrayView<const Scalar> >&ArrayOfPtrs,
00468                  size_t NumVectors);
00469 
00480     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
00481                  const Teuchos::ArrayRCP<Scalar>& data,
00482                  const size_t LDA,
00483                  const size_t numVectors);
00484 
00486     template <class Node2>
00487     Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> >
00488     clone(const Teuchos::RCP<Node2> &node2) const;
00489 
00491     virtual ~MultiVector();
00492 
00494 
00495 
00496 
00505     void
00506     replaceGlobalValue (GlobalOrdinal globalRow,
00507                         size_t vectorIndex,
00508                         const Scalar &value);
00509 
00518     void
00519     sumIntoGlobalValue (GlobalOrdinal globalRow,
00520                         size_t vectorIndex,
00521                         const Scalar &value);
00522 
00531     void
00532     replaceLocalValue (LocalOrdinal myRow,
00533                        size_t vectorIndex,
00534                        const Scalar &value);
00535 
00544     void
00545     sumIntoLocalValue (LocalOrdinal myRow,
00546                        size_t vectorIndex,
00547                        const Scalar &value);
00548 
00550     void putScalar (const Scalar &value);
00551 
00567     void randomize();
00568 
00634     void replaceMap (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map);
00635 
00642     void reduce();
00643 
00664     MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>&
00665     operator= (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source);
00666 
00668 
00683 
00684 
00689     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00690     subCopy (const Teuchos::Range1D &colRng) const;
00691 
00693     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00694     subCopy (const Teuchos::ArrayView<const size_t> &cols) const;
00695 
00700     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00701     subView (const Teuchos::Range1D &colRng) const;
00702 
00704     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00705     subView (const Teuchos::ArrayView<const size_t> &cols) const;
00706 
00711     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00712     subViewNonConst (const Teuchos::Range1D &colRng);
00713 
00715     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00716     subViewNonConst (const Teuchos::ArrayView<const size_t> &cols);
00717 
00780     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00781     offsetView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& subMap,
00782                 size_t offset) const;
00783 
00801     Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00802     offsetViewNonConst (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &subMap,
00803                         size_t offset);
00804 
00806     Teuchos::RCP<const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00807     getVector (size_t j) const;
00808 
00810     Teuchos::RCP<Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
00811     getVectorNonConst (size_t j);
00812 
00814     Teuchos::ArrayRCP<const Scalar> getData(size_t j) const;
00815 
00817     Teuchos::ArrayRCP<Scalar> getDataNonConst(size_t j);
00818 
00825     void get1dCopy (Teuchos::ArrayView<Scalar> A, size_t LDA) const;
00826 
00832     void get2dCopy (Teuchos::ArrayView<const Teuchos::ArrayView<Scalar> > ArrayOfPtrs) const;
00833 
00839     Teuchos::ArrayRCP<const Scalar> get1dView() const;
00840 
00842     Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > get2dView() const;
00843 
00849     Teuchos::ArrayRCP<Scalar> get1dViewNonConst();
00850 
00852     Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > get2dViewNonConst();
00853 
00858     KokkosClassic::MultiVector<Scalar,Node> getLocalMV () const;
00859 
00870     TEUCHOS_DEPRECATED
00871     KokkosClassic::MultiVector<Scalar,Node>& getLocalMVNonConst ();
00872 
00874 
00875 
00876 
00890     void
00891     dot (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00892          const Teuchos::ArrayView<Scalar>& dots) const;
00893 
00895     void abs(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A);
00896 
00898     void reciprocal(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A);
00899 
00907     void scale (const Scalar &alpha);
00908 
00917     void scale (Teuchos::ArrayView<const Scalar> alpha);
00918 
00927     void
00928     scale (const Scalar& alpha,
00929            const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A);
00930 
00937     void
00938     update (const Scalar& alpha,
00939             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00940             const Scalar& beta);
00941 
00948     void
00949     update (const Scalar& alpha,
00950             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00951             const Scalar& beta,
00952             const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
00953             const Scalar& gamma);
00954 
00960     void norm1(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const;
00961 
00968     void norm2(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const;
00969 
00975     void normInf (const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const;
00976 
00979     void
00980     normWeighted (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& weights,
00981                   const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const;
00982 
00985     void meanValue (const Teuchos::ArrayView<Scalar>& means) const;
00986 
00992     void
00993     multiply (Teuchos::ETransp transA,
00994               Teuchos::ETransp transB,
00995               const Scalar& alpha,
00996               const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
00997               const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
00998               const Scalar& beta);
00999 
01020     void
01021     elementWiseMultiply (Scalar scalarAB,
01022                          const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A,
01023                          const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B,
01024                          Scalar scalarThis);
01026 
01027 
01028 
01030     size_t getNumVectors() const;
01031 
01033     size_t getLocalLength() const;
01034 
01036     global_size_t getGlobalLength() const;
01037 
01043     size_t getStride() const;
01044 
01048     bool isConstantStride() const;
01049 
01051 
01053 
01054 
01056     virtual std::string description() const;
01057 
01086     virtual void
01087     describe (Teuchos::FancyOStream& out,
01088               const Teuchos::EVerbosityLevel verbLevel =
01089               Teuchos::Describable::verbLevel_default) const;
01091 
01105     virtual void
01106     removeEmptyProcessesInPlace (const Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >& newMap);
01107 
01113     void setCopyOrView (const Teuchos::DataAccess copyOrView) {
01114       hasViewSemantics_ = (copyOrView == Teuchos::View);
01115     }
01116 
01122     Teuchos::DataAccess getCopyOrView () const {
01123       return hasViewSemantics_ ? Teuchos::View : Teuchos::Copy;
01124     }
01125 
01126   protected:
01127     // template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01128     // friend MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
01129     // createCopy (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node >& src);
01130 
01131     typedef KokkosClassic::MultiVector<Scalar,Node> KMV;
01132     typedef KokkosClassic::DefaultArithmetic<KMV>   MVT;
01133 
01135     KMV lclMV_;
01136 
01149     Array<size_t> whichVectors_;
01150 
01162     bool hasViewSemantics_;
01163 
01165 
01166 
01167     // Implementation detail of the nonmember "constructor" function
01168     // createMultiVectorFromView.  Please consider this function
01169     // DEPRECATED.
01170     template <class MultiVectorType>
01171     friend struct Details::CreateMultiVectorFromView;
01172 
01184     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01185                  const Teuchos::ArrayRCP<Scalar>& view,
01186                  size_t LDA,
01187                  size_t NumVectors,
01188                  EPrivateHostViewConstructor /* dummy */);
01189 
01190     bool vectorIndexOutOfRange (size_t VectorIndex) const;
01191 
01197     template <class T>
01198     ArrayRCP<T> getSubArrayRCP(ArrayRCP<T> arr, size_t j) const;
01199 
01203     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01204                  Teuchos::ArrayRCP<Scalar> data,
01205                  size_t LDA,
01206                  Teuchos::ArrayView<const size_t> whichVectors,
01207                  EPrivateComputeViewConstructor /* dummy */);
01208 
01212     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01213                  Teuchos::ArrayRCP<Scalar> data,
01214                  size_t LDA,
01215                  size_t NumVectors,
01216                  EPrivateComputeViewConstructor /* dummy */);
01217 
01225     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01226                  const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector,
01227                  EPrivateComputeViewConstructor /* dummy */);
01228 
01236     MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01237                  const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector,
01238                  Teuchos::ArrayView<const size_t> whichVectors,
01239                  EPrivateComputeViewConstructor /* dummy */);
01240 
01242 
01243 
01244 
01249     virtual bool
01250     checkSizes (const SrcDistObject& sourceObj);
01251 
01253     virtual size_t constantNumberOfPackets () const;
01254 
01255 #if TPETRA_USE_KOKKOS_DISTOBJECT
01256     virtual void
01257     copyAndPermute (
01258       const SrcDistObject& sourceObj,
01259       size_t numSameIDs,
01260       const Kokkos::View<const LocalOrdinal*, device_type> &permuteToLIDs,
01261       const Kokkos::View<const LocalOrdinal*, device_type> &permuteFromLIDs);
01262 
01263     virtual void
01264     packAndPrepare (
01265       const SrcDistObject& sourceObj,
01266       const Kokkos::View<const LocalOrdinal*, device_type> &exportLIDs,
01267       Kokkos::View<Scalar*, device_type> &exports,
01268       const Kokkos::View<size_t*, device_type> &numPacketsPerLID,
01269       size_t& constantNumPackets,
01270       Distributor &distor);
01271 
01272     virtual void
01273     unpackAndCombine (
01274       const Kokkos::View<const LocalOrdinal*, device_type> &importLIDs,
01275       const Kokkos::View<const Scalar*, device_type> &imports,
01276       const Kokkos::View<size_t*, device_type> &numPacketsPerLID,
01277       size_t constantNumPackets,
01278       Distributor &distor,
01279       CombineMode CM);
01280 #else
01281     virtual void
01282     copyAndPermute (const SrcDistObject& sourceObj,
01283                     size_t numSameIDs,
01284                     const ArrayView<const LocalOrdinal>& permuteToLIDs,
01285                     const ArrayView<const LocalOrdinal>& permuteFromLIDs);
01286 
01287     virtual void
01288     packAndPrepare (const SrcDistObject& sourceObj,
01289                     const ArrayView<const LocalOrdinal>& exportLIDs,
01290                     Array<Scalar>& exports,
01291                     const ArrayView<size_t>& numExportPacketsPerLID,
01292                     size_t& constantNumPackets,
01293                     Distributor& distor);
01294 
01295     virtual void
01296     unpackAndCombine (const ArrayView<const LocalOrdinal>& importLIDs,
01297                       const ArrayView<const Scalar>& imports,
01298                       const ArrayView<size_t>& numPacketsPerLID,
01299                       size_t constantNumPackets,
01300                       Distributor& distor,
01301                       CombineMode CM);
01302 #endif
01303 
01304     void createViews () const;
01305     void createViewsNonConst (KokkosClassic::ReadWriteOption rwo);
01306     void releaseViews () const;
01307 
01309     mutable ArrayRCP<Scalar> ncview_;
01310 
01312     mutable ArrayRCP<const Scalar> cview_;
01313 
01315 
01316 #if TPETRA_USE_KOKKOS_DISTOBJECT
01317 
01318     Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged>
01319     getKokkosView() const {
01320       Teuchos::ArrayRCP<const Scalar> buff = MVT::getValues (lclMV_);
01321       Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> v(
01322         buff.getRawPtr(), buff.size());
01323       return v;
01324     }
01325     Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged>
01326     getKokkosViewNonConst() {
01327       Teuchos::ArrayRCP<Scalar> buff = MVT::getValuesNonConst (lclMV_);
01328       Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> v(
01329         buff.getRawPtr(), buff.size());
01330       return v;
01331     }
01332 
01333 #endif
01334   };
01335 
01336 
01356   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01357   MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>
01358   createCopy (const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& src);
01359 
01360 
01381   template <class DS, class DL, class DG, class DN,
01382             class SS, class SL, class SG, class SN>
01383   void
01384   deep_copy (MultiVector<DS,DL,DG,DN>& dst,
01385              const MultiVector<SS,SL,SG,SN>& src);
01386 
01387   namespace Details {
01413     template<class DstMultiVecType, class SrcMultiVecType>
01414     struct MultiVectorCloner {
01415       typedef DstMultiVecType dst_mv_type;
01416       typedef SrcMultiVecType src_mv_type;
01417 
01418       static Teuchos::RCP<dst_mv_type>
01419       clone (const src_mv_type& X,
01420              const Teuchos::RCP<typename dst_mv_type::node_type>& node2);
01421     };
01422 
01423     // Partial specialization of MultiVectorCloner for when the source
01424     // and destination MultiVector types have the same Scalar type,
01425     // but all their other template parameters might be different.
01426     template<class ScalarType,
01427              class DstLocalOrdinalType, class DstGlobalOrdinalType, class DstNodeType,
01428              class SrcLocalOrdinalType, class SrcGlobalOrdinalType, class SrcNodeType>
01429     struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType>,
01430                               ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> >
01431     {
01432       typedef ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType> dst_mv_type;
01433       typedef ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> src_mv_type;
01434 
01435       static Teuchos::RCP<dst_mv_type>
01436       clone (const src_mv_type& X,
01437              const Teuchos::RCP<typename src_mv_type::node_type>& node2)
01438       {
01439         using Teuchos::ArrayRCP;
01440         using Teuchos::RCP;
01441         using Teuchos::rcp;
01442         typedef typename src_mv_type::map_type src_map_type;
01443         typedef typename dst_mv_type::map_type dst_map_type;
01444         typedef typename dst_mv_type::node_type dst_node_type;
01445 
01446         // Clone X's Map to have the new Node type.
01447         RCP<const src_map_type> map1 = X.getMap ();
01448         RCP<const dst_map_type> map2 = map1.is_null () ?
01449           Teuchos::null : map1->template clone<dst_node_type> (node2);
01450 
01451         const size_t lclNumRows = X.getLocalLength ();
01452         const size_t numCols = X.getNumVectors ();
01453         const size_t LDA = lclNumRows;
01454 
01455         // Get a host deep copy of X's data.
01456         ArrayRCP<ScalarType> data1 (LDA * numCols);
01457         X.get1dCopy (data1 (), LDA);
01458 
01459         // Create the destination MultiVector.  This might do another
01460         // deep copy; I'm not really worried about that.  clone()
01461         // doesn't have to be super fast; it just can't be too slow.
01462         return rcp (new dst_mv_type (map2, data1 (), LDA, numCols));
01463       }
01464     };
01465 
01466     // Partial specialization of MultiVectorCloner for when the source
01467     // and destination MultiVector types are the same.
01468     template<class ScalarType, class LocalOrdinalType, class GlobalOrdinalType, class NodeType>
01469     struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType>,
01470                               ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> >
01471     {
01472       typedef ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> dst_mv_type;
01473       typedef dst_mv_type src_mv_type;
01474 
01475       static Teuchos::RCP<dst_mv_type>
01476       clone (const src_mv_type& X, const Teuchos::RCP<NodeType>& )
01477       {
01478         // Create a deep copy.
01479         RCP<dst_mv_type> X_clone = rcp (new dst_mv_type (X, Teuchos::Copy));
01480         // Set the cloned MultiVector to have the same copy-or-view
01481         // semantics as the input MultiVector X.
01482         X_clone->setCopyOrView (X.getCopyOrView ());
01483 
01484         return X_clone;
01485       }
01486     };
01487 
01488     template<class MultiVectorType>
01489     Teuchos::RCP<MultiVectorType>
01490     CreateMultiVectorFromView<MultiVectorType>::
01491     create (const Teuchos::RCP<const map_type>& map,
01492             const Teuchos::ArrayRCP<scalar_type>& view,
01493             const size_t LDA,
01494             const size_t numVectors)
01495     {
01496       using Teuchos::rcp;
01497       typedef Tpetra::details::ViewAccepter<node_type> VAN;
01498 
01499       // This uses a protected MultiVector constructor, but this
01500       // nonmember function was declared a friend of MultiVector.
01501       //
01502       // The ViewAccepter expression will fail to compile for
01503       // unsupported Kokkos Node types.
01504       return rcp (new MultiVectorType (map, VAN::template acceptView<scalar_type> (view),
01505                                        LDA, numVectors, HOST_VIEW_CONSTRUCTOR));
01506     }
01507   } // namespace Details
01508 
01509 
01510   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01511   template <class Node2>
01512   Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> >
01513   MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
01514   clone (const Teuchos::RCP<Node2>& node2) const
01515   {
01516     typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> dst_mv_type;
01517     typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> src_mv_type;
01518     typedef Details::MultiVectorCloner<dst_mv_type, src_mv_type> cloner_type;
01519     return cloner_type::clone (*this, node2);
01520   }
01521 
01522 
01531   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01532   Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
01533   createMultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01534                      const size_t numVectors)
01535   {
01536     using Teuchos::rcp;
01537     typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
01538 
01539     const bool initToZero = true;
01540     return rcp (new MV (map, numVectors, initToZero));
01541   }
01542 
01543 } // namespace Tpetra
01544 
01545 // Include KokkosRefactor partial specialization if enabled
01546 #if defined(TPETRA_HAVE_KOKKOS_REFACTOR)
01547 #include "Tpetra_KokkosRefactor_MultiVector_decl.hpp"
01548 #endif
01549 
01550 // Define createMultiVectorFromView after the above include, so that
01551 // the function can pick up the partial specialization of
01552 // CreateMultiVectorFromView.
01553 
01554 namespace Tpetra {
01555 
01581   template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
01582   Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
01583   createMultiVectorFromView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map,
01584                              const Teuchos::ArrayRCP<Scalar>& view,
01585                              const size_t LDA,
01586                              const size_t numVectors)
01587   {
01588     typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> mv_type;
01589     typedef Details::CreateMultiVectorFromView<mv_type> impl_type;
01590     return impl_type::create (map, view, LDA, numVectors);
01591   }
01592 
01593 } // namespace Tpetra
01594 
01595 #endif // TPETRA_MULTIVECTOR_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines