42 #ifndef TPETRA_DETAILS_GETNUMDIAGS_HPP
43 #define TPETRA_DETAILS_GETNUMDIAGS_HPP
52 #include "Tpetra_CrsGraph.hpp"
53 #include "Teuchos_CommHelpers.hpp"
65 template<
class LocalGraphType,
class LocalMapType>
69 const LocalMapType& rowMap,
70 const LocalMapType& colMap) :
71 G_ (G), rowMap_ (rowMap), colMap_ (colMap)
76 using result_type =
typename LocalMapType::local_ordinal_type;
79 KOKKOS_INLINE_FUNCTION
void
80 operator () (
const typename LocalMapType::local_ordinal_type lclRow,
81 result_type& diagCount)
const
83 using LO =
typename LocalMapType::local_ordinal_type;
84 using LOT = typename ::Tpetra::Details::OrdinalTraits<LO>;
86 auto G_row = G_.rowConst (lclRow);
87 const LO numEnt = G_row.length;
92 const LO lclDiagCol = colMap_.getLocalElement (rowMap_.getGlobalElement (lclRow));
94 if (lclDiagCol != LOT::invalid ()) {
97 for (LO k = 0; k < numEnt; ++k) {
98 if (lclDiagCol == G_row(k)) {
109 LocalMapType rowMap_;
110 LocalMapType colMap_;
113 template<
class LO,
class GO,
class NT>
114 typename ::Tpetra::CrsGraph<LO, GO, NT>::local_ordinal_type
115 countLocalNumDiagsInFillCompleteGraph (const ::Tpetra::CrsGraph<LO, GO, NT>& G)
118 using local_map_type =
typename crs_graph_type::map_type::local_map_type;
119 using local_graph_type =
typename crs_graph_type::local_graph_type;
120 using functor_type = CountLocalNumDiags<local_graph_type, local_map_type>;
121 using execution_space =
typename crs_graph_type::device_type::execution_space;
122 using policy_type = Kokkos::RangePolicy<execution_space, LO>;
125 const auto colMap = G.getColMap ();
126 if (rowMap.get () ==
nullptr || colMap.get () ==
nullptr) {
131 functor_type f (G.getLocalGraph (), rowMap->getLocalMap (), colMap->getLocalMap ());
132 Kokkos::parallel_reduce (policy_type (0, G.getNodeNumRows ()), f, lclNumDiags);
146 template<
class MapType>
147 typename MapType::local_ordinal_type
148 getLocalDiagonalColumnIndex (
const typename MapType::local_ordinal_type lclRow,
149 const MapType& rowMap,
150 const MapType& colMap)
152 return colMap.getLocalElement (rowMap.getGlobalElement (lclRow));
156 template<
class LO,
class GO,
class NT>
157 typename ::Tpetra::RowGraph<LO, GO, NT>::local_ordinal_type
158 countLocalNumDiagsInNonFillCompleteLocallyIndexedGraphWithRowViews (const ::Tpetra::RowGraph<LO, GO, NT>& G)
160 using LOT = typename ::Tpetra::Details::OrdinalTraits<LO>;
162 const auto rowMap = G.getRowMap ();
163 const auto colMap = G.getColMap ();
164 if (rowMap.get () ==
nullptr || colMap.get () ==
nullptr) {
168 TEUCHOS_TEST_FOR_EXCEPTION
169 (! G.supportsRowViews (), std::logic_error,
"Not implemented!");
171 Teuchos::ArrayView<const LO> lclColInds;
172 const LO lclNumRows =
static_cast<LO
> (G.getNodeNumRows ());
175 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
176 G.getLocalRowView (lclRow, lclColInds);
177 const LO numEnt =
static_cast<LO
> (lclColInds.size ());
179 const LO lclDiagCol = colMap->getLocalElement (rowMap->getGlobalElement (lclRow));
181 if (lclDiagCol != LOT::invalid ()) {
184 for (LO k = 0; k < numEnt; ++k) {
185 if (lclDiagCol == lclColInds[k]) {
199 template<
class LO,
class GO,
class NT>
200 typename ::Tpetra::RowGraph<LO, GO, NT>::local_ordinal_type
201 countLocalNumDiagsInNonFillCompleteLocallyIndexedGraphWithoutRowViews (const ::Tpetra::RowGraph<LO, GO, NT>& G)
203 using LOT = typename ::Tpetra::Details::OrdinalTraits<LO>;
205 const auto rowMap = G.getRowMap ();
206 const auto colMap = G.getColMap ();
207 if (rowMap.get () ==
nullptr || colMap.get () ==
nullptr) {
211 Teuchos::Array<LO> lclColIndsBuf;
212 const LO lclNumRows =
static_cast<LO
> (G.getNodeNumRows ());
215 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
216 size_t numEntSizeT = G.getNumEntriesInLocalRow (lclRow);
217 const LO numEnt =
static_cast<LO
> (numEntSizeT);
218 if (static_cast<LO> (lclColIndsBuf.size ()) < numEnt) {
219 lclColIndsBuf.resize (numEnt);
221 Teuchos::ArrayView<LO> lclColInds = lclColIndsBuf (0, numEnt);
222 G.getLocalRowCopy (lclRow, lclColInds, numEntSizeT);
225 const LO lclDiagCol =
226 colMap->getLocalElement (rowMap->getGlobalElement (lclRow));
228 if (lclDiagCol != LOT::invalid ()) {
231 for (LO k = 0; k < numEnt; ++k) {
232 if (lclDiagCol == lclColInds[k]) {
246 template<
class LO,
class GO,
class NT>
247 typename ::Tpetra::RowGraph<LO, GO, NT>::local_ordinal_type
248 countLocalNumDiagsInNonFillCompleteGloballyIndexedGraphWithRowViews (const ::Tpetra::RowGraph<LO, GO, NT>& G)
250 const auto rowMap = G.getRowMap ();
251 if (rowMap.get () ==
nullptr) {
255 Teuchos::ArrayView<const GO> gblColInds;
256 const LO lclNumRows =
static_cast<LO
> (G.getNodeNumRows ());
259 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
260 const GO gblRow = rowMap->getGlobalElement (lclRow);
261 G.getGlobalRowView (gblRow, gblColInds);
262 const LO numEnt =
static_cast<LO
> (gblColInds.size ());
266 for (LO k = 0; k < numEnt; ++k) {
267 if (gblRow == gblColInds[k]) {
280 template<
class LO,
class GO,
class NT>
281 typename ::Tpetra::RowGraph<LO, GO, NT>::local_ordinal_type
282 countLocalNumDiagsInNonFillCompleteGloballyIndexedGraphWithoutRowViews (const ::Tpetra::RowGraph<LO, GO, NT>& G)
284 const auto rowMap = G.getRowMap ();
285 if (rowMap.get () ==
nullptr) {
289 Teuchos::Array<GO> gblColIndsBuf;
290 const LO lclNumRows =
static_cast<LO
> (G.getNodeNumRows ());
293 for (LO lclRow = 0; lclRow < lclNumRows; ++lclRow) {
294 size_t numEntSizeT = G.getNumEntriesInLocalRow (lclRow);
295 const LO numEnt =
static_cast<LO
> (numEntSizeT);
296 if (static_cast<LO> (gblColIndsBuf.size ()) < numEnt) {
297 gblColIndsBuf.resize (numEnt);
299 Teuchos::ArrayView<GO> gblColInds = gblColIndsBuf (0, numEnt);
300 const GO gblRow = rowMap->getGlobalElement (lclRow);
301 G.getGlobalRowCopy (gblRow, gblColInds, numEntSizeT);
306 for (LO k = 0; k < numEnt; ++k) {
307 if (gblRow == gblColInds[k]) {
325 template<
class MatrixType>
327 static typename MatrixType::local_ordinal_type
328 getLocalNumDiags (
const MatrixType& A)
330 using LO =
typename MatrixType::local_ordinal_type;
331 using GO =
typename MatrixType::global_ordinal_type;
332 using NT =
typename MatrixType::node_type;
335 auto G = A.getGraph ();
336 if (G.get () ==
nullptr) {
346 template<
class LO,
class GO,
class NT>
349 getLocalNumDiags (const ::Tpetra::RowGraph<LO, GO, NT>& G)
353 const crs_graph_type* G_crs =
dynamic_cast<const crs_graph_type*
> (&G);
354 if (G_crs !=
nullptr && G_crs->isFillComplete ()) {
355 return countLocalNumDiagsInFillCompleteGraph (*G_crs);
358 if (G.isLocallyIndexed ()) {
359 if (G.supportsRowViews ()) {
360 return countLocalNumDiagsInNonFillCompleteLocallyIndexedGraphWithRowViews (G);
363 return countLocalNumDiagsInNonFillCompleteLocallyIndexedGraphWithoutRowViews (G);
366 else if (G.isGloballyIndexed ()) {
367 if (G.supportsRowViews ()) {
368 return countLocalNumDiagsInNonFillCompleteGloballyIndexedGraphWithRowViews (G);
371 return countLocalNumDiagsInNonFillCompleteGloballyIndexedGraphWithoutRowViews (G);
382 template<
class LO,
class GO,
class NT>
385 getLocalNumDiags (const ::Tpetra::CrsGraph<LO, GO, NT>& G)
395 template<
class CrsGraphType>
396 typename CrsGraphType::local_ordinal_type
404 template<
class CrsGraphType>
405 typename CrsGraphType::global_ordinal_type
408 using GO =
typename CrsGraphType::global_ordinal_type;
410 const auto map = G.getRowMap ();
411 if (map.get () ==
nullptr) {
415 const auto comm = map->getComm ();
416 if (comm.get () ==
nullptr) {
422 using Teuchos::REDUCE_SUM;
423 using Teuchos::reduceAll;
424 using Teuchos::outArg;
427 reduceAll<int, GO> (*comm, REDUCE_SUM, lclNumDiags, outArg (gblNumDiags));
436 #endif // TPETRA_DETAILS_GETNUMDIAGS_HPP
Teuchos::RCP< const map_type > getRowMap() const override
Returns the Map that describes the row distribution in this graph.
Import KokkosSparse::OrdinalTraits, a traits class for "invalid" (flag) values of integer types...
An abstract interface for graphs accessed by rows.
Kokkos::parallel_reduce functor for counting the local number of diagonal entries in a sparse graph...
CrsGraphType::global_ordinal_type getGlobalNumDiags(const CrsGraphType &G)
Number of populated diagonal entries in the given sparse graph, over all processes in the graph's (MP...
CrsGraphType::local_ordinal_type getLocalNumDiags(const CrsGraphType &G)
Number of populated diagonal entries in the given sparse graph, on the calling (MPI) process...
KOKKOS_INLINE_FUNCTION void operator()(const typename LocalMapType::local_ordinal_type lclRow, result_type &diagCount) const
Reduction function: result is (diagonal count, error count).
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Implementation of Tpetra::Details::getLocalNumDiags (see below).