Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_OverlappingRowMatrix_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4 //
5 // Copyright 2009 NTESS and the Ifpack2 contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef IFPACK2_OVERLAPPINGROWMATRIX_DEF_HPP
11 #define IFPACK2_OVERLAPPINGROWMATRIX_DEF_HPP
12 
13 #include <sstream>
14 
15 #include <Ifpack2_OverlappingRowMatrix_decl.hpp>
16 #include <Ifpack2_Details_OverlappingRowGraph.hpp>
17 #include <Tpetra_CrsMatrix.hpp>
18 #include <Tpetra_Import.hpp>
19 #include "Tpetra_Map.hpp"
20 #include <Teuchos_CommHelpers.hpp>
21 #include <unordered_set>
22 
23 namespace Ifpack2 {
24 
25 template<class MatrixType>
28  const int overlapLevel) :
29  A_ (Teuchos::rcp_dynamic_cast<const crs_matrix_type> (A, true)),
30  OverlapLevel_ (overlapLevel)
31 {
32  using Teuchos::RCP;
33  using Teuchos::rcp;
34  using Teuchos::Array;
35  using Teuchos::outArg;
36  using Teuchos::REDUCE_SUM;
37  using Teuchos::reduceAll;
38  typedef Tpetra::global_size_t GST;
39  typedef Tpetra::CrsGraph<local_ordinal_type,
40  global_ordinal_type, node_type> crs_graph_type;
42  OverlapLevel_ <= 0, std::runtime_error,
43  "Ifpack2::OverlappingRowMatrix: OverlapLevel must be > 0.");
45  (A_.is_null (), std::runtime_error,
46  "Ifpack2::OverlappingRowMatrix: The input matrix must be a "
47  "Tpetra::CrsMatrix with the same scalar_type, local_ordinal_type, "
48  "global_ordinal_type, and device_type typedefs as MatrixType.");
50  A_->getComm()->getSize() == 1, std::runtime_error,
51  "Ifpack2::OverlappingRowMatrix: Matrix must be "
52  "distributed over more than one MPI process.");
53 
54 
55  RCP<const crs_graph_type> A_crsGraph = A_->getCrsGraph ();
56  const size_t numMyRowsA = A_->getLocalNumRows ();
57  const global_ordinal_type global_invalid =
59 
60  // Temp arrays
61  Array<global_ordinal_type> ExtElements;
62  // Use an unordered_set to efficiently keep track of which GIDs have already
63  // been added to ExtElements. Still need ExtElements because we also want a
64  // list of the GIDs ordered LID in the ColMap.
65  std::unordered_set<global_ordinal_type> ExtElementSet;
66  RCP<map_type> TmpMap;
67  RCP<crs_graph_type> TmpGraph;
68  RCP<import_type> TmpImporter;
69  RCP<const map_type> RowMap, ColMap;
70  Kokkos::resize(ExtHaloStarts_, OverlapLevel_+1);
71  ExtHaloStarts_h = Kokkos::create_mirror_view(ExtHaloStarts_);
72 
73  // The big import loop
74  for (int overlap = 0 ; overlap < OverlapLevel_ ; ++overlap) {
75  ExtHaloStarts_h(overlap) = (size_t) ExtElements.size();
76 
77  // Get the current maps
78  if (overlap == 0) {
79  RowMap = A_->getRowMap ();
80  ColMap = A_->getColMap ();
81  }
82  else {
83  RowMap = TmpGraph->getRowMap ();
84  ColMap = TmpGraph->getColMap ();
85  }
86 
87  const size_t size = ColMap->getLocalNumElements () - RowMap->getLocalNumElements ();
88  Array<global_ordinal_type> mylist (size);
89  size_t count = 0;
90 
91  // define the set of rows that are in ColMap but not in RowMap
92  for (local_ordinal_type i = 0 ; (size_t) i < ColMap->getLocalNumElements() ; ++i) {
93  const global_ordinal_type GID = ColMap->getGlobalElement (i);
94  if (A_->getRowMap ()->getLocalElement (GID) == global_invalid) {
95  // unordered_set insert can return a pair, where the second element is
96  // true if a new element was inserted, false otherwise.
97  if(ExtElementSet.insert(GID).second)
98  {
99  ExtElements.push_back (GID);
100  mylist[count] = GID;
101  ++count;
102  }
103  }
104  }
105 
106  // On last import round, TmpMap, TmpGraph, and TmpImporter are unneeded,
107  // so don't build them.
108  if (overlap + 1 < OverlapLevel_) {
109  //map consisting of GIDs that are in the current halo level-set
110  TmpMap = rcp (new map_type (global_invalid, mylist (0, count),
112  A_->getComm ()));
113  //graph whose rows are the current halo level-set to import
114  TmpGraph = rcp (new crs_graph_type (TmpMap, 0));
115  TmpImporter = rcp (new import_type (A_->getRowMap (), TmpMap));
116 
117  //import from original matrix graph to current halo level-set graph
118  TmpGraph->doImport (*A_crsGraph, *TmpImporter, Tpetra::INSERT);
119  TmpGraph->fillComplete (A_->getDomainMap (), TmpMap);
120  }
121  } // end overlap loop
122  ExtHaloStarts_h[OverlapLevel_] = (size_t) ExtElements.size();
123  Kokkos::deep_copy(ExtHaloStarts_,ExtHaloStarts_h);
124 
125  // build the map containing all the nodes (original
126  // matrix + extended matrix)
127  Array<global_ordinal_type> mylist (numMyRowsA + ExtElements.size ());
128  for (local_ordinal_type i = 0; (size_t)i < numMyRowsA; ++i) {
129  mylist[i] = A_->getRowMap ()->getGlobalElement (i);
130  }
131  for (local_ordinal_type i = 0; i < ExtElements.size (); ++i) {
132  mylist[i + numMyRowsA] = ExtElements[i];
133  }
134 
135 
136  RowMap_ = rcp (new map_type (global_invalid, mylist (),
138  A_->getComm ()));
139  Importer_ = rcp (new import_type (A_->getRowMap (), RowMap_));
140  ColMap_ = RowMap_;
141 
142  // now build the map corresponding to all the external nodes
143  // (with respect to A().RowMatrixRowMap().
144  ExtMap_ = rcp (new map_type (global_invalid, ExtElements (),
146  A_->getComm ()));
147  ExtImporter_ = rcp (new import_type (A_->getRowMap (), ExtMap_));
148 
149  {
150  auto ExtMatrixDynGraph = rcp (new crs_matrix_type (ExtMap_, ColMap_, 0));
151  ExtMatrixDynGraph->doImport (*A_, *ExtImporter_, Tpetra::INSERT);
152  ExtMatrixDynGraph->fillComplete (A_->getDomainMap (), RowMap_);
153  auto ExtLclMatrix = ExtMatrixDynGraph->getLocalMatrixDevice();
154  auto ExtMatrixStaticGraph = rcp (new crs_graph_type(ExtLclMatrix.graph,
155  ExtMap_,
156  ColMap_,
157  ExtMatrixDynGraph->getDomainMap(),
158  ExtMatrixDynGraph->getRangeMap()));
159  ExtMatrix_ = rcp (new crs_matrix_type(ExtMatrixStaticGraph, ExtLclMatrix.values));
160  ExtMatrix_->fillComplete ();
161  }
162 
163  // fix indices for overlapping matrix
164  const size_t numMyRowsB = ExtMatrix_->getLocalNumRows ();
165 
166  GST NumMyNonzeros_tmp = A_->getLocalNumEntries () + ExtMatrix_->getLocalNumEntries ();
167  GST NumMyRows_tmp = numMyRowsA + numMyRowsB;
168  {
169  GST inArray[2], outArray[2];
170  inArray[0] = NumMyNonzeros_tmp;
171  inArray[1] = NumMyRows_tmp;
172  outArray[0] = 0;
173  outArray[1] = 0;
174  reduceAll<int, GST> (* (A_->getComm ()), REDUCE_SUM, 2, inArray, outArray);
175  NumGlobalNonzeros_ = outArray[0];
176  NumGlobalRows_ = outArray[1];
177  }
178  // reduceAll<int, GST> (* (A_->getComm ()), REDUCE_SUM, NumMyNonzeros_tmp,
179  // outArg (NumGlobalNonzeros_));
180  // reduceAll<int, GST> (* (A_->getComm ()), REDUCE_SUM, NumMyRows_tmp,
181  // outArg (NumGlobalRows_));
182 
183  MaxNumEntries_ = A_->getLocalMaxNumRowEntries ();
184  if (MaxNumEntries_ < ExtMatrix_->getLocalMaxNumRowEntries ()) {
185  MaxNumEntries_ = ExtMatrix_->getLocalMaxNumRowEntries ();
186  }
187 
188  // Create the graph (returned by getGraph()).
189  typedef Details::OverlappingRowGraph<row_graph_type> row_graph_impl_type;
190  RCP<row_graph_impl_type> graph =
191  rcp (new row_graph_impl_type (A_->getGraph (),
192  ExtMatrix_->getGraph (),
193  RowMap_,
194  ColMap_,
195  NumGlobalRows_,
196  NumGlobalRows_, // # global cols == # global rows
197  NumGlobalNonzeros_,
198  MaxNumEntries_,
199  Importer_,
200  ExtImporter_));
201  graph_ = Teuchos::rcp_const_cast<const row_graph_type>
202  (Teuchos::rcp_implicit_cast<row_graph_type> (graph));
203  // Resize temp arrays
204  Kokkos::resize(Indices_,MaxNumEntries_);
205  Kokkos::resize(Values_,MaxNumEntries_);
206 }
207 
208 
209 template<class MatrixType>
212 {
213  return A_->getComm ();
214 }
215 
216 
217 
218 
219 template<class MatrixType>
222 {
223  // FIXME (mfh 12 July 2013) Is this really the right Map to return?
224  return RowMap_;
225 }
226 
227 
228 template<class MatrixType>
231 {
232  // FIXME (mfh 12 July 2013) Is this really the right Map to return?
233  return ColMap_;
234 }
235 
236 
237 template<class MatrixType>
240 {
241  // The original matrix's domain map is irrelevant; we want the map associated
242  // with the overlap. This can then be used by LocalFilter, for example, while
243  // letting LocalFilter still filter based on domain and range maps (instead of
244  // column and row maps).
245  // FIXME Ideally, this would be the same map but restricted to a local
246  // communicator. If replaceCommWithSubset were free, that would be the way to
247  // go. That would require a new Map ctor. For now, we'll stick with ColMap_'s
248  // global communicator.
249  return ColMap_;
250 }
251 
252 
253 template<class MatrixType>
256 {
257  return RowMap_;
258 }
259 
260 
261 template<class MatrixType>
264 {
265  return graph_;
266 }
267 
268 
269 template<class MatrixType>
271 {
272  return NumGlobalRows_;
273 }
274 
275 
276 template<class MatrixType>
278 {
279  return NumGlobalRows_;
280 }
281 
282 
283 template<class MatrixType>
285 {
286  return A_->getLocalNumRows () + ExtMatrix_->getLocalNumRows ();
287 }
288 
289 
290 template<class MatrixType>
292 {
293  return this->getLocalNumRows ();
294 }
295 
296 
297 template<class MatrixType>
298 typename MatrixType::global_ordinal_type
300 {
301  return A_->getIndexBase();
302 }
303 
304 
305 template<class MatrixType>
307 {
308  return NumGlobalNonzeros_;
309 }
310 
311 
312 template<class MatrixType>
314 {
315  return A_->getLocalNumEntries () + ExtMatrix_->getLocalNumEntries ();
316 }
317 
318 
319 template<class MatrixType>
320 size_t
322 getNumEntriesInGlobalRow (global_ordinal_type globalRow) const
323 {
324  const local_ordinal_type localRow = RowMap_->getLocalElement (globalRow);
327  } else {
328  return getNumEntriesInLocalRow (localRow);
329  }
330 }
331 
332 
333 template<class MatrixType>
334 size_t
336 getNumEntriesInLocalRow (local_ordinal_type localRow) const
337 {
338  using Teuchos::as;
339  const size_t numMyRowsA = A_->getLocalNumRows ();
340  if (as<size_t> (localRow) < numMyRowsA) {
341  return A_->getNumEntriesInLocalRow (localRow);
342  } else {
343  return ExtMatrix_->getNumEntriesInLocalRow (as<local_ordinal_type> (localRow - numMyRowsA));
344  }
345 }
346 
347 
348 template<class MatrixType>
350 {
351  return std::max<size_t>(A_->getGlobalMaxNumRowEntries(), ExtMatrix_->getGlobalMaxNumRowEntries());
352 }
353 
354 
355 template<class MatrixType>
357 {
358  return MaxNumEntries_;
359 }
360 
361 template<class MatrixType>
362 typename MatrixType::local_ordinal_type OverlappingRowMatrix<MatrixType>::getBlockSize() const
363 {
364  return A_->getBlockSize();
365 }
366 
367 template<class MatrixType>
369 {
370  return true;
371 }
372 
373 
374 template<class MatrixType>
376 {
377  return true;
378 }
379 
380 
381 template<class MatrixType>
383 {
384  return false;
385 }
386 
387 
388 template<class MatrixType>
390 {
391  return true;
392 }
393 
394 
395 template<class MatrixType>
396 void
398  getGlobalRowCopy (global_ordinal_type GlobalRow,
399  nonconst_global_inds_host_view_type &Indices,
400  nonconst_values_host_view_type &Values,
401  size_t& NumEntries) const
402 {
403  throw std::runtime_error("Ifpack2::OverlappingRowMatrix::getGlobalRowCopy() not supported.");
404 }
405 
406 template<class MatrixType>
407 void
409  getLocalRowCopy (local_ordinal_type LocalRow,
410  nonconst_local_inds_host_view_type &Indices,
411  nonconst_values_host_view_type &Values,
412  size_t& NumEntries) const
413 {
414  using Teuchos::as;
415  const size_t numMyRowsA = A_->getLocalNumRows ();
416  if (as<size_t> (LocalRow) < numMyRowsA) {
417  A_->getLocalRowCopy (LocalRow, Indices, Values, NumEntries);
418  } else {
419  ExtMatrix_->getLocalRowCopy (LocalRow - as<local_ordinal_type> (numMyRowsA),
420  Indices, Values, NumEntries);
421  }
422 }
423 
424 template<class MatrixType>
425 void
427 getGlobalRowView (global_ordinal_type GlobalRow,
428  global_inds_host_view_type &indices,
429  values_host_view_type &values) const {
430  const local_ordinal_type LocalRow = RowMap_->getLocalElement (GlobalRow);
432  indices = global_inds_host_view_type();
433  values = values_host_view_type();
434  } else {
435  if (Teuchos::as<size_t> (LocalRow) < A_->getLocalNumRows ()) {
436  A_->getGlobalRowView (GlobalRow, indices, values);
437  } else {
438  ExtMatrix_->getGlobalRowView (GlobalRow, indices, values);
439  }
440  }
441 }
442 
443 template<class MatrixType>
444 void
446  getLocalRowView (local_ordinal_type LocalRow,
447  local_inds_host_view_type & indices,
448  values_host_view_type & values) const {
449  using Teuchos::as;
450  const size_t numMyRowsA = A_->getLocalNumRows ();
451  if (as<size_t> (LocalRow) < numMyRowsA) {
452  A_->getLocalRowView (LocalRow, indices, values);
453  } else {
454  ExtMatrix_->getLocalRowView (LocalRow - as<local_ordinal_type> (numMyRowsA),
455  indices, values);
456  }
457 
458 }
459 
460 template<class MatrixType>
461 void
463 getLocalDiagCopy (Tpetra::Vector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& diag) const
464 {
465  using Teuchos::Array;
466 
467  //extract diagonal of original matrix
468  vector_type baseDiag(A_->getRowMap()); // diagonal of original matrix A_
469  A_->getLocalDiagCopy(baseDiag);
470  Array<scalar_type> baseDiagVals(baseDiag.getLocalLength());
471  baseDiag.get1dCopy(baseDiagVals());
472  //extra diagonal of ghost matrix
473  vector_type extDiag(ExtMatrix_->getRowMap());
474  ExtMatrix_->getLocalDiagCopy(extDiag);
475  Array<scalar_type> extDiagVals(extDiag.getLocalLength());
476  extDiag.get1dCopy(extDiagVals());
477 
478  Teuchos::ArrayRCP<scalar_type> allDiagVals = diag.getDataNonConst();
479  if (allDiagVals.size() != baseDiagVals.size() + extDiagVals.size()) {
480  std::ostringstream errStr;
481  errStr << "Ifpack2::OverlappingRowMatrix::getLocalDiagCopy : Mismatch in diagonal lengths, "
482  << allDiagVals.size() << " != " << baseDiagVals.size() << "+" << extDiagVals.size();
483  throw std::runtime_error(errStr.str());
484  }
485  for (Teuchos::Ordinal i=0; i<baseDiagVals.size(); ++i)
486  allDiagVals[i] = baseDiagVals[i];
487  Teuchos_Ordinal offset=baseDiagVals.size();
488  for (Teuchos::Ordinal i=0; i<extDiagVals.size(); ++i)
489  allDiagVals[i+offset] = extDiagVals[i];
490 }
491 
492 
493 template<class MatrixType>
494 void
496 leftScale (const Tpetra::Vector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& /* x */)
497 {
498  throw std::runtime_error("Ifpack2::OverlappingRowMatrix does not support leftScale.");
499 }
500 
501 
502 template<class MatrixType>
503 void
505 rightScale (const Tpetra::Vector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& /* x */)
506 {
507  throw std::runtime_error("Ifpack2::OverlappingRowMatrix does not support leftScale.");
508 }
509 
510 
511 template<class MatrixType>
512 typename OverlappingRowMatrix<MatrixType>::mag_type
514 {
515  throw std::runtime_error("Ifpack2::OverlappingRowMatrix does not support getFrobeniusNorm.");
516 }
517 
518 
519 template<class MatrixType>
520 void
522 apply (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &X,
523  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &Y,
524  Teuchos::ETransp mode,
525  scalar_type alpha,
526  scalar_type beta) const
527 {
528  using MV = Tpetra::MultiVector<scalar_type, local_ordinal_type,
529  global_ordinal_type, node_type>;
531  (X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
532  "Ifpack2::OverlappingRowMatrix::apply: X.getNumVectors() = "
533  << X.getNumVectors() << " != Y.getNumVectors() = " << Y.getNumVectors()
534  << ".");
535  // If X aliases Y, we'll need to copy X.
536  bool aliases = X.aliases(Y);
537  if (aliases) {
538  MV X_copy (X, Teuchos::Copy);
539  this->apply (X_copy, Y, mode, alpha, beta);
540  return;
541  }
542 
543  const auto& rowMap0 = * (A_->getRowMap ());
544  const auto& colMap0 = * (A_->getColMap ());
545  MV X_0 (X, mode == Teuchos::NO_TRANS ? colMap0 : rowMap0, 0);
546  MV Y_0 (Y, mode == Teuchos::NO_TRANS ? rowMap0 : colMap0, 0);
547  A_->localApply (X_0, Y_0, mode, alpha, beta);
548 
549  const auto& rowMap1 = * (ExtMatrix_->getRowMap ());
550  const auto& colMap1 = * (ExtMatrix_->getColMap ());
551  MV X_1 (X, mode == Teuchos::NO_TRANS ? colMap1 : rowMap1, 0);
552  MV Y_1 (Y, mode == Teuchos::NO_TRANS ? rowMap1 : colMap1, A_->getLocalNumRows ());
553  ExtMatrix_->localApply (X_1, Y_1, mode, alpha, beta);
554 }
555 
556 
557 template<class MatrixType>
558 void
560 importMultiVector (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &X,
561  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &OvX,
562  Tpetra::CombineMode CM)
563 {
564  OvX.doImport (X, *Importer_, CM);
565 }
566 
567 
568 template<class MatrixType>
569 void
570 OverlappingRowMatrix<MatrixType>::
571 exportMultiVector (const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &OvX,
572  Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &X,
573  Tpetra::CombineMode CM)
574 {
575  X.doExport (OvX, *Importer_, CM);
576 }
577 
578 
579 template<class MatrixType>
581 {
582  return true;
583 }
584 
585 
586 template<class MatrixType>
588 {
589  return false;
590 }
591 
592 template<class MatrixType>
594 {
595  std::ostringstream oss;
596  if (isFillComplete()) {
597  oss << "{ isFillComplete: true"
598  << ", global rows: " << getGlobalNumRows()
599  << ", global columns: " << getGlobalNumCols()
600  << ", global entries: " << getGlobalNumEntries()
601  << " }";
602  }
603  else {
604  oss << "{ isFillComplete: false"
605  << ", global rows: " << getGlobalNumRows()
606  << " }";
607  }
608  return oss.str();
609 }
610 
611 template<class MatrixType>
612 void OverlappingRowMatrix<MatrixType>::describe(Teuchos::FancyOStream &out,
613  const Teuchos::EVerbosityLevel verbLevel) const
614 {
615  using std::endl;
616  using std::setw;
617  using Teuchos::as;
618  using Teuchos::VERB_DEFAULT;
619  using Teuchos::VERB_NONE;
620  using Teuchos::VERB_LOW;
621  using Teuchos::VERB_MEDIUM;
622  using Teuchos::VERB_HIGH;
623  using Teuchos::VERB_EXTREME;
624  using Teuchos::RCP;
625  using Teuchos::null;
626  using Teuchos::ArrayView;
627 
628  Teuchos::EVerbosityLevel vl = verbLevel;
629  if (vl == VERB_DEFAULT) {
630  vl = VERB_LOW;
631  }
632  RCP<const Teuchos::Comm<int> > comm = this->getComm();
633  const int myRank = comm->getRank();
634  const int numProcs = comm->getSize();
635  size_t width = 1;
636  for (size_t dec=10; dec<getGlobalNumRows(); dec *= 10) {
637  ++width;
638  }
639  width = std::max<size_t> (width, as<size_t> (11)) + 2;
640  Teuchos::OSTab tab(out);
641  // none: print nothing
642  // low: print O(1) info from node 0
643  // medium: print O(P) info, num entries per process
644  // high: print O(N) info, num entries per row
645  // extreme: print O(NNZ) info: print indices and values
646  //
647  // for medium and higher, print constituent objects at specified verbLevel
648  if (vl != VERB_NONE) {
649  if (myRank == 0) {
650  out << this->description() << std::endl;
651  }
652  // O(1) globals, minus what was already printed by description()
653  //if (isFillComplete() && myRank == 0) {
654  // out << "Global max number of entries in a row: " << getGlobalMaxNumRowEntries() << std::endl;
655  //}
656  // constituent objects
657  if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
658  if (myRank == 0) {
659  out << endl << "Row map:" << endl;
660  }
661  getRowMap()->describe(out,vl);
662  //
663  if (getColMap() != null) {
664  if (getColMap() == getRowMap()) {
665  if (myRank == 0) {
666  out << endl << "Column map is row map.";
667  }
668  }
669  else {
670  if (myRank == 0) {
671  out << endl << "Column map:" << endl;
672  }
673  getColMap()->describe(out,vl);
674  }
675  }
676  if (getDomainMap() != null) {
677  if (getDomainMap() == getRowMap()) {
678  if (myRank == 0) {
679  out << endl << "Domain map is row map.";
680  }
681  }
682  else if (getDomainMap() == getColMap()) {
683  if (myRank == 0) {
684  out << endl << "Domain map is column map.";
685  }
686  }
687  else {
688  if (myRank == 0) {
689  out << endl << "Domain map:" << endl;
690  }
691  getDomainMap()->describe(out,vl);
692  }
693  }
694  if (getRangeMap() != null) {
695  if (getRangeMap() == getDomainMap()) {
696  if (myRank == 0) {
697  out << endl << "Range map is domain map." << endl;
698  }
699  }
700  else if (getRangeMap() == getRowMap()) {
701  if (myRank == 0) {
702  out << endl << "Range map is row map." << endl;
703  }
704  }
705  else {
706  if (myRank == 0) {
707  out << endl << "Range map: " << endl;
708  }
709  getRangeMap()->describe(out,vl);
710  }
711  }
712  if (myRank == 0) {
713  out << endl;
714  }
715  }
716  // O(P) data
717  if (vl == VERB_MEDIUM || vl == VERB_HIGH || vl == VERB_EXTREME) {
718  for (int curRank = 0; curRank < numProcs; ++curRank) {
719  if (myRank == curRank) {
720  out << "Process rank: " << curRank << std::endl;
721  out << " Number of entries: " << getLocalNumEntries() << std::endl;
722  out << " Max number of entries per row: " << getLocalMaxNumRowEntries() << std::endl;
723  }
724  comm->barrier();
725  comm->barrier();
726  comm->barrier();
727  }
728  }
729  // O(N) and O(NNZ) data
730  if (vl == VERB_HIGH || vl == VERB_EXTREME) {
731  for (int curRank = 0; curRank < numProcs; ++curRank) {
732  if (myRank == curRank) {
733  out << std::setw(width) << "Proc Rank"
734  << std::setw(width) << "Global Row"
735  << std::setw(width) << "Num Entries";
736  if (vl == VERB_EXTREME) {
737  out << std::setw(width) << "(Index,Value)";
738  }
739  out << endl;
740  for (size_t r = 0; r < getLocalNumRows (); ++r) {
741  const size_t nE = getNumEntriesInLocalRow(r);
742  typename MatrixType::global_ordinal_type gid = getRowMap()->getGlobalElement(r);
743  out << std::setw(width) << myRank
744  << std::setw(width) << gid
745  << std::setw(width) << nE;
746  if (vl == VERB_EXTREME) {
747  if (isGloballyIndexed()) {
748  global_inds_host_view_type rowinds;
749  values_host_view_type rowvals;
750  getGlobalRowView (gid, rowinds, rowvals);
751  for (size_t j = 0; j < nE; ++j) {
752  out << " (" << rowinds[j]
753  << ", " << rowvals[j]
754  << ") ";
755  }
756  }
757  else if (isLocallyIndexed()) {
758  local_inds_host_view_type rowinds;
759  values_host_view_type rowvals;
760  getLocalRowView (r, rowinds, rowvals);
761  for (size_t j=0; j < nE; ++j) {
762  out << " (" << getColMap()->getGlobalElement(rowinds[j])
763  << ", " << rowvals[j]
764  << ") ";
765  }
766  } // globally or locally indexed
767  } // vl == VERB_EXTREME
768  out << endl;
769  } // for each row r on this process
770 
771  } // if (myRank == curRank)
772  comm->barrier();
773  comm->barrier();
774  comm->barrier();
775  }
776 
777  out.setOutputToRootOnly(0);
778  out << "===========\nlocal matrix\n=================" << std::endl;
779  out.setOutputToRootOnly(-1);
780  A_->describe(out,Teuchos::VERB_EXTREME);
781  out.setOutputToRootOnly(0);
782  out << "===========\nend of local matrix\n=================" << std::endl;
783  comm->barrier();
784  out.setOutputToRootOnly(0);
785  out << "=================\nghost matrix\n=================" << std::endl;
786  out.setOutputToRootOnly(-1);
787  ExtMatrix_->describe(out,Teuchos::VERB_EXTREME);
788  out.setOutputToRootOnly(0);
789  out << "===========\nend of ghost matrix\n=================" << std::endl;
790  }
791  }
792 }
793 
794 template<class MatrixType>
796 OverlappingRowMatrix<MatrixType>::getUnderlyingMatrix() const
797 {
798  return A_;
799 }
800 
801 template<class MatrixType>
803 OverlappingRowMatrix<MatrixType>::getExtMatrix() const
804 {
805  return ExtMatrix_;
806 }
807 
808 template<class MatrixType>
809 Kokkos::View<size_t*, typename OverlappingRowMatrix<MatrixType>::device_type>
810 OverlappingRowMatrix<MatrixType>::getExtHaloStarts() const
811 {
812  return ExtHaloStarts_;
813 }
814 
815 template<class MatrixType>
816 typename Kokkos::View<size_t*, typename OverlappingRowMatrix<MatrixType>::device_type>::HostMirror
817 OverlappingRowMatrix<MatrixType>::getExtHaloStartsHost() const
818 {
819  return ExtHaloStarts_h;
820 }
821 
822 template<class MatrixType>
823 void OverlappingRowMatrix<MatrixType>::doExtImport()
824 {
825  ExtMatrix_->resumeFill();
826  ExtMatrix_->doImport (*A_, *ExtImporter_, Tpetra::REPLACE);
827  ExtMatrix_->fillComplete (A_->getDomainMap (), RowMap_);
828 }
829 
830 } // namespace Ifpack2
831 
832 #define IFPACK2_OVERLAPPINGROWMATRIX_INSTANT(S,LO,GO,N) \
833  template class Ifpack2::OverlappingRowMatrix< Tpetra::RowMatrix<S, LO, GO, N> >;
834 
835 #endif // IFPACK2_OVERLAPPINGROWMATRIX_DEF_HPP
virtual bool isGloballyIndexed() const
Whether this matrix is globally indexed.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:382
virtual mag_type getFrobeniusNorm() const
Returns the Frobenius norm of the matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:513
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual bool isFillComplete() const
true if fillComplete() has been called, else false.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:389
virtual void getLocalRowCopy(local_ordinal_type LocalRow, nonconst_local_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const
Extract a list of entries in a specified local row of the graph. Put into storage allocated by callin...
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:409
size_type size() const
virtual void leftScale(const Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &x)
Scales the RowMatrix on the left with the Vector x.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:496
virtual size_t getLocalMaxNumRowEntries() const
The maximum number of entries in any row on the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:356
virtual size_t getLocalNumRows() const
The number of rows owned by the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:284
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:211
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getRowMap() const
The Map that describes the distribution of rows over processes.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:221
virtual global_size_t getGlobalNumRows() const
The global number of rows in this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:270
virtual global_size_t getGlobalNumCols() const
The global number of columns in this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:277
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual bool isLocallyIndexed() const
Whether this matrix is locally indexed.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:375
virtual void getGlobalRowCopy(global_ordinal_type GlobalRow, nonconst_global_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const
Extract a list of entries in a specified global row of this matrix. Put into pre-allocated storage...
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:398
virtual local_ordinal_type getBlockSize() const
The number of degrees of freedom per mesh point.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:362
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getRangeMap() const
The Map that describes the range of this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:255
virtual size_t getLocalNumCols() const
The number of columns owned by the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:291
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getDomainMap() const
The Map that describes the domain of this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:239
Sparse graph (Tpetra::RowGraph subclass) with ghost rows.
Definition: Ifpack2_Details_OverlappingRowGraph_decl.hpp:32
virtual void getLocalRowView(local_ordinal_type LocalRow, local_inds_host_view_type &indices, values_host_view_type &values) const
Extract a const, non-persisting view of local indices in a specified row of the matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:446
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
virtual size_t getNumEntriesInGlobalRow(global_ordinal_type globalRow) const
The number of entries in the given global row that are owned by the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:322
virtual global_size_t getGlobalNumEntries() const
The global number of entries in this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:306
virtual bool hasTransposeApply() const
Whether this operator&#39;s apply() method can apply the adjoint (transpose).
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:580
virtual global_ordinal_type getIndexBase() const
The index base for global indices for this matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:299
virtual bool hasColMap() const
Whether this matrix has a column Map.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:368
virtual void getGlobalRowView(global_ordinal_type GlobalRow, global_inds_host_view_type &indices, values_host_view_type &values) const
Extract a const, non-persisting view of global indices in a specified row of the matrix.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:427
virtual size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const
The number of entries in the given local row that are owned by the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:336
virtual void rightScale(const Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &x)
Scales the RowMatrix on the right with the Vector x.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:505
virtual Teuchos::RCP< const Tpetra::RowGraph< local_ordinal_type, global_ordinal_type, node_type > > getGraph() const
This matrix&#39;s graph.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:263
TypeTo as(const TypeFrom &t)
virtual void getLocalDiagCopy(Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:463
Sparse matrix (Tpetra::RowMatrix subclass) with ghost rows.
Definition: Ifpack2_OverlappingRowMatrix_decl.hpp:25
OverlappingRowMatrix(const Teuchos::RCP< const row_matrix_type > &A, const int overlapLevel)
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:27
virtual void apply(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
Computes the operator-multivector application.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:522
virtual size_t getLocalNumEntries() const
The number of entries in this matrix owned by the calling process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:313
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getColMap() const
The Map that describes the distribution of columns over processes.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:230
virtual bool supportsRowViews() const
true if row views are supported, else false.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:587
virtual size_t getGlobalMaxNumRowEntries() const
The maximum number of entries in any row on any process.
Definition: Ifpack2_OverlappingRowMatrix_def.hpp:349
bool is_null() const