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