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