Tpetra parallel linear algebra  Version of the Day
Tpetra_CrsGraph_decl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 #ifndef TPETRA_CRSGRAPH_DECL_HPP
43 #define TPETRA_CRSGRAPH_DECL_HPP
44 
52 
53 #include "Tpetra_ConfigDefs.hpp"
54 #include "Tpetra_RowGraph.hpp"
55 #include "Tpetra_DistObject.hpp"
56 #include "Tpetra_Exceptions.hpp"
57 
58 #include "KokkosCompat_ClassicNodeAPI_Wrapper.hpp"
59 #include "Kokkos_DualView.hpp"
60 #include "Kokkos_StaticCrsGraph.hpp"
61 
62 #include "Teuchos_Describable.hpp"
63 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
64 
65 
66 namespace Tpetra {
67 
68 #ifndef DOXYGEN_SHOULD_SKIP_THIS
69  //
70  // Dear users: These are just forward declarations. Please skip
71  // over them and go down to the CrsMatrix class declaration. Thank
72  // you.
73  //
74  template <class LO, class GO, class N, const bool isClassic>
75  class CrsGraph;
76 
77  // forward declaration (needed for "friend" inside CrsGraph)
78  template <class S, class LO, class GO, class N, const bool isClassic>
79  class CrsMatrix;
80 
81  namespace Experimental {
82  // forward declaration (needed for "friend" inside CrsGraph)
83  template<class S, class LO, class GO, class N>
84  class BlockCrsMatrix;
85  } // namespace Experimental
86 
87  namespace Details {
88  // Forward declaration of an implementation detail of CrsGraph::clone.
89  template<class OutputCrsGraphType, class InputCrsGraphType>
90  class CrsGraphCopier {
91  public:
92  static Teuchos::RCP<OutputCrsGraphType>
93  clone (const InputCrsGraphType& graphIn,
94  const Teuchos::RCP<typename OutputCrsGraphType::node_type> nodeOut,
95  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
96  };
97  } // namespace Details
98 #endif // DOXYGEN_SHOULD_SKIP_THIS
99 
108  struct RowInfo {
109  size_t localRow;
110  size_t allocSize;
111  size_t numEntries;
112  size_t offset1D;
113  };
114 
115  enum ELocalGlobal {
116  LocalIndices,
117  GlobalIndices
118  };
119 
120  namespace Details {
161  STORAGE_2D, //<! 2-D storage
162  STORAGE_1D_UNPACKED, //<! 1-D "unpacked" storage
163  STORAGE_1D_PACKED, //<! 1-D "packed" storage
164  STORAGE_UB //<! Invalid value; upper bound on enum values
165  };
166  } // namespace Details
167 
226  template <class LocalOrdinal = Details::DefaultTypes::local_ordinal_type,
227  class GlobalOrdinal = Details::DefaultTypes::global_ordinal_type,
229  const bool classic = Node::classic>
230  class CrsGraph :
231  public RowGraph<LocalOrdinal, GlobalOrdinal, Node>,
232  public DistObject<GlobalOrdinal,
233  LocalOrdinal,
234  GlobalOrdinal,
235  Node>,
236  public Teuchos::ParameterListAcceptorDefaultBase
237  {
238  static_assert (! classic, "The 'classic' version of Tpetra was deprecated long ago, and has been removed.");
239 
240  template <class S, class LO, class GO, class N, const bool isClassic>
241  friend class CrsMatrix;
242  template <class LO2, class GO2, class N2, const bool isClassic>
243  friend class CrsGraph;
244  template <class S, class LO, class GO, class N>
245  friend class ::Tpetra::Experimental::BlockCrsMatrix;
246 
249 
250  public:
252  typedef LocalOrdinal local_ordinal_type;
254  typedef GlobalOrdinal global_ordinal_type;
256  typedef Node node_type;
257 
259  typedef typename Node::device_type device_type;
261  typedef typename device_type::execution_space execution_space;
262 
264  typedef Kokkos::StaticCrsGraph<LocalOrdinal,
265  Kokkos::LayoutLeft,
266  execution_space> local_graph_type;
268  typedef local_graph_type LocalStaticCrsGraphType TPETRA_DEPRECATED;
269 
271  typedef typename local_graph_type::row_map_type t_RowPtrs TPETRA_DEPRECATED;
273  typedef typename local_graph_type::row_map_type::non_const_type t_RowPtrsNC TPETRA_DEPRECATED;
275  typedef typename local_graph_type::entries_type::non_const_type t_LocalOrdinal_1D TPETRA_DEPRECATED;
276 
283 
285 
286 
305  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
306  size_t maxNumEntriesPerRow,
307  ProfileType pftype = DynamicProfile,
308  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
309 
327  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
328  const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
329  const ProfileType pftype = DynamicProfile,
330  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
331 
350  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
351  const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
352  const ProfileType pftype = DynamicProfile,
353  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
354 
376  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
377  const Teuchos::RCP<const map_type>& colMap,
378  const size_t maxNumEntriesPerRow,
379  const ProfileType pftype = DynamicProfile,
380  const Teuchos::RCP<Teuchos::ParameterList>& params = null);
381 
400  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
401  const Teuchos::RCP<const map_type>& colMap,
402  const Kokkos::DualView<const size_t*, execution_space>& numEntPerRow,
403  ProfileType pftype = DynamicProfile,
404  const Teuchos::RCP<Teuchos::ParameterList>& params = null);
405 
425  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
426  const Teuchos::RCP<const map_type>& colMap,
427  const Teuchos::ArrayRCP<const size_t>& numEntPerRow,
428  ProfileType pftype = DynamicProfile,
429  const Teuchos::RCP<Teuchos::ParameterList>& params = null);
430 
450  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
451  const Teuchos::RCP<const map_type>& colMap,
452  const typename local_graph_type::row_map_type& rowPointers,
453  const typename local_graph_type::entries_type::non_const_type& columnIndices,
454  const Teuchos::RCP<Teuchos::ParameterList>& params = null);
455 
475  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
476  const Teuchos::RCP<const map_type>& colMap,
477  const Teuchos::ArrayRCP<size_t> & rowPointers,
478  const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices,
479  const Teuchos::RCP<Teuchos::ParameterList>& params = null);
480 
499  CrsGraph (const Teuchos::RCP<const map_type>& rowMap,
500  const Teuchos::RCP<const map_type>& colMap,
501  const local_graph_type& lclGraph,
502  const Teuchos::RCP<Teuchos::ParameterList>& params);
503 
531  template<class Node2>
532  Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node2, Node2::classic> >
533  clone (const Teuchos::RCP<Node2>& node2,
534  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null) const
535  {
537  typedef CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> input_crs_graph_type;
538  typedef Details::CrsGraphCopier<output_crs_graph_type, input_crs_graph_type> copier_type;
539  return copier_type::clone (*this, node2, params);
540  }
541 
543  virtual ~CrsGraph();
544 
546 
548 
550  void setParameterList (const Teuchos::RCP<Teuchos::ParameterList>& params);
551 
553  Teuchos::RCP<const ParameterList> getValidParameters () const;
554 
556 
558 
580  void
581  insertGlobalIndices (GlobalOrdinal globalRow,
582  const Teuchos::ArrayView<const GlobalOrdinal>& indices);
583 
585 
599  void
600  insertLocalIndices (const LocalOrdinal localRow,
601  const Teuchos::ArrayView<const LocalOrdinal> &indices);
602 
604 
613  void removeLocalIndices (LocalOrdinal localRow);
614 
616 
623 
629  void globalAssemble ();
630 
639  void resumeFill (const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
640 
658  void
659  fillComplete (const Teuchos::RCP<const map_type> &domainMap,
660  const Teuchos::RCP<const map_type> &rangeMap,
661  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
662 
669  void fillComplete (const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null);
670 
681  void
682  expertStaticFillComplete (const Teuchos::RCP<const map_type> & domainMap,
683  const Teuchos::RCP<const map_type> & rangeMap,
684  const Teuchos::RCP<const import_type> &importer=Teuchos::null,
685  const Teuchos::RCP<const export_type> &exporter=Teuchos::null,
686  const Teuchos::RCP<Teuchos::ParameterList> &params=Teuchos::null);
688 
690 
692  Teuchos::RCP<const Comm<int> > getComm() const;
693 
695  Teuchos::RCP<node_type> getNode() const;
696 
698  Teuchos::RCP<const map_type> getRowMap () const;
699 
701  Teuchos::RCP<const map_type> getColMap () const;
702 
704  Teuchos::RCP<const map_type> getDomainMap () const;
705 
707  Teuchos::RCP<const map_type> getRangeMap () const;
708 
710  Teuchos::RCP<const import_type> getImporter () const;
711 
713  Teuchos::RCP<const export_type> getExporter () const;
714 
716 
718  global_size_t getGlobalNumRows() const;
719 
721 
724  global_size_t getGlobalNumCols() const;
725 
727  size_t getNodeNumRows() const;
728 
730 
732  size_t getNodeNumCols() const;
733 
735  GlobalOrdinal getIndexBase() const;
736 
738 
740  global_size_t getGlobalNumEntries() const;
741 
743  size_t getNodeNumEntries() const;
744 
746 
747  size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const;
748 
750 
751  size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const;
752 
754 
761  size_t getNodeAllocationSize() const;
762 
764 
765  size_t getNumAllocatedEntriesInGlobalRow(GlobalOrdinal globalRow) const;
766 
768 
769  size_t getNumAllocatedEntriesInLocalRow(LocalOrdinal localRow) const;
770 
772 
774  global_size_t getGlobalNumDiags() const;
775 
777 
779  size_t getNodeNumDiags() const;
780 
793  size_t getGlobalMaxNumRowEntries() const;
794 
796 
798  size_t getNodeMaxNumRowEntries() const;
799 
814  bool hasColMap() const;
815 
823  bool isLowerTriangular() const;
824 
832  bool isUpperTriangular() const;
833 
835  bool isLocallyIndexed() const;
836 
838  bool isGloballyIndexed() const;
839 
841  bool isFillComplete() const;
842 
844  bool isFillActive() const;
845 
853  bool isSorted() const;
854 
856 
862  bool isStorageOptimized() const;
863 
865  ProfileType getProfileType() const;
866 
872  void
873  getGlobalRowCopy (GlobalOrdinal GlobalRow,
874  const Teuchos::ArrayView<GlobalOrdinal>& Indices,
875  size_t& NumIndices) const;
876 
884  void
885  getLocalRowCopy (LocalOrdinal LocalRow,
886  const Teuchos::ArrayView<LocalOrdinal>& indices,
887  size_t& NumIndices) const;
888 
890 
898  void
899  getGlobalRowView (GlobalOrdinal GlobalRow,
900  Teuchos::ArrayView<const GlobalOrdinal>& Indices) const;
901 
903 
911  void
912  getLocalRowView (LocalOrdinal LocalRow,
913  Teuchos::ArrayView<const LocalOrdinal>& indices) const;
914 
916 
918 
920  std::string description() const;
921 
923  void
924  describe (Teuchos::FancyOStream& out,
925  const Teuchos::EVerbosityLevel verbLevel =
926  Teuchos::Describable::verbLevel_default) const;
927 
929 
931 
932  virtual bool
933  checkSizes (const SrcDistObject& source);
934 
935  virtual void
936  copyAndPermute (const SrcDistObject& source,
937  size_t numSameIDs,
938  const Teuchos::ArrayView<const LocalOrdinal> &permuteToLIDs,
939  const Teuchos::ArrayView<const LocalOrdinal> &permuteFromLIDs);
940 
941  virtual void
942  packAndPrepare (const SrcDistObject& source,
943  const Teuchos::ArrayView<const LocalOrdinal> &exportLIDs,
944  Teuchos::Array<GlobalOrdinal> &exports,
945  const Teuchos::ArrayView<size_t> & numPacketsPerLID,
946  size_t& constantNumPackets,
947  Distributor &distor);
948 
949  virtual void
950  pack (const Teuchos::ArrayView<const LocalOrdinal>& exportLIDs,
951  Teuchos::Array<GlobalOrdinal>& exports,
952  const Teuchos::ArrayView<size_t>& numPacketsPerLID,
953  size_t& constantNumPackets,
954  Distributor& distor) const;
955 
956  virtual void
957  unpackAndCombine (const Teuchos::ArrayView<const LocalOrdinal> &importLIDs,
958  const Teuchos::ArrayView<const GlobalOrdinal> &imports,
959  const Teuchos::ArrayView<size_t> &numPacketsPerLID,
960  size_t constantNumPackets,
961  Distributor &distor,
962  CombineMode CM);
964 
966 
989  void
990  getNumEntriesPerLocalRowUpperBound (Teuchos::ArrayRCP<const size_t>& boundPerLocalRow,
991  size_t& boundForAllLocalRows,
992  bool& boundSameForAllLocalRows) const;
993 
1002  void
1003  setAllIndices (const typename local_graph_type::row_map_type& rowPointers,
1004  const typename local_graph_type::entries_type::non_const_type& columnIndices);
1005 
1014  void
1015  setAllIndices (const Teuchos::ArrayRCP<size_t> & rowPointers,
1016  const Teuchos::ArrayRCP<LocalOrdinal> & columnIndices);
1017 
1025  Teuchos::ArrayRCP<const size_t> getNodeRowPtrs () const;
1026 
1028 
1030  Teuchos::ArrayRCP<const LocalOrdinal> getNodePackedIndices() const;
1031 
1042  void replaceColMap (const Teuchos::RCP<const map_type>& newColMap);
1043 
1063  void
1064  reindexColumns (const Teuchos::RCP<const map_type>& newColMap,
1065  const Teuchos::RCP<const import_type>& newImport = Teuchos::null,
1066  const bool sortIndicesInEachRow = true);
1067 
1080  void
1081  replaceDomainMapAndImporter (const Teuchos::RCP<const map_type>& newDomainMap,
1082  const Teuchos::RCP<const import_type>& newImporter);
1083 
1111  virtual void
1112  removeEmptyProcessesInPlace (const Teuchos::RCP<const map_type>& newMap);
1114 
1115  template<class ViewType, class OffsetViewType >
1116  struct pack_functor {
1117  typedef typename ViewType::execution_space execution_space;
1118  ViewType src;
1119  ViewType dest;
1120  OffsetViewType src_offset;
1121  OffsetViewType dest_offset;
1122  typedef typename OffsetViewType::non_const_value_type ScalarIndx;
1123 
1124  pack_functor(ViewType dest_, ViewType src_, OffsetViewType dest_offset_, OffsetViewType src_offset_):
1125  src(src_),dest(dest_),src_offset(src_offset_),dest_offset(dest_offset_) {};
1126 
1127  KOKKOS_INLINE_FUNCTION
1128  void operator() (size_t row) const {
1129  ScalarIndx i = src_offset(row);
1130  ScalarIndx j = dest_offset(row);
1131  const ScalarIndx k = dest_offset(row+1);
1132  for(;j<k;j++,i++) {
1133  dest(j) = src(i);
1134  }
1135  }
1136  };
1137 
1138  protected:
1139  // these structs are conveniences, to cut down on the number of
1140  // arguments to some of the methods below.
1141  struct SLocalGlobalViews {
1142  Teuchos::ArrayView<const GlobalOrdinal> ginds;
1143  Teuchos::ArrayView<const LocalOrdinal> linds;
1144  };
1145  struct SLocalGlobalNCViews {
1146  Teuchos::ArrayView<GlobalOrdinal> ginds;
1147  Teuchos::ArrayView<LocalOrdinal> linds;
1148  };
1149 
1150  bool indicesAreAllocated () const;
1151  void allocateIndices (const ELocalGlobal lg);
1152 
1153  template <class T>
1154  Teuchos::ArrayRCP<Teuchos::Array<T> > allocateValues2D () const;
1155 
1156  template <class T>
1157  RowInfo updateLocalAllocAndValues (const RowInfo rowInfo,
1158  const size_t newAllocSize,
1159  Teuchos::Array<T>& rowVals)
1160  {
1161 #ifdef HAVE_TPETRA_DEBUG
1162  TEUCHOS_TEST_FOR_EXCEPT( ! isLocallyIndexed () );
1163  TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated() );
1164  TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1165  TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1166  TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1167 #endif // HAVE_TPETRA_DEBUG
1168 
1169  // Teuchos::ArrayRCP::resize automatically copies over values on reallocation.
1170  lclInds2D_[rowInfo.localRow].resize (newAllocSize);
1171  rowVals.resize (newAllocSize);
1172  nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1173 
1174  RowInfo rowInfoOut = rowInfo;
1175  rowInfoOut.allocSize = newAllocSize;
1176  return rowInfoOut;
1177  }
1178 
1179  template <class T>
1180  RowInfo
1181  updateGlobalAllocAndValues (const RowInfo rowInfo,
1182  const size_t newAllocSize,
1183  Teuchos::Array<T>& rowVals)
1184  {
1185 #ifdef HAVE_TPETRA_DEBUG
1186  TEUCHOS_TEST_FOR_EXCEPT( ! isGloballyIndexed () );
1187  TEUCHOS_TEST_FOR_EXCEPT( ! indicesAreAllocated () );
1188  TEUCHOS_TEST_FOR_EXCEPT( newAllocSize == 0 );
1189  TEUCHOS_TEST_FOR_EXCEPT( newAllocSize < rowInfo.allocSize );
1190  TEUCHOS_TEST_FOR_EXCEPT( ! rowMap_->isNodeLocalElement (rowInfo.localRow) );
1191 #endif // HAVE_TPETRA_DEBUG
1192 
1193  // Teuchos::ArrayRCP::resize automatically copies over values on reallocation.
1194  gblInds2D_[rowInfo.localRow].resize (newAllocSize);
1195  rowVals.resize (newAllocSize);
1196  nodeNumAllocated_ += (newAllocSize - rowInfo.allocSize);
1197 
1198  RowInfo rowInfoOut = rowInfo;
1199  rowInfoOut.allocSize = newAllocSize;
1200  return rowInfoOut;
1201  }
1202 
1204 
1205 
1207  void makeColMap ();
1208  void makeIndicesLocal ();
1209  void makeImportExport ();
1210 
1212 
1214 
1215  template<ELocalGlobal lg>
1216  size_t filterIndices (const SLocalGlobalNCViews& inds) const
1217  {
1218  using Teuchos::ArrayView;
1219  static_assert (lg == GlobalIndices || lg == LocalIndices,
1220  "Tpetra::CrsGraph::filterIndices: The template parameter "
1221  "lg must be either GlobalIndices or LocalIndicies.");
1222 
1223  const map_type& cmap = *colMap_;
1224  size_t numFiltered = 0;
1225 #ifdef HAVE_TPETRA_DEBUG
1226  size_t numFiltered_debug = 0;
1227 #endif
1228  if (lg == GlobalIndices) {
1229  ArrayView<GlobalOrdinal> ginds = inds.ginds;
1230  typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1231  typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1232  while (cptr != ginds.end()) {
1233  if (cmap.isNodeGlobalElement(*cptr)) {
1234  *fend++ = *cptr;
1235 #ifdef HAVE_TPETRA_DEBUG
1236  ++numFiltered_debug;
1237 #endif
1238  }
1239  ++cptr;
1240  }
1241  numFiltered = fend - ginds.begin();
1242  }
1243  else if (lg == LocalIndices) {
1244  ArrayView<LocalOrdinal> linds = inds.linds;
1245  typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1246  typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1247  while (cptr != linds.end()) {
1248  if (cmap.isNodeLocalElement(*cptr)) {
1249  *fend++ = *cptr;
1250 #ifdef HAVE_TPETRA_DEBUG
1251  ++numFiltered_debug;
1252 #endif
1253  }
1254  ++cptr;
1255  }
1256  numFiltered = fend - linds.begin();
1257  }
1258 #ifdef HAVE_TPETRA_DEBUG
1259  TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1260 #endif
1261  return numFiltered;
1262  }
1263 
1264 
1265  template<class T>
1266  size_t
1267  filterGlobalIndicesAndValues (const Teuchos::ArrayView<GlobalOrdinal>& ginds,
1268  const Teuchos::ArrayView<T>& vals) const
1269  {
1270  using Teuchos::ArrayView;
1271  const map_type& cmap = *colMap_;
1272  size_t numFiltered = 0;
1273  typename ArrayView<T>::iterator fvalsend = vals.begin();
1274  typename ArrayView<T>::iterator valscptr = vals.begin();
1275 #ifdef HAVE_TPETRA_DEBUG
1276  size_t numFiltered_debug = 0;
1277 #endif
1278  typename ArrayView<GlobalOrdinal>::iterator fend = ginds.begin();
1279  typename ArrayView<GlobalOrdinal>::iterator cptr = ginds.begin();
1280  while (cptr != ginds.end()) {
1281  if (cmap.isNodeGlobalElement (*cptr)) {
1282  *fend++ = *cptr;
1283  *fvalsend++ = *valscptr;
1284 #ifdef HAVE_TPETRA_DEBUG
1285  ++numFiltered_debug;
1286 #endif
1287  }
1288  ++cptr;
1289  ++valscptr;
1290  }
1291  numFiltered = fend - ginds.begin();
1292 #ifdef HAVE_TPETRA_DEBUG
1293  TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1294  TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1295  const size_t numFilteredActual =
1296  static_cast<size_t> (fvalsend - vals.begin ());
1297  TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1298 #endif // HAVE_TPETRA_DEBUG
1299  return numFiltered;
1300  }
1301 
1302  template<class T>
1303  size_t
1304  filterLocalIndicesAndValues (const Teuchos::ArrayView<LocalOrdinal>& linds,
1305  const Teuchos::ArrayView<T>& vals) const
1306  {
1307  using Teuchos::ArrayView;
1308  const map_type& cmap = *colMap_;
1309  size_t numFiltered = 0;
1310  typename ArrayView<T>::iterator fvalsend = vals.begin();
1311  typename ArrayView<T>::iterator valscptr = vals.begin();
1312 #ifdef HAVE_TPETRA_DEBUG
1313  size_t numFiltered_debug = 0;
1314 #endif
1315  typename ArrayView<LocalOrdinal>::iterator fend = linds.begin();
1316  typename ArrayView<LocalOrdinal>::iterator cptr = linds.begin();
1317  while (cptr != linds.end()) {
1318  if (cmap.isNodeLocalElement (*cptr)) {
1319  *fend++ = *cptr;
1320  *fvalsend++ = *valscptr;
1321 #ifdef HAVE_TPETRA_DEBUG
1322  ++numFiltered_debug;
1323 #endif
1324  }
1325  ++cptr;
1326  ++valscptr;
1327  }
1328  numFiltered = fend - linds.begin();
1329 #ifdef HAVE_TPETRA_DEBUG
1330  TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFiltered_debug );
1331  TEUCHOS_TEST_FOR_EXCEPT( valscptr != vals.end() );
1332  const size_t numFilteredActual =
1333  Teuchos::as<size_t> (fvalsend - vals.begin ());
1334  TEUCHOS_TEST_FOR_EXCEPT( numFiltered != numFilteredActual );
1335 #endif
1336  return numFiltered;
1337  }
1338 
1368  size_t
1369  insertIndices (const RowInfo& rowInfo,
1370  const SLocalGlobalViews& newInds,
1371  const ELocalGlobal lg,
1372  const ELocalGlobal I);
1373 
1413  template<class Scalar>
1414  void
1415  insertIndicesAndValues (const RowInfo& rowInfo,
1416  const SLocalGlobalViews& newInds,
1417  const Teuchos::ArrayView<Scalar>& oldRowVals,
1418  const Teuchos::ArrayView<const Scalar>& newRowVals,
1419  const ELocalGlobal lg,
1420  const ELocalGlobal I);
1421  void
1422  insertGlobalIndicesImpl (const LocalOrdinal myRow,
1423  const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1424  void
1425  insertLocalIndicesImpl (const LocalOrdinal myRow,
1426  const Teuchos::ArrayView<const LocalOrdinal> &indices);
1428  void
1429  insertLocalIndicesFiltered (const LocalOrdinal localRow,
1430  const Teuchos::ArrayView<const LocalOrdinal> &indices);
1431 
1433  void
1434  insertGlobalIndicesFiltered (const GlobalOrdinal localRow,
1435  const Teuchos::ArrayView<const GlobalOrdinal> &indices);
1436 
1464  template<class Scalar, class BinaryFunction>
1465  LocalOrdinal
1467  const Teuchos::ArrayView<Scalar>& rowVals,
1468  const Teuchos::ArrayView<const LocalOrdinal>& inds,
1469  const Teuchos::ArrayView<const Scalar>& newVals,
1470  BinaryFunction f) const
1471  {
1472  typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1473  const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1474  const size_type numElts = inds.size ();
1475  size_t hint = 0; // Guess for the current index k into rowVals
1476 
1477  // Get a view of the column indices in the row. This amortizes
1478  // the cost of getting the view over all the entries of inds.
1479  Teuchos::ArrayView<const LocalOrdinal> colInds = getLocalView (rowInfo);
1480 
1481  LocalOrdinal numValid = 0; // number of valid local column indices
1482  for (size_type j = 0; j < numElts; ++j) {
1483  const size_t k = findLocalIndex (rowInfo, inds[j], colInds, hint);
1484  if (k != STINV) {
1485  rowVals[k] = f (rowVals[k], newVals[j]); // use binary function f
1486  hint = k+1;
1487  ++numValid;
1488  }
1489  }
1490  return numValid;
1491  }
1492 
1512  template<class Scalar, class BinaryFunction>
1513  LocalOrdinal
1515  const Teuchos::ArrayView<Scalar>& rowVals,
1516  const Teuchos::ArrayView<const GlobalOrdinal>& inds,
1517  const Teuchos::ArrayView<const Scalar>& newVals,
1518  BinaryFunction f) const
1519  {
1520  typedef typename Teuchos::ArrayView<Scalar>::size_type size_type;
1521  const size_t STINV = Teuchos::OrdinalTraits<size_t>::invalid ();
1522  const size_type numElts = inds.size ();
1523  size_t hint = 0; // guess at the index's relative offset in the row
1524 
1525  LocalOrdinal numValid = 0; // number of valid local column indices
1526  for (size_type j = 0; j < numElts; ++j) {
1527  const size_t k = findGlobalIndex (rowInfo, inds[j], hint);
1528  if (k != STINV) {
1529  rowVals[k] = f (rowVals[k], newVals[j]); // use binary function f
1530  hint = k+1;
1531  numValid++;
1532  }
1533  }
1534  return numValid;
1535  }
1536 
1538 
1540 
1542  bool isMerged () const;
1543 
1549  void setLocallyModified ();
1550 
1552  void sortAllIndices ();
1553 
1555  void sortRowIndices (const RowInfo rowinfo);
1556 
1571  template <class Scalar>
1572  void sortRowIndicesAndValues (const RowInfo rowinfo,
1573  const Teuchos::ArrayView<Scalar>& values);
1574 
1583  void mergeAllIndices ();
1584 
1589  void mergeRowIndices (RowInfo rowinfo);
1590 
1601  template<class Scalar>
1602  void
1603  mergeRowIndicesAndValues (RowInfo rowinfo,
1604  const Teuchos::ArrayView<Scalar>& rowValues);
1606 
1616  void
1617  setDomainRangeMaps (const Teuchos::RCP<const map_type>& domainMap,
1618  const Teuchos::RCP<const map_type>& rangeMap);
1619 
1620  void staticAssertions() const;
1621  void clearGlobalConstants();
1622  void computeGlobalConstants();
1623 
1626  RowInfo getRowInfo (const size_t myRow) const;
1627 
1631  Teuchos::ArrayView<const LocalOrdinal>
1632  getLocalView (const RowInfo rowinfo) const;
1633 
1637  Teuchos::ArrayView<LocalOrdinal>
1638  getLocalViewNonConst (const RowInfo rowinfo);
1639 
1643  Teuchos::ArrayView<const GlobalOrdinal>
1644  getGlobalView (const RowInfo rowinfo) const;
1645 
1649  Teuchos::ArrayView<GlobalOrdinal>
1650  getGlobalViewNonConst (const RowInfo rowinfo);
1651 
1686  size_t
1687  findLocalIndex (RowInfo rowinfo,
1688  LocalOrdinal ind,
1689  size_t hint = 0) const;
1690 
1719  size_t
1720  findLocalIndex (RowInfo rowinfo,
1721  LocalOrdinal ind,
1722  Teuchos::ArrayView<const LocalOrdinal> colInds,
1723  size_t hint = 0) const;
1724 
1733  size_t findGlobalIndex (RowInfo rowinfo, GlobalOrdinal ind, size_t hint = 0) const;
1734 
1739  local_graph_type getLocalGraph () const;
1740 
1742  TPETRA_DEPRECATED local_graph_type getLocalGraph_Kokkos () const;
1743 
1744  void fillLocalGraph (const Teuchos::RCP<Teuchos::ParameterList>& params);
1745 
1747  bool hasRowInfo () const;
1748 
1750  void checkInternalState () const;
1751 
1753  Teuchos::RCP<const map_type> rowMap_;
1755  Teuchos::RCP<const map_type> colMap_;
1757  Teuchos::RCP<const map_type> rangeMap_;
1759  Teuchos::RCP<const map_type> domainMap_;
1760 
1767  Teuchos::RCP<const import_type> importer_;
1768 
1774  Teuchos::RCP<const export_type> exporter_;
1775 
1777  local_graph_type lclGraph_;
1778 
1779  // Local and Global Counts
1780  // nodeNumEntries_ and nodeNumAllocated_ are required to be always consistent
1781  // nodeMaxNumEntries_, nodeNumDiags_ and the global quantities are computed during fillComplete() and only valid when isFillComplete()
1782  global_size_t globalNumEntries_, globalNumDiags_, globalMaxNumRowEntries_;
1783  size_t nodeNumEntries_, nodeNumDiags_, nodeMaxNumRowEntries_, nodeNumAllocated_;
1784 
1787 
1805  Kokkos::DualView<const size_t*, Kokkos::LayoutLeft, execution_space> k_numAllocPerRow_;
1806 
1817 
1819 
1820 
1828  typename local_graph_type::entries_type::non_const_type k_lclInds1D_;
1829 
1831  typedef Kokkos::View<GlobalOrdinal*, execution_space> t_GlobalOrdinal_1D;
1832 
1840  t_GlobalOrdinal_1D k_gblInds1D_;
1841 
1869  typename local_graph_type::row_map_type::const_type k_rowPtrs_;
1870 
1872 
1884 
1896  Teuchos::ArrayRCP<Teuchos::Array<LocalOrdinal> > lclInds2D_;
1897 
1909  Teuchos::ArrayRCP<Teuchos::Array<GlobalOrdinal> > gblInds2D_;
1910 
1911  typedef Kokkos::DualView<size_t*, Kokkos::LayoutLeft, execution_space> t_numRowEntries_;
1912 
1919  t_numRowEntries_ k_numRowEntries_;
1920 
1922 
1933 
1934  bool indicesAreAllocated_;
1935  bool indicesAreLocal_;
1936  bool indicesAreGlobal_;
1937  bool fillComplete_;
1938 
1952 
1954  std::map<GlobalOrdinal, std::vector<GlobalOrdinal> > nonlocals_;
1955 
1971 
1972  }; // class CrsGraph
1973 
1980  template <class LocalOrdinal, class GlobalOrdinal, class Node, const bool classic = Node::classic>
1981  Teuchos::RCP<CrsGraph<LocalOrdinal, GlobalOrdinal, Node, classic> >
1982  createCrsGraph (const Teuchos::RCP<const Map<LocalOrdinal, GlobalOrdinal, Node> > &map,
1983  size_t maxNumEntriesPerRow = 0,
1984  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
1985  {
1986  using Teuchos::rcp;
1988  return rcp (new graph_type (map, maxNumEntriesPerRow, DynamicProfile, params));
1989  }
1990 
1991  namespace Details {
1992 
1993  template<class LocalOrdinal,
1994  class GlobalOrdinal,
1995  class OutputNodeType,
1996  class InputNodeType>
1997  class CrsGraphCopier<CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType>,
1998  CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> > {
1999  public:
2000  typedef CrsGraph<LocalOrdinal, GlobalOrdinal, InputNodeType> input_crs_graph_type;
2001  typedef CrsGraph<LocalOrdinal, GlobalOrdinal, OutputNodeType> output_crs_graph_type;
2002 
2003  static Teuchos::RCP<output_crs_graph_type>
2004  clone (const input_crs_graph_type& graphIn,
2005  const Teuchos::RCP<OutputNodeType> &nodeOut,
2006  const Teuchos::RCP<Teuchos::ParameterList>& params = Teuchos::null)
2007  {
2008  using Teuchos::arcp;
2009  using Teuchos::ArrayRCP;
2010  using Teuchos::ArrayView;
2011  using Teuchos::null;
2012  using Teuchos::outArg;
2013  using Teuchos::ParameterList;
2014  using Teuchos::parameterList;
2015  using Teuchos::RCP;
2016  using Teuchos::rcp;
2017  using Teuchos::REDUCE_MIN;
2018  using Teuchos::reduceAll;
2019  using Teuchos::sublist;
2020  using std::cerr;
2021  using std::endl;
2022  typedef LocalOrdinal LO;
2023  typedef GlobalOrdinal GO;
2024  typedef typename ArrayView<const GO>::size_type size_type;
2025  typedef ::Tpetra::Map<LO, GO, InputNodeType> input_map_type;
2026  typedef ::Tpetra::Map<LO, GO, OutputNodeType> output_map_type;
2027  const char prefix[] = "Tpetra::Details::CrsGraphCopier::clone: ";
2028 
2029  // Set parameters' default values.
2030  bool debug = false;
2031  bool fillCompleteClone = true;
2032  bool useLocalIndices = graphIn.hasColMap ();
2033  ProfileType pftype = StaticProfile;
2034  // If the user provided a ParameterList, get values from there.
2035  if (! params.is_null ()) {
2036  fillCompleteClone = params->get ("fillComplete clone", fillCompleteClone);
2037  useLocalIndices = params->get ("Locally indexed clone", useLocalIndices);
2038  if (params->get ("Static profile clone", true) == false) {
2039  pftype = DynamicProfile;
2040  }
2041  debug = params->get ("Debug", debug);
2042  }
2043 
2044  const Teuchos::Comm<int>& comm = * (graphIn.getRowMap ()->getComm ());
2045  const int myRank = comm.getRank ();
2046 
2047  TEUCHOS_TEST_FOR_EXCEPTION(
2048  ! graphIn.hasColMap () && useLocalIndices, std::runtime_error,
2049  prefix << "You asked clone() to use local indices (by setting the "
2050  "\"Locally indexed clone\" parameter to true), but the source graph "
2051  "does not yet have a column Map, so this is impossible.");
2052 
2053  if (debug) {
2054  std::ostringstream os;
2055  os << "Process " << myRank << ": Cloning row Map" << endl;
2056  cerr << os.str ();
2057  }
2058 
2059  RCP<const output_map_type> clonedRowMap =
2060  graphIn.getRowMap ()->template clone<OutputNodeType> (nodeOut);
2061 
2062  // Invoke the output graph's constructor, using the input graph's
2063  // upper bounds on the number of entries in each local row.
2064  RCP<output_crs_graph_type> clonedGraph; // returned by this function
2065  {
2066  ArrayRCP<const size_t> numEntriesPerRow;
2067  size_t numEntriesForAll = 0;
2068  bool boundSameForAllLocalRows = true;
2069 
2070  if (debug) {
2071  std::ostringstream os;
2072  os << "Process " << myRank << ": Getting per-row bounds" << endl;
2073  cerr << os.str ();
2074  }
2075  graphIn.getNumEntriesPerLocalRowUpperBound (numEntriesPerRow,
2076  numEntriesForAll,
2077  boundSameForAllLocalRows);
2078  if (debug) {
2079  std::ostringstream os;
2080  os << "Process " << myRank << ": numEntriesForAll = "
2081  << numEntriesForAll << endl;
2082  cerr << os.str ();
2083  }
2084 
2085  if (debug) {
2086  std::ostringstream os;
2087  os << "Process " << myRank << ": graphIn.getNodeMaxNumRowEntries() = "
2088  << graphIn.getNodeMaxNumRowEntries () << endl;
2089  cerr << os.str ();
2090  }
2091 
2092  RCP<ParameterList> graphparams;
2093  if (params.is_null ()) {
2094  graphparams = parameterList ("CrsGraph");
2095  } else {
2096  graphparams = sublist (params, "CrsGraph");
2097  }
2098  if (useLocalIndices) {
2099  RCP<const output_map_type> clonedColMap =
2100  graphIn.getColMap ()->template clone<OutputNodeType> (nodeOut);
2101  if (boundSameForAllLocalRows) {
2102  clonedGraph = rcp (new output_crs_graph_type (clonedRowMap, clonedColMap,
2103  numEntriesForAll, pftype,
2104  graphparams));
2105  } else {
2106  clonedGraph = rcp (new output_crs_graph_type (clonedRowMap, clonedColMap,
2107  numEntriesPerRow, pftype,
2108  graphparams));
2109  }
2110  } else {
2111  if (boundSameForAllLocalRows) {
2112  clonedGraph = rcp (new output_crs_graph_type (clonedRowMap,
2113  numEntriesForAll, pftype,
2114  graphparams));
2115  } else {
2116  clonedGraph = rcp (new output_crs_graph_type (clonedRowMap,
2117  numEntriesPerRow,
2118  pftype, graphparams));
2119  }
2120  }
2121 
2122  if (debug) {
2123  std::ostringstream os;
2124  os << "Process " << myRank << ": Invoked output graph's constructor" << endl;
2125  cerr << os.str ();
2126  }
2127 
2128  // done with these
2129  numEntriesPerRow = null;
2130  numEntriesForAll = 0;
2131  }
2132 
2133  const input_map_type& inputRowMap = * (graphIn.getRowMap ());
2134  const size_type numRows =
2135  static_cast<size_type> (inputRowMap.getNodeNumElements ());
2136 
2137  bool failed = false;
2138 
2139  if (useLocalIndices) {
2140  const LO localMinLID = inputRowMap.getMinLocalIndex ();
2141  const LO localMaxLID = inputRowMap.getMaxLocalIndex ();
2142 
2143  if (graphIn.isLocallyIndexed ()) {
2144  if (numRows != 0) {
2145  try {
2146  ArrayView<const LO> linds;
2147  for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
2148  graphIn.getLocalRowView (lrow, linds);
2149  if (linds.size () != 0) {
2150  clonedGraph->insertLocalIndices (lrow, linds);
2151  }
2152  }
2153  }
2154  catch (std::exception& e) {
2155  std::ostringstream os;
2156  os << "Process " << myRank << ": copying (reading local by view, "
2157  "writing local) indices into the output graph threw an "
2158  "exception: " << e.what () << endl;
2159  cerr << os.str ();
2160  failed = true;
2161  }
2162  }
2163  }
2164  else { // graphIn.isGloballyIndexed()
2165  TEUCHOS_TEST_FOR_EXCEPTION(
2166  ! graphIn.hasColMap () && useLocalIndices, std::invalid_argument,
2167  prefix << "You asked clone() to use local indices (by setting the "
2168  "\"Locally indexed clone\" parameter to true), but the source graph "
2169  "does not yet have a column Map, so this is impossible.");
2170 
2171  // The input graph has a column Map, but is globally indexed.
2172  // That's a bit weird, but we'll run with it. In this case,
2173  // getLocalRowView won't work, but getLocalRowCopy should
2174  // still work; it will just have to convert from global to
2175  // local indices internally.
2176 
2177  try {
2178  // Make space for getLocalRowCopy to put column indices.
2179  //
2180  // This is only a hint; we may have to resize in the loop
2181  // below. getNodeMaxNumRowEntries() may return nonsense if
2182  // fill is active. The key bool in CrsGraph is
2183  // haveLocalConstants_.
2184  size_t myMaxNumRowEntries =
2185  graphIn.isFillActive () ? static_cast<size_t> (0) :
2186  graphIn.getNodeMaxNumRowEntries ();
2187 
2188  Array<LO> linds (myMaxNumRowEntries);
2189 
2190  // Copy each row into the new graph, using local indices.
2191  for (LO lrow = localMinLID; lrow <= localMaxLID; ++lrow) {
2192  size_t theNumEntries = graphIn.getNumEntriesInLocalRow (lrow);
2193  if (theNumEntries > myMaxNumRowEntries) {
2194  myMaxNumRowEntries = theNumEntries;
2195  linds.resize (myMaxNumRowEntries);
2196  }
2197  graphIn.getLocalRowCopy (lrow, linds (), theNumEntries);
2198  if (theNumEntries != 0) {
2199  clonedGraph->insertLocalIndices (lrow, linds (0, theNumEntries));
2200  }
2201  }
2202  }
2203  catch (std::exception& e) {
2204  std::ostringstream os;
2205  os << "Process " << myRank << ": copying (reading local by copy, "
2206  "writing local) indices into the output graph threw an exception: "
2207  << e.what () << endl;
2208  cerr << os.str ();
2209  failed = true;
2210  }
2211  }
2212  }
2213  else { /* useGlobalIndices */
2214  if (numRows != 0) {
2215  const GlobalOrdinal localMinGID = inputRowMap.getMinGlobalIndex ();
2216  const GlobalOrdinal localMaxGID = inputRowMap.getMaxGlobalIndex ();
2217  const bool inputRowMapIsContiguous = inputRowMap.isContiguous ();
2218 
2219  if (graphIn.isGloballyIndexed ()) {
2220  ArrayView<const GlobalOrdinal> ginds;
2221 
2222  if (inputRowMapIsContiguous) {
2223  try {
2224  for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
2225  graphIn.getGlobalRowView (grow, ginds);
2226  if (ginds.size () != 0) {
2227  clonedGraph->insertGlobalIndices (grow, ginds);
2228  }
2229  }
2230  }
2231  catch (std::exception& e) {
2232  std::ostringstream os;
2233  os << "Process " << myRank << ": copying (reading global by view, "
2234  "writing global) indices into the output graph threw an "
2235  "exception: " << e.what () << endl;
2236  cerr << os.str ();
2237  failed = true;
2238  }
2239  }
2240  else { // input row Map is not contiguous
2241  try {
2242  ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
2243  for (size_type k = 0; k < numRows; ++k) {
2244  const GO grow = inputRowMapGIDs[k];
2245  graphIn.getGlobalRowView (grow, ginds);
2246  if (ginds.size () != 0) {
2247  clonedGraph->insertGlobalIndices (grow, ginds);
2248  }
2249  }
2250  }
2251  catch (std::exception& e) {
2252  std::ostringstream os;
2253  os << "Process " << myRank << ": copying (reading global by view, "
2254  "writing global) indices into the output graph threw an "
2255  "exception: " << e.what () << endl;
2256  cerr << os.str ();
2257  failed = true;
2258  }
2259  }
2260  }
2261  else { // graphIn.isLocallyIndexed()
2262  // Make space for getGlobalRowCopy to put column indices.
2263  //
2264  // This is only a hint; we may have to resize in the loop
2265  // below. getNodeMaxNumRowEntries() may return nonsense if
2266  // fill is active. The key bool in CrsGraph is
2267  // haveLocalConstants_.
2268  size_t myMaxNumRowEntries =
2269  graphIn.isFillActive () ? static_cast<size_t> (0) :
2270  graphIn.getNodeMaxNumRowEntries ();
2271 
2272  Array<GO> ginds (myMaxNumRowEntries);
2273 
2274  if (inputRowMapIsContiguous) {
2275  try {
2276  for (GO grow = localMinGID; grow <= localMaxGID; ++grow) {
2277  size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
2278  if (theNumEntries > myMaxNumRowEntries) {
2279  myMaxNumRowEntries = theNumEntries;
2280  ginds.resize (myMaxNumRowEntries);
2281  }
2282  graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
2283  if (theNumEntries != 0) {
2284  clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
2285  }
2286  }
2287  }
2288  catch (std::exception& e) {
2289  std::ostringstream os;
2290  os << "Process " << myRank << ": copying (reading global by copy, "
2291  "writing global) indices into the output graph threw an "
2292  "exception: " << e.what () << endl;
2293  cerr << os.str ();
2294  failed = true;
2295  }
2296  }
2297  else { // input row Map is not contiguous
2298  try {
2299  ArrayView<const GO> inputRowMapGIDs = inputRowMap.getNodeElementList ();
2300  for (size_type k = 0; k < numRows; ++k) {
2301  const GO grow = inputRowMapGIDs[k];
2302 
2303  size_t theNumEntries = graphIn.getNumEntriesInGlobalRow (grow);
2304  if (theNumEntries > myMaxNumRowEntries) {
2305  myMaxNumRowEntries = theNumEntries;
2306  ginds.resize (myMaxNumRowEntries);
2307  }
2308  graphIn.getGlobalRowCopy (grow, ginds (), theNumEntries);
2309  if (theNumEntries != 0) {
2310  clonedGraph->insertGlobalIndices (grow, ginds (0, theNumEntries));
2311  }
2312  }
2313  }
2314  catch (std::exception& e) {
2315  std::ostringstream os;
2316  os << "Process " << myRank << ": copying (reading global by copy, "
2317  "writing global) indices into the output graph threw an "
2318  "exception: " << e.what () << endl;
2319  cerr << os.str ();
2320  failed = true;
2321  }
2322  }
2323  }
2324  } // numRows != 0
2325  }
2326 
2327  if (debug) {
2328  std::ostringstream os;
2329  os << "Process " << myRank << ": copied entries" << endl;
2330  cerr << os.str ();
2331  }
2332 
2333  if (fillCompleteClone) {
2334  RCP<ParameterList> fillparams = params.is_null () ?
2335  parameterList ("fillComplete") :
2336  sublist (params, "fillComplete");
2337  try {
2338  RCP<const output_map_type> clonedRangeMap;
2339  RCP<const output_map_type> clonedDomainMap;
2340  if (! graphIn.getRangeMap ().is_null () &&
2341  graphIn.getRangeMap () != graphIn.getRowMap ()) {
2342  clonedRangeMap =
2343  graphIn.getRangeMap ()->template clone<OutputNodeType> (nodeOut);
2344  }
2345  else {
2346  clonedRangeMap = clonedRowMap;
2347  }
2348  if (! graphIn.getDomainMap ().is_null ()
2349  && graphIn.getDomainMap () != graphIn.getRowMap ()) {
2350  clonedDomainMap =
2351  graphIn.getDomainMap ()->template clone<OutputNodeType> (nodeOut);
2352  }
2353  else {
2354  clonedDomainMap = clonedRowMap;
2355  }
2356 
2357  if (debug) {
2358  std::ostringstream os;
2359  os << "Process " << myRank << ": About to call fillComplete on "
2360  "cloned graph" << endl;
2361  cerr << os.str ();
2362  }
2363  clonedGraph->fillComplete (clonedDomainMap, clonedRangeMap, fillparams);
2364  }
2365  catch (std::exception &e) {
2366  failed = true;
2367  std::ostringstream os;
2368  os << prefix << "Process " << myRank << ": Caught the following "
2369  "exception while calling fillComplete() on clone of type"
2370  << endl << Teuchos::typeName (*clonedGraph) << endl;
2371  cerr << os.str ();
2372  }
2373  }
2374 
2375  int lclSuccess = failed ? 0 : 1;
2376  int gblSuccess = 1;
2377  reduceAll<int, int> (comm, REDUCE_MIN, lclSuccess, outArg (gblSuccess));
2378  TEUCHOS_TEST_FOR_EXCEPTION(
2379  gblSuccess != 1, std::logic_error, prefix <<
2380  "Clone failed on at least one process.");
2381 
2382  if (debug) {
2383  std::ostringstream os;
2384  os << "Process " << myRank << ": Done with CrsGraph::clone" << endl;
2385  cerr << os.str ();
2386  }
2387  return clonedGraph;
2388  }
2389  };
2390 
2391  } // namespace Details
2392 } // namespace Tpetra
2393 
2394 #endif // TPETRA_CRSGRAPH_DECL_HPP
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
bool haveGlobalConstants_
Whether all processes have computed global constants.
Teuchos::RCP< CrsGraph< LocalOrdinal, GlobalOrdinal, Node2, Node2::classic > > clone(const Teuchos::RCP< Node2 > &node2, const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null) const
Create a cloned CrsGraph for a different Node type.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
An abstract interface for graphs accessed by rows.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
bool indicesAreSorted_
Whether the graph&#39;s indices are sorted in each row, on this process.
GlobalOrdinal global_ordinal_type
This class&#39; second template parameter; the type of global indices.
bool noRedundancies_
Whether the graph&#39;s indices are non-redundant (merged) in each row, on this process.
KokkosClassic::DefaultNode::DefaultNodeType node_type
Default value of Node template parameter.
local_graph_type LocalStaticCrsGraphType TPETRA_DEPRECATED
DEPRECATED; use local_graph_type (above) instead.
bool sortGhostsAssociatedWithEachProcessor_
Whether to require makeColMap() (and therefore fillComplete()) to order column Map GIDs associated wi...
Node::device_type device_type
This class&#39; Kokkos device type.
Teuchos::RCP< const map_type > rangeMap_
The Map describing the range of the (matrix corresponding to the) graph.
ProfileType pftype_
Whether the graph was allocated with static or dynamic profile.
t_numRowEntries_ k_numRowEntries_
The number of local entries in each locally owned row.
local_graph_type::entries_type::non_const_type k_lclInds1D_
Local column indices for all rows.
Teuchos::ArrayRCP< Teuchos::Array< GlobalOrdinal > > gblInds2D_
Global column indices for all rows.
LocalOrdinal local_ordinal_type
This class&#39; first template parameter; the type of local indices.
Teuchos::RCP< CrsGraph< LocalOrdinal, GlobalOrdinal, Node, classic > > createCrsGraph(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, size_t maxNumEntriesPerRow=0, const Teuchos::RCP< Teuchos::ParameterList > &params=Teuchos::null)
Nonmember function to create an empty CrsGraph given a row Map and the max number of entries allowed ...
void removeEmptyProcessesInPlace(Teuchos::RCP< DistObjectType > &input, const Teuchos::RCP< const Map< typename DistObjectType::local_ordinal_type, typename DistObjectType::global_ordinal_type, typename DistObjectType::node_type > > &newMap)
Remove processes which contain no elements in this object&#39;s Map.
bool upperTriangular_
Whether the graph is locally upper triangular.
Teuchos::RCP< const map_type > domainMap_
The Map describing the domain of the (matrix corresponding to the) graph.
Allocation information for a locally owned row in a CrsGraph or CrsMatrix.
int local_ordinal_type
Default value of LocalOrdinal template parameter.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
Teuchos::RCP< const map_type > colMap_
The Map describing the distribution of columns of the graph.
Implementation details of Tpetra.
size_t numAllocForAllRows_
The maximum number of entries to allow in each locally owned row.
size_t global_size_t
Global size_t object.
Kokkos::StaticCrsGraph< LocalOrdinal, Kokkos::LayoutLeft, execution_space > local_graph_type
The type of the part of the sparse graph on each MPI process.
bool haveLocalConstants_
Whether this process has computed local constants.
t_GlobalOrdinal_1D k_gblInds1D_
Global column indices for all rows.
local_graph_type lclGraph_
Local graph; only initialized after first fillComplete() call.
LocalOrdinal transformLocalValues(RowInfo rowInfo, const Teuchos::ArrayView< Scalar > &rowVals, const Teuchos::ArrayView< const LocalOrdinal > &inds, const Teuchos::ArrayView< const Scalar > &newVals, BinaryFunction f) const
Transform the given values using local indices.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Kokkos::DualView< const size_t *, Kokkos::LayoutLeft, execution_space > k_numAllocPerRow_
The maximum number of entries to allow in each locally owned row, per row.
Abstract base class for objects that can be the source of an Import or Export operation.
Teuchos::RCP< const import_type > importer_
The Import from the domain Map to the column Map.
Node node_type
This class&#39; Kokkos Node type.
Teuchos::RCP< const map_type > rowMap_
The Map describing the distribution of rows of the graph.
Teuchos::ArrayRCP< Teuchos::Array< LocalOrdinal > > lclInds2D_
Local column indices for all rows.
Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The Map specialization used by this class.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
LocalOrdinal transformGlobalValues(RowInfo rowInfo, const Teuchos::ArrayView< Scalar > &rowVals, const Teuchos::ArrayView< const GlobalOrdinal > &inds, const Teuchos::ArrayView< const Scalar > &newVals, BinaryFunction f) const
Transform the given values using global indices.
Describes a parallel distribution of objects over processes.
Details::EStorageStatus storageStatus_
Status of the graph&#39;s storage, when not in a fill-complete state.
device_type::execution_space execution_space
This class&#39; Kokkos execution space.
local_graph_type::entries_type::non_const_type t_LocalOrdinal_1D TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::entries_type::non_const_type instead.
local_graph_type::row_map_type::const_type k_rowPtrs_
Row offsets for "1-D" storage.
std::map< GlobalOrdinal, std::vector< GlobalOrdinal > > nonlocals_
Nonlocal data given to insertGlobalValues or sumIntoGlobalValues.
local_graph_type::row_map_type t_RowPtrs TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::row_map_type instead.
local_graph_type::row_map_type::non_const_type t_RowPtrsNC TPETRA_DEPRECATED
DEPRECATED; use local_graph_type::row_map_type::non_const_type instead.
Kokkos::View< GlobalOrdinal *, execution_space > t_GlobalOrdinal_1D
Type of the k_gblInds1D_ array of global column indices.
Base class for distributed Tpetra objects that support data redistribution.
Tpetra::Export< LocalOrdinal, GlobalOrdinal, Node > export_type
The Export specialization used by this class.
EStorageStatus
Status of the graph&#39;s or matrix&#39;s storage, when not in a fill-complete state.
Teuchos::RCP< const export_type > exporter_
The Export from the row Map to the range Map.
bool lowerTriangular_
Whether the graph is locally lower triangular.
Tpetra::Import< LocalOrdinal, GlobalOrdinal, Node > import_type
The Import specialization used by this class.