Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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
23namespace Ifpack2 {
24
25template <class MatrixType>
27 OverlappingRowMatrix(const Teuchos::RCP<const row_matrix_type> &A,
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;
41 TEUCHOS_TEST_FOR_EXCEPTION(
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.");
48 TEUCHOS_TEST_FOR_EXCEPTION(
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 =
56 Teuchos::OrdinalTraits<global_ordinal_type>::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),
107 Teuchos::OrdinalTraits<global_ordinal_type>::zero(),
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(),
132 Teuchos::OrdinalTraits<global_ordinal_type>::zero(),
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(),
140 Teuchos::OrdinalTraits<global_ordinal_type>::zero(),
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
202template <class MatrixType>
203Teuchos::RCP<const Teuchos::Comm<int> >
205 return A_->getComm();
206}
207
208template <class MatrixType>
209Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
211 // FIXME (mfh 12 July 2013) Is this really the right Map to return?
212 return RowMap_;
213}
214
215template <class MatrixType>
216Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
218 // FIXME (mfh 12 July 2013) Is this really the right Map to return?
219 return ColMap_;
220}
221
222template <class MatrixType>
223Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
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
236template <class MatrixType>
237Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
239 return RowMap_;
240}
241
242template <class MatrixType>
243Teuchos::RCP<const Tpetra::RowGraph<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
245 return graph_;
246}
247
248template <class MatrixType>
250 return NumGlobalRows_;
251}
252
253template <class MatrixType>
255 return NumGlobalRows_;
256}
257
258template <class MatrixType>
260 return A_->getLocalNumRows() + ExtMatrix_->getLocalNumRows();
261}
262
263template <class MatrixType>
265 return this->getLocalNumRows();
266}
267
268template <class MatrixType>
269typename MatrixType::global_ordinal_type
271 return A_->getIndexBase();
272}
273
274template <class MatrixType>
276 return NumGlobalNonzeros_;
277}
278
279template <class MatrixType>
281 return A_->getLocalNumEntries() + ExtMatrix_->getLocalNumEntries();
282}
283
284template <class MatrixType>
285size_t
287 getNumEntriesInGlobalRow(global_ordinal_type globalRow) const {
288 const local_ordinal_type localRow = RowMap_->getLocalElement(globalRow);
289 if (localRow == Teuchos::OrdinalTraits<local_ordinal_type>::invalid()) {
290 return Teuchos::OrdinalTraits<size_t>::invalid();
291 } else {
292 return getNumEntriesInLocalRow(localRow);
293 }
294}
295
296template <class MatrixType>
297size_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
309template <class MatrixType>
311 return std::max<size_t>(A_->getGlobalMaxNumRowEntries(), ExtMatrix_->getGlobalMaxNumRowEntries());
312}
313
314template <class MatrixType>
316 return MaxNumEntries_;
317}
318
319template <class MatrixType>
320typename MatrixType::local_ordinal_type OverlappingRowMatrix<MatrixType>::getBlockSize() const {
321 return A_->getBlockSize();
322}
323
324template <class MatrixType>
326 return true;
327}
328
329template <class MatrixType>
331 return true;
332}
333
334template <class MatrixType>
336 return false;
337}
338
339template <class MatrixType>
341 return true;
342}
343
344template <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
353template <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
369template <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);
375 if (LocalRow == Teuchos::OrdinalTraits<local_ordinal_type>::invalid()) {
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
387template <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
402template <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
432template <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
438template <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
444template <class MatrixType>
445typename OverlappingRowMatrix<MatrixType>::mag_type
447 throw std::runtime_error("Ifpack2::OverlappingRowMatrix does not support getFrobeniusNorm.");
448}
449
450template <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
484template <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
492template <class MatrixType>
493void 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
500template <class MatrixType>
502 return true;
503}
504
505template <class MatrixType>
507 return false;
508}
509
510template <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
527template <class MatrixType>
528void 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
712template <class MatrixType>
713Teuchos::RCP<const Tpetra::CrsMatrix<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
714OverlappingRowMatrix<MatrixType>::getUnderlyingMatrix() const {
715 return A_;
716}
717
718template <class MatrixType>
719Teuchos::RCP<const Tpetra::CrsMatrix<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
720OverlappingRowMatrix<MatrixType>::getExtMatrix() const {
721 return ExtMatrix_;
722}
723
724template <class MatrixType>
725Kokkos::View<size_t *, typename OverlappingRowMatrix<MatrixType>::device_type>
726OverlappingRowMatrix<MatrixType>::getExtHaloStarts() const {
727 return ExtHaloStarts_;
728}
729
730template <class MatrixType>
731typename Kokkos::View<size_t *, typename OverlappingRowMatrix<MatrixType>::device_type>::host_mirror_type
732OverlappingRowMatrix<MatrixType>::getExtHaloStartsHost() const {
733 return ExtHaloStarts_h;
734}
735
736template <class MatrixType>
737void 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
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:75
Sparse matrix (Tpetra::RowMatrix subclass) with ghost rows.
Definition Ifpack2_OverlappingRowMatrix_decl.hpp:25
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 bool hasTransposeApply() const
Whether this operator's apply() method can apply the adjoint (transpose).
Definition Ifpack2_OverlappingRowMatrix_def.hpp:501
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 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
virtual bool isLocallyIndexed() const
Whether this matrix is locally indexed.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:330
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 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
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 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 size_t getGlobalMaxNumRowEntries() const
The maximum number of entries in any row on any process.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:310
virtual global_size_t getGlobalNumCols() const
The global number of columns in this matrix.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:254
virtual bool isGloballyIndexed() const
Whether this matrix is globally indexed.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:335
virtual global_ordinal_type getIndexBase() const
The index base for global indices for this matrix.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:270
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::RowGraph< local_ordinal_type, global_ordinal_type, node_type > > getGraph() const
This matrix's graph.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:244
virtual size_t getLocalNumCols() const
The number of columns owned by the calling process.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:264
virtual size_t getLocalNumRows() const
The number of rows owned by the calling process.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:259
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 local_ordinal_type getBlockSize() const
The number of degrees of freedom per mesh point.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:320
virtual bool hasColMap() const
Whether this matrix has a column Map.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:325
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:204
virtual global_size_t getGlobalNumRows() const
The global number of rows in this matrix.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:249
virtual bool supportsRowViews() const
true if row views are supported, else false.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:506
virtual global_size_t getGlobalNumEntries() const
The global number of entries in this matrix.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:275
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 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
OverlappingRowMatrix(const Teuchos::RCP< const row_matrix_type > &A, const int overlapLevel)
Definition Ifpack2_OverlappingRowMatrix_def.hpp:27
virtual size_t getLocalMaxNumRowEntries() const
The maximum number of entries in any row on the calling process.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:315
virtual bool isFillComplete() const
true if fillComplete() has been called, else false.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:340
virtual mag_type getFrobeniusNorm() const
Returns the Frobenius norm of the matrix.
Definition Ifpack2_OverlappingRowMatrix_def.hpp:446
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
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
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40