MueLu Version of the Day
Loading...
Searching...
No Matches
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 "KokkosKernels_ArithTraits.hpp"
15
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
36template <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
135template <class local_matrix_type, class functor_type>
136class 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.c_str());
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
247template <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 = KokkosKernels::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
326template <class local_matrix_type, lumpingType lumpingChoice, bool constructFilteredA = true>
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 local_graph_type = typename local_matrix_type::staticcrsgraph_type;
333 using results_view = Kokkos::View<DecisionType*, memory_space>;
334 using ATS = KokkosKernels::ArithTraits<scalar_type>;
335 using magnitudeType = typename ATS::magnitudeType;
336
337 local_matrix_type A;
340 local_matrix_type filteredA;
342 const scalar_type zero = ATS::zero();
343 const scalar_type one = ATS::one();
344
345 public:
346 PointwiseFillNoReuseFunctor(local_matrix_type& A_, results_view& results_, local_graph_type& graph_, local_matrix_type& filteredA_, magnitudeType dirichletThreshold_)
347 : A(A_)
348 , results(results_)
349 , graph(graph_)
350 , filteredA(filteredA_)
351 , dirichletThreshold(dirichletThreshold_) {
352 static_assert(constructFilteredA || (lumpingChoice == no_lumping));
353 }
354
355 KOKKOS_INLINE_FUNCTION
356 void operator()(const local_ordinal_type rlid) const {
357 auto rowA = A.row(rlid);
358 size_t K = A.graph.row_map(rlid);
359 local_ordinal_type j = graph.row_map(rlid);
360 scalar_type droppedSum = zero;
361 scalar_type keptRowSumAbs = zero;
362 local_ordinal_type diagOffset = -1;
363 for (local_ordinal_type k = 0; k < rowA.length; ++k) {
364 if constexpr (lumpingChoice != no_lumping) {
365 local_ordinal_type clid = rowA.colidx(k);
366 if (rlid == clid) {
367 diagOffset = j;
368 }
369 }
370 if (results(K + k) == KEEP) {
371 graph.entries(j) = rowA.colidx(k);
372 if constexpr (constructFilteredA)
373 filteredA.values(j) = rowA.value(k);
374 if constexpr (lumpingChoice == distributed_lumping) {
375 keptRowSumAbs += ATS::magnitude(filteredA.values(j));
376 }
377 ++j;
378 } else if constexpr (lumpingChoice != no_lumping) {
379 droppedSum += rowA.value(k);
380 }
381 }
382 if constexpr (lumpingChoice == diag_lumping) {
383 filteredA.values(diagOffset) += droppedSum;
384 if ((dirichletThreshold >= 0.0) && (ATS::real(filteredA.values(diagOffset)) <= dirichletThreshold))
385 filteredA.values(diagOffset) = one;
386 } else if constexpr (lumpingChoice == distributed_lumping) {
387 if (ATS::real(droppedSum) >= ATS::real(zero)) {
388 filteredA.values(diagOffset) += droppedSum;
389 } else {
390 for (local_ordinal_type k = graph.row_map(rlid); k < j; ++k) {
391 filteredA.values(k) += droppedSum * ATS::magnitude(filteredA.values(k)) / keptRowSumAbs;
392 }
393 }
394 }
395 }
396};
397
398template <class local_matrix_type>
400 public:
401 using local_ordinal_type = typename local_matrix_type::ordinal_type;
402 using memory_space = typename local_matrix_type::memory_space;
403 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
404
405 local_matrix_type A;
408
409 public:
410 BlockRowComparison(local_matrix_type& A_, local_ordinal_type bsize_, block_indices_view_type ghosted_point_to_block_)
411 : A(A_)
412 , bsize(bsize_)
413 , ghosted_point_to_block(ghosted_point_to_block_) {}
414
415 template <class local_matrix_type2>
416 struct Comparator {
417 private:
418 using local_ordinal_type = typename local_matrix_type2::ordinal_type;
419 using memory_space = typename local_matrix_type2::memory_space;
420 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
421
422 const local_matrix_type2 A;
425
426 public:
427 KOKKOS_INLINE_FUNCTION
428 Comparator(const local_matrix_type2& A_, local_ordinal_type bsize_, local_ordinal_type brlid_, block_indices_view_type ghosted_point_to_block_)
429 : A(A_)
430 , offset(A_.graph.row_map(bsize_ * brlid_))
431 , ghosted_point_to_block(ghosted_point_to_block_) {}
432
433 KOKKOS_INLINE_FUNCTION
434 bool operator()(size_t x, size_t y) const {
435 return ghosted_point_to_block(A.graph.entries(offset + x)) < ghosted_point_to_block(A.graph.entries(offset + y));
436 }
437 };
438
440
441 KOKKOS_INLINE_FUNCTION
445};
446
457template <class local_matrix_type,
458 class functor_type,
459 class... remaining_functor_types>
461 private:
462 using scalar_type = typename local_matrix_type::value_type;
463 using local_ordinal_type = typename local_matrix_type::ordinal_type;
464 using memory_space = typename local_matrix_type::memory_space;
465 using results_view = Kokkos::View<DecisionType*, memory_space>;
466 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
467 using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
468
469 using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
470 using ATS = KokkosKernels::ArithTraits<local_ordinal_type>;
471
472 local_matrix_type A;
478
479 functor_type functor;
480
483
484 VectorCountingFunctor<local_matrix_type, remaining_functor_types...> remainingFunctors;
485
486#ifdef MUELU_COALESCE_DROP_DEBUG
487 std::string functorName;
488#endif
489
490 public:
491 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_)
492 : A(A_)
493 , blockSize(blockSize_)
494 , ghosted_point_to_block(ghosted_point_to_block_)
495 , results(results_)
496 , filtered_rowptr(filtered_rowptr_)
497 , graph_rowptr(graph_rowptr_)
498 , functor(functor_)
500 , remainingFunctors(A_, blockSize_, ghosted_point_to_block_, results_, filtered_rowptr_, graph_rowptr_, remainingFunctors_...) {
501 permutation = permutation_type("permutation", A.nnz());
502#ifdef MUELU_COALESCE_DROP_DEBUG
503 std::string mangledFunctorName = typeid(decltype(functor)).name();
504 int status = 0;
505 char* demangledFunctorName = 0;
506 demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
507 functorName = demangledFunctorName;
508#endif
509 }
510
511 KOKKOS_INLINE_FUNCTION
512 void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest, const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src) const {
513 dest.first += src.first;
514 dest.second += src.second;
515 }
516
517 KOKKOS_INLINE_FUNCTION
518 void operatorRow(const local_ordinal_type rlid) const {
519 functor(rlid);
520 remainingFunctors.operatorRow(rlid);
521 }
522
523 KOKKOS_INLINE_FUNCTION
524 void operator()(const local_ordinal_type brlid, Kokkos::pair<local_ordinal_type, local_ordinal_type>& nnz, const bool& final) const {
525 auto nnz_filtered = &nnz.first;
526 auto nnz_graph = &nnz.second;
527
528#ifdef MUELU_COALESCE_DROP_DEBUG
529 Kokkos::printf("\nStarting on block row %d\n", brlid);
530#endif
531 for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
532#ifdef MUELU_COALESCE_DROP_DEBUG
533 {
534 Kokkos::printf("\nStarting on row %d\n", rlid);
535
536 auto row = A.rowConst(rlid);
537
538 Kokkos::printf("indices: ");
539 for (local_ordinal_type k = 0; k < row.length; ++k) {
540 auto clid = row.colidx(k);
541 Kokkos::printf("%5d ", clid);
542 }
543 Kokkos::printf("\n");
544
545 Kokkos::printf("values: ");
546 for (local_ordinal_type k = 0; k < row.length; ++k) {
547 auto val = row.value(k);
548 Kokkos::printf("%5f ", val);
549 }
550 Kokkos::printf("\n");
551 }
552#endif
553
554 functor(rlid);
555 remainingFunctors.operatorRow(rlid);
556
557#ifdef MUELU_COALESCE_DROP_DEBUG
558 {
559 Kokkos::printf("%s\n", functorName.c_str());
560
561 auto row = A.rowConst(rlid);
562 const size_t offset = A.graph.row_map(rlid);
563
564 Kokkos::printf("decisions: ");
565 for (local_ordinal_type k = 0; k < row.length; ++k) {
566 Kokkos::printf("%5d ", results(offset + k));
567 }
568 Kokkos::printf("\n");
569 }
570#endif
571
572#ifdef MUELU_COALESCE_DROP_DEBUG
573 Kokkos::printf("Done with row %d\n", rlid);
574#endif
575
576 size_t start = A.graph.row_map(rlid);
577 size_t end = A.graph.row_map(rlid + 1);
578 for (size_t i = start; i < end; ++i) {
579 if (results(i) == KEEP) {
580 ++(*nnz_filtered);
581 }
582 }
583 if (final)
584 filtered_rowptr(rlid + 1) = *nnz_filtered;
585 }
586
587#ifdef MUELU_COALESCE_DROP_DEBUG
588 Kokkos::printf("Done with block row %d\nGraph indices ", brlid);
589#endif
590
591 // column lids for all rows in the block
592 auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
593 A.graph.row_map(blockSize * (brlid + 1))));
594 // set up a permutatation index
595 auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
596 A.graph.row_map(blockSize * (brlid + 1))));
597 for (size_t i = 0; i < block_permutation.extent(0); ++i)
598 block_permutation(i) = i;
599 // get permuatation for sorted column indices of the entire block
600 auto comparator = comparison.getComparator(brlid);
601 Misc::serialHeapSort(block_permutation, comparator);
602
603 local_ordinal_type prev_bclid = -1;
604 bool alreadyAdded = false;
605
606 // loop over all sorted entries in block
607 auto offset = A.graph.row_map(blockSize * brlid);
608 for (size_t i = 0; i < block_permutation.extent(0); ++i) {
609 auto idx = offset + block_permutation(i);
610 auto clid = A.graph.entries(idx);
611 auto bclid = ghosted_point_to_block(clid);
612
613 // unseen block column index
614 if (bclid > prev_bclid)
615 alreadyAdded = false;
616
617 // add entry to graph
618 if (!alreadyAdded && (results(idx) == KEEP)) {
619 ++(*nnz_graph);
620 alreadyAdded = true;
621#ifdef MUELU_COALESCE_DROP_DEBUG
622 Kokkos::printf("%5d ", bclid);
623#endif
624 }
625 prev_bclid = bclid;
626 }
627#ifdef MUELU_COALESCE_DROP_DEBUG
628 Kokkos::printf("\n");
629#endif
630 if (final)
631 graph_rowptr(brlid + 1) = *nnz_graph;
632 }
633};
634
635template <class local_matrix_type,
636 class functor_type>
637class VectorCountingFunctor<local_matrix_type, functor_type> {
638 private:
639 using scalar_type = typename local_matrix_type::value_type;
640 using local_ordinal_type = typename local_matrix_type::ordinal_type;
641 using memory_space = typename local_matrix_type::memory_space;
642 using results_view = Kokkos::View<DecisionType*, memory_space>;
643 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
644 using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
645
646 using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
647 using ATS = KokkosKernels::ArithTraits<local_ordinal_type>;
648
649 local_matrix_type A;
655
656 functor_type functor;
657
658#ifdef MUELU_COALESCE_DROP_DEBUG
659 std::string functorName;
660#endif
661
664
665 public:
666 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_)
667 : A(A_)
668 , blockSize(blockSize_)
669 , ghosted_point_to_block(ghosted_point_to_block_)
670 , results(results_)
671 , filtered_rowptr(filtered_rowptr_)
672 , graph_rowptr(graph_rowptr_)
673 , functor(functor_)
675 permutation = permutation_type("permutation", A.nnz());
676#ifdef MUELU_COALESCE_DROP_DEBUG
677 std::string mangledFunctorName = typeid(decltype(functor)).name();
678 int status = 0;
679 char* demangledFunctorName = 0;
680 demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
681 functorName = demangledFunctorName;
682#endif
683 }
684
685 KOKKOS_INLINE_FUNCTION
686 void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest, const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src) const {
687 dest.first += src.first;
688 dest.second += src.second;
689 }
690
691 KOKKOS_INLINE_FUNCTION
692 void operatorRow(const local_ordinal_type rlid) const {
693 functor(rlid);
694 }
695
696 KOKKOS_INLINE_FUNCTION
697 void operator()(const local_ordinal_type brlid, Kokkos::pair<local_ordinal_type, local_ordinal_type>& nnz, const bool& final) const {
698 auto nnz_filtered = &nnz.first;
699 auto nnz_graph = &nnz.second;
700
701#ifdef MUELU_COALESCE_DROP_DEBUG
702 Kokkos::printf("\nStarting on block row %d\n", brlid);
703#endif
704 for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
705#ifdef MUELU_COALESCE_DROP_DEBUG
706 {
707 Kokkos::printf("\nStarting on row %d\n", rlid);
708
709 auto row = A.rowConst(rlid);
710
711 Kokkos::printf("indices: ");
712 for (local_ordinal_type k = 0; k < row.length; ++k) {
713 auto clid = row.colidx(k);
714 Kokkos::printf("%5d ", clid);
715 }
716 Kokkos::printf("\n");
717
718 Kokkos::printf("values: ");
719 for (local_ordinal_type k = 0; k < row.length; ++k) {
720 auto val = row.value(k);
721 Kokkos::printf("%5f ", val);
722 }
723 Kokkos::printf("\n");
724 }
725#endif
726
727 functor(rlid);
728
729#ifdef MUELU_COALESCE_DROP_DEBUG
730 {
731 Kokkos::printf("%s\n", functorName.c_str());
732
733 auto row = A.rowConst(rlid);
734 const size_t offset = A.graph.row_map(rlid);
735
736 Kokkos::printf("decisions: ");
737 for (local_ordinal_type k = 0; k < row.length; ++k) {
738 Kokkos::printf("%5d ", results(offset + k));
739 }
740 Kokkos::printf("\n");
741 }
742#endif
743
744#ifdef MUELU_COALESCE_DROP_DEBUG
745 Kokkos::printf("Done with row %d\n", rlid);
746#endif
747
748 size_t start = A.graph.row_map(rlid);
749 size_t end = A.graph.row_map(rlid + 1);
750 for (size_t i = start; i < end; ++i) {
751 if (results(i) == KEEP) {
752 ++(*nnz_filtered);
753 }
754 }
755 if (final)
756 filtered_rowptr(rlid + 1) = *nnz_filtered;
757 }
758
759#ifdef MUELU_COALESCE_DROP_DEBUG
760 Kokkos::printf("Done with block row %d\nGraph indices ", brlid);
761#endif
762
763 // column lids for all rows in the block
764 auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
765 A.graph.row_map(blockSize * (brlid + 1))));
766 // set up a permutation index
767 auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
768 A.graph.row_map(blockSize * (brlid + 1))));
769 for (size_t i = 0; i < block_permutation.extent(0); ++i)
770 block_permutation(i) = i;
771 // get permutation for sorted column indices of the entire block
772 auto comparator = comparison.getComparator(brlid);
773 Misc::serialHeapSort(block_permutation, comparator);
774
775 local_ordinal_type prev_bclid = -1;
776 bool alreadyAdded = false;
777
778 // loop over all sorted entries in block
779 auto offset = A.graph.row_map(blockSize * brlid);
780 for (size_t i = 0; i < block_permutation.extent(0); ++i) {
781 auto idx = offset + block_permutation(i);
782 auto clid = A.graph.entries(idx);
783 auto bclid = ghosted_point_to_block(clid);
784
785 // unseen block column index
786 if (bclid > prev_bclid)
787 alreadyAdded = false;
788
789 // add entry to graph
790 if (!alreadyAdded && (results(idx) == KEEP)) {
791 ++(*nnz_graph);
792 alreadyAdded = true;
793#ifdef MUELU_COALESCE_DROP_DEBUG
794 Kokkos::printf("%5d ", bclid);
795#endif
796 }
797 prev_bclid = bclid;
798 }
799#ifdef MUELU_COALESCE_DROP_DEBUG
800 Kokkos::printf("\n");
801#endif
802 if (final)
803 graph_rowptr(brlid + 1) = *nnz_graph;
804 }
805};
806
814template <class local_matrix_type, bool lumping, bool reuse, bool constructFilteredA = true>
816 private:
817 using scalar_type = typename local_matrix_type::value_type;
818 using local_ordinal_type = typename local_matrix_type::ordinal_type;
819 using local_graph_type = typename local_matrix_type::staticcrsgraph_type;
820 using memory_space = typename local_matrix_type::memory_space;
821 using results_view = Kokkos::View<DecisionType*, memory_space>;
822 using ATS = KokkosKernels::ArithTraits<scalar_type>;
823 using OTS = KokkosKernels::ArithTraits<local_ordinal_type>;
824 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
825 using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
826 using magnitudeType = typename ATS::magnitudeType;
827
828 local_matrix_type A;
832 local_matrix_type filteredA;
835 const scalar_type zero = ATS::zero();
836 const scalar_type one = ATS::one();
837
840
841 public:
842 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_)
843 : A(A_)
844 , blockSize(blockSize_)
845 , ghosted_point_to_block(ghosted_point_to_block_)
846 , results(results_)
847 , filteredA(filteredA_)
848 , graph(graph_)
849 , dirichletThreshold(dirichletThreshold_)
851 permutation = permutation_type("permutation", A.nnz());
852 }
853
854 KOKKOS_INLINE_FUNCTION
855 void operator()(const local_ordinal_type brlid) const {
856 if constexpr (constructFilteredA) {
857 for (local_ordinal_type rlid = blockSize * brlid; rlid < blockSize * (brlid + 1); ++rlid) {
858 auto rowA = A.row(rlid);
859 size_t row_start = A.graph.row_map(rlid);
860 auto rowFilteredA = filteredA.row(rlid);
861 local_ordinal_type j = 0;
862 scalar_type diagCorrection = zero;
863 local_ordinal_type diagOffset = -1;
864 for (local_ordinal_type k = 0; k < rowA.length; ++k) {
865 if constexpr (lumping) {
866 local_ordinal_type clid = rowA.colidx(k);
867 if (rlid == clid) {
868 diagOffset = j;
869 }
870 }
871 if (results(row_start + k) == KEEP) {
872 rowFilteredA.colidx(j) = rowA.colidx(k);
873 rowFilteredA.value(j) = rowA.value(k);
874 ++j;
875 } else if constexpr (lumping) {
876 diagCorrection += rowA.value(k);
877 if constexpr (reuse) {
878 rowFilteredA.colidx(j) = rowA.colidx(k);
879 rowFilteredA.value(j) = zero;
880 ++j;
881 }
882 } else if constexpr (reuse) {
883 rowFilteredA.colidx(j) = rowA.colidx(k);
884 rowFilteredA.value(j) = zero;
885 ++j;
886 }
887 }
888 if constexpr (lumping) {
889 rowFilteredA.value(diagOffset) += diagCorrection;
890 if ((dirichletThreshold >= 0.0) && (ATS::real(rowFilteredA.value(diagOffset)) <= dirichletThreshold))
891 rowFilteredA.value(diagOffset) = one;
892 }
893 }
894 }
895
896 // column lids for all rows in the block
897 auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
898 A.graph.row_map(blockSize * (brlid + 1))));
899 // set up a permuatation index
900 auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
901 A.graph.row_map(blockSize * (brlid + 1))));
902 for (size_t i = 0; i < block_permutation.extent(0); ++i)
903 block_permutation(i) = i;
904 // get permutation for sorted column indices of the entire block
905 auto comparator = comparison.getComparator(brlid);
906 Misc::serialHeapSort(block_permutation, comparator);
907
908 local_ordinal_type prev_bclid = -1;
909 bool alreadyAdded = false;
910 local_ordinal_type j = graph.row_map(brlid);
911
912 // loop over all sorted entries in block
913 auto offset = A.graph.row_map(blockSize * brlid);
914 for (size_t i = 0; i < block_permutation.extent(0); ++i) {
915 auto idx = offset + block_permutation(i);
916 auto clid = A.graph.entries(idx);
917 auto bclid = ghosted_point_to_block(clid);
918
919 // unseen block column index
920 if (bclid > prev_bclid)
921 alreadyAdded = false;
922
923 // add entry to graph
924 if (!alreadyAdded && (results(idx) == KEEP)) {
925 graph.entries(j) = bclid;
926 ++j;
927 alreadyAdded = true;
928 }
929 prev_bclid = bclid;
930 }
931 }
932};
933
934template <class local_matrix_type>
936 private:
937 using scalar_type = typename local_matrix_type::value_type;
938 using local_ordinal_type = typename local_matrix_type::ordinal_type;
939 using memory_space = typename local_matrix_type::memory_space;
940 using results_view = Kokkos::View<DecisionType*, memory_space>;
941 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
942 using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
943
944 using rowptr_type = typename local_matrix_type::row_map_type::non_const_type;
945 using ATS = KokkosKernels::ArithTraits<local_ordinal_type>;
946
947 local_matrix_type A;
951
954
955 public:
956 MergeCountFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, rowptr_type& merged_rowptr_)
957 : A(A_)
958 , blockSize(blockSize_)
959 , ghosted_point_to_block(ghosted_point_to_block_)
960 , merged_rowptr(merged_rowptr_)
962 permutation = permutation_type("permutation", A.nnz());
963 }
964
965 KOKKOS_INLINE_FUNCTION
966 void operator()(const local_ordinal_type brlid, local_ordinal_type& nnz_graph, const bool& final) const {
967 // column lids for all rows in the block
968 auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
969 A.graph.row_map(blockSize * (brlid + 1))));
970 // set up a permutation index
971 auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
972 A.graph.row_map(blockSize * (brlid + 1))));
973 for (size_t i = 0; i < block_permutation.extent(0); ++i)
974 block_permutation(i) = i;
975 // get permutation for sorted column indices of the entire block
976 auto comparator = comparison.getComparator(brlid);
977 Misc::serialHeapSort(block_permutation, comparator);
978
979 local_ordinal_type prev_bclid = -1;
980 bool alreadyAdded = false;
981
982 // loop over all sorted entries in block
983 auto offset = A.graph.row_map(blockSize * brlid);
984 for (size_t i = 0; i < block_permutation.extent(0); ++i) {
985 auto idx = offset + block_permutation(i);
986 auto clid = A.graph.entries(idx);
987 auto bclid = ghosted_point_to_block(clid);
988
989 // unseen block column index
990 if (bclid > prev_bclid)
991 alreadyAdded = false;
992
993 // add entry to graph
994 if (!alreadyAdded) {
995 ++nnz_graph;
996 alreadyAdded = true;
997#ifdef MUELU_COALESCE_DROP_DEBUG
998 Kokkos::printf("%5d ", bclid);
999#endif
1000 }
1001 prev_bclid = bclid;
1002 }
1003#ifdef MUELU_COALESCE_DROP_DEBUG
1004 Kokkos::printf("\n");
1005#endif
1006 if (final)
1007 merged_rowptr(brlid + 1) = nnz_graph;
1008 }
1009};
1010
1011template <class local_matrix_type>
1013 private:
1014 using scalar_type = typename local_matrix_type::value_type;
1015 using local_ordinal_type = typename local_matrix_type::ordinal_type;
1016 using local_graph_type = typename local_matrix_type::staticcrsgraph_type;
1017 using memory_space = typename local_matrix_type::memory_space;
1018 using results_view = Kokkos::View<DecisionType*, memory_space>;
1019 using ATS = KokkosKernels::ArithTraits<scalar_type>;
1020 using OTS = KokkosKernels::ArithTraits<local_ordinal_type>;
1021 using block_indices_view_type = Kokkos::View<local_ordinal_type*, memory_space>;
1022 using permutation_type = Kokkos::View<local_ordinal_type*, memory_space>;
1023 using magnitudeType = typename ATS::magnitudeType;
1024
1025 local_matrix_type A;
1028 local_matrix_type mergedA;
1029 const scalar_type zero = ATS::zero();
1030 const scalar_type one = ATS::one();
1031
1034
1035 public:
1036 MergeFillFunctor(local_matrix_type& A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, local_matrix_type& mergedA_)
1037 : A(A_)
1038 , blockSize(blockSize_)
1039 , ghosted_point_to_block(ghosted_point_to_block_)
1040 , mergedA(mergedA_)
1042 permutation = permutation_type("permutation", A.nnz());
1043 }
1044
1045 KOKKOS_INLINE_FUNCTION
1046 void operator()(const local_ordinal_type brlid) const {
1047 // column lids for all rows in the block
1048 auto block_clids = Kokkos::subview(A.graph.entries, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
1049 A.graph.row_map(blockSize * (brlid + 1))));
1050 // set up a permuatation index
1051 auto block_permutation = Kokkos::subview(permutation, Kokkos::make_pair(A.graph.row_map(blockSize * brlid),
1052 A.graph.row_map(blockSize * (brlid + 1))));
1053 for (size_t i = 0; i < block_permutation.extent(0); ++i)
1054 block_permutation(i) = i;
1055 // get permutation for sorted column indices of the entire block
1056 auto comparator = comparison.getComparator(brlid);
1057 Misc::serialHeapSort(block_permutation, comparator);
1058
1059 local_ordinal_type prev_bclid = -1;
1060 bool alreadyAdded = false;
1061 local_ordinal_type j = mergedA.graph.row_map(brlid);
1062
1063 // loop over all sorted entries in block
1064 auto offset = A.graph.row_map(blockSize * brlid);
1065 for (size_t i = 0; i < block_permutation.extent(0); ++i) {
1066 auto idx = offset + block_permutation(i);
1067 auto clid = A.graph.entries(idx);
1068 auto bclid = ghosted_point_to_block(clid);
1069
1070 // unseen block column index
1071 if (bclid > prev_bclid)
1072 alreadyAdded = false;
1073
1074 // add entry to graph
1075 if (!alreadyAdded) {
1076 mergedA.graph.entries(j) = bclid;
1077 mergedA.values(j) = one;
1078 ++j;
1079 alreadyAdded = true;
1080 }
1081 prev_bclid = bclid;
1082 }
1083 }
1084};
1085
1086template <class local_matrix_type, class local_graph_type>
1088 private:
1089 using scalar_type = typename local_matrix_type::value_type;
1090 using local_ordinal_type = typename local_matrix_type::ordinal_type;
1091 using memory_space = typename local_matrix_type::memory_space;
1092 using results_view = Kokkos::View<DecisionType*, memory_space>;
1093
1094 local_matrix_type A;
1096 local_graph_type graph;
1097
1098 public:
1099 GraphConstruction(local_matrix_type& A_, results_view& results_, local_graph_type& graph_)
1100 : A(A_)
1101 , results(results_)
1102 , graph(graph_) {}
1103
1104 KOKKOS_INLINE_FUNCTION
1105 void operator()(const local_ordinal_type rlid) const {
1106 auto rowA = A.row(rlid);
1107 size_t row_start = A.graph.row_map(rlid);
1108 local_ordinal_type jj = 0;
1109 local_ordinal_type graph_offset = graph.row_map(rlid);
1110 for (local_ordinal_type k = 0; k < rowA.length; ++k) {
1111 if (results(row_start + k) == KEEP) {
1112 graph.entries(graph_offset + jj) = rowA.colidx(k);
1113 ++jj;
1114 }
1115 }
1116 }
1117};
1118
1119} // namespace MueLu::MatrixConstruction
1120
1121#endif
BlockRowComparison(local_matrix_type &A_, local_ordinal_type bsize_, block_indices_view_type ghosted_point_to_block_)
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type brlid) const
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
typename local_matrix_type::memory_space memory_space
GraphConstruction(local_matrix_type &A_, results_view &results_, local_graph_type &graph_)
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::memory_space memory_space
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
typename local_matrix_type::memory_space memory_space
typename local_matrix_type::value_type scalar_type
MergeCountFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, rowptr_type &merged_rowptr_)
typename local_matrix_type::row_map_type::non_const_type rowptr_type
KokkosKernels::ArithTraits< local_ordinal_type > ATS
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, local_ordinal_type &nnz_graph, const bool &final) const
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
typename local_matrix_type::ordinal_type local_ordinal_type
BlockRowComparison< local_matrix_type > comparison
typename local_matrix_type::value_type scalar_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
typename local_matrix_type::staticcrsgraph_type local_graph_type
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::memory_space memory_space
KokkosKernels::ArithTraits< scalar_type > ATS
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
KokkosKernels::ArithTraits< local_ordinal_type > OTS
BlockRowComparison< local_matrix_type > comparison
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid) const
MergeFillFunctor(local_matrix_type &A_, local_ordinal_type blockSize_, block_indices_view_type ghosted_point_to_block_, local_matrix_type &mergedA_)
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, bool firstFunctor_, functor_type &functor_)
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, functor_type &functor_)
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid, local_ordinal_type &nnz, const bool &final) const
Functor that executes a sequence of sub-functors on each row for a problem with blockSize == 1.
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< DecisionType *, memory_space > results_view
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid, local_ordinal_type &nnz, const bool &final) const
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::row_map_type::non_const_type rowptr_type
PointwiseCountingFunctor< local_matrix_type, remaining_functor_types... > remainingFunctors
PointwiseCountingFunctor(local_matrix_type &A_, results_view &results_, rowptr_type &rowptr_, functor_type &functor_, remaining_functor_types &... remainingFunctors_)
Functor does not reuse the graph of the matrix for a problem with blockSize == 1.
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::staticcrsgraph_type local_graph_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
PointwiseFillNoReuseFunctor(local_matrix_type &A_, results_view &results_, local_graph_type &graph_, local_matrix_type &filteredA_, magnitudeType dirichletThreshold_)
Functor that fills the filtered matrix while reusing the graph of the matrix before dropping,...
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
Kokkos::View< DecisionType *, memory_space > results_view
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_)
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_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, Kokkos::pair< local_ordinal_type, local_ordinal_type > &nnz, const bool &final) const
KOKKOS_INLINE_FUNCTION void operatorRow(const local_ordinal_type rlid) const
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_)
Functor that executes a sequence of sub-functors on each block of rows.
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_)
typename local_matrix_type::row_map_type::non_const_type rowptr_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid, Kokkos::pair< local_ordinal_type, local_ordinal_type > &nnz, const bool &final) const
KokkosKernels::ArithTraits< local_ordinal_type > ATS
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
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
VectorCountingFunctor< local_matrix_type, remaining_functor_types... > remainingFunctors
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION void operatorRow(const local_ordinal_type rlid) const
typename local_matrix_type::memory_space memory_space
Kokkos::View< DecisionType *, memory_space > results_view
KokkosKernels::ArithTraits< local_ordinal_type > OTS
BlockRowComparison< local_matrix_type > comparison
typename local_matrix_type::staticcrsgraph_type local_graph_type
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type brlid) const
Kokkos::View< DecisionType *, memory_space > results_view
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_)
KokkosKernels::ArithTraits< scalar_type > ATS
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
typename local_matrix_type::memory_space memory_space
KOKKOS_INLINE_FUNCTION void serialHeapSort(view_type &v, comparator_type comparator)
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_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_)