Tpetra Matrix/Vector Services Version of the Day
Tpetra_CrsGraph_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_CRSGRAPH_DECL_HPP
00043 #define TPETRA_CRSGRAPH_DECL_HPP
00044 
00045 #include <Teuchos_CompileTimeAssert.hpp>
00046 #include <Teuchos_Describable.hpp>
00047 #include <Teuchos_ParameterListAcceptorDefaultBase.hpp>
00048 
00049 #include <Kokkos_DefaultNode.hpp>
00050 #include <Kokkos_DefaultKernels.hpp>
00051 
00052 #include "Tpetra_ConfigDefs.hpp"
00053 #include "Tpetra_RowGraph.hpp"
00054 #include "Tpetra_DistObject.hpp"
00055 #include "Tpetra_Exceptions.hpp"
00056 
00057 
00058 namespace Tpetra {
00059 
00060 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00061   // forward declaration
00062   template <class S, class LO, class GO, class N, class SpMatOps>
00063   class CrsMatrix;
00064 #endif
00065 
00074   struct RowInfo {
00075     size_t localRow;
00076     size_t allocSize;
00077     size_t numEntries;
00078     size_t offset1D;
00079   };
00080 
00081   enum ELocalGlobal {
00082     LocalIndices,
00083     GlobalIndices
00084   };
00085 
00163   template <class LocalOrdinal,
00164             class GlobalOrdinal = LocalOrdinal,
00165             class Node = KokkosClassic::DefaultNode::DefaultNodeType,
00166             class LocalMatOps = typename KokkosClassic::DefaultKernels<void,LocalOrdinal,Node>::SparseOps >
00167   class CrsGraph :
00168     public RowGraph<LocalOrdinal,GlobalOrdinal,Node>,
00169     public DistObject<GlobalOrdinal,LocalOrdinal,GlobalOrdinal,Node>,
00170     public Teuchos::ParameterListAcceptorDefaultBase
00171   {
00172     template <class S, class LO, class GO, class N, class SpMatOps>
00173     friend class CrsMatrix;
00174     template <class LO2, class GO2, class N2, class SpMatOps2>
00175     friend class CrsGraph;
00176 
00177   public:
00179     typedef LocalOrdinal local_ordinal_type;
00181     typedef GlobalOrdinal global_ordinal_type;
00183     typedef Node node_type;
00184 
00186     typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, node_type> map_type;
00188     typedef Tpetra::Import<LocalOrdinal, GlobalOrdinal, node_type> import_type;
00190     typedef Tpetra::Export<LocalOrdinal, GlobalOrdinal, node_type> export_type;
00191 
00193 
00194 
00212     CrsGraph (const RCP<const map_type>& rowMap,
00213               size_t maxNumEntriesPerRow,
00214               ProfileType pftype = DynamicProfile,
00215               const RCP<ParameterList>& params = null);
00216 
00234     CrsGraph (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& rowMap,
00235               const ArrayRCP<const size_t>& NumEntriesPerRowToAlloc,
00236               ProfileType pftype = DynamicProfile,
00237               const RCP<ParameterList>& params = null);
00238 
00258     CrsGraph (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& rowMap,
00259               const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& colMap,
00260               size_t maxNumEntriesPerRow,
00261               ProfileType pftype = DynamicProfile,
00262               const RCP<ParameterList>& params = null);
00263 
00283     CrsGraph (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& rowMap,
00284               const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& colMap,
00285               const ArrayRCP<const size_t> &NumEntriesPerRowToAlloc,
00286               ProfileType pftype = DynamicProfile,
00287               const RCP<ParameterList>& params = null);
00288 
00308     CrsGraph (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& rowMap,
00309               const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> >& colMap,
00310               const ArrayRCP<size_t> & rowPointers,
00311               const ArrayRCP<LocalOrdinal> & columnIndices,
00312               const RCP<ParameterList>& params = null);
00313 
00314 
00342     template<class Node2>
00343     RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node2,
00344                  typename KokkosClassic::DefaultKernels<void, LocalOrdinal, Node2>::SparseOps> >
00345     clone (const Teuchos::RCP<Node2> &node2,
00346            const Teuchos::RCP<Teuchos::ParameterList> &params = null) const
00347     {
00348       using Teuchos::arcp;
00349       using Teuchos::ArrayRCP;
00350       using Teuchos::RCP;
00351       using Teuchos::ParameterList;
00352       using std::endl;
00353       typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node2,
00354         typename KokkosClassic::DefaultKernels<void,LocalOrdinal,Node2>::SparseOps> CrsGraph2;
00355       typedef Map<LocalOrdinal, GlobalOrdinal, Node2> Map2;
00356       const char tfecfFuncName[] = "clone()";
00357 
00358       bool fillCompleteClone  = true;
00359       bool useLocalIndices    = hasColMap();
00360       ProfileType pftype = StaticProfile;
00361       if (! params.is_null ()) {
00362         fillCompleteClone = params->get ("fillComplete clone", fillCompleteClone);
00363         useLocalIndices = params->get ("Locally indexed clone", useLocalIndices);
00364         if (params->get ("Static profile clone",true) == false) {
00365           pftype = DynamicProfile;
00366         }
00367       }
00368 
00369       TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
00370         hasColMap() == false && useLocalIndices == true,
00371         std::runtime_error,
00372         ": You asked clone() to use local indices (by setting the \"Locally "
00373         "indexed clone\" parameter to true), but the source graph does not "
00374         "yet have a column Map, so this is impossible.");
00375 
00376       RCP<const Map2> clonedRowMap = rowMap_->template clone<Node2> (node2);
00377       RCP<CrsGraph2> clonedGraph;
00378       ArrayRCP<const size_t> numEntries;
00379       size_t numEntriesForAll = 0;
00380       if (indicesAreAllocated() == false) {
00381         if (numAllocPerRow_ != null) {
00382           numEntries = numAllocPerRow_;
00383         }
00384         else {
00385           numEntriesForAll = numAllocForAllRows_;
00386         }
00387       }
00388       else if (numRowEntries_ != null) {
00389         numEntries = numRowEntries_;
00390       }
00391       else if (nodeNumAllocated_ == 0) {
00392         numEntriesForAll = 0;
00393       }
00394       else {
00395         // left with the case that we have optimized storage. in this case, we have to construct a list of row sizes.
00396         TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
00397           getProfileType() != StaticProfile, std::logic_error,
00398           "Internal logic error. Please report this to Tpetra team.");
00399         const size_t numRows = getNodeNumRows();
00400         numEntriesForAll = 0;
00401         ArrayRCP<size_t> numEnt;
00402         if (numRows) {
00403           numEnt = arcp<size_t> (numRows);
00404         }
00405         for (size_t i=0; i<numRows; ++i) {
00406           numEnt[i] = rowPtrs_[i+1] - rowPtrs_[i];
00407         }
00408         numEntries = numEnt;
00409       }
00410 
00411       RCP<ParameterList> graphparams = sublist(params,"CrsGraph");
00412       if (useLocalIndices) {
00413         RCP<const Map2> clonedColMap = colMap_->template clone<Node2>(node2);
00414         if (numEntries == null) {
00415           clonedGraph = rcp (new CrsGraph2 (clonedRowMap, clonedColMap, numEntriesForAll, pftype, graphparams));
00416         }
00417         else {
00418           clonedGraph = rcp (new CrsGraph2 (clonedRowMap, clonedColMap, numEntries, pftype, graphparams));
00419         }
00420       }
00421       else {
00422         if (numEntries.is_null ()) {
00423           clonedGraph = rcp (new CrsGraph2 (clonedRowMap, numEntriesForAll, pftype, graphparams));
00424         }
00425         else {
00426           clonedGraph = rcp (new CrsGraph2 (clonedRowMap, numEntries, pftype, graphparams));
00427         }
00428       }
00429       // done with these
00430       numEntries = null;
00431       numEntriesForAll = 0;
00432 
00433       if (useLocalIndices) {
00434         clonedGraph->allocateIndices(LocalIndices);
00435         if (this->isLocallyIndexed ()) {
00436           ArrayView<const LocalOrdinal> linds;
00437           for (LocalOrdinal lrow = rowMap_->getMinLocalIndex ();
00438                lrow <= rowMap_->getMaxLocalIndex ();
00439                ++lrow) {
00440             this->getLocalRowView (lrow, linds);
00441             if (linds.size ()) {
00442               clonedGraph->insertLocalIndices (lrow, linds);
00443             }
00444           }
00445         }
00446         else { // this->isGloballyIndexed()
00447           Array<LocalOrdinal> linds;
00448           for (LocalOrdinal lrow =  rowMap_->getMinLocalIndex();
00449                lrow <= rowMap_->getMaxLocalIndex();
00450                ++lrow) {
00451             size_t theNumEntries;
00452             linds.resize (this->getNumEntriesInLocalRow (lrow));
00453             this->getLocalRowCopy (rowMap_->getGlobalElement (lrow), linds (), theNumEntries);
00454             if (theNumEntries) {
00455               clonedGraph->insertLocalIndices (lrow, linds (0, theNumEntries));
00456             }
00457           }
00458         }
00459       }
00460       else { /* useGlobalIndices */
00461         clonedGraph->allocateIndices (GlobalIndices);
00462         if (this->isGloballyIndexed ()) {
00463           ArrayView<const GlobalOrdinal> ginds;
00464           for (GlobalOrdinal grow =  rowMap_->getMinGlobalIndex();
00465                grow <= rowMap_->getMaxGlobalIndex();
00466                ++grow) {
00467             this->getGlobalRowView (grow, ginds);
00468             if (ginds.size ()) {
00469               clonedGraph->insertGlobalIndices (grow, ginds);
00470             }
00471           }
00472         }
00473         else { // this->isLocallyIndexed()
00474           Array<GlobalOrdinal> ginds;
00475           for (GlobalOrdinal grow =  rowMap_->getMinGlobalIndex();
00476                grow <= rowMap_->getMaxGlobalIndex();
00477                ++grow) {
00478             size_t theNumEntries;
00479             ginds.resize (this->getNumEntriesInGlobalRow (grow));
00480             this->getGlobalRowCopy (grow, ginds (), theNumEntries);
00481             if (theNumEntries) {
00482               clonedGraph->insertGlobalIndices (grow, ginds (0,theNumEntries));
00483             }
00484           }
00485         }
00486       }
00487 
00488       if (fillCompleteClone) {
00489         RCP<ParameterList> fillparams = sublist (params, "fillComplete");
00490         try {
00491           RCP<const Map2> clonedRangeMap;
00492           RCP<const Map2> clonedDomainMap;
00493           if (rangeMap_ != null && rangeMap_ != rowMap_) {
00494             clonedRangeMap  = rangeMap_->template clone<Node2>(node2);
00495           }
00496           else {
00497             clonedRangeMap = clonedRowMap;
00498           }
00499           if (domainMap_ != null && domainMap_ != rowMap_) {
00500             clonedDomainMap = domainMap_->template clone<Node2>(node2);
00501           }
00502           else {
00503             clonedDomainMap = clonedRowMap;
00504           }
00505           clonedGraph->fillComplete (clonedDomainMap, clonedRangeMap, fillparams);
00506         }
00507         catch (std::exception &e) {
00508           const bool caughtExceptionOnClone = true;
00509           TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
00510             caughtExceptionOnClone, std::runtime_error,
00511             ": Caught the following exception while calling fillComplete() on "
00512             "clone of type" << endl << Teuchos::typeName (*clonedGraph)
00513             << endl << ":" << endl << e.what() << endl);
00514         }
00515       }
00516       return clonedGraph;
00517     }
00518 
00520     virtual ~CrsGraph();
00521 
00523 
00524 
00525 
00527     void setParameterList (const RCP<ParameterList>& params);
00528 
00530     RCP<const ParameterList> getValidParameters () const;
00531 
00533 
00534 
00535 
00557     void
00558     insertGlobalIndices (GlobalOrdinal globalRow,
00559                          const ArrayView<const GlobalOrdinal>& indices);
00560 
00562 
00576     void
00577     insertLocalIndices (const LocalOrdinal localRow,
00578                         const ArrayView<const LocalOrdinal> &indices);
00579 
00581 
00590     void removeLocalIndices (LocalOrdinal localRow);
00591 
00593 
00594 
00600 
00606     void globalAssemble ();
00607 
00616     void resumeFill (const RCP<ParameterList> &params = null);
00617 
00635     void
00636     fillComplete (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &domainMap,
00637                   const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &rangeMap,
00638                   const RCP<ParameterList> &params = null);
00639 
00646     void fillComplete (const RCP<ParameterList> &params = null);
00647 
00658     void
00659     expertStaticFillComplete (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & domainMap,
00660                               const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > & rangeMap,
00661                               const RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > &importer=Teuchos::null,
00662                               const RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > &exporter=Teuchos::null,
00663                               const RCP<ParameterList> &params=Teuchos::null);
00665 
00666 
00667 
00669     RCP<const Comm<int> > getComm() const;
00670 
00672     RCP<Node> getNode() const;
00673 
00675     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > getRowMap() const;
00676 
00678     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > getColMap() const;
00679 
00681     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > getDomainMap() const;
00682 
00684     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > getRangeMap() const;
00685 
00687     RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > getImporter() const;
00688 
00690     RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > getExporter() const;
00691 
00693 
00695     global_size_t getGlobalNumRows() const;
00696 
00698 
00701     global_size_t getGlobalNumCols() const;
00702 
00704     size_t getNodeNumRows() const;
00705 
00707 
00709     size_t getNodeNumCols() const;
00710 
00712     GlobalOrdinal getIndexBase() const;
00713 
00715 
00717     global_size_t getGlobalNumEntries() const;
00718 
00720     size_t getNodeNumEntries() const;
00721 
00723 
00724     size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const;
00725 
00727 
00728     size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const;
00729 
00731 
00738     size_t getNodeAllocationSize() const;
00739 
00741 
00742     size_t getNumAllocatedEntriesInGlobalRow(GlobalOrdinal globalRow) const;
00743 
00745 
00746     size_t getNumAllocatedEntriesInLocalRow(LocalOrdinal localRow) const;
00747 
00749 
00751     global_size_t getGlobalNumDiags() const;
00752 
00754 
00756     size_t getNodeNumDiags() const;
00757 
00770     size_t getGlobalMaxNumRowEntries() const;
00771 
00773 
00775     size_t getNodeMaxNumRowEntries() const;
00776 
00791     bool hasColMap() const;
00792 
00800     bool isLowerTriangular() const;
00801 
00809     bool isUpperTriangular() const;
00810 
00826     bool isLocallyIndexed() const;
00827 
00843     bool isGloballyIndexed() const;
00844 
00853     bool isFillComplete() const;
00854 
00869     bool isFillActive() const;
00870 
00872 
00875     bool isSorted() const;
00876 
00878 
00884     bool isStorageOptimized() const;
00885 
00887     ProfileType getProfileType() const;
00888 
00936     void
00937     getGlobalRowCopy (GlobalOrdinal GlobalRow,
00938                       const ArrayView<GlobalOrdinal>& Indices,
00939                       size_t& NumIndices) const;
00940 
00987     void
00988     getLocalRowCopy (LocalOrdinal LocalRow,
00989                      const ArrayView<LocalOrdinal>& indices,
00990                      size_t& NumIndices) const;
00991 
01011     void
01012     getGlobalRowView (GlobalOrdinal GlobalRow,
01013                       ArrayView<const GlobalOrdinal>& Indices) const;
01014 
01034     void
01035     getLocalRowView (LocalOrdinal LocalRow,
01036                      ArrayView<const LocalOrdinal>& indices) const;
01037 
01039 
01040 
01041 
01043     std::string description() const;
01044 
01046     void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const;
01047 
01049 
01050 
01051 
01052     virtual bool
01053     checkSizes (const SrcDistObject& source);
01054 
01055     virtual void
01056     copyAndPermute (const SrcDistObject& source,
01057                     size_t numSameIDs,
01058                     const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
01059                     const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs);
01060 
01061     virtual void
01062     packAndPrepare (const SrcDistObject& source,
01063                     const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
01064                     Teuchos::Array<GlobalOrdinal> &exports,
01065                     const Teuchos::ArrayView<size_t> & numPacketsPerLID,
01066                     size_t& constantNumPackets,
01067                     Distributor &distor);
01068 
01069     virtual void
01070     pack (const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
01071           Teuchos::Array<GlobalOrdinal>& exports,
01072           const Teuchos::ArrayView<size_t>& numPacketsPerLID,
01073           size_t& constantNumPackets,
01074           Distributor& distor) const;
01075 
01076     virtual void
01077     unpackAndCombine (const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
01078                       const Teuchos::ArrayView<const GlobalOrdinal> &imports,
01079                       const Teuchos::ArrayView<size_t> &numPacketsPerLID,
01080                       size_t constantNumPackets,
01081                       Distributor &distor,
01082                       CombineMode CM);
01084 
01085 
01086 
01095     void
01096     setAllIndices (const ArrayRCP<size_t> & rowPointers,
01097                    const ArrayRCP<LocalOrdinal> & columnIndices);
01098 
01100 
01103     ArrayRCP<const size_t> getNodeRowPtrs() const;
01104 
01106 
01108     ArrayRCP<const LocalOrdinal> getNodePackedIndices() const;
01109 
01114     void replaceColMap (const Teuchos::RCP<const map_type>& newColMap);
01115 
01128     void
01129     replaceDomainMapAndImporter (const Teuchos::RCP<const map_type>& newDomainMap,
01130                                  const Teuchos::RCP<const import_type>& newImporter);
01131 
01159     virtual void
01160     removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
01162 
01163   private:
01164     // We forbid copy construction by declaring this method private
01165     // and not implementing it.
01166     CrsGraph (const CrsGraph<LocalOrdinal,GlobalOrdinal,Node>& rhs);
01167 
01168     // We forbid assignment (operator=) by declaring this method
01169     // private and not implementing it.
01170     CrsGraph<LocalOrdinal,GlobalOrdinal,Node>&
01171     operator= (const CrsGraph<LocalOrdinal,GlobalOrdinal,Node>& rhs);
01172 
01173   protected:
01174     typedef typename LocalMatOps::template graph<LocalOrdinal,Node>::graph_type local_graph_type;
01175 
01176     // these structs are conveniences, to cut down on the number of
01177     // arguments to some of the methods below.
01178     struct SLocalGlobalViews {
01179       ArrayView<const GlobalOrdinal> ginds;
01180       ArrayView<const LocalOrdinal>  linds;
01181     };
01182     struct SLocalGlobalNCViews {
01183       ArrayView<GlobalOrdinal>       ginds;
01184       ArrayView<LocalOrdinal>        linds;
01185     };
01186     //
01187     // Allocation
01188     //
01189     bool indicesAreAllocated() const;
01190 
01191     void allocateIndices (ELocalGlobal lg);
01192 
01193     template <class T>
01194     ArrayRCP<T> allocateValues1D () const;
01195     template <class T>
01196     ArrayRCP<Array<T> > allocateValues2D () const;
01197 
01198     template <ELocalGlobal lg, class T>
01199     RowInfo updateAllocAndValues (RowInfo rowinfo, size_t newAllocSize, Array<T>& rowVals)
01200     {
01201 #ifdef HAVE_TPETRA_DEBUG
01202       TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement(rowinfo.localRow) );
01203       TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowinfo.allocSize );
01204       TEUCHOS_TEST_FOR_EXCEPT( (lg == LocalIndices && ! isLocallyIndexed()) ||
01205                                (lg == GlobalIndices && ! isGloballyIndexed()) );
01206       TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
01207       TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated() );
01208 #endif
01209       // ArrayRCP::resize automatically copies over values on reallocation.
01210       if (lg == LocalIndices) {
01211         lclInds2D_[rowinfo.localRow].resize (newAllocSize);
01212       }
01213       else { // lg == GlobalIndices
01214         gblInds2D_[rowinfo.localRow].resize (newAllocSize);
01215       }
01216       rowVals.resize (newAllocSize);
01217       nodeNumAllocated_ += (newAllocSize - rowinfo.allocSize);
01218       rowinfo.allocSize = newAllocSize;
01219       return rowinfo;
01220     }
01221 
01223 
01224 
01226     void makeColMap ();
01227     void makeIndicesLocal ();
01228     void makeImportExport ();
01229 
01231 
01232 
01233 
01234     template<ELocalGlobal lg>
01235     size_t filterIndices (const SLocalGlobalNCViews &inds) const;
01236 
01237     template<class T>
01238     size_t
01239     filterGlobalIndicesAndValues (const ArrayView<GlobalOrdinal>& ginds,
01240                                   const ArrayView<T>& vals) const
01241     {
01242       const Map<LocalOrdinal,GlobalOrdinal,Node>& cmap = *colMap_;
01243       size_t numFiltered = 0;
01244       typename ArrayView<T>::iterator fvalsend = vals.begin();
01245       typename ArrayView<T>::iterator valscptr = vals.begin();
01246 #ifdef HAVE_TPETRA_DEBUG
01247       size_t numFiltered_debug = 0;
01248 #endif
01249       typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
01250       typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
01251       while (cptr != ginds.end()) {
01252         if (cmap.isNodeGlobalElement (*cptr)) {
01253           *fend++ = *cptr;
01254           *fvalsend++ = *valscptr;
01255 #ifdef HAVE_TPETRA_DEBUG
01256           ++numFiltered_debug;
01257 #endif
01258         }
01259         ++cptr;
01260         ++valscptr;
01261       }
01262       numFiltered = fend - ginds.begin();
01263 #ifdef HAVE_TPETRA_DEBUG
01264       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
01265       TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
01266       const size_t numFilteredActual =
01267         Teuchos::as<size_t> (fvalsend - vals.begin ());
01268       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
01269 #endif
01270       return numFiltered;
01271     }
01272 
01273     template<class T>
01274     size_t
01275     filterLocalIndicesAndValues (const ArrayView<LocalOrdinal>& linds,
01276                                  const ArrayView<T>& vals) const
01277     {
01278       const Map<LocalOrdinal,GlobalOrdinal,Node>& cmap = *colMap_;
01279       size_t numFiltered = 0;
01280       typename ArrayView<T>::iterator fvalsend = vals.begin();
01281       typename ArrayView<T>::iterator valscptr = vals.begin();
01282 #ifdef HAVE_TPETRA_DEBUG
01283       size_t numFiltered_debug = 0;
01284 #endif
01285       typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
01286       typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
01287       while (cptr != linds.end()) {
01288         if (cmap.isNodeLocalElement (*cptr)) {
01289           *fend++ = *cptr;
01290           *fvalsend++ = *valscptr;
01291 #ifdef HAVE_TPETRA_DEBUG
01292           ++numFiltered_debug;
01293 #endif
01294         }
01295         ++cptr;
01296         ++valscptr;
01297       }
01298       numFiltered = fend - linds.begin();
01299 #ifdef HAVE_TPETRA_DEBUG
01300       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
01301       TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
01302       const size_t numFilteredActual =
01303         Teuchos::as<size_t> (fvalsend - vals.begin ());
01304       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
01305 #endif
01306       return numFiltered;
01307     }
01308 
01338     size_t
01339     insertIndices (const RowInfo& rowInfo,
01340                    const SLocalGlobalViews& newInds,
01341                    const ELocalGlobal lg,
01342                    const ELocalGlobal I);
01343 
01383     template<class Scalar>
01384     void
01385     insertIndicesAndValues (const RowInfo& rowInfo,
01386                             const SLocalGlobalViews& newInds,
01387                             const ArrayView<Scalar>& oldRowVals,
01388                             const ArrayView<const Scalar>& newRowVals,
01389                             const ELocalGlobal lg,
01390                             const ELocalGlobal I)
01391     {
01392       const size_t numNewInds = insertIndices (rowInfo, newInds, lg, I);
01393       typename ArrayView<const Scalar>::const_iterator newRowValsBegin =
01394         newRowVals.begin ();
01395       std::copy (newRowValsBegin, newRowValsBegin + numNewInds,
01396                  oldRowVals.begin () + rowInfo.numEntries);
01397     }
01398 
01399     void
01400     insertGlobalIndicesImpl (const LocalOrdinal myRow,
01401                              const ArrayView<const GlobalOrdinal> &indices);
01402     void
01403     insertLocalIndicesImpl (const LocalOrdinal myRow,
01404                             const ArrayView<const LocalOrdinal> &indices);
01406     void
01407     insertLocalIndicesFiltered (const LocalOrdinal localRow,
01408                                 const ArrayView<const LocalOrdinal> &indices);
01409 
01411     void
01412     insertGlobalIndicesFiltered (const GlobalOrdinal localRow,
01413                                  const ArrayView<const GlobalOrdinal> &indices);
01414 
01437     template<class Scalar, class BinaryFunction>
01438     void
01439     transformLocalValues (RowInfo rowInfo,
01440                           const Teuchos::ArrayView<Scalar>& rowVals,
01441                           const Teuchos::ArrayView<const LocalOrdinal>& inds,
01442                           const Teuchos::ArrayView<const Scalar>& newVals,
01443                           BinaryFunction f) const
01444     {
01445       const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid();
01446       const size_t numElts = Teuchos::as<size_t> (inds.size ());
01447       size_t hint = 0; // Guess for the current index k into rowVals
01448 
01449       // Get a view of the column indices in the row.  This amortizes
01450       // the cost of getting the view over all the entries of inds.
01451       ArrayView<const LocalOrdinal> colInds = getLocalView (rowInfo);
01452 
01453       for (size_t j = 0; j < numElts; ++j) {
01454         const size_t k = findLocalIndex (rowInfo, inds[j], colInds, hint);
01455         if (k != STINV) {
01456           rowVals[k] = f( rowVals[k], newVals[j] );
01457           hint = k+1;
01458         }
01459       }
01460     }
01461 
01476     template<class Scalar, class BinaryFunction>
01477     void
01478     transformGlobalValues (RowInfo rowInfo,
01479                            const Teuchos::ArrayView<Scalar>& rowVals,
01480                            const Teuchos::ArrayView<const GlobalOrdinal>& inds,
01481                            const Teuchos::ArrayView<const Scalar>& newVals,
01482                            BinaryFunction f) const
01483     {
01484       const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid();
01485       const size_t numElts = Teuchos::as<size_t> (inds.size ());
01486       size_t hint = 0; // hint is a guess as to wheter the index is
01487 
01488       for (size_t j = 0; j < numElts; ++j) {
01489         const size_t k = findGlobalIndex (rowInfo, inds[j], hint);
01490         if (k != STINV) {
01491           rowVals[k] = f( rowVals[k], newVals[j] );
01492           hint = k+1;
01493         }
01494       }
01495     }
01496 
01498 
01499 
01500 
01502     bool isMerged () const;
01503 
01509     void setLocallyModified ();
01510 
01512     void sortAllIndices ();
01513 
01515     void sortRowIndices (RowInfo rowinfo);
01516 
01531     template <class Scalar>
01532     void sortRowIndicesAndValues (RowInfo rowinfo, ArrayView<Scalar> values);
01533 
01542     void mergeAllIndices ();
01543 
01548     void mergeRowIndices (RowInfo rowinfo);
01549 
01550 
01561     template<class Scalar>
01562     void
01563     mergeRowIndicesAndValues (RowInfo rowinfo,
01564                               const Teuchos::ArrayView<Scalar>& rowValues);
01566 
01576     void
01577     setDomainRangeMaps (const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &domainMap,
01578                         const RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &rangeMap);
01579 
01580     void staticAssertions() const;
01581     // global consts
01582     void clearGlobalConstants();
01583     void computeGlobalConstants();
01584 
01586 
01587 
01591     RowInfo getRowInfo (size_t myRow) const;
01592 
01599     ArrayView<const LocalOrdinal> getLocalView (RowInfo rowinfo) const;
01600 
01607     ArrayView<LocalOrdinal> getLocalViewNonConst (RowInfo rowinfo);
01608 
01615     ArrayView<const GlobalOrdinal> getGlobalView (RowInfo rowinfo) const;
01616 
01623     ArrayView<GlobalOrdinal> getGlobalViewNonConst (RowInfo rowinfo);
01624 
01659     size_t
01660     findLocalIndex (RowInfo rowinfo,
01661                     LocalOrdinal ind,
01662                     size_t hint = 0) const;
01663 
01692     size_t
01693     findLocalIndex (RowInfo rowinfo,
01694                     LocalOrdinal ind,
01695                     ArrayView<const LocalOrdinal> colInds,
01696                     size_t hint = 0) const;
01697 
01705     size_t findGlobalIndex (RowInfo rowinfo, GlobalOrdinal ind, size_t hint = 0) const;
01706 
01708 
01709 
01710 
01711     void fillLocalGraph(const RCP<ParameterList> &params);
01712     const RCP<const local_graph_type> getLocalGraph() const;
01713     const RCP<local_graph_type> getLocalGraphNonConst();
01714 
01716 
01725     void checkInternalState() const;
01726 
01728     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > rowMap_;
01730     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > colMap_;
01732     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > rangeMap_;
01734     RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > domainMap_;
01735 
01742     RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > importer_;
01743 
01749     RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > exporter_;
01750 
01751     // local data, stored in a KokkosClassic::CrsGraph. only initialized after fillComplete()
01752     RCP<local_graph_type> lclGraph_;
01753 
01754     // Local and Global Counts
01755     // nodeNumEntries_ and nodeNumAllocated_ are required to be always consistent
01756     // nodeMaxNumEntries_, nodeNumDiags_ and the global quantities are computed during fillComplete() and only valid when isFillComplete()
01757     global_size_t globalNumEntries_, globalNumDiags_, globalMaxNumRowEntries_;
01758     size_t          nodeNumEntries_,   nodeNumDiags_,   nodeMaxNumRowEntries_, nodeNumAllocated_;
01759 
01761     ProfileType pftype_;
01762 
01772     ArrayRCP<const size_t> numAllocPerRow_;
01773 
01778     size_t numAllocForAllRows_;
01779 
01780     // graph indices. before allocation, all are null.
01781     // after allocation, except during makeIndicesLocal(), one of local or global is null.
01782     // we will never have 1D and 2D structures being non-null
01783     // this is host memory
01784     // 1D == StaticAllocation, 2D == DynamicAllocation
01786     //
01787     // 1D/Static structures
01788     //
01790 
01792     ArrayRCP< LocalOrdinal>                     lclInds1D_;
01794     ArrayRCP<GlobalOrdinal>                     gblInds1D_;
01795     // offset to the beg entries of each row. only used for 1D (Static) allocation.
01796     // i.e., indices for row R are lclInds1D_[i] for i in [b,e) where b = rowPtrs_[R] and e = rowPtrs_[R+1]
01797     // only the first numRowEntries_[R] of these are valid
01798     // both of these are null for 2D (Dynamic) allocations
01799     // rowPtrs_ has length N+1, while numRowEntries_ has length N
01800     // we may delete this to save memory on fillComplete, if "Delete Row Pointers" is specified
01801     ArrayRCP<size_t> rowPtrs_;
01802 
01804     //
01805     // 2D/Dynamic structures.
01806     //
01808 
01810     ArrayRCP<Array< LocalOrdinal> > lclInds2D_;
01811 
01813     ArrayRCP<Array<GlobalOrdinal> > gblInds2D_;
01814 
01819     ArrayRCP<size_t> numRowEntries_;
01820 
01821     bool indicesAreAllocated_;
01822     bool indicesAreLocal_;
01823     bool indicesAreGlobal_;
01824     bool fillComplete_;
01826     bool lowerTriangular_;
01828     bool upperTriangular_;
01830     bool indicesAreSorted_;
01833     bool noRedundancies_;
01835     bool haveLocalConstants_;
01837     bool haveGlobalConstants_;
01838 
01846     std::map<GlobalOrdinal, std::vector<GlobalOrdinal> > nonlocals_;
01847 
01860     bool haveRowInfo_;
01861 
01862     inline bool hasRowInfo() const {
01863 #ifdef HAVE_TPETRA_DEBUG
01864       bool actuallyHasRowInfo = true;
01865       if (indicesAreAllocated() && getProfileType() == StaticProfile && rowPtrs_ == null) {
01866         actuallyHasRowInfo = false;
01867       }
01868       TEUCHOS_TEST_FOR_EXCEPTION(
01869         actuallyHasRowInfo != haveRowInfo_,
01870         std::logic_error, "Internal logic error. Please contact Tpetra team.");
01871 #endif // HAVE_TPETRA_DEBUG
01872       return haveRowInfo_;
01873     }
01874   }; // class CrsGraph
01875 
01882   template <class LocalOrdinal, class GlobalOrdinal, class Node>
01883   Teuchos::RCP<CrsGraph<LocalOrdinal,GlobalOrdinal,Node> >
01884   createCrsGraph (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &map,
01885                    size_t maxNumEntriesPerRow = 0,
01886                    const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
01887   {
01888     using Teuchos::rcp;
01889     typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node> graph_type;
01890     return rcp (new graph_type (map, maxNumEntriesPerRow, DynamicProfile, params));
01891   }
01892 
01893 
01894 } // namespace Tpetra
01895 
01896 // Include KokkosRefactor partial specialisation if enabled
01897 #if defined(TPETRA_HAVE_KOKKOS_REFACTOR)
01898 #include "Tpetra_KokkosRefactor_CrsGraph_decl.hpp"
01899 #endif
01900 
01901 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines