|
Tpetra Matrix/Vector Services
Version of the Day
|
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 #include <Tpetra_Map_decl.hpp> 00049 #if TPETRA_USE_KOKKOS_DISTOBJECT 00050 #include "Tpetra_DistObjectKA.hpp" 00051 #else 00052 #include "Tpetra_DistObject.hpp" 00053 #endif 00054 #include "Tpetra_ViewAccepter.hpp" 00055 #include <Kokkos_MultiVector.hpp> 00056 #include <Teuchos_BLAS_types.hpp> 00057 00058 namespace KokkosClassic { 00059 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00060 // forward declaration of DefaultArithmetic 00061 template<class KokkosMultiVectorType> 00062 class DefaultArithmetic; 00063 #endif // DOXYGEN_SHOULD_SKIP_THIS 00064 } // namespace KokkosClassic 00065 00066 namespace Tpetra { 00067 00068 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00069 // forward declaration of Vector, needed to prevent circular inclusions 00070 template<class S, class LO, class GO, class N> class Vector; 00071 #endif // DOXYGEN_SHOULD_SKIP_THIS 00072 00073 00074 namespace Details { 00083 template<class MultiVectorType> 00084 struct CreateMultiVectorFromView { 00085 typedef typename MultiVectorType::scalar_type scalar_type; 00086 typedef typename MultiVectorType::local_ordinal_type local_ordinal_type; 00087 typedef typename MultiVectorType::global_ordinal_type global_ordinal_type; 00088 typedef typename MultiVectorType::node_type node_type; 00089 typedef ::Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type> map_type; 00090 00091 static Teuchos::RCP<MultiVectorType> 00092 create (const Teuchos::RCP<const map_type>& map, 00093 const Teuchos::ArrayRCP<scalar_type>& view, 00094 const size_t LDA, 00095 const size_t numVectors); 00096 }; 00097 } // namespace Details 00098 00099 00329 template<class Scalar = double, 00330 class LocalOrdinal = Map<>::local_ordinal_type, 00331 class GlobalOrdinal = typename Map<LocalOrdinal>::global_ordinal_type, 00332 class Node = typename Map<LocalOrdinal, GlobalOrdinal>::node_type> 00333 class MultiVector : 00334 #if TPETRA_USE_KOKKOS_DISTOBJECT 00335 public DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node> 00336 #else 00337 public DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> 00338 #endif 00339 { 00340 public: 00342 00343 00345 typedef Scalar scalar_type; 00347 typedef LocalOrdinal local_ordinal_type; 00349 typedef GlobalOrdinal global_ordinal_type; 00351 typedef Node node_type; 00352 00358 typedef scalar_type dot_type; 00359 00366 typedef typename Teuchos::ScalarTraits<scalar_type>::magnitudeType mag_type; 00367 00368 #if TPETRA_USE_KOKKOS_DISTOBJECT 00369 typedef DistObjectKA<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO; 00370 typedef typename DO::device_type device_type; 00371 #else 00372 typedef DistObject<Scalar, LocalOrdinal, GlobalOrdinal, Node> DO; 00373 #endif 00374 00376 00377 00378 00380 MultiVector (); 00381 00394 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 00395 size_t NumVectors, 00396 bool zeroOut=true); 00397 00403 MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &source); 00404 00422 MultiVector (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source, 00423 const Teuchos::DataAccess copyOrView); 00424 00440 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 00441 const Teuchos::ArrayView<const Scalar>& A, 00442 size_t LDA, 00443 size_t NumVectors); 00444 00458 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 00459 const Teuchos::ArrayView<const Teuchos::ArrayView<const Scalar> >&ArrayOfPtrs, 00460 size_t NumVectors); 00461 00472 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 00473 const Teuchos::ArrayRCP<Scalar>& data, 00474 const size_t LDA, 00475 const size_t numVectors); 00476 00478 template <class Node2> 00479 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> > 00480 clone(const Teuchos::RCP<Node2> &node2) const; 00481 00483 virtual ~MultiVector(); 00484 00486 00487 00488 00497 void 00498 replaceGlobalValue (GlobalOrdinal globalRow, 00499 size_t vectorIndex, 00500 const Scalar &value); 00501 00510 void 00511 sumIntoGlobalValue (GlobalOrdinal globalRow, 00512 size_t vectorIndex, 00513 const Scalar &value); 00514 00523 void 00524 replaceLocalValue (LocalOrdinal myRow, 00525 size_t vectorIndex, 00526 const Scalar &value); 00527 00536 void 00537 sumIntoLocalValue (LocalOrdinal myRow, 00538 size_t vectorIndex, 00539 const Scalar &value); 00540 00542 void putScalar (const Scalar &value); 00543 00559 void randomize(); 00560 00626 void replaceMap (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map); 00627 00634 void reduce(); 00635 00656 MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& 00657 operator= (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& source); 00658 00660 00675 00676 00681 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00682 subCopy (const Teuchos::Range1D &colRng) const; 00683 00685 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00686 subCopy (const Teuchos::ArrayView<const size_t> &cols) const; 00687 00692 Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00693 subView (const Teuchos::Range1D &colRng) const; 00694 00696 Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00697 subView (const Teuchos::ArrayView<const size_t> &cols) const; 00698 00703 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00704 subViewNonConst (const Teuchos::Range1D &colRng); 00705 00707 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00708 subViewNonConst (const Teuchos::ArrayView<const size_t> &cols); 00709 00772 Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00773 offsetView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& subMap, 00774 size_t offset) const; 00775 00793 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00794 offsetViewNonConst (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &subMap, 00795 size_t offset); 00796 00798 Teuchos::RCP<const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00799 getVector (size_t j) const; 00800 00802 Teuchos::RCP<Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 00803 getVectorNonConst (size_t j); 00804 00806 Teuchos::ArrayRCP<const Scalar> getData(size_t j) const; 00807 00809 Teuchos::ArrayRCP<Scalar> getDataNonConst(size_t j); 00810 00817 void get1dCopy (Teuchos::ArrayView<Scalar> A, size_t LDA) const; 00818 00824 void get2dCopy (Teuchos::ArrayView<const Teuchos::ArrayView<Scalar> > ArrayOfPtrs) const; 00825 00831 Teuchos::ArrayRCP<const Scalar> get1dView() const; 00832 00834 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > get2dView() const; 00835 00841 Teuchos::ArrayRCP<Scalar> get1dViewNonConst(); 00842 00844 Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > get2dViewNonConst(); 00845 00850 KokkosClassic::MultiVector<Scalar,Node> getLocalMV () const; 00851 00862 TEUCHOS_DEPRECATED 00863 KokkosClassic::MultiVector<Scalar,Node>& getLocalMVNonConst (); 00864 00866 00867 00868 00882 void 00883 dot (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A, 00884 const Teuchos::ArrayView<Scalar>& dots) const; 00885 00887 void abs(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A); 00888 00890 void reciprocal(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &A); 00891 00899 void scale (const Scalar &alpha); 00900 00909 void scale (Teuchos::ArrayView<const Scalar> alpha); 00910 00919 void 00920 scale (const Scalar& alpha, 00921 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A); 00922 00929 void 00930 update (const Scalar& alpha, 00931 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A, 00932 const Scalar& beta); 00933 00940 void 00941 update (const Scalar& alpha, 00942 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A, 00943 const Scalar& beta, 00944 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B, 00945 const Scalar& gamma); 00946 00952 void norm1(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const; 00953 00960 void norm2(const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &norms) const; 00961 00967 void normInf (const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const; 00968 00971 void 00972 normWeighted (const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& weights, 00973 const Teuchos::ArrayView<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>& norms) const; 00974 00977 void meanValue (const Teuchos::ArrayView<Scalar>& means) const; 00978 00984 void 00985 multiply (Teuchos::ETransp transA, 00986 Teuchos::ETransp transB, 00987 const Scalar& alpha, 00988 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A, 00989 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B, 00990 const Scalar& beta); 00991 01012 void 01013 elementWiseMultiply (Scalar scalarAB, 01014 const Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& A, 01015 const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& B, 01016 Scalar scalarThis); 01018 01019 01020 01022 size_t getNumVectors() const; 01023 01025 size_t getLocalLength() const; 01026 01028 global_size_t getGlobalLength() const; 01029 01035 size_t getStride() const; 01036 01040 bool isConstantStride() const; 01041 01043 01045 01046 01048 virtual std::string description() const; 01049 01078 virtual void 01079 describe (Teuchos::FancyOStream& out, 01080 const Teuchos::EVerbosityLevel verbLevel = 01081 Teuchos::Describable::verbLevel_default) const; 01083 01097 virtual void 01098 removeEmptyProcessesInPlace (const Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> >& newMap); 01099 01105 void setCopyOrView (const Teuchos::DataAccess copyOrView) { 01106 hasViewSemantics_ = (copyOrView == Teuchos::View); 01107 } 01108 01114 Teuchos::DataAccess getCopyOrView () const { 01115 return hasViewSemantics_ ? Teuchos::View : Teuchos::Copy; 01116 } 01117 01132 void 01133 assign (const MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& src); 01134 01135 protected: 01136 typedef KokkosClassic::MultiVector<Scalar,Node> KMV; 01137 typedef KokkosClassic::DefaultArithmetic<KMV> MVT; 01138 01140 KMV lclMV_; 01141 01154 Array<size_t> whichVectors_; 01155 01167 bool hasViewSemantics_; 01168 01170 01171 01172 // Implementation detail of the nonmember "constructor" function 01173 // createMultiVectorFromView. Please consider this function 01174 // DEPRECATED. 01175 template <class MultiVectorType> 01176 friend struct Details::CreateMultiVectorFromView; 01177 01189 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01190 const Teuchos::ArrayRCP<Scalar>& view, 01191 size_t LDA, 01192 size_t NumVectors, 01193 EPrivateHostViewConstructor /* dummy */); 01194 01195 bool vectorIndexOutOfRange (size_t VectorIndex) const; 01196 01202 template <class T> 01203 ArrayRCP<T> getSubArrayRCP(ArrayRCP<T> arr, size_t j) const; 01204 01208 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01209 Teuchos::ArrayRCP<Scalar> data, 01210 size_t LDA, 01211 Teuchos::ArrayView<const size_t> whichVectors, 01212 EPrivateComputeViewConstructor /* dummy */); 01213 01217 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01218 Teuchos::ArrayRCP<Scalar> data, 01219 size_t LDA, 01220 size_t NumVectors, 01221 EPrivateComputeViewConstructor /* dummy */); 01222 01230 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01231 const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector, 01232 EPrivateComputeViewConstructor /* dummy */); 01233 01241 MultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01242 const KokkosClassic::MultiVector<Scalar, Node>& localMultiVector, 01243 Teuchos::ArrayView<const size_t> whichVectors, 01244 EPrivateComputeViewConstructor /* dummy */); 01245 01247 01248 01249 01254 virtual bool 01255 checkSizes (const SrcDistObject& sourceObj); 01256 01258 virtual size_t constantNumberOfPackets () const; 01259 01260 #if TPETRA_USE_KOKKOS_DISTOBJECT 01261 virtual void 01262 copyAndPermute ( 01263 const SrcDistObject& sourceObj, 01264 size_t numSameIDs, 01265 const Kokkos::View<const LocalOrdinal*, device_type> &permuteToLIDs, 01266 const Kokkos::View<const LocalOrdinal*, device_type> &permuteFromLIDs); 01267 01268 virtual void 01269 packAndPrepare ( 01270 const SrcDistObject& sourceObj, 01271 const Kokkos::View<const LocalOrdinal*, device_type> &exportLIDs, 01272 Kokkos::View<Scalar*, device_type> &exports, 01273 const Kokkos::View<size_t*, device_type> &numPacketsPerLID, 01274 size_t& constantNumPackets, 01275 Distributor &distor); 01276 01277 virtual void 01278 unpackAndCombine ( 01279 const Kokkos::View<const LocalOrdinal*, device_type> &importLIDs, 01280 const Kokkos::View<const Scalar*, device_type> &imports, 01281 const Kokkos::View<size_t*, device_type> &numPacketsPerLID, 01282 size_t constantNumPackets, 01283 Distributor &distor, 01284 CombineMode CM); 01285 #else 01286 virtual void 01287 copyAndPermute (const SrcDistObject& sourceObj, 01288 size_t numSameIDs, 01289 const ArrayView<const LocalOrdinal>& permuteToLIDs, 01290 const ArrayView<const LocalOrdinal>& permuteFromLIDs); 01291 01292 virtual void 01293 packAndPrepare (const SrcDistObject& sourceObj, 01294 const ArrayView<const LocalOrdinal>& exportLIDs, 01295 Array<Scalar>& exports, 01296 const ArrayView<size_t>& numExportPacketsPerLID, 01297 size_t& constantNumPackets, 01298 Distributor& distor); 01299 01300 virtual void 01301 unpackAndCombine (const ArrayView<const LocalOrdinal>& importLIDs, 01302 const ArrayView<const Scalar>& imports, 01303 const ArrayView<size_t>& numPacketsPerLID, 01304 size_t constantNumPackets, 01305 Distributor& distor, 01306 CombineMode CM); 01307 #endif 01308 01309 void createViews () const; 01310 void createViewsNonConst (KokkosClassic::ReadWriteOption rwo); 01311 void releaseViews () const; 01312 01314 mutable ArrayRCP<Scalar> ncview_; 01315 01317 mutable ArrayRCP<const Scalar> cview_; 01318 01320 01321 #if TPETRA_USE_KOKKOS_DISTOBJECT 01322 01323 Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> 01324 getKokkosView() const { 01325 Teuchos::ArrayRCP<const Scalar> buff = MVT::getValues (lclMV_); 01326 Kokkos::View<const Scalar*, device_type, Kokkos::MemoryUnmanaged> v( 01327 buff.getRawPtr(), buff.size()); 01328 return v; 01329 } 01330 Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> 01331 getKokkosViewNonConst() { 01332 Teuchos::ArrayRCP<Scalar> buff = MVT::getValuesNonConst (lclMV_); 01333 Kokkos::View<Scalar*, device_type, Kokkos::MemoryUnmanaged> v( 01334 buff.getRawPtr(), buff.size()); 01335 return v; 01336 } 01337 01338 #endif 01339 }; 01340 01361 template <class DS, class DL, class DG, class DN, 01362 class SS, class SL, class SG, class SN> 01363 void 01364 deep_copy (MultiVector<DS,DL,DG,DN>& dst, 01365 const MultiVector<SS,SL,SG,SN>& src); 01366 // { 01367 // TEUCHOS_TEST_FOR_EXCEPTION( 01368 // true, std::logic_error, "The fully generic version of Tpetra::deep_copy " 01369 // "is not implemented."); 01370 // } 01371 01372 template <class SS, class SL, class SG, class SN> 01373 void 01374 deep_copy (MultiVector<SS,SL,SG,SN>& dst, const MultiVector<SS,SL,SG,SN>& src) 01375 { 01376 // NOTE (mfh 11 Sep 2014) We can't implement deep_copy with 01377 // shallow-copy operator=, because that would invalidate existing 01378 // views of dst! 01379 dst.assign (src); 01380 } 01381 01393 template <class ST, class LO, class GO, class NT> 01394 MultiVector<ST, LO, GO, NT> 01395 createCopy (const MultiVector<ST, LO, GO, NT>& src); 01396 01397 namespace Details { 01423 template<class DstMultiVecType, class SrcMultiVecType> 01424 struct MultiVectorCloner { 01425 typedef DstMultiVecType dst_mv_type; 01426 typedef SrcMultiVecType src_mv_type; 01427 01428 static Teuchos::RCP<dst_mv_type> 01429 clone (const src_mv_type& X, 01430 const Teuchos::RCP<typename dst_mv_type::node_type>& node2); 01431 }; 01432 01433 // Partial specialization of MultiVectorCloner for when the source 01434 // and destination MultiVector types have the same Scalar type, 01435 // but all their other template parameters might be different. 01436 template<class ScalarType, 01437 class DstLocalOrdinalType, class DstGlobalOrdinalType, class DstNodeType, 01438 class SrcLocalOrdinalType, class SrcGlobalOrdinalType, class SrcNodeType> 01439 struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType>, 01440 ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> > 01441 { 01442 typedef ::Tpetra::MultiVector<ScalarType, DstLocalOrdinalType, DstGlobalOrdinalType, DstNodeType> dst_mv_type; 01443 typedef ::Tpetra::MultiVector<ScalarType, SrcLocalOrdinalType, SrcGlobalOrdinalType, SrcNodeType> src_mv_type; 01444 01445 static Teuchos::RCP<dst_mv_type> 01446 clone (const src_mv_type& X, 01447 const Teuchos::RCP<typename src_mv_type::node_type>& node2) 01448 { 01449 using Teuchos::ArrayRCP; 01450 using Teuchos::RCP; 01451 using Teuchos::rcp; 01452 typedef typename src_mv_type::map_type src_map_type; 01453 typedef typename dst_mv_type::map_type dst_map_type; 01454 typedef typename dst_mv_type::node_type dst_node_type; 01455 01456 // Clone X's Map to have the new Node type. 01457 RCP<const src_map_type> map1 = X.getMap (); 01458 RCP<const dst_map_type> map2 = map1.is_null () ? 01459 Teuchos::null : map1->template clone<dst_node_type> (node2); 01460 01461 const size_t lclNumRows = X.getLocalLength (); 01462 const size_t numCols = X.getNumVectors (); 01463 const size_t LDA = lclNumRows; 01464 01465 // Get a host deep copy of X's data. 01466 ArrayRCP<ScalarType> data1 (LDA * numCols); 01467 X.get1dCopy (data1 (), LDA); 01468 01469 // Create the destination MultiVector. This might do another 01470 // deep copy; I'm not really worried about that. clone() 01471 // doesn't have to be super fast; it just can't be too slow. 01472 return rcp (new dst_mv_type (map2, data1 (), LDA, numCols)); 01473 } 01474 }; 01475 01476 // Partial specialization of MultiVectorCloner for when the source 01477 // and destination MultiVector types are the same. 01478 template<class ScalarType, class LocalOrdinalType, class GlobalOrdinalType, class NodeType> 01479 struct MultiVectorCloner< ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType>, 01480 ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> > 01481 { 01482 typedef ::Tpetra::MultiVector<ScalarType, LocalOrdinalType, GlobalOrdinalType, NodeType> dst_mv_type; 01483 typedef dst_mv_type src_mv_type; 01484 01485 static Teuchos::RCP<dst_mv_type> 01486 clone (const src_mv_type& X, const Teuchos::RCP<NodeType>& ) 01487 { 01488 // Create a deep copy. 01489 RCP<dst_mv_type> X_clone = rcp (new dst_mv_type (X, Teuchos::Copy)); 01490 // Set the cloned MultiVector to have the same copy-or-view 01491 // semantics as the input MultiVector X. 01492 X_clone->setCopyOrView (X.getCopyOrView ()); 01493 01494 return X_clone; 01495 } 01496 }; 01497 01498 template<class MultiVectorType> 01499 Teuchos::RCP<MultiVectorType> 01500 CreateMultiVectorFromView<MultiVectorType>:: 01501 create (const Teuchos::RCP<const map_type>& map, 01502 const Teuchos::ArrayRCP<scalar_type>& view, 01503 const size_t LDA, 01504 const size_t numVectors) 01505 { 01506 using Teuchos::rcp; 01507 typedef Tpetra::details::ViewAccepter<node_type> VAN; 01508 01509 // This uses a protected MultiVector constructor, but this 01510 // nonmember function was declared a friend of MultiVector. 01511 // 01512 // The ViewAccepter expression will fail to compile for 01513 // unsupported Kokkos Node types. 01514 return rcp (new MultiVectorType (map, VAN::template acceptView<scalar_type> (view), 01515 LDA, numVectors, HOST_VIEW_CONSTRUCTOR)); 01516 } 01517 } // namespace Details 01518 01519 01520 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node> 01521 template <class Node2> 01522 Teuchos::RCP<MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> > 01523 MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>:: 01524 clone (const Teuchos::RCP<Node2>& node2) const 01525 { 01526 typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node2> dst_mv_type; 01527 typedef MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> src_mv_type; 01528 typedef Details::MultiVectorCloner<dst_mv_type, src_mv_type> cloner_type; 01529 return cloner_type::clone (*this, node2); 01530 } 01531 01540 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node> 01541 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 01542 createMultiVector (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01543 const size_t numVectors) 01544 { 01545 typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV; 01546 return Teuchos::rcp (new MV (map, numVectors)); 01547 } 01548 01549 } // namespace Tpetra 01550 01551 // Include KokkosRefactor partial specialization if enabled 01552 #if defined(TPETRA_HAVE_KOKKOS_REFACTOR) 01553 #include "Tpetra_KokkosRefactor_MultiVector_decl.hpp" 01554 #endif 01555 01556 // Define createMultiVectorFromView after the above include, so that 01557 // the function can pick up the partial specialization of 01558 // CreateMultiVectorFromView. 01559 01560 namespace Tpetra { 01561 01587 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node> 01588 Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > 01589 createMultiVectorFromView (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& map, 01590 const Teuchos::ArrayRCP<Scalar>& view, 01591 const size_t LDA, 01592 const size_t numVectors) 01593 { 01594 typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> mv_type; 01595 typedef Details::CreateMultiVectorFromView<mv_type> impl_type; 01596 return impl_type::create (map, view, LDA, numVectors); 01597 } 01598 01599 } // namespace Tpetra 01600 01601 #endif // TPETRA_MULTIVECTOR_DECL_HPP
1.7.6.1