10#ifndef MUELU_CUTDROP_HPP
11#define MUELU_CUTDROP_HPP
13#include "Kokkos_Core.hpp"
14#include "KokkosKernels_ArithTraits.hpp"
16#include "MueLu_Utilities.hpp"
17#include "Xpetra_Matrix.hpp"
18#include "Xpetra_MultiVector.hpp"
33template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
36 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
48 using ATS = KokkosKernels::ArithTraits<scalar_type>;
50 using values_view = Kokkos::View<magnitudeType*, memory_space>;
55 :
A(A_.getLocalMatrixDevice())
57 ,
values(
"UnscaledComparison::values",
A.nnz()) {}
59 template <
class local_matrix_type2>
67 using ATS = KokkosKernels::ArithTraits<scalar_type>;
69 using values_view = Kokkos::View<magnitudeType*, memory_space>;
71 const local_matrix_type2
A;
77 KOKKOS_INLINE_FUNCTION
80 ,
offset(A_.graph.row_map(rlid_))
82 ,
values(Kokkos::subview(values_, Kokkos::make_pair(
A.graph.row_map(rlid_),
A.graph.row_map(rlid_ + 1)))) {
83 for (
auto i = 0U; i <
values.extent(0); ++i) {
88 KOKKOS_FORCEINLINE_FUNCTION
93 KOKKOS_INLINE_FUNCTION
114 KOKKOS_INLINE_FUNCTION
116 return ATS::magnitude(
A.values(
offset + x) *
A.values(
offset + x));
122 KOKKOS_INLINE_FUNCTION
132template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node, Misc::StrengthMeasure measure>
135 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
140 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
141 using diag_view_type =
typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
148 using ATS = KokkosKernels::ArithTraits<scalar_type>;
158 :
A(A_.getLocalMatrixDevice())
160 ,
values(
"ScaledComparison::values",
A.nnz()) {
163 auto lclDiag2d =
diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
164 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
167 auto lcl2d =
diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
168 diag = Kokkos::subview(lcl2d, Kokkos::ALL(), 0);
172 template <
class local_matrix_type2,
class diag_view_type2>
180 using ATS = KokkosKernels::ArithTraits<scalar_type>;
182 using mATS = KokkosKernels::ArithTraits<magnitudeType>;
185 const local_matrix_type2
A;
193 KOKKOS_INLINE_FUNCTION
198 ,
offset(A_.graph.row_map(rlid_))
200 ,
values(Kokkos::subview(values_, Kokkos::make_pair(
A.graph.row_map(rlid_),
A.graph.row_map(rlid_ + 1)))) {
201 for (
auto i = 0U; i <
values.extent(0); ++i) {
206 KOKKOS_INLINE_FUNCTION
211 KOKKOS_INLINE_FUNCTION
232 KOKKOS_INLINE_FUNCTION
235 auto x_aij = ATS::magnitude(
A.values(
offset + x) *
A.values(
offset + x));
237 return (x_aij / x_aiiajj);
239 auto val =
A.values(
offset + x);
240 auto neg_aij = -ATS::real(val);
241 auto max_neg_aik = ATS::real(
diag(
rlid));
242 auto v = neg_aij / max_neg_aik;
243 if (ATS::real(v) <= mATS::zero()) {
244 return -ATS::magnitude(v * v);
246 return ATS::magnitude(v * v);
249 auto val =
A.values(
offset + x);
251 const bool is_nonpositive = ATS::real(val) <= mATS::zero();
252 magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val);
255 return (aij2 / x_aiiajj);
262 KOKKOS_INLINE_FUNCTION
269template <Misc::StrengthMeasure measure,
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
281template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node,
class DistanceFunctorType>
284 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
289 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
290 using diag_view_type =
typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
297 using ATS = KokkosKernels::ArithTraits<scalar_type>;
308 :
A(A_.getLocalMatrixDevice())
311 ,
values(
"UnscaledDistanceLaplacianComparison::values",
A.nnz()) {
314 auto lclDiag2d =
diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
315 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
318 template <
class local_matrix_type2,
class DistanceFunctorType2,
class diag_view_type2>
326 using ATS = KokkosKernels::ArithTraits<scalar_type>;
330 const local_matrix_type2
A;
341 KOKKOS_INLINE_FUNCTION
347 ,
offset(A_.graph.row_map(rlid_))
349 ,
values(Kokkos::subview(values_, Kokkos::make_pair(
A.graph.row_map(rlid_),
A.graph.row_map(rlid_ + 1)))) {
350 for (
auto i = 0U; i <
values.extent(0); ++i) {
355 KOKKOS_FORCEINLINE_FUNCTION
360 KOKKOS_INLINE_FUNCTION
381 KOKKOS_INLINE_FUNCTION
383 auto clid =
A.graph.entries(
offset + x);
390 auto aij2 = ATS::magnitude(val) * ATS::magnitude(val);
397 KOKKOS_INLINE_FUNCTION
407template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node,
class DistanceFunctorType, Misc::StrengthMeasure measure>
410 using matrix_type = Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
415 using diag_vec_type = Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>;
416 using diag_view_type =
typename Kokkos::DualView<const scalar_type*, Kokkos::LayoutStride, typename Node::device_type, Kokkos::MemoryUnmanaged>::t_dev;
423 using ATS = KokkosKernels::ArithTraits<scalar_type>;
435 :
A(A_.getLocalMatrixDevice())
438 ,
values(
"ScaledDistanceLaplacianComparison::values",
A.nnz()) {
442 auto lclDiag2d =
diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
443 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
446 auto lclDiag2d =
diagVec->getLocalViewDevice(Tpetra::Access::ReadOnly);
447 diag = Kokkos::subview(lclDiag2d, Kokkos::ALL(), 0);
451 template <
class local_matrix_type2,
class DistanceFunctorType2,
class diag_view_type2>
459 using ATS = KokkosKernels::ArithTraits<scalar_type>;
461 using mATS = KokkosKernels::ArithTraits<magnitudeType>;
465 const local_matrix_type2
A;
478 KOKKOS_INLINE_FUNCTION
484 ,
offset(A_.graph.row_map(rlid_))
486 ,
values(Kokkos::subview(values_, Kokkos::make_pair(
A.graph.row_map(
rlid),
A.graph.row_map(
rlid + 1)))) {
487 for (
auto i = 0U; i <
values.extent(0); ++i) {
492 KOKKOS_FORCEINLINE_FUNCTION
497 KOKKOS_INLINE_FUNCTION
518 KOKKOS_INLINE_FUNCTION
520 auto clid =
A.graph.entries(
offset + x);
529 auto aiiajj = ATS::magnitude(
diag(
rlid)) * ATS::magnitude(
diag(clid));
530 auto aij2 = ATS::magnitude(val) * ATS::magnitude(val);
531 return (aij2 / aiiajj);
533 auto neg_aij = -ATS::real(val);
534 auto max_neg_aik = ATS::real(
diag(
rlid));
535 auto v = ATS::magnitude(neg_aij / max_neg_aik);
536 if (ATS::real(neg_aij) >=
mzero)
541 auto aiiajj = ATS::magnitude(
diag(
rlid)) * ATS::magnitude(
diag(clid));
542 const bool is_nonpositive = ATS::real(val) <= mATS::zero();
543 magnitudeType aij2 = ATS::magnitude(val) * ATS::magnitude(val);
547 return aij2 / aiiajj;
554 KOKKOS_INLINE_FUNCTION
561template <Misc::StrengthMeasure measure,
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node,
class DistanceFunctorType>
563 DistanceFunctorType& dist2_,
578template <
class comparison_type>
587 using ATS = KokkosKernels::ArithTraits<scalar_type>;
595 Kokkos::View<local_ordinal_type*, memory_space>
index;
603 index = Kokkos::View<local_ordinal_type*, memory_space>(
"indices",
A.nnz());
606 KOKKOS_FORCEINLINE_FUNCTION
608 auto row =
A.rowConst(rlid);
609 size_t nnz = row.length;
611 auto drop_view = Kokkos::subview(
results, Kokkos::make_pair(
A.graph.row_map(rlid),
A.graph.row_map(rlid + 1)));
612 auto row_permutation = Kokkos::subview(
index, Kokkos::make_pair(
A.graph.row_map(rlid),
A.graph.row_map(rlid + 1)));
614 auto comparator =
comparison.getComparator(rlid);
616#ifdef MUELU_COALESCE_DROP_DEBUG
618 Kokkos::printf(
"SoC: ");
620 Kokkos::printf(
"%5f ", comparator.get_value(k));
622 Kokkos::printf(
"\n");
626 for (
size_t i = 0; i < nnz; ++i) {
627 row_permutation(i) = i;
631 size_t keepStart = 0;
632 size_t dropStart = nnz;
634 for (
size_t i = 1; i < nnz; ++i) {
635 auto const& x = row_permutation(i - 1);
636 auto const& y = row_permutation(i);
643 if (
eps *
eps * x_aij > y_aij) {
651 for (
size_t i = keepStart; i < nnz; ++i) {
652 drop_view(row_permutation(i)) = Kokkos::max(dropStart <= i ?
DROP :
KEEP, drop_view(row_permutation(i)));
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
KokkosKernels::ArithTraits< scalar_type > ATS
Kokkos::View< const bool *, memory_space > boundary_nodes_view
KOKKOS_FORCEINLINE_FUNCTION void operator()(const local_ordinal_type &rlid) const
comparison_type comparison
CutDropFunctor(comparison_type &comparison_, magnitudeType threshold)
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type::memory_space memory_space
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
KokkosKernels::ArithTraits< scalar_type > ATS
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
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
KokkosKernels::ArithTraits< scalar_type > ATS
typename local_matrix_type::ordinal_type local_ordinal_type
DistanceFunctorType dist2
typename matrix_type::local_matrix_device_type local_matrix_type
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
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
Teuchos::RCP< diag_vec_type > diagVec
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
KokkosKernels::ArithTraits< scalar_type > ATS
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::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 ATS::magnitudeType magnitudeType
KokkosKernels::ArithTraits< scalar_type > ATS
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
Teuchos::RCP< diag_vec_type > diagVec
DistanceFunctorType dist2
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)
@ SignedSmoothedAggregationMeasure
@ SignedRugeStuebenMeasure
@ SmoothedAggregationMeasure
KOKKOS_INLINE_FUNCTION magnitudeType get_value(size_t x) const
KokkosKernels::ArithTraits< scalar_type > ATS
const local_ordinal_type offset
const results_view results
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_)
typename ATS::magnitudeType magnitudeType
Kokkos::View< DecisionType *, memory_space > results_view
Kokkos::View< magnitudeType *, memory_space > values_view
typename local_matrix_type2::ordinal_type local_ordinal_type
const local_ordinal_type rlid
const diag_view_type2 diag
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
typename local_matrix_type2::memory_space memory_space
const local_matrix_type2 A
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
KokkosKernels::ArithTraits< magnitudeType > mATS
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
const DistanceFunctorType2 * dist2
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
KokkosKernels::ArithTraits< scalar_type > ATS
const local_ordinal_type rlid
typename local_matrix_type2::memory_space memory_space
const local_matrix_type2 A
const results_view results
Kokkos::View< DecisionType *, memory_space > results_view
typename local_matrix_type2::ordinal_type local_ordinal_type
typename ATS::magnitudeType magnitudeType
const diag_view_type2 diag
KokkosKernels::ArithTraits< magnitudeType > mATS
const magnitudeType mzero
Kokkos::View< magnitudeType *, memory_space > values_view
const local_ordinal_type offset
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_, local_ordinal_type rlid_, const results_view &results_, values_view &values_)
Kokkos::View< DecisionType *, memory_space > results_view
KokkosKernels::ArithTraits< scalar_type > ATS
const local_ordinal_type offset
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
typename ATS::magnitudeType magnitudeType
Kokkos::View< magnitudeType *, memory_space > values_view
const local_matrix_type2 A
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
const results_view results
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
const local_ordinal_type offset
typename ATS::magnitudeType magnitudeType
KOKKOS_INLINE_FUNCTION magnitudeType get_value_impl(size_t x) const
KokkosKernels::ArithTraits< scalar_type > ATS
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
const diag_view_type2 diag
Kokkos::View< DecisionType *, memory_space > results_view
const local_matrix_type2 A
const results_view results
const DistanceFunctorType2 * dist2
KOKKOS_INLINE_FUNCTION bool operator()(size_t x, size_t y) const
const local_ordinal_type rlid
typename local_matrix_type2::value_type scalar_type
typename local_matrix_type2::ordinal_type local_ordinal_type
typename local_matrix_type2::memory_space memory_space