|
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_KOKKOSREFACTOR_MAP_DECL_HPP 00043 #define TPETRA_KOKKOSREFACTOR_MAP_DECL_HPP 00044 00045 #include <KokkosCompat_ClassicNodeAPI_Wrapper.hpp> 00046 #include <Kokkos_Core.hpp> 00047 #include <Kokkos_UnorderedMap.hpp> 00048 #include "Tpetra_KokkosRefactor_Details_Map.hpp" 00049 00050 namespace Tpetra { 00051 00193 template <class LocalOrdinal, 00194 class GlobalOrdinal, 00195 class DeviceType> 00196 class Map<LocalOrdinal, 00197 GlobalOrdinal, 00198 Kokkos::Compat::KokkosDeviceWrapperNode<DeviceType> > : 00199 public Teuchos::Describable { 00200 public: 00202 00203 00205 typedef LocalOrdinal local_ordinal_type; 00207 typedef GlobalOrdinal global_ordinal_type; 00209 typedef Kokkos::Compat::KokkosDeviceWrapperNode<DeviceType> node_type; 00211 typedef DeviceType device_type; 00212 00213 private: 00214 typedef Details::Map<LocalOrdinal, GlobalOrdinal, device_type> device_impl_type; 00215 typedef typename device_type::host_mirror_device_type host_mirror_device_type; 00216 typedef Details::Map<LocalOrdinal, GlobalOrdinal, host_mirror_device_type> host_impl_type; 00217 00218 public: 00219 00261 Map (const global_size_t globalNumIndices, 00262 const GlobalOrdinal indexBase, 00263 const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 00264 const LocalGlobal lg = GloballyDistributed, 00265 const Teuchos::RCP<node_type> &node = KokkosClassic::Details::getNode<node_type> ()); 00266 00306 Map (const global_size_t globalNumIndices, 00307 const size_t myNumIndices, 00308 const GlobalOrdinal indexBase, 00309 const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 00310 const Teuchos::RCP<node_type> &node = KokkosClassic::Details::getNode<node_type> ()); 00311 00347 Map (const global_size_t globalNumIndices, 00348 const Kokkos::View<const GlobalOrdinal*, device_type>& myGlobalIndices, 00349 const GlobalOrdinal indexBase, 00350 const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 00351 const Teuchos::RCP<node_type> &node = KokkosClassic::Details::getNode<node_type> ()); 00352 00387 Map (const global_size_t globalNumIndices, 00388 const Teuchos::ArrayView<const GlobalOrdinal>& myGlobalIndices, 00389 const GlobalOrdinal indexBase, 00390 const Teuchos::RCP<const Teuchos::Comm<int> >& comm, 00391 const Teuchos::RCP<node_type>& node = KokkosClassic::Details::getNode<node_type> ()); 00392 00403 Map (); 00404 00406 00407 00408 00409 00410 00411 00412 00413 00414 00415 00423 GlobalOrdinal invalidGlobalIndex () const; 00424 00432 LocalOrdinal invalidLocalIndex () const; 00433 00440 global_size_t getGlobalNumElements() const; 00441 00443 size_t getNodeNumElements () const; 00444 00446 GlobalOrdinal getIndexBase () const; 00447 00455 LocalOrdinal getInvalidLocalIndex () const; 00456 00458 LocalOrdinal getMinLocalIndex () const; 00459 00465 LocalOrdinal getMaxLocalIndex () const; 00466 00474 GlobalOrdinal getInvalidGlobalIndex () const; 00475 00477 GlobalOrdinal getMinGlobalIndex () const; 00478 00480 GlobalOrdinal getMaxGlobalIndex () const; 00481 00483 GlobalOrdinal getMinAllGlobalIndex () const; 00484 00486 GlobalOrdinal getMaxAllGlobalIndex () const; 00487 00492 LocalOrdinal getLocalElement (const GlobalOrdinal globalIndex) const; 00493 00498 GlobalOrdinal getGlobalElement (const LocalOrdinal localIndex) const; 00499 00501 bool isNodeLocalElement (const LocalOrdinal localIndex) const; 00502 00504 bool isNodeGlobalElement (const GlobalOrdinal globalIndex) const; 00505 00512 bool isUniform () const; 00513 00525 bool isContiguous () const; 00526 00546 bool isDistributed () const; 00547 00549 00550 00551 00552 00553 00554 00559 bool isOneToOne () const; 00560 00581 template<class OutDeviceType> 00582 Details::Map<LocalOrdinal, GlobalOrdinal, OutDeviceType> 00583 getDeviceView () { 00584 // MapMirrorer finds which of mapDevice_ or mapHost_ (if either) 00585 // is initialized, and returns a mirror of that. It's a shallow 00586 // copy if the device types are the same, else it's a deep copy. 00587 return Details::MapMirrorer<Details::Map<LocalOrdinal, GlobalOrdinal, OutDeviceType>, 00588 device_impl_type, host_impl_type>::mirror (mapDevice_, mapHost_); 00589 } 00590 00622 LookupStatus 00623 getRemoteIndexList (const Teuchos::ArrayView<const GlobalOrdinal>& GIDs, 00624 const Teuchos::ArrayView< int>& PIDs, 00625 const Teuchos::ArrayView< LocalOrdinal>& LIDs) const; 00626 00651 LookupStatus 00652 getRemoteIndexList (const Teuchos::ArrayView<const GlobalOrdinal> & GIDs, 00653 const Teuchos::ArrayView< int> & PIDs) const; 00654 00661 Teuchos::ArrayView<const GlobalOrdinal> getNodeElementList () const; 00662 00687 bool isCompatible (const Map<LocalOrdinal, GlobalOrdinal, node_type>& map) const; 00688 00719 bool isSameAs (const Map<LocalOrdinal, GlobalOrdinal, node_type>& map) const; 00720 00722 00723 00724 00726 Teuchos::RCP<const Teuchos::Comm<int> > getComm () const; 00727 00729 Teuchos::RCP<node_type> getNode () const; 00730 00732 00733 00734 00736 std::string description() const; 00737 00739 void 00740 describe (Teuchos::FancyOStream &out, 00741 const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const; 00742 00744 00745 00746 00748 template <class OutNodeType> 00749 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, OutNodeType> > 00750 clone (const Teuchos::RCP<OutNodeType>& node2) const; 00751 00799 RCP<const Map<LocalOrdinal, GlobalOrdinal, node_type> > 00800 removeEmptyProcesses () const; 00801 00829 RCP<const Map<LocalOrdinal, GlobalOrdinal, node_type> > 00830 replaceCommWithSubset (const Teuchos::RCP<const Teuchos::Comm<int> >& newComm) const; 00832 00833 00838 bool locallySameAs (const Map<LocalOrdinal, GlobalOrdinal, node_type>& map) const; 00839 00840 protected: 00841 // This lets other specializations of Map access all of this 00842 // specialization's internal methods and data, so that we can 00843 // implement clone() without exposing the details of Map to users. 00844 template <class LO, class GO, class N> friend class Map; 00845 00846 private: 00847 template<class OutMapType, class InMapType> 00848 friend struct Details::MapCloner; 00849 00857 void setupDirectory () const; 00858 00860 Teuchos::RCP<const Teuchos::Comm<int> > comm_; 00861 00867 Teuchos::RCP<node_type> node_; 00868 00874 mutable device_impl_type mapDevice_; 00875 00881 mutable host_impl_type mapHost_; 00882 00910 mutable Teuchos::RCP<Directory<LocalOrdinal, GlobalOrdinal, node_type> > directory_; 00911 }; 00912 00913 00914 00915 namespace Details { 00916 template<class LO, class GO, class InDeviceType, class OutNodeType> 00917 struct MapCloner<Tpetra::Map<LO, GO, OutNodeType>, 00918 Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> > > { 00919 typedef OutNodeType out_node_type; 00920 typedef Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> in_node_type; 00921 typedef Tpetra::Map<LO, GO, OutNodeType> out_map_type; 00922 typedef Tpetra::Map<LO, GO, in_node_type> in_map_type; 00923 00924 static out_map_type 00925 clone (const in_map_type& mapIn, 00926 const Teuchos::RCP<out_node_type>& nodeOut) 00927 { 00928 if (mapIn.isUniform ()) { 00929 const Tpetra::LocalGlobal lg = mapIn.isDistributed () ? 00930 Tpetra::GloballyDistributed : Tpetra::LocallyReplicated; 00931 return out_map_type (mapIn.getGlobalNumElements (), 00932 mapIn.getIndexBase (), 00933 mapIn.getComm (), lg, nodeOut); 00934 } 00935 else if (mapIn.isContiguous ()) { 00936 return out_map_type (mapIn.getGlobalNumElements (), 00937 mapIn.getNodeNumElements (), 00938 mapIn.getIndexBase (), 00939 mapIn.getComm (), nodeOut); 00940 } 00941 else { 00942 return out_map_type (mapIn.getGlobalNumElements (), 00943 mapIn.getNodeElementList (), 00944 mapIn.getIndexBase (), 00945 mapIn.getComm (), nodeOut); 00946 } 00947 } 00948 }; 00949 00950 template<class LO, class GO, class InNodeType, class OutDeviceType> 00951 struct MapCloner<Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<OutDeviceType> >, 00952 Tpetra::Map<LO, GO, InNodeType> > { 00953 typedef Kokkos::Compat::KokkosDeviceWrapperNode<OutDeviceType> out_node_type; 00954 typedef InNodeType in_node_type; 00955 typedef Tpetra::Map<LO, GO, out_node_type> out_map_type; 00956 typedef Tpetra::Map<LO, GO, in_node_type> in_map_type; 00957 00958 static out_map_type 00959 clone (const in_map_type& mapIn, 00960 const Teuchos::RCP<out_node_type>& nodeOut) 00961 { 00962 if (mapIn.isUniform ()) { 00963 const Tpetra::LocalGlobal lg = mapIn.isDistributed () ? 00964 Tpetra::GloballyDistributed : Tpetra::LocallyReplicated; 00965 return out_map_type (mapIn.getGlobalNumElements (), 00966 mapIn.getIndexBase (), 00967 mapIn.getComm (), lg, nodeOut); 00968 } 00969 else if (mapIn.isContiguous ()) { 00970 return out_map_type (mapIn.getGlobalNumElements (), 00971 mapIn.getNodeNumElements (), 00972 mapIn.getIndexBase (), 00973 mapIn.getComm (), nodeOut); 00974 } 00975 else { 00976 return out_map_type (mapIn.getGlobalNumElements (), 00977 mapIn.getNodeElementList (), 00978 mapIn.getIndexBase (), 00979 mapIn.getComm (), nodeOut); 00980 } 00981 } 00982 }; 00983 00984 template<class LO, class GO, class InDeviceType, class OutDeviceType> 00985 struct MapCloner<Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<OutDeviceType> >, 00986 Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> > > 00987 { 00988 typedef Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<OutDeviceType> > out_map_type; 00989 typedef Tpetra::Map<LO, GO, Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> > in_map_type; 00990 typedef Kokkos::Compat::KokkosDeviceWrapperNode<OutDeviceType> out_node_type; 00991 00992 static out_map_type 00993 clone (const in_map_type& mapIn, 00994 const Teuchos::RCP<out_node_type>& nodeOut) 00995 { 00996 typedef ::Tpetra::Directory<typename out_map_type::local_ordinal_type, 00997 typename out_map_type::global_ordinal_type, 00998 typename out_map_type::node_type> out_dir_type; 00999 01000 out_map_type mapOut; // Make an empty Map. 01001 01002 mapOut.comm_ = mapIn.comm_; 01003 mapOut.node_ = nodeOut; 01004 mapOut.mapDevice_.template create_copy_view<InDeviceType> (mapIn.mapDevice_); 01005 mapOut.mapHost_.template create_copy_view<typename InDeviceType::host_mirror_device_type> (mapIn.mapHost_); 01006 01007 // mfh 02 Apr 2013: While Map only needs to create the Directory 01008 // on demand in getRemoteIndexList, we have a Directory here that 01009 // we can clone inexpensively, so there is no harm in creating it 01010 // here. 01011 // 01012 // FIXME (mfh 09 May 2014) clone() doesn't quite work -- the 01013 // Directory has the wrong implementation type, for some 01014 // reason -- but it's always correct to let the output Map 01015 // initialize the Directory on its own. 01016 if (false && ! mapIn.directory_.is_null ()) { 01017 mapOut.directory_ = mapIn.directory_->template clone<out_node_type> (mapOut); 01018 } else { 01019 // It's created here, but not initialized yet. The output 01020 // Map will initialize it on demand, if needed. 01021 mapOut.directory_ = Teuchos::rcp (new out_dir_type ()); 01022 } 01023 return mapOut; 01024 } 01025 }; 01026 01027 } // namespace Details 01028 01029 template <class LocalOrdinal, class GlobalOrdinal, class InDeviceType> 01030 template <class OutNodeType> 01031 Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, OutNodeType> > 01032 Map<LocalOrdinal, GlobalOrdinal, Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> >:: 01033 clone (const Teuchos::RCP<OutNodeType>& outNode) const 01034 { 01035 typedef Kokkos::Compat::KokkosDeviceWrapperNode<InDeviceType> in_node_type; 01036 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, in_node_type> in_map_type; 01037 typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, OutNodeType> out_map_type; 01038 typedef Tpetra::Details::MapCloner<out_map_type, in_map_type> cloner_type; 01039 // Copy constructor does a shallow copy. 01040 return Teuchos::rcp (new out_map_type (cloner_type::clone (*this, outNode))); 01041 } 01042 01043 } // namespace Tpetra 01044 01045 #endif // TPETRA_KOKKOSREFACTOR_MAP_DECL_HPP 01046
1.7.6.1