MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_MatrixConstruction.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_MATRIXCONSTRUCTION_HPP
11 #define MUELU_MATRIXCONSTRUCTION_HPP
12 
13 #include "Kokkos_Core.hpp"
14 #include "Kokkos_ArithTraits.hpp"
15 
16 #include "MueLu_DroppingCommon.hpp"
17 
18 #include "Xpetra_MatrixFactory.hpp"
19 
20 #ifdef MUELU_COALESCE_DROP_DEBUG
21 // For demangling function names
22 #include <cxxabi.h>
23 #endif
24 
25 namespace MueLu::MatrixConstruction {
36 template <class local_matrix_type, class functor_type, class... remaining_functor_types>
38  private:
39  using scalar_type = typename local_matrix_type::value_type;
40  using local_ordinal_type = typename local_matrix_type::ordinal_type;
41  using memory_space = typename local_matrix_type::memory_space;
42  using results_view = Kokkos::View<DecisionType*, memory_space>;
43 
44  using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
45 
46  local_matrix_type A;
49  functor_type functor;
50  PointwiseCountingFunctor<local_matrix_type, remaining_functor_types...> remainingFunctors;
52 
53 #ifdef MUELU_COALESCE_DROP_DEBUG
54  std::string functorName;
55 #endif
56 
57  public:
58  PointwiseCountingFunctor(local_matrix_type& A_, results_view& results_, rowptr_type& rowptr_, functor_type& functor_, remaining_functor_types&... remainingFunctors_)
59  : A(A_)
60  , results(results_)
61  , rowptr(rowptr_)
62  , functor(functor_)
63  , remainingFunctors(A_, results_, rowptr_, false, remainingFunctors_...)
64  , firstFunctor(true) {
65 #ifdef MUELU_COALESCE_DROP_DEBUG
66  std::string mangledFunctorName = typeid(decltype(functor)).name();
67  int status = 0;
68  char* demangledFunctorName = 0;
69  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
70  functorName = demangledFunctorName;
71 #endif
72  }
73 
74  PointwiseCountingFunctor(local_matrix_type& A_, results_view& results_, rowptr_type& rowptr_, bool firstFunctor_, functor_type& functor_, remaining_functor_types&... remainingFunctors_)
75  : A(A_)
76  , results(results_)
77  , rowptr(rowptr_)
78  , functor(functor_)
79  , remainingFunctors(A_, results_, rowptr_, false, remainingFunctors_...)
80  , firstFunctor(firstFunctor_) {
81 #ifdef MUELU_COALESCE_DROP_DEBUG
82  std::string mangledFunctorName = typeid(decltype(functor)).name();
83  int status = 0;
84  char* demangledFunctorName = 0;
85  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
86  functorName = demangledFunctorName;
87 #endif
88  }
89 
90  KOKKOS_INLINE_FUNCTION
91  void operator()(const local_ordinal_type rlid, local_ordinal_type& nnz, const bool& final) const {
92 #ifdef MUELU_COALESCE_DROP_DEBUG
93  if (firstFunctor) {
94  Kokkos::printf("\nStarting on row %d\n", rlid);
95 
96  auto row = A.rowConst(rlid);
97 
98  Kokkos::printf("indices: ");
99  for (local_ordinal_type k = 0; k < row.length; ++k) {
100  auto clid = row.colidx(k);
101  Kokkos::printf("%5d ", clid);
102  }
103  Kokkos::printf("\n");
104 
105  Kokkos::printf("values: ");
106  for (local_ordinal_type k = 0; k < row.length; ++k) {
107  auto val = row.value(k);
108  Kokkos::printf("%5f ", val);
109  }
110  Kokkos::printf("\n");
111  }
112 #endif
113 
114  functor(rlid);
115 
116 #ifdef MUELU_COALESCE_DROP_DEBUG
117  {
118  Kokkos::printf("%s\n", functorName.c_str());
119 
120  auto row = A.rowConst(rlid);
121  const size_t offset = A.graph.row_map(rlid);
122 
123  Kokkos::printf("decisions: ");
124  for (local_ordinal_type k = 0; k < row.length; ++k) {
125  Kokkos::printf("%5d ", results(offset + k));
126  }
127  Kokkos::printf("\n");
128  }
129 #endif
130 
131  remainingFunctors(rlid, nnz, final);
132  }
133 };
134 
135 template <class local_matrix_type, class functor_type>
136 class PointwiseCountingFunctor<local_matrix_type, functor_type> {
137  private:
138  using scalar_type = typename local_matrix_type::value_type;
139  using local_ordinal_type = typename local_matrix_type::ordinal_type;
140  using memory_space = typename local_matrix_type::memory_space;
141  using results_view = Kokkos::View<DecisionType*, memory_space>;
142 
143  using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
144 
145  local_matrix_type A;
148  functor_type functor;
150 
151 #ifdef MUELU_COALESCE_DROP_DEBUG
152  std::string functorName;
153 #endif
154 
155  public:
156  PointwiseCountingFunctor(local_matrix_type& A_, results_view& results_, rowptr_type& rowptr_, functor_type& functor_)
157  : A(A_)
158  , results(results_)
159  , rowptr(rowptr_)
160  , functor(functor_)
161  , firstFunctor(true) {
162 #ifdef MUELU_COALESCE_DROP_DEBUG
163  std::string mangledFunctorName = typeid(decltype(functor)).name();
164  int status = 0;
165  char* demangledFunctorName = 0;
166  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
167  functorName = demangledFunctorName;
168 #endif
169  }
170 
171  PointwiseCountingFunctor(local_matrix_type& A_, results_view& results_, rowptr_type& rowptr_, bool firstFunctor_, functor_type& functor_)
172  : A(A_)
173  , results(results_)
174  , rowptr(rowptr_)
175  , functor(functor_)
176  , firstFunctor(firstFunctor_) {
177 #ifdef MUELU_COALESCE_DROP_DEBUG
178  std::string mangledFunctorName = typeid(decltype(functor)).name();
179  int status = 0;
180  char* demangledFunctorName = 0;
181  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
182  functorName = demangledFunctorName;
183 #endif
184  }
185 
186  KOKKOS_INLINE_FUNCTION
187  void operator()(const local_ordinal_type rlid, local_ordinal_type& nnz, const bool& final) const {
188 #ifdef MUELU_COALESCE_DROP_DEBUG
189  if (firstFunctor) {
190  Kokkos::printf("\nStarting on row %d\n", rlid);
191 
192  auto row = A.rowConst(rlid);
193 
194  Kokkos::printf("indices: ");
195  for (local_ordinal_type k = 0; k < row.length; ++k) {
196  auto clid = row.colidx(k);
197  Kokkos::printf("%5d ", clid);
198  }
199  Kokkos::printf("\n");
200 
201  Kokkos::printf("values: ");
202  for (local_ordinal_type k = 0; k < row.length; ++k) {
203  auto val = row.value(k);
204  Kokkos::printf("%5f ", val);
205  }
206  Kokkos::printf("\n");
207  }
208 #endif
209 
210  functor(rlid);
211 
212 #ifdef MUELU_COALESCE_DROP_DEBUG
213  Kokkos::printf("%s\n", functorName);
214 
215  auto row = A.rowConst(rlid);
216  const size_t offset = A.graph.row_map(rlid);
217 
218  Kokkos::printf("decisions: ");
219  for (local_ordinal_type k = 0; k < row.length; ++k) {
220  Kokkos::printf("%5d ", results(offset + k));
221  }
222 
223  Kokkos::printf("\n");
224  Kokkos::printf("Done with row %d\n", rlid);
225 #endif
226 
227  size_t start = A.graph.row_map(rlid);
228  size_t end = A.graph.row_map(rlid + 1);
229  for (size_t i = start; i < end; ++i) {
230  if (results(i) == KEEP) {
231  ++nnz;
232  }
233  }
234  if (final)
235  rowptr(rlid + 1) = nnz;
236  }
237 };
238 
247 template <class local_matrix_type, class local_graph_type, bool lumping>
249  private:
250  using scalar_type = typename local_matrix_type::value_type;
251  using local_ordinal_type = typename local_matrix_type::ordinal_type;
252  using memory_space = typename local_matrix_type::memory_space;
253  using results_view = Kokkos::View<DecisionType*, memory_space>;
254  using ATS = Kokkos::ArithTraits<scalar_type>;
255  using magnitudeType = typename ATS::magnitudeType;
256 
257  local_matrix_type A;
259  local_matrix_type filteredA;
260  local_graph_type graph;
262  const scalar_type zero = ATS::zero();
263  const scalar_type one = ATS::one();
264 
265  public:
266  PointwiseFillReuseFunctor(local_matrix_type& A_, results_view& results_, local_matrix_type& filteredA_, local_graph_type& graph_, magnitudeType dirichletThreshold_)
267  : A(A_)
268  , results(results_)
269  , filteredA(filteredA_)
270  , graph(graph_)
271  , dirichletThreshold(dirichletThreshold_) {}
272 
273  KOKKOS_INLINE_FUNCTION
274  void operator()(const local_ordinal_type rlid) const {
275  auto rowA = A.row(rlid);
276  size_t row_start = A.graph.row_map(rlid);
277  auto rowFilteredA = filteredA.row(rlid);
278  local_ordinal_type j = 0;
279  local_ordinal_type jj = 0;
280  local_ordinal_type graph_offset = graph.row_map(rlid);
281  scalar_type diagCorrection = zero;
282  local_ordinal_type diagOffset = -1;
283  for (local_ordinal_type k = 0; k < rowA.length; ++k) {
284  if constexpr (lumping) {
285  local_ordinal_type clid = rowA.colidx(k);
286  if (rlid == clid) {
287  diagOffset = j;
288  }
289  }
290  if (results(row_start + k) == KEEP) {
291  rowFilteredA.colidx(j) = rowA.colidx(k);
292  rowFilteredA.value(j) = rowA.value(k);
293  ++j;
294  graph.entries(graph_offset + jj) = rowA.colidx(k);
295  ++jj;
296  } else if constexpr (lumping) {
297  diagCorrection += rowA.value(k);
298  rowFilteredA.colidx(j) = rowA.colidx(k);
299  rowFilteredA.value(j) = zero;
300  ++j;
301  } else {
302  rowFilteredA.colidx(j) = rowA.colidx(k);
303  rowFilteredA.value(j) = zero;
304  ++j;
305  }
306  }
307  if constexpr (lumping) {
308  rowFilteredA.value(diagOffset) += diagCorrection;
309  if ((dirichletThreshold >= 0.0) && (ATS::real(rowFilteredA.value(diagOffset)) <= dirichletThreshold))
310  rowFilteredA.value(diagOffset) = one;
311  }
312  }
313 };
317 
326 template <class local_matrix_type, lumpingType lumpingChoice>
328  private:
329  using scalar_type = typename local_matrix_type::value_type;
330  using local_ordinal_type = typename local_matrix_type::ordinal_type;
331  using memory_space = typename local_matrix_type::memory_space;
332  using results_view = Kokkos::View<DecisionType*, memory_space>;
333  using ATS = Kokkos::ArithTraits<scalar_type>;
334  using magnitudeType = typename ATS::magnitudeType;
335 
336  local_matrix_type A;
338  local_matrix_type filteredA;
340  const scalar_type zero = ATS::zero();
341  const scalar_type one = ATS::one();
342 
343  public:
344  PointwiseFillNoReuseFunctor(local_matrix_type& A_, results_view& results_, local_matrix_type& filteredA_, magnitudeType dirichletThreshold_)
345  : A(A_)
346  , results(results_)
347  , filteredA(filteredA_)
348  , dirichletThreshold(dirichletThreshold_) {}
349 
350  KOKKOS_INLINE_FUNCTION
351  void operator()(const local_ordinal_type rlid) const {
352  auto rowA = A.row(rlid);
353  size_t K = A.graph.row_map(rlid);
354  auto rowFilteredA = filteredA.row(rlid);
355  local_ordinal_type j = 0;
356  scalar_type droppedSum = zero;
357  scalar_type keptRowSumAbs = zero;
358  local_ordinal_type diagOffset = -1;
359  for (local_ordinal_type k = 0; k < rowA.length; ++k) {
360  if constexpr (lumpingChoice != no_lumping) {
361  local_ordinal_type clid = rowA.colidx(k);
362  if (rlid == clid) {
363  diagOffset = j;
364  }
365  }
366  if (results(K + k) == KEEP) {
367  rowFilteredA.colidx(j) = rowA.colidx(k);
368  rowFilteredA.value(j) = rowA.value(k);
369  if constexpr (lumpingChoice == distributed_lumping) {
370  keptRowSumAbs += ATS::magnitude(rowFilteredA.value(j));
371  }
372  ++j;
373  } else if constexpr (lumpingChoice != no_lumping) {
374  droppedSum += rowA.value(k);
375  }
376  }
377  if constexpr (lumpingChoice == diag_lumping) {
378  rowFilteredA.value(diagOffset) += droppedSum;
379  if ((dirichletThreshold >= 0.0) && (ATS::real(rowFilteredA.value(diagOffset)) <= dirichletThreshold))
380  rowFilteredA.value(diagOffset) = one;
381  } else if constexpr (lumpingChoice == distributed_lumping) {
382  if (ATS::real(droppedSum) >= ATS::real(zero)) {
383  rowFilteredA.value(diagOffset) += droppedSum;
384 
385  } else {
386  for (local_ordinal_type k = 0; k < j; ++k) {
387  rowFilteredA.value(k) += droppedSum * ATS::magnitude(rowFilteredA.value(k)) / keptRowSumAbs;
388  }
389  }
390  }
391  }
392 };
393 
394 template <class local_matrix_type>
396  public:
397  using local_ordinal_type = typename local_matrix_type::ordinal_type;
398  using memory_space = typename local_matrix_type::memory_space;
399  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
400 
401  local_matrix_type A;
404 
405  public:
406  BlockRowComparison(local_matrix_type& A_, local_ordinal_type bsize_, block_indices_view_type ghosted_point_to_block_)
407  : A(A_)
408  , bsize(bsize_)
409  , ghosted_point_to_block(ghosted_point_to_block_) {}
410 
411  template <class local_matrix_type2>
412  struct Comparator {
413  private:
414  using local_ordinal_type = typename local_matrix_type2::ordinal_type;
415  using memory_space = typename local_matrix_type2::memory_space;
416  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
417 
418  const local_matrix_type2 A;
421 
422  public:
423  KOKKOS_INLINE_FUNCTION
424  Comparator(const local_matrix_type2& A_, local_ordinal_type bsize_, local_ordinal_type brlid_, block_indices_view_type ghosted_point_to_block_)
425  : A(A_)
426  , offset(A_.graph.row_map(bsize_ * brlid_))
427  , ghosted_point_to_block(ghosted_point_to_block_) {}
428 
429  KOKKOS_INLINE_FUNCTION
430  bool operator()(size_t x, size_t y) const {
431  return ghosted_point_to_block(A.graph.entries(offset + x)) < ghosted_point_to_block(A.graph.entries(offset + y));
432  }
433  };
434 
436 
437  KOKKOS_INLINE_FUNCTION
440  }
441 };
442 
453 template <class local_matrix_type,
454  class functor_type,
455  class... remaining_functor_types>
457  private:
458  using scalar_type = typename local_matrix_type::value_type;
459  using local_ordinal_type = typename local_matrix_type::ordinal_type;
460  using memory_space = typename local_matrix_type::memory_space;
461  using results_view = Kokkos::View<DecisionType*, memory_space>;
462  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
463  using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
464 
465  using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
466  using ATS = Kokkos::ArithTraits<local_ordinal_type>;
467 
468  local_matrix_type A;
474 
475  functor_type functor;
476 
479 
480  VectorCountingFunctor<local_matrix_type, remaining_functor_types...> remainingFunctors;
481 
482 #ifdef MUELU_COALESCE_DROP_DEBUG
483  std::string functorName;
484 #endif
485 
486  public:
487  VectorCountingFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view& results_, rowptr_type& filtered_rowptr_, rowptr_type& graph_rowptr_, functor_type& functor_, remaining_functor_types&... remainingFunctors_)
488  : A(A_)
489  , blockSize(blockSize_)
490  , ghosted_point_to_block(ghosted_point_to_block_)
491  , results(results_)
492  , filtered_rowptr(filtered_rowptr_)
493  , graph_rowptr(graph_rowptr_)
494  , functor(functor_)
496  , remainingFunctors(A_, blockSize_, ghosted_point_to_block_, results_, filtered_rowptr_, graph_rowptr_, remainingFunctors_...) {
497  permutation = permutation_type("permutation", A.nnz());
498 #ifdef MUELU_COALESCE_DROP_DEBUG
499  std::string mangledFunctorName = typeid(decltype(functor)).name();
500  int status = 0;
501  char* demangledFunctorName = 0;
502  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
503  functorName = demangledFunctorName;
504 #endif
505  }
506 
507  KOKKOS_INLINE_FUNCTION
508  void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest, const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src) const {
509  dest.first += src.first;
510  dest.second += src.second;
511  }
512 
513  KOKKOS_INLINE_FUNCTION
514  void operatorRow(const local_ordinal_type rlid) const {
515  functor(rlid);
516  remainingFunctors.operatorRow(rlid);
517  }
518 
519  KOKKOS_INLINE_FUNCTION
520  void operator()(const local_ordinal_type brlid, Kokkos::pair<local_ordinal_type, local_ordinal_type>& nnz, const bool& final) const {
521  auto nnz_filtered = &nnz.first;
522  auto nnz_graph = &nnz.second;
523 
524 #ifdef MUELU_COALESCE_DROP_DEBUG
525  Kokkos::printf("\nStarting on block row %d\n", brlid);
526 #endif
527  for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
528 #ifdef MUELU_COALESCE_DROP_DEBUG
529  {
530  Kokkos::printf("\nStarting on row %d\n", rlid);
531 
532  auto row = A.rowConst(rlid);
533 
534  Kokkos::printf("indices: ");
535  for (local_ordinal_type k = 0; k < row.length; ++k) {
536  auto clid = row.colidx(k);
537  Kokkos::printf("%5d ", clid);
538  }
539  Kokkos::printf("\n");
540 
541  Kokkos::printf("values: ");
542  for (local_ordinal_type k = 0; k < row.length; ++k) {
543  auto val = row.value(k);
544  Kokkos::printf("%5f ", val);
545  }
546  Kokkos::printf("\n");
547  }
548 #endif
549 
550  functor(rlid);
551  remainingFunctors.operatorRow(rlid);
552 
553 #ifdef MUELU_COALESCE_DROP_DEBUG
554  {
555  Kokkos::printf("%s\n", functorName.c_str());
556 
557  auto row = A.rowConst(rlid);
558  const size_t offset = A.graph.row_map(rlid);
559 
560  Kokkos::printf("decisions: ");
561  for (local_ordinal_type k = 0; k < row.length; ++k) {
562  Kokkos::printf("%5d ", results(offset + k));
563  }
564  Kokkos::printf("\n");
565  }
566 #endif
567 
568 #ifdef MUELU_COALESCE_DROP_DEBUG
569  Kokkos::printf("Done with row %d\n", rlid);
570 #endif
571 
572  size_t start = A.graph.row_map(rlid);
573  size_t end = A.graph.row_map(rlid + 1);
574  for (size_t i = start; i < end; ++i) {
575  if (results(i) == KEEP) {
576  ++(*nnz_filtered);
577  }
578  }
579  if (final)
580  filtered_rowptr(rlid + 1) = *nnz_filtered;
581  }
582 
583 #ifdef MUELU_COALESCE_DROP_DEBUG
584  Kokkos::printf("Done with block row %d\nGraph indices ", brlid);
585 #endif
586 
587  // column lids for all rows in the block
588  auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
589  A.graph.row_map(blockSize * (brlid + 1))));
590  // set up a permutatation index
591  auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
592  A.graph.row_map(blockSize * (brlid + 1))));
593  for (size_t i = 0; i < block_permutation.extent(0); ++i)
594  block_permutation(i) = i;
595  // get permuatation for sorted column indices of the entire block
596  auto comparator = comparison.getComparator(brlid);
597  Misc::serialHeapSort(block_permutation, comparator);
598 
599  local_ordinal_type prev_bclid = -1;
600  bool alreadyAdded = false;
601 
602  // loop over all sorted entries in block
603  auto offset = A.graph.row_map(blockSize * brlid);
604  for (size_t i = 0; i < block_permutation.extent(0); ++i) {
605  auto idx = offset + block_permutation(i);
606  auto clid = A.graph.entries(idx);
607  auto bclid = ghosted_point_to_block(clid);
608 
609  // unseen block column index
610  if (bclid > prev_bclid)
611  alreadyAdded = false;
612 
613  // add entry to graph
614  if (!alreadyAdded && (results(idx) == KEEP)) {
615  ++(*nnz_graph);
616  alreadyAdded = true;
617 #ifdef MUELU_COALESCE_DROP_DEBUG
618  Kokkos::printf("%5d ", bclid);
619 #endif
620  }
621  prev_bclid = bclid;
622  }
623 #ifdef MUELU_COALESCE_DROP_DEBUG
624  Kokkos::printf("\n");
625 #endif
626  if (final)
627  graph_rowptr(brlid + 1) = *nnz_graph;
628  }
629 };
630 
631 template <class local_matrix_type,
632  class functor_type>
633 class VectorCountingFunctor<local_matrix_type, functor_type> {
634  private:
635  using scalar_type = typename local_matrix_type::value_type;
636  using local_ordinal_type = typename local_matrix_type::ordinal_type;
637  using memory_space = typename local_matrix_type::memory_space;
638  using results_view = Kokkos::View<DecisionType*, memory_space>;
639  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
640  using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
641 
642  using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
643  using ATS = Kokkos::ArithTraits<local_ordinal_type>;
644 
645  local_matrix_type A;
651 
653  functor_type functor;
654 
655 #ifdef MUELU_COALESCE_DROP_DEBUG
656  std::string functorName;
657 #endif
658 
661 
662  public:
663  VectorCountingFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view& results_, rowptr_type& filtered_rowptr_, rowptr_type& graph_rowptr_, functor_type& functor_)
664  : A(A_)
665  , blockSize(blockSize_)
666  , ghosted_point_to_block(ghosted_point_to_block_)
667  , results(results_)
668  , filtered_rowptr(filtered_rowptr_)
669  , graph_rowptr(graph_rowptr_)
670  , functor(functor_)
672  permutation = permutation_type("permutation", A.nnz());
673 #ifdef MUELU_COALESCE_DROP_DEBUG
674  std::string mangledFunctorName = typeid(decltype(functor)).name();
675  int status = 0;
676  char* demangledFunctorName = 0;
677  demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
678  functorName = demangledFunctorName;
679 #endif
680  }
681 
682  KOKKOS_INLINE_FUNCTION
683  void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest, const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src) const {
684  dest.first += src.first;
685  dest.second += src.second;
686  }
687 
688  KOKKOS_INLINE_FUNCTION
689  void operatorRow(const local_ordinal_type rlid) const {
690  functor(rlid);
691  }
692 
693  KOKKOS_INLINE_FUNCTION
694  void operator()(const local_ordinal_type brlid, Kokkos::pair<local_ordinal_type, local_ordinal_type>& nnz, const bool& final) const {
695  auto nnz_filtered = &nnz.first;
696  auto nnz_graph = &nnz.second;
697 
698 #ifdef MUELU_COALESCE_DROP_DEBUG
699  Kokkos::printf("\nStarting on block row %d\n", brlid);
700 #endif
701  for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
702 #ifdef MUELU_COALESCE_DROP_DEBUG
703  {
704  Kokkos::printf("\nStarting on row %d\n", rlid);
705 
706  auto row = A.rowConst(rlid);
707 
708  Kokkos::printf("indices: ");
709  for (local_ordinal_type k = 0; k < row.length; ++k) {
710  auto clid = row.colidx(k);
711  Kokkos::printf("%5d ", clid);
712  }
713  Kokkos::printf("\n");
714 
715  Kokkos::printf("values: ");
716  for (local_ordinal_type k = 0; k < row.length; ++k) {
717  auto val = row.value(k);
718  Kokkos::printf("%5f ", val);
719  }
720  Kokkos::printf("\n");
721  }
722 #endif
723 
724  functor(rlid);
725 
726 #ifdef MUELU_COALESCE_DROP_DEBUG
727  {
728  Kokkos::printf("%s\n", functorName.c_str());
729 
730  auto row = A.rowConst(rlid);
731  const size_t offset = A.graph.row_map(rlid);
732 
733  Kokkos::printf("decisions: ");
734  for (local_ordinal_type k = 0; k < row.length; ++k) {
735  Kokkos::printf("%5d ", results(offset + k));
736  }
737  Kokkos::printf("\n");
738  }
739 #endif
740 
741 #ifdef MUELU_COALESCE_DROP_DEBUG
742  Kokkos::printf("Done with row %d\n", rlid);
743 #endif
744 
745  size_t start = A.graph.row_map(rlid);
746  size_t end = A.graph.row_map(rlid + 1);
747  for (size_t i = start; i < end; ++i) {
748  if (results(i) == KEEP) {
749  ++(*nnz_filtered);
750  }
751  }
752  if (final)
753  filtered_rowptr(rlid + 1) = *nnz_filtered;
754  }
755 
756 #ifdef MUELU_COALESCE_DROP_DEBUG
757  Kokkos::printf("Done with block row %d\nGraph indices ", brlid);
758 #endif
759 
760  // column lids for all rows in the block
761  auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
762  A.graph.row_map(blockSize * (brlid + 1))));
763  // set up a permutation index
764  auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
765  A.graph.row_map(blockSize * (brlid + 1))));
766  for (size_t i = 0; i < block_permutation.extent(0); ++i)
767  block_permutation(i) = i;
768  // get permutation for sorted column indices of the entire block
769  auto comparator = comparison.getComparator(brlid);
770  Misc::serialHeapSort(block_permutation, comparator);
771 
772  local_ordinal_type prev_bclid = -1;
773  bool alreadyAdded = false;
774 
775  // loop over all sorted entries in block
776  auto offset = A.graph.row_map(blockSize * brlid);
777  for (size_t i = 0; i < block_permutation.extent(0); ++i) {
778  auto idx = offset + block_permutation(i);
779  auto clid = A.graph.entries(idx);
780  auto bclid = ghosted_point_to_block(clid);
781 
782  // unseen block column index
783  if (bclid > prev_bclid)
784  alreadyAdded = false;
785 
786  // add entry to graph
787  if (!alreadyAdded && (results(idx) == KEEP)) {
788  ++(*nnz_graph);
789  alreadyAdded = true;
790 #ifdef MUELU_COALESCE_DROP_DEBUG
791  Kokkos::printf("%5d ", bclid);
792 #endif
793  }
794  prev_bclid = bclid;
795  }
796 #ifdef MUELU_COALESCE_DROP_DEBUG
797  Kokkos::printf("\n");
798 #endif
799  if (final)
800  graph_rowptr(brlid + 1) = *nnz_graph;
801  }
802 };
803 
811 template <class local_matrix_type, bool lumping, bool reuse>
813  private:
814  using scalar_type = typename local_matrix_type::value_type;
815  using local_ordinal_type = typename local_matrix_type::ordinal_type;
816  using local_graph_type = typename local_matrix_type::staticcrsgraph_type;
817  using memory_space = typename local_matrix_type::memory_space;
818  using results_view = Kokkos::View<DecisionType*, memory_space>;
819  using ATS = Kokkos::ArithTraits<scalar_type>;
820  using OTS = Kokkos::ArithTraits<local_ordinal_type>;
821  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
822  using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
823  using magnitudeType = typename ATS::magnitudeType;
824 
825  local_matrix_type A;
829  local_matrix_type filteredA;
832  const scalar_type zero = ATS::zero();
833  const scalar_type one = ATS::one();
834 
837 
838  public:
839  VectorFillFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view& results_, local_matrix_type& filteredA_, local_graph_type& graph_, magnitudeType dirichletThreshold_)
840  : A(A_)
841  , blockSize(blockSize_)
842  , ghosted_point_to_block(ghosted_point_to_block_)
843  , results(results_)
844  , filteredA(filteredA_)
845  , graph(graph_)
846  , dirichletThreshold(dirichletThreshold_)
848  permutation = permutation_type("permutation", A.nnz());
849  }
850 
851  KOKKOS_INLINE_FUNCTION
852  void operator()(const local_ordinal_type brlid) const {
853  for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
854  auto rowA = A.row(rlid);
855  size_t row_start = A.graph.row_map(rlid);
856  auto rowFilteredA = filteredA.row(rlid);
857  local_ordinal_type j = 0;
858  scalar_type diagCorrection = zero;
859  local_ordinal_type diagOffset = -1;
860  for (local_ordinal_type k = 0; k < rowA.length; ++k) {
861  if constexpr (lumping) {
862  local_ordinal_type clid = rowA.colidx(k);
863  if (rlid == clid) {
864  diagOffset = j;
865  }
866  }
867  if (results(row_start + k) == KEEP) {
868  rowFilteredA.colidx(j) = rowA.colidx(k);
869  rowFilteredA.value(j) = rowA.value(k);
870  ++j;
871  } else if constexpr (lumping) {
872  diagCorrection += rowA.value(k);
873  if constexpr (reuse) {
874  rowFilteredA.colidx(j) = rowA.colidx(k);
875  rowFilteredA.value(j) = zero;
876  ++j;
877  }
878  } else if constexpr (reuse) {
879  rowFilteredA.colidx(j) = rowA.colidx(k);
880  rowFilteredA.value(j) = zero;
881  ++j;
882  }
883  }
884  if constexpr (lumping) {
885  rowFilteredA.value(diagOffset) += diagCorrection;
886  if ((dirichletThreshold >= 0.0) && (ATS::real(rowFilteredA.value(diagOffset)) <= dirichletThreshold))
887  rowFilteredA.value(diagOffset) = one;
888  }
889  }
890 
891  // column lids for all rows in the block
892  auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
893  A.graph.row_map(blockSize * (brlid + 1))));
894  // set up a permuatation index
895  auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
896  A.graph.row_map(blockSize * (brlid + 1))));
897  for (size_t i = 0; i < block_permutation.extent(0); ++i)
898  block_permutation(i) = i;
899  // get permutation for sorted column indices of the entire block
900  auto comparator = comparison.getComparator(brlid);
901  Misc::serialHeapSort(block_permutation, comparator);
902 
903  local_ordinal_type prev_bclid = -1;
904  bool alreadyAdded = false;
905  local_ordinal_type j = graph.row_map(brlid);
906 
907  // loop over all sorted entries in block
908  auto offset = A.graph.row_map(blockSize * brlid);
909  for (size_t i = 0; i < block_permutation.extent(0); ++i) {
910  auto idx = offset + block_permutation(i);
911  auto clid = A.graph.entries(idx);
912  auto bclid = ghosted_point_to_block(clid);
913 
914  // unseen block column index
915  if (bclid > prev_bclid)
916  alreadyAdded = false;
917 
918  // add entry to graph
919  if (!alreadyAdded && (results(idx) == KEEP)) {
920  graph.entries(j) = bclid;
921  ++j;
922  alreadyAdded = true;
923  }
924  prev_bclid = bclid;
925  }
926  }
927 };
928 
929 template <class local_matrix_type>
931  private:
932  using scalar_type = typename local_matrix_type::value_type;
933  using local_ordinal_type = typename local_matrix_type::ordinal_type;
934  using memory_space = typename local_matrix_type::memory_space;
935  using results_view = Kokkos::View<DecisionType*, memory_space>;
936  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
937  using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
938 
939  using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
940  using ATS = Kokkos::ArithTraits<local_ordinal_type>;
941 
942  local_matrix_type A;
946 
949 
950  public:
951  MergeCountFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, rowptr_type& merged_rowptr_)
952  : A(A_)
953  , blockSize(blockSize_)
954  , ghosted_point_to_block(ghosted_point_to_block_)
955  , merged_rowptr(merged_rowptr_)
957  permutation = permutation_type("permutation", A.nnz());
958  }
959 
960  KOKKOS_INLINE_FUNCTION
961  void operator()(const local_ordinal_type brlid, local_ordinal_type& nnz_graph, const bool& final) const {
962  // column lids for all rows in the block
963  auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
964  A.graph.row_map(blockSize * (brlid + 1))));
965  // set up a permutation index
966  auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
967  A.graph.row_map(blockSize * (brlid + 1))));
968  for (size_t i = 0; i < block_permutation.extent(0); ++i)
969  block_permutation(i) = i;
970  // get permutation for sorted column indices of the entire block
971  auto comparator = comparison.getComparator(brlid);
972  Misc::serialHeapSort(block_permutation, comparator);
973 
974  local_ordinal_type prev_bclid = -1;
975  bool alreadyAdded = false;
976 
977  // loop over all sorted entries in block
978  auto offset = A.graph.row_map(blockSize * brlid);
979  for (size_t i = 0; i < block_permutation.extent(0); ++i) {
980  auto idx = offset + block_permutation(i);
981  auto clid = A.graph.entries(idx);
982  auto bclid = ghosted_point_to_block(clid);
983 
984  // unseen block column index
985  if (bclid > prev_bclid)
986  alreadyAdded = false;
987 
988  // add entry to graph
989  if (!alreadyAdded) {
990  ++nnz_graph;
991  alreadyAdded = true;
992 #ifdef MUELU_COALESCE_DROP_DEBUG
993  Kokkos::printf("%5d ", bclid);
994 #endif
995  }
996  prev_bclid = bclid;
997  }
998 #ifdef MUELU_COALESCE_DROP_DEBUG
999  Kokkos::printf("\n");
1000 #endif
1001  if (final)
1002  merged_rowptr(brlid + 1) = nnz_graph;
1003  }
1004 };
1005 
1006 template <class local_matrix_type>
1008  private:
1009  using scalar_type = typename local_matrix_type::value_type;
1010  using local_ordinal_type = typename local_matrix_type::ordinal_type;
1011  using local_graph_type = typename local_matrix_type::staticcrsgraph_type;
1012  using memory_space = typename local_matrix_type::memory_space;
1013  using results_view = Kokkos::View<DecisionType*, memory_space>;
1014  using ATS = Kokkos::ArithTraits<scalar_type>;
1015  using OTS = Kokkos::ArithTraits<local_ordinal_type>;
1016  using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
1017  using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
1018  using magnitudeType = typename ATS::magnitudeType;
1019 
1020  local_matrix_type A;
1023  local_matrix_type mergedA;
1024  const scalar_type zero = ATS::zero();
1025  const scalar_type one = ATS::one();
1026 
1029 
1030  public:
1031  MergeFillFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, local_matrix_type& mergedA_)
1032  : A(A_)
1033  , blockSize(blockSize_)
1034  , ghosted_point_to_block(ghosted_point_to_block_)
1035  , mergedA(mergedA_)
1037  permutation = permutation_type("permutation", A.nnz());
1038  }
1039 
1040  KOKKOS_INLINE_FUNCTION
1041  void operator()(const local_ordinal_type brlid) const {
1042  // column lids for all rows in the block
1043  auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
1044  A.graph.row_map(blockSize * (brlid + 1))));
1045  // set up a permuatation index
1046  auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
1047  A.graph.row_map(blockSize * (brlid + 1))));
1048  for (size_t i = 0; i < block_permutation.extent(0); ++i)
1049  block_permutation(i) = i;
1050  // get permutation for sorted column indices of the entire block
1051  auto comparator = comparison.getComparator(brlid);
1052  Misc::serialHeapSort(block_permutation, comparator);
1053 
1054  local_ordinal_type prev_bclid = -1;
1055  bool alreadyAdded = false;
1056  local_ordinal_type j = mergedA.graph.row_map(brlid);
1057 
1058  // loop over all sorted entries in block
1059  auto offset = A.graph.row_map(blockSize * brlid);
1060  for (size_t i = 0; i < block_permutation.extent(0); ++i) {
1061  auto idx = offset + block_permutation(i);
1062  auto clid = A.graph.entries(idx);
1063  auto bclid = ghosted_point_to_block(clid);
1064 
1065  // unseen block column index
1066  if (bclid > prev_bclid)
1067  alreadyAdded = false;
1068 
1069  // add entry to graph
1070  if (!alreadyAdded) {
1071  mergedA.graph.entries(j) = bclid;
1072  mergedA.values(j) = one;
1073  ++j;
1074  alreadyAdded = true;
1075  }
1076  prev_bclid = bclid;
1077  }
1078  }
1079 };
1080 
1081 template <class local_matrix_type, class local_graph_type>
1083  private:
1084  using scalar_type = typename local_matrix_type::value_type;
1085  using local_ordinal_type = typename local_matrix_type::ordinal_type;
1086  using memory_space = typename local_matrix_type::memory_space;
1087  using results_view = Kokkos::View<DecisionType*, memory_space>;
1088 
1089  local_matrix_type A;
1091  local_graph_type graph;
1092 
1093  public:
1094  GraphConstruction(local_matrix_type& A_, results_view& results_, local_graph_type& graph_)
1095  : A(A_)
1096  , results(results_)
1097  , graph(graph_) {}
1098 
1099  KOKKOS_INLINE_FUNCTION
1100  void operator()(const local_ordinal_type rlid) const {
1101  auto rowA = A.row(rlid);
1102  size_t row_start = A.graph.row_map(rlid);
1103  local_ordinal_type jj = 0;
1104  local_ordinal_type graph_offset = graph.row_map(rlid);
1105  for (local_ordinal_type k = 0; k < rowA.length; ++k) {
1106  if (results(row_start + k) == KEEP) {
1107  graph.entries(graph_offset + jj) = rowA.colidx(k);
1108  ++jj;
1109  }
1110  }
1111  }
1112 };
1113 
1114 } // namespace MueLu::MatrixConstruction
1115 
1116 #endif
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
Kokkos::ArithTraits< local_ordinal_type > OTS
typename local_matrix_type::memory_space memory_space
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::memory_space memory_space
Kokkos::ArithTraits< local_ordinal_type > OTS
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
typename local_matrix_type::row_map_type::non_const_type rowptr_type
Kokkos::View< DecisionType *, memory_space > results_view
KOKKOS_INLINE_FUNCTION void operatorRow(const local_ordinal_type rlid) const
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid, local_ordinal_type &nnz, const bool &final) const
KOKKOS_INLINE_FUNCTION void operatorRow(const local_ordinal_type rlid) const
typename local_matrix_type::memory_space memory_space
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type brlid) const
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
Kokkos::View< DecisionType *, memory_space > results_view
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, functor_type &functor_)
PointwiseCountingFunctor< local_matrix_type, remaining_functor_types...> remainingFunctors
KOKKOS_INLINE_FUNCTION void join(Kokkos::pair< local_ordinal_type, local_ordinal_type > &dest, const Kokkos::pair< local_ordinal_type, local_ordinal_type > &src) const
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::ordinal_type local_ordinal_type
VectorCountingFunctor< local_matrix_type, remaining_functor_types...> remainingFunctors
typename local_matrix_type::memory_space memory_space
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, bool firstFunctor_, functor_type &functor_, remaining_functor_types &...remainingFunctors_)
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, Kokkos::pair< local_ordinal_type, local_ordinal_type > &nnz, const bool &final) const
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::memory_space memory_space
BlockRowComparison< local_matrix_type > comparison
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
typename local_matrix_type::value_type scalar_type
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::ArithTraits< local_ordinal_type > ATS
BlockRowComparison< local_matrix_type > comparison
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::ArithTraits< local_ordinal_type > ATS
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::memory_space memory_space
PointwiseFillNoReuseFunctor(local_matrix_type &A_, results_view &results_, local_matrix_type &filteredA_, magnitudeType dirichletThreshold_)
typename local_matrix_type::row_map_type::non_const_type rowptr_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
KOKKOS_INLINE_FUNCTION void serialHeapSort(view_type &v, comparator_type comparator)
typename local_matrix_type::value_type scalar_type
VectorCountingFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view &results_, rowptr_type &filtered_rowptr_, rowptr_type &graph_rowptr_, functor_type &functor_, remaining_functor_types &...remainingFunctors_)
Functor that executes a sequence of sub-functors on each block of rows.
typename local_matrix_type::ordinal_type local_ordinal_type
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, functor_type &functor_, remaining_functor_types &...remainingFunctors_)
VectorFillFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view &results_, local_matrix_type &filteredA_, local_graph_type &graph_, magnitudeType dirichletThreshold_)
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, bool firstFunctor_, functor_type &functor_)
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
Functor that fills the filtered matrix while reusing the graph of the matrix before dropping...
typename local_matrix_type::ordinal_type local_ordinal_type
PointwiseFillReuseFunctor(local_matrix_type &A_, results_view &results_, local_matrix_type &filteredA_, local_graph_type &graph_, magnitudeType dirichletThreshold_)
MergeCountFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, rowptr_type &merged_rowptr_)
Functor that executes a sequence of sub-functors on each row for a problem with blockSize == 1...
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, Kokkos::pair< local_ordinal_type, local_ordinal_type > &nnz, const bool &final) const
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION Comparator(const local_matrix_type2 &A_, local_ordinal_type bsize_, local_ordinal_type brlid_, block_indices_view_type ghosted_point_to_block_)
void start()
typename local_matrix_type::value_type scalar_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid, local_ordinal_type &nnz, const bool &final) const
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, local_ordinal_type &nnz_graph, const bool &final) const
typename local_matrix_type::row_map_type::non_const_type rowptr_type
typename local_matrix_type::memory_space memory_space
typename local_matrix_type::value_type scalar_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
VectorCountingFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, results_view &results_, rowptr_type &filtered_rowptr_, rowptr_type &graph_rowptr_, functor_type &functor_)
typename local_matrix_type::staticcrsgraph_type local_graph_type
Functor does not reuse the graph of the matrix for a problem with blockSize == 1. ...
BlockRowComparison< local_matrix_type > comparison
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid) const
BlockRowComparison(local_matrix_type &A_, local_ordinal_type bsize_, block_indices_view_type ghosted_point_to_block_)
Kokkos::View< DecisionType *, memory_space > results_view
BlockRowComparison< local_matrix_type > comparison
TransListIter end
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
GraphConstruction(local_matrix_type &A_, results_view &results_, local_graph_type &graph_)
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid) const
typename local_matrix_type::ordinal_type local_ordinal_type
MergeFillFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, local_matrix_type &mergedA_)
KOKKOS_INLINE_FUNCTION void join(Kokkos::pair< local_ordinal_type, local_ordinal_type > &dest, const Kokkos::pair< local_ordinal_type, local_ordinal_type > &src) const
typename local_matrix_type::staticcrsgraph_type local_graph_type