Tpetra Matrix/Vector Services  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Tpetra_KokkosRefactor_Map_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_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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines