MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_CutDrop.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_CUTDROP_HPP
11#define MUELU_CUTDROP_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
20#include "MueLu_Utilities.hpp"
21#include "Xpetra_Matrix.hpp"
22#include "Xpetra_MultiVector.hpp"
24
25namespace MueLu::CutDrop {
26
32
37template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
39 public:
40 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
41
42 using local_matrix_type = typename matrix_type::local_matrix_device_type;
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
50
51 private:
52#if KOKKOS_VERSION >= 40799
53 using ATS = KokkosKernels::ArithTraits<scalar_type>;
54#else
55 using ATS = Kokkos::ArithTraits<scalar_type>;
56#endif
57 using magnitudeType = typename ATS::magnitudeType;
58 using values_view = Kokkos::View<magnitudeType*, memory_space>;
60
61 public:
63 : A(A_.getLocalMatrixDevice())
64 , results(results_)
65 , values("UnscaledComparison::values", A.nnz()) {}
66
67 template <class local_matrix_type2>
68 struct Comparator {
69 private:
70 using scalar_type = typename local_matrix_type2::value_type;
71 using local_ordinal_type = typename local_matrix_type2::ordinal_type;
72 using memory_space = typename local_matrix_type2::memory_space;
73 using results_view = Kokkos::View<DecisionType*, memory_space>;
74
75#if KOKKOS_VERSION >= 40799
76 using ATS = KokkosKernels::ArithTraits<scalar_type>;
77#else
78 using ATS = Kokkos::ArithTraits<scalar_type>;
79#endif
80 using magnitudeType = typename ATS::magnitudeType;
81 using values_view = Kokkos::View<magnitudeType*, memory_space>;
82
83 const local_matrix_type2 A;
87
88 public:
89 KOKKOS_INLINE_FUNCTION
90 Comparator(const local_matrix_type2& A_, local_ordinal_type rlid_, const results_view& results_, values_view& values_)
91 : A(A_)
92 , offset(A_.graph.row_map(rlid_))
93 , results(results_)
94 , values(Kokkos::subview(values_, Kokkos::make_pair(A.graph.row_map(rlid_), A.graph.row_map(rlid_ + 1)))) {
95 for (auto i = 0U; i < values.extent(0); ++i) {
96 values(i) = get_value_impl(i);
97 }
98 }
99
100 KOKKOS_FORCEINLINE_FUNCTION
101 magnitudeType get_value(size_t x) const {
102 return values(x);
103 }
104
105 KOKKOS_INLINE_FUNCTION
106 bool operator()(size_t x, size_t y) const {
107 if (results(offset + x) != UNDECIDED) {
108 if (results(offset + y) != UNDECIDED) {
109 // does not matter
110 return (x < y);
111 } else {
112 // sort undecided to the right
113 return true;
114 }
115 } else {
116 if (results(offset + y) != UNDECIDED) {
117 // sort undecided to the right
118 return false;
119 } else {
120 return get_value(x) > get_value(y);
121 }
122 }
123 }
124
125 private:
126 KOKKOS_INLINE_FUNCTION
128 return ATS::magnitude(A.values(offset + x) * A.values(offset + x));
129 }
130 };
131
133
134 KOKKOS_INLINE_FUNCTION
138};
139
144template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, Misc::StrengthMeasure measure>
146 public:
147 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
148 using local_matrix_type = typename matrix_type::local_matrix_device_type;
149 using scalar_type = typename local_matrix_type::value_type;
150 using local_ordinal_type = typename local_matrix_type::ordinal_type;
151 using memory_space = typename local_matrix_type::memory_space;
152 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
153 using diag_view_type = typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
154 using results_view = Kokkos::View<DecisionType*, memory_space>;
155
158
159 private:
160#if KOKKOS_VERSION >= 40799
161 using ATS = KokkosKernels::ArithTraits<scalar_type>;
162#else
163 using ATS = Kokkos::ArithTraits<scalar_type>;
164#endif
165 using magnitudeType = typename ATS::magnitudeType;
166
167 Teuchos::RCP<diag_vec_type> diagVec;
169 using values_view = Kokkos::View<magnitudeType*, memory_space>;
171
172 public:
174 : A(A_.getLocalMatrixDevice())
175 , results(results_)
176 , values("ScaledComparison::values", A.nnz()) {
177 if constexpr ((measure == Misc::SmoothedAggregationMeasure) || (measure == Misc::SignedSmoothedAggregationMeasure)) {
179 auto lclDiag2d = diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
180 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
181 } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
183 auto lcl2d = diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
184 diag = Kokkos::subview(lcl2d, Kokkos::ALL(), 0);
185 }
186 }
187
188 template <class local_matrix_type2, class diag_view_type2>
189 struct Comparator {
190 private:
191 using scalar_type = typename local_matrix_type2::value_type;
192 using local_ordinal_type = typename local_matrix_type2::ordinal_type;
193 using memory_space = typename local_matrix_type2::memory_space;
194 using results_view = Kokkos::View<DecisionType*, memory_space>;
195
196#if KOKKOS_VERSION >= 40799
197 using ATS = KokkosKernels::ArithTraits<scalar_type>;
198#else
199 using ATS = Kokkos::ArithTraits<scalar_type>;
200#endif
201 using magnitudeType = typename ATS::magnitudeType;
202#if KOKKOS_VERSION >= 40799
203 using mATS = KokkosKernels::ArithTraits<magnitudeType>;
204#else
205 using mATS = Kokkos::ArithTraits<magnitudeType>;
206#endif
207 using values_view = Kokkos::View<magnitudeType*, memory_space>;
208
209 const local_matrix_type2 A;
210 const diag_view_type2 diag;
215
216 public:
217 KOKKOS_INLINE_FUNCTION
218 Comparator(const local_matrix_type2& A_, const diag_view_type2& diag_, const local_ordinal_type rlid_, const results_view& results_, values_view& values_)
219 : A(A_)
220 , diag(diag_)
221 , rlid(rlid_)
222 , offset(A_.graph.row_map(rlid_))
223 , results(results_)
224 , values(Kokkos::subview(values_, Kokkos::make_pair(A.graph.row_map(rlid_), A.graph.row_map(rlid_ + 1)))) {
225 for (auto i = 0U; i < values.extent(0); ++i) {
226 values(i) = get_value_impl(i);
227 }
228 }
229
230 KOKKOS_INLINE_FUNCTION
231 magnitudeType get_value(size_t x) const {
232 return values(x);
233 }
234
235 KOKKOS_INLINE_FUNCTION
236 bool operator()(size_t x, size_t y) const {
237 if (results(offset + x) != UNDECIDED) {
238 if (results(offset + y) != UNDECIDED) {
239 // does not matter
240 return (x < y);
241 } else {
242 // sort undecided to the right
243 return true;
244 }
245 } else {
246 if (results(offset + y) != UNDECIDED) {
247 // sort undecided to the right
248 return false;
249 } else {
250 return get_value(x) > get_value(y);
251 }
252 }
253 }
254
255 private:
256 KOKKOS_INLINE_FUNCTION
258 if constexpr (measure == Misc::SmoothedAggregationMeasure) {
259 auto x_aij = ATS::magnitude(A.values(offset + x) * A.values(offset + x));
260 auto x_aiiajj = ATS::magnitude(diag(rlid) * diag(A.graph.entries(offset + x)));
261 return (x_aij / x_aiiajj);
262 } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
263 auto val = A.values(offset + x);
264 auto neg_aij = -ATS::real(val);
265 auto max_neg_aik = ATS::real(diag(rlid));
266 auto v = neg_aij / max_neg_aik;
267 if (ATS::real(v) <= mATS::zero()) {
268 return -ATS::magnitude(v * v);
269 } else {
270 return ATS::magnitude(v * v);
271 }
272 } else if constexpr (measure == Misc::SignedSmoothedAggregationMeasure) {
273 auto val = A.values(offset + x);
274 auto x_aiiajj = ATS::magnitude(diag(rlid) * diag(A.graph.entries(offset + x)));
275 const bool is_nonpositive = ATS::real(val) <= mATS::zero();
276 magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val);
277 if (!is_nonpositive)
278 aij2 = -aij2;
279 return (aij2 / x_aiiajj);
280 }
281 }
282 };
283
285
286 KOKKOS_INLINE_FUNCTION
290};
291
292// helper function to allow partial template deduction
293template <Misc::StrengthMeasure measure, class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
294auto make_comparison_functor(Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A_,
296 if constexpr (measure == Misc::UnscaledMeasure) {
298 return functor;
299 } else {
301 return functor;
302 }
303}
304
305template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
307 public:
308 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
309 using local_matrix_type = typename matrix_type::local_matrix_device_type;
310 using scalar_type = typename local_matrix_type::value_type;
311 using local_ordinal_type = typename local_matrix_type::ordinal_type;
312 using memory_space = typename local_matrix_type::memory_space;
313 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
314 using diag_view_type = typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
315 using results_view = Kokkos::View<DecisionType*, memory_space>;
316
319
320 private:
321#if KOKKOS_VERSION >= 40799
322 using ATS = KokkosKernels::ArithTraits<scalar_type>;
323#else
324 using ATS = Kokkos::ArithTraits<scalar_type>;
325#endif
326 using magnitudeType = typename ATS::magnitudeType;
327 using values_view = Kokkos::View<magnitudeType*, memory_space>;
328
329 Teuchos::RCP<diag_vec_type> diagVec;
331 DistanceFunctorType dist2;
333
334 public:
335 UnscaledDistanceLaplacianComparison(matrix_type& A_, DistanceFunctorType& dist2_, results_view& results_)
336 : A(A_.getLocalMatrixDevice())
337 , results(results_)
338 , dist2(dist2_)
339 , values("UnscaledDistanceLaplacianComparison::values", A.nnz()) {
340 // Construct ghosted distance Laplacian diagonal
342 auto lclDiag2d = diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
343 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
344 }
345
346 template <class local_matrix_type2, class DistanceFunctorType2, class diag_view_type2>
347 struct Comparator {
348 private:
349 using scalar_type = typename local_matrix_type2::value_type;
350 using local_ordinal_type = typename local_matrix_type2::ordinal_type;
351 using memory_space = typename local_matrix_type2::memory_space;
352 using results_view = Kokkos::View<DecisionType*, memory_space>;
353
354#if KOKKOS_VERSION >= 40799
355 using ATS = KokkosKernels::ArithTraits<scalar_type>;
356#else
357 using ATS = Kokkos::ArithTraits<scalar_type>;
358#endif
359 using magnitudeType = typename ATS::magnitudeType;
360 using values_view = Kokkos::View<magnitudeType*, memory_space>;
361
362 const local_matrix_type2 A;
363 const diag_view_type2 diag;
364 const DistanceFunctorType2* dist2;
369
370 const scalar_type one = ATS::one();
371
372 public:
373 KOKKOS_INLINE_FUNCTION
374 Comparator(const local_matrix_type2& A_, const diag_view_type2& diag_, const DistanceFunctorType2* dist2_, local_ordinal_type rlid_, const results_view& results_, values_view& values_)
375 : A(A_)
376 , diag(diag_)
377 , dist2(dist2_)
378 , rlid(rlid_)
379 , offset(A_.graph.row_map(rlid_))
380 , results(results_)
381 , values(Kokkos::subview(values_, Kokkos::make_pair(A.graph.row_map(rlid_), A.graph.row_map(rlid_ + 1)))) {
382 for (auto i = 0U; i < values.extent(0); ++i) {
383 values(i) = get_value_impl(i);
384 }
385 }
386
387 KOKKOS_FORCEINLINE_FUNCTION
388 magnitudeType get_value(size_t x) const {
389 return values(x);
390 }
391
392 KOKKOS_INLINE_FUNCTION
393 bool operator()(size_t x, size_t y) const {
394 if (results(offset + x) != UNDECIDED) {
395 if (results(offset + y) != UNDECIDED) {
396 // does not matter
397 return (x < y);
398 } else {
399 // sort undecided to the right
400 return true;
401 }
402 } else {
403 if (results(offset + y) != UNDECIDED) {
404 // sort undecided to the right
405 return false;
406 } else {
407 return get_value(x) > get_value(y);
408 }
409 }
410 }
411
412 private:
413 KOKKOS_INLINE_FUNCTION
415 auto clid = A.graph.entries(offset + x);
416 scalar_type val;
417 if (rlid != clid) {
418 val = -one / dist2->distance2(rlid, clid);
419 } else {
420 val = diag(rlid);
421 }
422 auto aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
423 return aij2;
424 }
425 };
426
428
429 KOKKOS_INLINE_FUNCTION
433};
434
439template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType, Misc::StrengthMeasure measure>
441 public:
442 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
443 using local_matrix_type = typename matrix_type::local_matrix_device_type;
444 using scalar_type = typename local_matrix_type::value_type;
445 using local_ordinal_type = typename local_matrix_type::ordinal_type;
446 using memory_space = typename local_matrix_type::memory_space;
447 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
448 using diag_view_type = typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
449 using results_view = Kokkos::View<DecisionType*, memory_space>;
450
453
454 private:
455#if KOKKOS_VERSION >= 40799
456 using ATS = KokkosKernels::ArithTraits<scalar_type>;
457#else
458 using ATS = Kokkos::ArithTraits<scalar_type>;
459#endif
460 using magnitudeType = typename ATS::magnitudeType;
461
462 Teuchos::RCP<diag_vec_type> diagVec;
464 DistanceFunctorType dist2;
465
466 using values_view = Kokkos::View<magnitudeType*, memory_space>;
468
469 public:
470 ScaledDistanceLaplacianComparison(matrix_type& A_, DistanceFunctorType& dist2_, results_view& results_)
471 : A(A_.getLocalMatrixDevice())
472 , results(results_)
473 , dist2(dist2_)
474 , values("ScaledDistanceLaplacianComparison::values", A.nnz()) {
475 // Construct ghosted distance Laplacian diagonal
476 if constexpr ((measure == Misc::SmoothedAggregationMeasure) || (measure == Misc::SignedSmoothedAggregationMeasure)) {
478 auto lclDiag2d = diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
479 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
480 } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
482 auto lclDiag2d = diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
483 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
484 }
485 }
486
487 template <class local_matrix_type2, class DistanceFunctorType2, class diag_view_type2>
488 struct Comparator {
489 private:
490 using scalar_type = typename local_matrix_type2::value_type;
491 using local_ordinal_type = typename local_matrix_type2::ordinal_type;
492 using memory_space = typename local_matrix_type2::memory_space;
493 using results_view = Kokkos::View<DecisionType*, memory_space>;
494
495#if KOKKOS_VERSION >= 40799
496 using ATS = KokkosKernels::ArithTraits<scalar_type>;
497#else
498 using ATS = Kokkos::ArithTraits<scalar_type>;
499#endif
500 using magnitudeType = typename ATS::magnitudeType;
501#if KOKKOS_VERSION >= 40799
502 using mATS = KokkosKernels::ArithTraits<magnitudeType>;
503#else
504 using mATS = Kokkos::ArithTraits<magnitudeType>;
505#endif
506
507 using values_view = Kokkos::View<magnitudeType*, memory_space>;
508
509 const local_matrix_type2 A;
510 const diag_view_type2 diag;
511 const DistanceFunctorType2* dist2;
516
517 const scalar_type one = ATS::one();
518 const scalar_type zero = ATS::zero();
519 const magnitudeType mzero = mATS::zero();
520
521 public:
522 KOKKOS_INLINE_FUNCTION
523 Comparator(const local_matrix_type2& A_, const diag_view_type2& diag_, const DistanceFunctorType2* dist2_, local_ordinal_type rlid_, const results_view& results_, values_view& values_)
524 : A(A_)
525 , diag(diag_)
526 , dist2(dist2_)
527 , rlid(rlid_)
528 , offset(A_.graph.row_map(rlid_))
529 , results(results_)
530 , values(Kokkos::subview(values_, Kokkos::make_pair(A.graph.row_map(rlid), A.graph.row_map(rlid + 1)))) {
531 for (auto i = 0U; i < values.extent(0); ++i) {
532 values(i) = get_value_impl(i);
533 }
534 }
535
536 KOKKOS_FORCEINLINE_FUNCTION
537 magnitudeType get_value(size_t x) const {
538 return values(x);
539 }
540
541 KOKKOS_INLINE_FUNCTION
542 bool operator()(size_t x, size_t y) const {
543 if (results(offset + x) != UNDECIDED) {
544 if (results(offset + y) != UNDECIDED) {
545 // does not matter
546 return (x < y);
547 } else {
548 // sort undecided to the right
549 return true;
550 }
551 } else {
552 if (results(offset + y) != UNDECIDED) {
553 // sort undecided to the right
554 return false;
555 } else {
556 return get_value(x) > get_value(y);
557 }
558 }
559 }
560
561 private:
562 KOKKOS_INLINE_FUNCTION
564 auto clid = A.graph.entries(offset + x);
565 scalar_type val;
566 if (rlid != clid) {
567 val = -one / dist2->distance2(rlid, clid);
568 } else {
569 val = diag(rlid);
570 }
571
572 if constexpr (measure == Misc::SmoothedAggregationMeasure) {
573 auto aiiajj = ATS::magnitude(diag(rlid)) * ATS::magnitude(diag(clid)); // |a_ii|*|a_jj|
574 auto aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
575 return (aij2 / aiiajj);
576 } else if constexpr (measure == Misc::SignedRugeStuebenMeasure) {
577 auto neg_aij = -ATS::real(val);
578 auto max_neg_aik = ATS::real(diag(rlid));
579 auto v = ATS::magnitude(neg_aij / max_neg_aik);
580 if (ATS::real(neg_aij) >= mzero)
581 return v * v;
582 else
583 return -v * v;
584 } else if constexpr (measure == Misc::SignedSmoothedAggregationMeasure) {
585 auto aiiajj = ATS::magnitude(diag(rlid)) * ATS::magnitude(diag(clid)); // |a_ii|*|a_jj|
586 const bool is_nonpositive = ATS::real(val) <= mATS::zero();
587 magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val); // |a_ij|^2
588 // + |a_ij|^2, if a_ij < 0, - |a_ij|^2 if a_ij >=0
589 if (!is_nonpositive)
590 aij2 = -aij2;
591 return aij2 / aiiajj;
592 }
593 }
594 };
595
597
598 KOKKOS_INLINE_FUNCTION
602};
603
604// helper function to allow partial template deduction
605template <Misc::StrengthMeasure measure, class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node, class DistanceFunctorType>
606auto make_dlap_comparison_functor(Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A_,
607 DistanceFunctorType& dist2_,
609 if constexpr (measure == Misc::UnscaledMeasure) {
611 return functor;
612 } else {
614 return functor;
615 }
616}
617
622template <class comparison_type>
624 private:
625 using local_matrix_type = typename comparison_type::local_matrix_type;
626 using scalar_type = typename local_matrix_type::value_type;
627 using local_ordinal_type = typename local_matrix_type::ordinal_type;
628 using memory_space = typename local_matrix_type::memory_space;
629 using results_view = Kokkos::View<DecisionType*, memory_space>;
630
631#if KOKKOS_VERSION >= 40799
632 using ATS = KokkosKernels::ArithTraits<scalar_type>;
633#else
634 using ATS = Kokkos::ArithTraits<scalar_type>;
635#endif
636 using magnitudeType = typename ATS::magnitudeType;
637 using boundary_nodes_view = Kokkos::View<const bool*, memory_space>;
638
640 comparison_type comparison;
643 Kokkos::View<local_ordinal_type*, memory_space> index;
644
645 public:
646 CutDropFunctor(comparison_type& comparison_, magnitudeType threshold)
647 : A(comparison_.A)
648 , comparison(comparison_)
649 , eps(threshold)
650 , results(comparison_.results) {
651 index = Kokkos::View<local_ordinal_type*, memory_space>("indices", A.nnz());
652 }
653
654 KOKKOS_FORCEINLINE_FUNCTION
655 void operator()(const local_ordinal_type& rlid) const {
656 auto row = A.rowConst(rlid);
657 size_t nnz = row.length;
658
659 auto drop_view = Kokkos::subview(results, Kokkos::make_pair(A.graph.row_map(rlid), A.graph.row_map(rlid + 1)));
660 auto row_permutation = Kokkos::subview(index, Kokkos::make_pair(A.graph.row_map(rlid), A.graph.row_map(rlid + 1)));
661
662 auto comparator = comparison.getComparator(rlid);
663
664#ifdef MUELU_COALESCE_DROP_DEBUG
665 {
666 Kokkos::printf("SoC: ");
667 for (local_ordinal_type k = 0; k < row.length; ++k) {
668 Kokkos::printf("%5f ", comparator.get_value(k));
669 }
670 Kokkos::printf("\n");
671 }
672#endif
673
674 for (size_t i = 0; i < nnz; ++i) {
675 row_permutation(i) = i;
676 }
677 Misc::serialHeapSort(row_permutation, comparator);
678
679 size_t keepStart = 0;
680 size_t dropStart = nnz;
681 // find index where dropping starts
682 for (size_t i = 1; i < nnz; ++i) {
683 auto const& x = row_permutation(i - 1);
684 auto const& y = row_permutation(i);
685 if ((drop_view(x) != UNDECIDED) && (drop_view(y) == UNDECIDED))
686 keepStart = i;
687 if ((drop_view(x) != UNDECIDED) || (drop_view(y) != UNDECIDED))
688 continue;
689 magnitudeType x_aij = comparator.get_value(x);
690 magnitudeType y_aij = comparator.get_value(y);
691 if (eps * eps * x_aij > y_aij) {
692 if (i < dropStart) {
693 dropStart = i;
694 }
695 }
696 }
697
698 // drop everything to the right of where values stop passing threshold
699 for (size_t i = keepStart; i < nnz; ++i) {
700 drop_view(row_permutation(i)) = Kokkos::max(dropStart <= i ? DROP : KEEP, drop_view(row_permutation(i)));
701 }
702 }
703};
704
705} // namespace MueLu::CutDrop
706
707#endif
Order each row by a criterion, compare the ratio of values and drop all entries once the ratio is bel...
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< const bool *, memory_space > boundary_nodes_view
KOKKOS_FORCEINLINE_FUNCTION void operator()(const local_ordinal_type &rlid) const
CutDropFunctor(comparison_type &comparison_, magnitudeType threshold)
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::memory_space memory_space
Kokkos::ArithTraits< scalar_type > ATS
typename comparison_type::local_matrix_type local_matrix_type
typename ATS::magnitudeType magnitudeType
Kokkos::View< local_ordinal_type *, memory_space > index
typename local_matrix_type::value_type scalar_type
Orders entries of row by .
ScaledComparison(matrix_type &A_, results_view &results_)
typename ATS::magnitudeType magnitudeType
typename Kokkos::DualView< const scalar_type *, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged >::t_dev diag_view_type
Kokkos::View< DecisionType *, memory_space > results_view
Comparator< local_matrix_type, diag_view_type > comparator_type
Kokkos::View< magnitudeType *, memory_space > values_view
typename matrix_type::local_matrix_device_type local_matrix_type
Kokkos::ArithTraits< scalar_type > ATS
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > matrix_type
typename local_matrix_type::memory_space memory_space
Teuchos::RCP< diag_vec_type > diagVec
Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > diag_vec_type
typename local_matrix_type::value_type scalar_type
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type rlid) const
typename local_matrix_type::ordinal_type local_ordinal_type
Orders entries of row by where is the distance Laplacian.
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type rlid) const
typename local_matrix_type::ordinal_type local_ordinal_type
typename matrix_type::local_matrix_device_type local_matrix_type
typename Kokkos::DualView< const scalar_type *, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged >::t_dev diag_view_type
Kokkos::View< DecisionType *, memory_space > results_view
ScaledDistanceLaplacianComparison(matrix_type &A_, DistanceFunctorType &dist2_, results_view &results_)
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > matrix_type
Comparator< local_matrix_type, DistanceFunctorType, diag_view_type > comparator_type
Kokkos::View< magnitudeType *, memory_space > values_view
Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > diag_vec_type
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::memory_space memory_space
Orders entries of row by .
typename local_matrix_type::ordinal_type local_ordinal_type
typename ATS::magnitudeType magnitudeType
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > matrix_type
UnscaledComparison(matrix_type &A_, results_view &results_)
typename local_matrix_type::memory_space memory_space
Comparator< local_matrix_type > comparator_type
typename local_matrix_type::value_type scalar_type
Kokkos::ArithTraits< scalar_type > ATS
Kokkos::View< magnitudeType *, memory_space > values_view
Kokkos::View< DecisionType *, memory_space > results_view
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type rlid) const
typename matrix_type::local_matrix_device_type local_matrix_type
typename Kokkos::DualView< const scalar_type *, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged >::t_dev diag_view_type
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type rlid) const
UnscaledDistanceLaplacianComparison(matrix_type &A_, DistanceFunctorType &dist2_, results_view &results_)
typename local_matrix_type::memory_space memory_space
typename local_matrix_type::value_type scalar_type
Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > diag_vec_type
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > matrix_type
Kokkos::View< DecisionType *, memory_space > results_view
Comparator< local_matrix_type, DistanceFunctorType, diag_view_type > comparator_type
typename matrix_type::local_matrix_device_type local_matrix_type
typename local_matrix_type::ordinal_type local_ordinal_type
Kokkos::View< magnitudeType *, memory_space > values_view
static Teuchos::RCP< Vector > GetMatrixMaxMinusOffDiagonal(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A)
Return vector containing: max_{i\not=k}(-a_ik), for each for i in the matrix.
static RCP< Vector > GetMatrixOverlappedDiagonal(const Matrix &A)
Extract Overlapped Matrix Diagonal.
auto make_comparison_functor(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A_, typename ScaledComparison< Scalar, LocalOrdinal, GlobalOrdinal, Node, measure >::results_view &results_)
auto make_dlap_comparison_functor(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A_, DistanceFunctorType &dist2_, typename ScaledDistanceLaplacianComparison< Scalar, LocalOrdinal, GlobalOrdinal, Node, DistanceFunctorType, measure >::results_view &results_)
Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getDiagonal(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, DistanceFunctorType &distFunctor)
Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getMaxMinusOffDiagonal(Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, DistanceFunctorType &distFunctor)
KOKKOS_INLINE_FUNCTION void serialHeapSort(view_type &v, comparator_type comparator)
KOKKOS_INLINE_FUNCTION magnitudeType get_value(size_t x) const
Kokkos::ArithTraits< magnitudeType > mATS
KOKKOS_INLINE_FUNCTION Comparator(const local_matrix_type2 &A_, const diag_view_type2 &diag_, const local_ordinal_type rlid_, const results_view &results_, values_view &values_)
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::View< magnitudeType *, memory_space > values_view
typename local_matrix_type2::ordinal_type local_ordinal_type
Kokkos::ArithTraits< scalar_type > ATS
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
typename local_matrix_type2::memory_space memory_space
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
typename local_matrix_type2::value_type scalar_type
KOKKOS_INLINE_FUNCTION Comparator(const local_matrix_type2 &A_, const diag_view_type2 &diag_, const DistanceFunctorType2 *dist2_, local_ordinal_type rlid_, const results_view &results_, values_view &values_)
KOKKOS_FORCEINLINE_FUNCTION magnitudeType get_value(size_t x) const
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
typename local_matrix_type2::memory_space memory_space
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type2::ordinal_type local_ordinal_type
Kokkos::View< magnitudeType *, memory_space > values_view
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
KOKKOS_INLINE_FUNCTION Comparator(const local_matrix_type2 &A_, local_ordinal_type rlid_, const results_view &results_, values_view &values_)
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::ArithTraits< scalar_type > ATS
typename local_matrix_type2::value_type scalar_type
typename local_matrix_type2::ordinal_type local_ordinal_type
KOKKOS_FORCEINLINE_FUNCTION magnitudeType get_value(size_t x) const
typename local_matrix_type2::memory_space memory_space
Kokkos::View< magnitudeType *, memory_space > values_view
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
KOKKOS_FORCEINLINE_FUNCTION magnitudeType get_value(size_t x) const
KOKKOS_INLINE_FUNCTION Comparator(const local_matrix_type2 &A_, const diag_view_type2 &diag_, const DistanceFunctorType2 *dist2_, local_ordinal_type rlid_, const results_view &results_, values_view &values_)
Kokkos::View< magnitudeType *, memory_space > values_view
Kokkos::View< DecisionType *, memory_space > results_view
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
typename local_matrix_type2::ordinal_type local_ordinal_type