Tpetra Matrix/Vector Services  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
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 "Tpetra_ConfigDefs.hpp"
00046 
00047 #include <Teuchos_CompileTimeAssert.hpp>
00048 #include <Teuchos_Describable.hpp>
00049 #include <Teuchos_ParameterListAcceptorDefaultBase.hpp>
00050 
00051 #include <Kokkos_DefaultNode.hpp>
00052 #include <Kokkos_DefaultKernels.hpp>
00053 
00054 #include <Tpetra_RowGraph.hpp>
00055 #include <Tpetra_DistObject.hpp>
00056 #include <Tpetra_Exceptions.hpp>
00057 
00058 
00059 namespace Tpetra {
00060 
00061 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00062   //
00063   // Dear users: These are just forward declarations.  Please skip
00064   // over them and go down to the CrsMatrix class declaration.  Thank
00065   // you.
00066   //
00067   template <class LO, class GO, class N>
00068   class CrsGraph;
00069 
00070   template <class S, class LO, class GO, class N>
00071   class CrsMatrix;
00072 
00073   namespace Experimental {
00074     template<class S, class LO, class GO, class N>
00075     class BlockCrsMatrix;
00076   }
00077 
00078   namespace Details {
00079     // Forward declaration of an implementation detail of CrsGraph::clone.
00080     template<class OutputCrsGraphType, class InputCrsGraphType>
00081     class CrsGraphCopier {
00082     public:
00083       static Teuchos::RCP<OutputCrsGraphType>
00084       clone (const InputCrsGraphType& graphIn,
00085              const Teuchos::RCP<typename OutputCrsGraphType::node_type> nodeOut,
00086              const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
00087     };
00088   } // namespace Details
00089 
00090 #endif // DOXYGEN_SHOULD_SKIP_THIS
00091 
00100   struct RowInfo {
00101     size_t localRow;
00102     size_t allocSize;
00103     size_t numEntries;
00104     size_t offset1D;
00105   };
00106 
00107   enum ELocalGlobal {
00108     LocalIndices,
00109     GlobalIndices
00110   };
00111 
00170   template <class LocalOrdinal = RowGraph<>::local_ordinal_type,
00171             class GlobalOrdinal = typename RowGraph<LocalOrdinal>::global_ordinal_type,
00172             class Node = typename RowGraph<LocalOrdinal, GlobalOrdinal>::node_type>
00173   class CrsGraph :
00174     public RowGraph<LocalOrdinal,GlobalOrdinal,Node>,
00175     public DistObject<GlobalOrdinal,LocalOrdinal,GlobalOrdinal,Node>,
00176     public Teuchos::ParameterListAcceptorDefaultBase
00177   {
00178     template <class S, class LO, class GO, class N>
00179     friend class CrsMatrix;
00180     template <class S, class LO, class GO, class N>
00181     friend class Experimental::BlockCrsMatrix;
00182     template <class LO2, class GO2, class N2>
00183     friend class CrsGraph;
00184     template<class OutputCrsGraphType, class InputCrsGraphType>
00185     friend class Details::CrsGraphCopier;
00186 
00187   public:
00189     typedef LocalOrdinal local_ordinal_type;
00191     typedef GlobalOrdinal global_ordinal_type;
00193     typedef Node node_type;
00194 
00196     typedef Tpetra::Map<LocalOrdinal, GlobalOrdinal, node_type> map_type;
00198     typedef Tpetra::Import<LocalOrdinal, GlobalOrdinal, node_type> import_type;
00200     typedef Tpetra::Export<LocalOrdinal, GlobalOrdinal, node_type> export_type;
00201 
00203 
00204 
00222     CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
00223               size_t maxNumEntriesPerRow,
00224               ProfileType pftype = DynamicProfile,
00225               const Teuchos::RCP<Teuchos::ParameterList>& params = null);
00226 
00244     CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
00245               const Teuchos::ArrayRCP<const size_t>& NumEntriesPerRowToAlloc,
00246               ProfileType pftype = DynamicProfile,
00247               const Teuchos::RCP<Teuchos::ParameterList>& params = null);
00248 
00268     CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
00269               const Teuchos::RCP<const map_type>& colMap,
00270               size_t maxNumEntriesPerRow,
00271               ProfileType pftype = DynamicProfile,
00272               const Teuchos::RCP<Teuchos::ParameterList>& params = null);
00273 
00293     CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
00294               const Teuchos::RCP<const map_type>& colMap,
00295               const Teuchos::ArrayRCP<const size_t> &NumEntriesPerRowToAlloc,
00296               ProfileType pftype = DynamicProfile,
00297               const Teuchos::RCP<Teuchos::ParameterList>& params = null);
00298 
00318     CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
00319               const Teuchos::RCP<const map_type>& colMap,
00320               const Teuchos::ArrayRCP<size_t> & rowPointers,
00321               const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
00322               const Teuchos::RCP<Teuchos::ParameterList>& params = null);
00323 
00324 
00352     template<class Node2>
00353     Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node2> >
00354     clone (const Teuchos::RCP<Node2> &node2,
00355            const Teuchos::RCP<Teuchos::ParameterList> &params = null) const
00356     {
00357       typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node2> output_crs_graph_type;
00358       typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node> input_crs_graph_type;
00359       typedef Details::CrsGraphCopier<output_crs_graph_type, input_crs_graph_type> copier_type;
00360       return copier_type::clone (*this, node2, params);
00361     }
00362 
00364     virtual ~CrsGraph();
00365 
00367 
00368 
00369 
00371     void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params);
00372 
00374     Teuchos::RCP<const Teuchos::ParameterList> getValidParameters () const;
00375 
00377 
00378 
00379 
00401     void
00402     insertGlobalIndices (GlobalOrdinal globalRow,
00403                          const Teuchos::ArrayView<const GlobalOrdinal>& indices);
00404 
00406 
00420     void
00421     insertLocalIndices (const LocalOrdinal localRow,
00422                         const Teuchos::ArrayView<const LocalOrdinal> &indices);
00423 
00425 
00434     void removeLocalIndices (LocalOrdinal localRow);
00435 
00437 
00438 
00444 
00450     void globalAssemble ();
00451 
00460     void resumeFill (const Teuchos::RCP<Teuchos::ParameterList> &params = null);
00461 
00479     void
00480     fillComplete (const Teuchos::RCP<const map_type> &domainMap,
00481                   const Teuchos::RCP<const map_type> &rangeMap,
00482                   const Teuchos::RCP<Teuchos::ParameterList> &params = null);
00483 
00490     void fillComplete (const Teuchos::RCP<Teuchos::ParameterList> &params = null);
00491 
00502     void
00503     expertStaticFillComplete (const Teuchos::RCP<const map_type> & domainMap,
00504                               const Teuchos::RCP<const map_type> & rangeMap,
00505                               const Teuchos::RCP<const import_type>& importer = Teuchos::null,
00506                               const Teuchos::RCP<const export_type>& exporter = Teuchos::null,
00507                               const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
00509 
00510 
00511 
00513     Teuchos::RCP<const Comm<int> > getComm() const;
00514 
00516     Teuchos::RCP<Node> getNode() const;
00517 
00519     Teuchos::RCP<const map_type> getRowMap() const;
00520 
00522     Teuchos::RCP<const map_type> getColMap() const;
00523 
00525     Teuchos::RCP<const map_type> getDomainMap() const;
00526 
00528     Teuchos::RCP<const map_type> getRangeMap() const;
00529 
00531     Teuchos::RCP<const import_type> getImporter () const;
00532 
00534     Teuchos::RCP<const export_type> getExporter () const;
00535 
00537 
00539     global_size_t getGlobalNumRows() const;
00540 
00542 
00545     global_size_t getGlobalNumCols() const;
00546 
00548     size_t getNodeNumRows() const;
00549 
00551 
00553     size_t getNodeNumCols() const;
00554 
00556     GlobalOrdinal getIndexBase() const;
00557 
00559 
00561     global_size_t getGlobalNumEntries() const;
00562 
00564     size_t getNodeNumEntries() const;
00565 
00567 
00568     size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const;
00569 
00571 
00572     size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const;
00573 
00575 
00582     size_t getNodeAllocationSize() const;
00583 
00585 
00586     size_t getNumAllocatedEntriesInGlobalRow(GlobalOrdinal globalRow) const;
00587 
00589 
00590     size_t getNumAllocatedEntriesInLocalRow(LocalOrdinal localRow) const;
00591 
00593 
00595     global_size_t getGlobalNumDiags() const;
00596 
00598 
00600     size_t getNodeNumDiags() const;
00601 
00614     size_t getGlobalMaxNumRowEntries() const;
00615 
00617 
00619     size_t getNodeMaxNumRowEntries() const;
00620 
00635     bool hasColMap() const;
00636 
00644     bool isLowerTriangular() const;
00645 
00653     bool isUpperTriangular() const;
00654 
00670     bool isLocallyIndexed() const;
00671 
00687     bool isGloballyIndexed() const;
00688 
00697     bool isFillComplete() const;
00698 
00713     bool isFillActive() const;
00714 
00722     bool isSorted () const;
00723 
00725 
00731     bool isStorageOptimized() const;
00732 
00734     ProfileType getProfileType() const;
00735 
00783     void
00784     getGlobalRowCopy (GlobalOrdinal GlobalRow,
00785                       const Teuchos::ArrayView<GlobalOrdinal>& Indices,
00786                       size_t& NumIndices) const;
00787 
00834     void
00835     getLocalRowCopy (LocalOrdinal LocalRow,
00836                      const Teuchos::ArrayView<LocalOrdinal>& indices,
00837                      size_t& NumIndices) const;
00838 
00858     void
00859     getGlobalRowView (GlobalOrdinal GlobalRow,
00860                       Teuchos::ArrayView<const GlobalOrdinal>& Indices) const;
00861 
00881     void
00882     getLocalRowView (LocalOrdinal LocalRow,
00883                      Teuchos::ArrayView<const LocalOrdinal>& indices) const;
00884 
00886 
00887 
00888 
00890     std::string description() const;
00891 
00893     void
00894     describe (Teuchos::FancyOStream& out,
00895               const Teuchos::EVerbosityLevel verbLevel =
00896               Teuchos::Describable::verbLevel_default) const;
00898 
00899 
00900 
00901     virtual bool
00902     checkSizes (const SrcDistObject& source);
00903 
00904     virtual void
00905     copyAndPermute (const SrcDistObject& source,
00906                     size_t numSameIDs,
00907                     const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
00908                     const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs);
00909 
00910     virtual void
00911     packAndPrepare (const SrcDistObject& source,
00912                     const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
00913                     Teuchos::Array<GlobalOrdinal> &exports,
00914                     const Teuchos::ArrayView<size_t> & numPacketsPerLID,
00915                     size_t& constantNumPackets,
00916                     Distributor &distor);
00917 
00918     virtual void
00919     pack (const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
00920           Teuchos::Array<GlobalOrdinal>& exports,
00921           const Teuchos::ArrayView<size_t>& numPacketsPerLID,
00922           size_t& constantNumPackets,
00923           Distributor& distor) const;
00924 
00925     virtual void
00926     unpackAndCombine (const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
00927                       const Teuchos::ArrayView<const GlobalOrdinal> &imports,
00928                       const Teuchos::ArrayView<size_t> &numPacketsPerLID,
00929                       size_t constantNumPackets,
00930                       Distributor &distor,
00931                       CombineMode CM);
00933 
00934 
00935 
00958     void
00959     getNumEntriesPerLocalRowUpperBound (Teuchos::ArrayRCP<const size_t>& boundPerLocalRow,
00960                                         size_t& boundForAllLocalRows,
00961                                         bool& boundSameForAllLocalRows) const;
00962 
00971     void
00972     setAllIndices (const Teuchos::ArrayRCP<size_t> & rowPointers,
00973                    const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices);
00974 
00976 
00979     Teuchos::ArrayRCP<const size_t> getNodeRowPtrs() const;
00980 
00982 
00984     Teuchos::ArrayRCP<const LocalOrdinal> getNodePackedIndices() const;
00985 
00996     void replaceColMap (const Teuchos::RCP<const map_type>& newColMap);
00997 
01017     void
01018     reindexColumns (const Teuchos::RCP<const map_type>& newColMap,
01019                     const Teuchos::RCP<const import_type>& newImport = Teuchos::null,
01020                     const bool sortIndicesInEachRow = true);
01021 
01034     void
01035     replaceDomainMapAndImporter (const Teuchos::RCP<const map_type>& newDomainMap,
01036                                  const Teuchos::RCP<const import_type>& newImporter);
01037 
01065     virtual void
01066     removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
01068 
01069   protected:
01070     typedef typename KokkosClassic::DefaultKernels<void, LocalOrdinal, Node>::SparseOps
01071       sparse_ops_type;
01072     typedef typename sparse_ops_type::template graph<LocalOrdinal, Node>::graph_type
01073       local_graph_type;
01074 
01075     // these structs are conveniences, to cut down on the number of
01076     // arguments to some of the methods below.
01077     struct SLocalGlobalViews {
01078       Teuchos::ArrayView<const GlobalOrdinal> ginds;
01079       Teuchos::ArrayView<const LocalOrdinal>  linds;
01080     };
01081     struct SLocalGlobalNCViews {
01082       Teuchos::ArrayView<GlobalOrdinal>       ginds;
01083       Teuchos::ArrayView<LocalOrdinal>        linds;
01084     };
01085     //
01086     // Allocation
01087     //
01088     bool indicesAreAllocated() const;
01089 
01090     void allocateIndices (ELocalGlobal lg);
01091 
01092     template <class T>
01093     Teuchos::ArrayRCP<T> allocateValues1D () const;
01094     template <class T>
01095     Teuchos::ArrayRCP<Array<T> > allocateValues2D () const;
01096 
01097     template <ELocalGlobal lg, class T>
01098     RowInfo updateAllocAndValues (RowInfo rowinfo, size_t newAllocSize, Array<T>& rowVals)
01099     {
01100 #ifdef HAVE_TPETRA_DEBUG
01101       TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement(rowinfo.localRow) );
01102       TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowinfo.allocSize );
01103       TEUCHOS_TEST_FOR_EXCEPT( (lg == LocalIndices && ! isLocallyIndexed()) ||
01104                                (lg == GlobalIndices && ! isGloballyIndexed()) );
01105       TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
01106       TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated() );
01107 #endif
01108       // ArrayRCP::resize automatically copies over values on reallocation.
01109       if (lg == LocalIndices) {
01110         lclInds2D_[rowinfo.localRow].resize (newAllocSize);
01111       }
01112       else { // lg == GlobalIndices
01113         gblInds2D_[rowinfo.localRow].resize (newAllocSize);
01114       }
01115       rowVals.resize (newAllocSize);
01116       nodeNumAllocated_ += (newAllocSize - rowinfo.allocSize);
01117       rowinfo.allocSize = newAllocSize;
01118       return rowinfo;
01119     }
01120 
01122 
01123 
01125     void makeColMap ();
01126     void makeIndicesLocal ();
01127     void makeImportExport ();
01128 
01130 
01131 
01132 
01133     template<ELocalGlobal lg>
01134     size_t filterIndices (const SLocalGlobalNCViews &inds) const;
01135 
01136     template<class T>
01137     size_t
01138     filterGlobalIndicesAndValues (const Teuchos::ArrayView<GlobalOrdinal>& ginds,
01139                                   const Teuchos::ArrayView<T>& vals) const
01140     {
01141       using Teuchos::ArrayView;
01142 
01143       const map_type& cmap = *colMap_;
01144       size_t numFiltered = 0;
01145       typename ArrayView<T>::iterator fvalsend = vals.begin();
01146       typename ArrayView<T>::iterator valscptr = vals.begin();
01147 #ifdef HAVE_TPETRA_DEBUG
01148       size_t numFiltered_debug = 0;
01149 #endif
01150       typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
01151       typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
01152       while (cptr != ginds.end()) {
01153         if (cmap.isNodeGlobalElement (*cptr)) {
01154           *fend++ = *cptr;
01155           *fvalsend++ = *valscptr;
01156 #ifdef HAVE_TPETRA_DEBUG
01157           ++numFiltered_debug;
01158 #endif
01159         }
01160         ++cptr;
01161         ++valscptr;
01162       }
01163       numFiltered = fend - ginds.begin();
01164 #ifdef HAVE_TPETRA_DEBUG
01165       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
01166       TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
01167       const size_t numFilteredActual =
01168         static_cast<size_t> (fvalsend - vals.begin ());
01169       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
01170 #endif
01171       return numFiltered;
01172     }
01173 
01174     template<class T>
01175     size_t
01176     filterLocalIndicesAndValues (const Teuchos::ArrayView<LocalOrdinal>& linds,
01177                                  const Teuchos::ArrayView<T>& vals) const
01178     {
01179       using Teuchos::ArrayView;
01180 
01181       const map_type& cmap = *colMap_;
01182       size_t numFiltered = 0;
01183       typename ArrayView<T>::iterator fvalsend = vals.begin();
01184       typename ArrayView<T>::iterator valscptr = vals.begin();
01185 #ifdef HAVE_TPETRA_DEBUG
01186       size_t numFiltered_debug = 0;
01187 #endif
01188       typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
01189       typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
01190       while (cptr != linds.end()) {
01191         if (cmap.isNodeLocalElement (*cptr)) {
01192           *fend++ = *cptr;
01193           *fvalsend++ = *valscptr;
01194 #ifdef HAVE_TPETRA_DEBUG
01195           ++numFiltered_debug;
01196 #endif
01197         }
01198         ++cptr;
01199         ++valscptr;
01200       }
01201       numFiltered = fend - linds.begin();
01202 #ifdef HAVE_TPETRA_DEBUG
01203       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
01204       TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
01205       const size_t numFilteredActual =
01206         static_cast<size_t> (fvalsend - vals.begin ());
01207       TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
01208 #endif
01209       return numFiltered;
01210     }
01211 
01241     size_t
01242     insertIndices (const RowInfo& rowInfo,
01243                    const SLocalGlobalViews& newInds,
01244                    const ELocalGlobal lg,
01245                    const ELocalGlobal I);
01246 
01286     template<class Scalar>
01287     void
01288     insertIndicesAndValues (const RowInfo& rowInfo,
01289                             const SLocalGlobalViews& newInds,
01290                             const Teuchos::ArrayView<Scalar>& oldRowVals,
01291                             const Teuchos::ArrayView<const Scalar>& newRowVals,
01292                             const ELocalGlobal lg,
01293                             const ELocalGlobal I)
01294     {
01295       const size_t numNewInds = insertIndices (rowInfo, newInds, lg, I);
01296       typename Teuchos::ArrayView<const Scalar>::const_iterator newRowValsBegin =
01297         newRowVals.begin ();
01298       std::copy (newRowValsBegin, newRowValsBegin + numNewInds,
01299                  oldRowVals.begin () + rowInfo.numEntries);
01300     }
01301 
01302     void
01303     insertGlobalIndicesImpl (const LocalOrdinal myRow,
01304                              const Teuchos::ArrayView<const GlobalOrdinal> &indices);
01305     void
01306     insertLocalIndicesImpl (const LocalOrdinal myRow,
01307                             const Teuchos::ArrayView<const LocalOrdinal> &indices);
01309     void
01310     insertLocalIndicesFiltered (const LocalOrdinal localRow,
01311                                 const Teuchos::ArrayView<const LocalOrdinal> &indices);
01312 
01314     void
01315     insertGlobalIndicesFiltered (const GlobalOrdinal localRow,
01316                                  const Teuchos::ArrayView<const GlobalOrdinal> &indices);
01317 
01345     template<class Scalar, class BinaryFunction>
01346     LocalOrdinal
01347     transformLocalValues (RowInfo rowInfo,
01348                           const Teuchos::ArrayView<Scalar>& rowVals,
01349                           const Teuchos::ArrayView<const LocalOrdinal>& inds,
01350                           const Teuchos::ArrayView<const Scalar>& newVals,
01351                           BinaryFunction f) const
01352     {
01353       typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
01354       const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
01355       const size_type numElts = inds.size ();
01356       size_t hint = 0; // Guess for the current index k into rowVals
01357 
01358       // Get a view of the column indices in the row.  This amortizes
01359       // the cost of getting the view over all the entries of inds.
01360       Teuchos::ArrayView<const LocalOrdinal> colInds = getLocalView (rowInfo);
01361 
01362       LocalOrdinal numValid = 0; // number of valid local column indices
01363       for (size_type j = 0; j < numElts; ++j) {
01364         const size_t k = findLocalIndex (rowInfo, inds[j], colInds, hint);
01365         if (k != STINV) {
01366           rowVals[k] = f (rowVals[k], newVals[j]); // use binary function f
01367           hint = k+1;
01368           ++numValid;
01369         }
01370       }
01371       return numValid;
01372     }
01373 
01393     template<class Scalar, class BinaryFunction>
01394     LocalOrdinal
01395     transformGlobalValues (RowInfo rowInfo,
01396                            const Teuchos::ArrayView<Scalar>& rowVals,
01397                            const Teuchos::ArrayView<const GlobalOrdinal>& inds,
01398                            const Teuchos::ArrayView<const Scalar>& newVals,
01399                            BinaryFunction f) const
01400     {
01401       typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
01402       const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
01403       const size_type numElts = inds.size ();
01404       size_t hint = 0; // guess at the index's relative offset in the row
01405 
01406       LocalOrdinal numValid = 0; // number of valid local column indices
01407       for (size_type j = 0; j < numElts; ++j) {
01408         const size_t k = findGlobalIndex (rowInfo, inds[j], hint);
01409         if (k != STINV) {
01410           rowVals[k] = f (rowVals[k], newVals[j]); // use binary function f
01411           hint = k+1;
01412           numValid++;
01413         }
01414       }
01415       return numValid;
01416     }
01417 
01419 
01420 
01421 
01423     bool isMerged () const;
01424 
01430     void setLocallyModified ();
01431 
01433     void sortAllIndices ();
01434 
01436     void sortRowIndices (RowInfo rowinfo);
01437 
01452     template <class Scalar>
01453     void
01454     sortRowIndicesAndValues (const RowInfo rowinfo,
01455                              const Teuchos::ArrayView<Scalar>& values);
01456 
01465     void mergeAllIndices ();
01466 
01471     void mergeRowIndices (RowInfo rowinfo);
01472 
01483     template<class Scalar>
01484     void
01485     mergeRowIndicesAndValues (RowInfo rowinfo,
01486                               const Teuchos::ArrayView<Scalar>& rowValues);
01488 
01498     void
01499     setDomainRangeMaps (const Teuchos::RCP<const map_type> &domainMap,
01500                         const Teuchos::RCP<const map_type> &rangeMap);
01501 
01502     void staticAssertions() const;
01503     // global consts
01504     void clearGlobalConstants();
01505     void computeGlobalConstants();
01506 
01508 
01509 
01513     RowInfo getRowInfo (size_t myRow) const;
01514 
01521     Teuchos::ArrayView<const LocalOrdinal> getLocalView (RowInfo rowinfo) const;
01522 
01529     Teuchos::ArrayView<LocalOrdinal> getLocalViewNonConst (RowInfo rowinfo);
01530 
01537     Teuchos::ArrayView<const GlobalOrdinal> getGlobalView (RowInfo rowinfo) const;
01538 
01545     Teuchos::ArrayView<GlobalOrdinal> getGlobalViewNonConst (RowInfo rowinfo);
01546 
01581     size_t
01582     findLocalIndex (RowInfo rowinfo,
01583                     LocalOrdinal ind,
01584                     size_t hint = 0) const;
01585 
01614     size_t
01615     findLocalIndex (RowInfo rowinfo,
01616                     LocalOrdinal ind,
01617                     Teuchos::ArrayView<const LocalOrdinal> colInds,
01618                     size_t hint = 0) const;
01619 
01627     size_t findGlobalIndex (RowInfo rowinfo, GlobalOrdinal ind, size_t hint = 0) const;
01628 
01630 
01631 
01632 
01633     void fillLocalGraph (const Teuchos::RCP<Teuchos::ParameterList> &params);
01634     const Teuchos::RCP<const local_graph_type> getLocalGraph() const;
01635     const Teuchos::RCP<local_graph_type> getLocalGraphNonConst();
01636 
01638 
01647     void checkInternalState() const;
01648 
01650     Teuchos::RCP<const map_type> rowMap_;
01652     Teuchos::RCP<const map_type> colMap_;
01654     Teuchos::RCP<const map_type> rangeMap_;
01656     Teuchos::RCP<const map_type> domainMap_;
01657 
01664     Teuchos::RCP<const import_type> importer_;
01665 
01671     Teuchos::RCP<const export_type> exporter_;
01672 
01673     // local data, stored in a KokkosClassic::CrsGraph. only initialized after fillComplete()
01674     Teuchos::RCP<local_graph_type> lclGraph_;
01675 
01676     // Local and Global Counts
01677     // nodeNumEntries_ and nodeNumAllocated_ are required to be always consistent
01678     // nodeMaxNumEntries_, nodeNumDiags_ and the global quantities are computed during fillComplete() and only valid when isFillComplete()
01679     global_size_t globalNumEntries_, globalNumDiags_, globalMaxNumRowEntries_;
01680     size_t          nodeNumEntries_,   nodeNumDiags_,   nodeMaxNumRowEntries_, nodeNumAllocated_;
01681 
01683     ProfileType pftype_;
01684 
01694     Teuchos::ArrayRCP<const size_t> numAllocPerRow_;
01695 
01700     size_t numAllocForAllRows_;
01701 
01702     // graph indices. before allocation, all are null.
01703     // after allocation, except during makeIndicesLocal(), one of local or global is null.
01704     // we will never have 1D and 2D structures being non-null
01705     // this is host memory
01706     // 1D == StaticAllocation, 2D == DynamicAllocation
01708     //
01709     // 1D/Static structures
01710     //
01712 
01714     Teuchos::ArrayRCP<LocalOrdinal> lclInds1D_;
01716     Teuchos::ArrayRCP<GlobalOrdinal> gblInds1D_;
01717     // offset to the beg entries of each row. only used for 1D (Static) allocation.
01718     // i.e., indices for row R are lclInds1D_[i] for i in [b,e) where b = rowPtrs_[R] and e = rowPtrs_[R+1]
01719     // only the first numRowEntries_[R] of these are valid
01720     // both of these are null for 2D (Dynamic) allocations
01721     // rowPtrs_ has length N+1, while numRowEntries_ has length N
01722     // we may delete this to save memory on fillComplete, if "Delete Row Pointers" is specified
01723     Teuchos::ArrayRCP<size_t> rowPtrs_;
01724 
01726     //
01727     // 2D/Dynamic structures.
01728     //
01730 
01732     Teuchos::ArrayRCP<Teuchos::Array<LocalOrdinal> > lclInds2D_;
01733 
01735     Teuchos::ArrayRCP<Teuchos::Array<GlobalOrdinal> > gblInds2D_;
01736 
01741     Teuchos::ArrayRCP<size_t> numRowEntries_;
01742 
01743     bool indicesAreAllocated_;
01744     bool indicesAreLocal_;
01745     bool indicesAreGlobal_;
01746     bool fillComplete_;
01748     bool lowerTriangular_;
01750     bool upperTriangular_;
01752     bool indicesAreSorted_;
01755     bool noRedundancies_;
01757     bool haveLocalConstants_;
01759     bool haveGlobalConstants_;
01760 
01768     std::map<GlobalOrdinal, std::vector<GlobalOrdinal> > nonlocals_;
01769 
01781     bool hasRowInfo () const;
01782 
01797     bool sortGhostsAssociatedWithEachProcessor_;
01798 
01799   }; // class CrsGraph
01800 
01807   template <class LocalOrdinal, class GlobalOrdinal, class Node>
01808   Teuchos::RCP<CrsGraph<LocalOrdinal,GlobalOrdinal,Node> >
01809   createCrsGraph (const Teuchos::RCP<const Map<LocalOrdinal,GlobalOrdinal,Node> > &map,
01810                    size_t maxNumEntriesPerRow = 0,
01811                    const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
01812   {
01813     using Teuchos::rcp;
01814     typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node> graph_type;
01815     return rcp (new graph_type (map, maxNumEntriesPerRow, DynamicProfile, params));
01816   }
01817 
01818 
01819 
01820 namespace Details {
01821 
01822 template<class LocalOrdinal, class GlobalOrdinal, class OutputNodeType, class InputNodeType>
01823 class CrsGraphCopier<CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType>,
01824                      CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> > {
01825 public:
01826   typedef CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> input_crs_graph_type;
01827   typedef CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType> output_crs_graph_type;
01828 
01829   static Teuchos::RCP<output_crs_graph_type>
01830   clone (const input_crs_graph_type& graphIn,
01831          const Teuchos::RCP<OutputNodeType> &nodeOut,
01832          const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
01833   {
01834     using Teuchos::arcp;
01835     using Teuchos::ArrayRCP;
01836     using Teuchos::ArrayView;
01837     using Teuchos::null;
01838     using Teuchos::outArg;
01839     using Teuchos::ParameterList;
01840     using Teuchos::parameterList;
01841     using Teuchos::RCP;
01842     using Teuchos::rcp;
01843     using Teuchos::REDUCE_MIN;
01844     using Teuchos::reduceAll;
01845     using Teuchos::sublist;
01846     using std::cerr;
01847     using std::endl;
01848     typedef LocalOrdinal LO;
01849     typedef GlobalOrdinal GO;
01850     typedef typename ArrayView<const GO>::size_type size_type;
01851     typedef ::Tpetra::Map<LO, GO, InputNodeType> input_map_type;
01852     typedef ::Tpetra::Map<LO, GO, OutputNodeType> output_map_type;
01853     const char prefix[] = "Tpetra::Details::CrsGraphCopier::clone: ";
01854 
01855     // Set parameters' default values.
01856     bool debug = false;
01857     bool fillCompleteClone = true;
01858     bool useLocalIndices = graphIn.hasColMap ();
01859     ProfileType pftype = StaticProfile;
01860     // If the user provided a ParameterList, get values from there.
01861     if (! params.is_null ()) {
01862       fillCompleteClone = params->get ("fillComplete clone", fillCompleteClone);
01863       useLocalIndices = params->get ("Locally indexed clone", useLocalIndices);
01864       if (params->get ("Static profile clone", true) == false) {
01865         pftype = DynamicProfile;
01866       }
01867       debug = params->get ("Debug", debug);
01868     }
01869 
01870     const Teuchos::Comm<int>& comm = * (graphIn.getRowMap ()->getComm ());
01871     const int myRank = comm.getRank ();
01872 
01873     TEUCHOS_TEST_FOR_EXCEPTION(
01874       ! graphIn.hasColMap () && useLocalIndices, std::runtime_error,
01875       prefix << "You asked clone() to use local indices (by setting the "
01876       "\"Locally indexed clone\" parameter to true), but the source graph "
01877       "does not yet have a column Map, so this is impossible.");
01878 
01879     if (debug) {
01880       std::ostringstream os;
01881       os << "Process " << myRank << ": Cloning row Map" << endl;
01882       cerr << os.str ();
01883     }
01884 
01885     RCP<const output_map_type> clonedRowMap =
01886       graphIn.getRowMap ()->template clone<OutputNodeType> (nodeOut);
01887 
01888     // Invoke the output graph's constructor, using the input graph's
01889     // upper bounds on the number of entries in each local row.
01890     RCP<output_crs_graph_type> clonedGraph; // returned by this function
01891     {
01892       ArrayRCP<const size_t> numEntriesPerRow;
01893       size_t numEntriesForAll = 0;
01894       bool boundSameForAllLocalRows = true;
01895 
01896       if (debug) {
01897         std::ostringstream os;
01898         os << "Process " << myRank << ": Getting per-row bounds" << endl;
01899         cerr << os.str ();
01900       }
01901       graphIn.getNumEntriesPerLocalRowUpperBound (numEntriesPerRow,
01902                                                   numEntriesForAll,
01903                                                   boundSameForAllLocalRows);
01904       if (debug) {
01905         std::ostringstream os;
01906         os << "Process " << myRank << ": numEntriesForAll = "
01907            << numEntriesForAll << endl;
01908         cerr << os.str ();
01909       }
01910 
01911       if (debug) {
01912         std::ostringstream os;
01913         os << "Process " << myRank << ": graphIn.getNodeMaxNumRowEntries() = "
01914            << graphIn.getNodeMaxNumRowEntries () << endl;
01915         cerr << os.str ();
01916       }
01917 
01918       RCP<ParameterList> graphparams;
01919       if (params.is_null ()) {
01920         graphparams = parameterList ("CrsGraph");
01921       } else {
01922         graphparams = sublist (params, "CrsGraph");
01923       }
01924       if (useLocalIndices) {
01925         RCP<const output_map_type> clonedColMap =
01926           graphIn.getColMap ()->template clone<OutputNodeType> (nodeOut);
01927         if (boundSameForAllLocalRows) {
01928           clonedGraph = rcp (new output_crs_graph_type (clonedRowMap, clonedColMap,
01929                                                         numEntriesForAll, pftype,
01930                                                         graphparams));
01931         } else {
01932           clonedGraph = rcp (new output_crs_graph_type (clonedRowMap, clonedColMap,
01933                                                         numEntriesPerRow, pftype,
01934                                                         graphparams));
01935         }
01936       } else {
01937         if (boundSameForAllLocalRows) {
01938           clonedGraph = rcp (new output_crs_graph_type (clonedRowMap,
01939                                                         numEntriesForAll, pftype,
01940                                                         graphparams));
01941         } else {
01942           clonedGraph = rcp (new output_crs_graph_type (clonedRowMap,
01943                                                         numEntriesPerRow,
01944                                                         pftype, graphparams));
01945         }
01946       }
01947 
01948       if (debug) {
01949         std::ostringstream os;
01950         os << "Process " << myRank << ": Invoked output graph's constructor" << endl;
01951         cerr << os.str ();
01952       }
01953 
01954       // done with these
01955       numEntriesPerRow = null;
01956       numEntriesForAll = 0;
01957     }
01958 
01959     const input_map_type& inputRowMap = * (graphIn.getRowMap ());
01960     const size_type numRows =
01961       static_cast<size_type> (inputRowMap.getNodeNumElements ());
01962 
01963     bool failed = false;
01964 
01965     if (useLocalIndices) {
01966       const LO localMinLID = inputRowMap.getMinLocalIndex ();
01967       const LO localMaxLID = inputRowMap.getMaxLocalIndex ();
01968 
01969       if (graphIn.isLocallyIndexed ()) {
01970         if (numRows != 0) {
01971           try {
01972             ArrayView<const LO> linds;
01973             for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
01974               graphIn.getLocalRowView (lrow, linds);
01975               if (linds.size () != 0) {
01976                 clonedGraph->insertLocalIndices (lrow, linds);
01977               }
01978             }
01979           }
01980           catch (std::exception& e) {
01981             std::ostringstream os;
01982             os << "Process " << myRank << ": copying (reading local by view, "
01983               "writing local) indices into the output graph threw an "
01984               "exception: " << e.what () << endl;
01985             cerr << os.str ();
01986             failed = true;
01987           }
01988         }
01989       }
01990       else { // graphIn.isGloballyIndexed()
01991         TEUCHOS_TEST_FOR_EXCEPTION(
01992           ! graphIn.hasColMap () && useLocalIndices, std::invalid_argument,
01993           prefix << "You asked clone() to use local indices (by setting the "
01994           "\"Locally indexed clone\" parameter to true), but the source graph "
01995           "does not yet have a column Map, so this is impossible.");
01996 
01997         // The input graph has a column Map, but is globally indexed.
01998         // That's a bit weird, but we'll run with it.  In this case,
01999         // getLocalRowView won't work, but getLocalRowCopy should
02000         // still work; it will just have to convert from global to
02001         // local indices internally.
02002 
02003         try {
02004           // Make space for getLocalRowCopy to put column indices.
02005           //
02006           // This is only a hint; we may have to resize in the loop
02007           // below.  getNodeMaxNumRowEntries() may return nonsense if
02008           // fill is active.  The key bool in CrsGraph is
02009           // haveLocalConstants_.
02010           size_t myMaxNumRowEntries =
02011             graphIn.isFillActive () ? static_cast<size_t> (0) :
02012             graphIn.getNodeMaxNumRowEntries ();
02013 
02014           Array<LO> linds (myMaxNumRowEntries);
02015 
02016           // Copy each row into the new graph, using local indices.
02017           for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
02018             size_t theNumEntries = graphIn.getNumEntriesInLocalRow (lrow);
02019             if (theNumEntries > myMaxNumRowEntries) {
02020               myMaxNumRowEntries = theNumEntries;
02021               linds.resize (myMaxNumRowEntries);
02022             }
02023             graphIn.getLocalRowCopy (lrow, linds (), theNumEntries);
02024             if (theNumEntries != 0) {
02025               clonedGraph->insertLocalIndices (lrow, linds (0, theNumEntries));
02026             }
02027           }
02028         }
02029         catch (std::exception& e) {
02030           std::ostringstream os;
02031           os << "Process " << myRank << ": copying (reading local by copy, "
02032             "writing local) indices into the output graph threw an exception: "
02033              << e.what () << endl;
02034           cerr << os.str ();
02035           failed = true;
02036         }
02037       }
02038     }
02039     else { /* useGlobalIndices */
02040       if (numRows != 0) {
02041         const GlobalOrdinal localMinGID = inputRowMap.getMinGlobalIndex ();
02042         const GlobalOrdinal localMaxGID = inputRowMap.getMaxGlobalIndex ();
02043         const bool inputRowMapIsContiguous = inputRowMap.isContiguous ();
02044 
02045         if (graphIn.isGloballyIndexed ()) {
02046           ArrayView<const GlobalOrdinal> ginds;
02047 
02048           if (inputRowMapIsContiguous) {
02049             try {
02050               for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
02051                 graphIn.getGlobalRowView (grow, ginds);
02052                 if (ginds.size () != 0) {
02053                   clonedGraph->insertGlobalIndices (grow, ginds);
02054                 }
02055               }
02056             }
02057             catch (std::exception& e) {
02058               std::ostringstream os;
02059               os << "Process " << myRank << ": copying (reading global by view, "
02060                 "writing global) indices into the output graph threw an "
02061                 "exception: " << e.what () << endl;
02062               cerr << os.str ();
02063               failed = true;
02064             }
02065           }
02066           else { // input row Map is not contiguous
02067             try {
02068               ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
02069               for (size_type k = 0; k < numRows; ++k) {
02070                 const GO grow = inputRowMapGIDs[k];
02071                 graphIn.getGlobalRowView (grow, ginds);
02072                 if (ginds.size () != 0) {
02073                   clonedGraph->insertGlobalIndices (grow, ginds);
02074                 }
02075               }
02076             }
02077             catch (std::exception& e) {
02078               std::ostringstream os;
02079               os << "Process " << myRank << ": copying (reading global by view, "
02080                 "writing global) indices into the output graph threw an "
02081                 "exception: " << e.what () << endl;
02082               cerr << os.str ();
02083               failed = true;
02084             }
02085           }
02086         }
02087         else { // graphIn.isLocallyIndexed()
02088           // Make space for getGlobalRowCopy to put column indices.
02089           //
02090           // This is only a hint; we may have to resize in the loop
02091           // below.  getNodeMaxNumRowEntries() may return nonsense if
02092           // fill is active.  The key bool in CrsGraph is
02093           // haveLocalConstants_.
02094           size_t myMaxNumRowEntries =
02095             graphIn.isFillActive () ? static_cast<size_t> (0) :
02096             graphIn.getNodeMaxNumRowEntries ();
02097 
02098           Array<GO> ginds (myMaxNumRowEntries);
02099 
02100           if (inputRowMapIsContiguous) {
02101             try {
02102               for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
02103                 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
02104                 if (theNumEntries > myMaxNumRowEntries) {
02105                   myMaxNumRowEntries = theNumEntries;
02106                   ginds.resize (myMaxNumRowEntries);
02107                 }
02108                 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
02109                 if (theNumEntries != 0) {
02110                   clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
02111                 }
02112               }
02113             }
02114             catch (std::exception& e) {
02115               std::ostringstream os;
02116               os << "Process " << myRank << ": copying (reading global by copy, "
02117                 "writing global) indices into the output graph threw an "
02118                 "exception: " << e.what () << endl;
02119               cerr << os.str ();
02120               failed = true;
02121             }
02122           }
02123           else { // input row Map is not contiguous
02124             try {
02125               ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
02126               for (size_type k = 0; k < numRows; ++k) {
02127                 const GO grow = inputRowMapGIDs[k];
02128 
02129                 size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
02130                 if (theNumEntries > myMaxNumRowEntries) {
02131                   myMaxNumRowEntries = theNumEntries;
02132                   ginds.resize (myMaxNumRowEntries);
02133                 }
02134                 graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
02135                 if (theNumEntries != 0) {
02136                   clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
02137                 }
02138               }
02139             }
02140             catch (std::exception& e) {
02141               std::ostringstream os;
02142               os << "Process " << myRank << ": copying (reading global by copy, "
02143                 "writing global) indices into the output graph threw an "
02144                 "exception: " << e.what () << endl;
02145               cerr << os.str ();
02146               failed = true;
02147             }
02148           }
02149         }
02150       } // numRows != 0
02151     }
02152 
02153     if (debug) {
02154       std::ostringstream os;
02155       os << "Process " << myRank << ": copied entries" << endl;
02156       cerr << os.str ();
02157     }
02158 
02159     if (fillCompleteClone) {
02160       RCP<ParameterList> fillparams = params.is_null () ?
02161         parameterList ("fillComplete") :
02162         sublist (params, "fillComplete");
02163       try {
02164         RCP<const output_map_type> clonedRangeMap;
02165         RCP<const output_map_type> clonedDomainMap;
02166         if (! graphIn.getRangeMap ().is_null () &&
02167             graphIn.getRangeMap () != graphIn.getRowMap ()) {
02168           clonedRangeMap =
02169             graphIn.getRangeMap ()->template clone<OutputNodeType> (nodeOut);
02170         }
02171         else {
02172           clonedRangeMap = clonedRowMap;
02173         }
02174         if (! graphIn.getDomainMap ().is_null ()
02175             && graphIn.getDomainMap () != graphIn.getRowMap ()) {
02176           clonedDomainMap =
02177             graphIn.getDomainMap ()->template clone<OutputNodeType> (nodeOut);
02178         }
02179         else {
02180           clonedDomainMap = clonedRowMap;
02181         }
02182 
02183         if (debug) {
02184           std::ostringstream os;
02185           os << "Process " << myRank << ": About to call fillComplete on "
02186             "cloned graph" << endl;
02187           cerr << os.str ();
02188         }
02189         clonedGraph->fillComplete (clonedDomainMap, clonedRangeMap, fillparams);
02190       }
02191       catch (std::exception &e) {
02192         failed = true;
02193         std::ostringstream os;
02194         os << prefix << "Process " << myRank << ": Caught the following "
02195           "exception while calling fillComplete() on clone of type"
02196            << endl << Teuchos::typeName (*clonedGraph) << endl;
02197         cerr << os.str ();
02198       }
02199     }
02200 
02201     int lclSuccess = failed ? 0 : 1;
02202     int gblSuccess = 1;
02203     reduceAll<int, int> (comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
02204     TEUCHOS_TEST_FOR_EXCEPTION(
02205       gblSuccess != 1, std::logic_error, prefix <<
02206       "Clone failed on at least one process.");
02207 
02208     if (debug) {
02209       std::ostringstream os;
02210       os << "Process " << myRank << ": Done with CrsGraph::clone" << endl;
02211       cerr << os.str ();
02212     }
02213     return clonedGraph;
02214   }
02215 };
02216 
02217 } // namespace Details
02218 } // namespace Tpetra
02219 
02220 // Include KokkosRefactor partial specialisation if enabled
02221 #if defined(TPETRA_HAVE_KOKKOS_REFACTOR)
02222 #include "Tpetra_KokkosRefactor_CrsGraph_decl.hpp"
02223 #endif
02224 
02225 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines