10 #ifndef MUELU_MATRIXCONSTRUCTION_HPP
11 #define MUELU_MATRIXCONSTRUCTION_HPP
13 #include "Kokkos_Core.hpp"
14 #include "Kokkos_ArithTraits.hpp"
18 #ifdef MUELU_COALESCE_DROP_DEBUG
23 namespace MueLu::MatrixConstruction {
34 template <
class local_matrix_type,
class functor_type,
class... remaining_functor_types>
42 using rowptr_type =
typename local_matrix_type::row_map_type::non_const_type;
51 #ifdef MUELU_COALESCE_DROP_DEBUG
52 std::string functorName;
63 #ifdef MUELU_COALESCE_DROP_DEBUG
64 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
66 char* demangledFunctorName = 0;
67 demangledFunctorName = abi::__cxa_demangle(functorName.c_str(), 0, 0, &status);
68 functorName = demangledFunctorName;
79 #ifdef MUELU_COALESCE_DROP_DEBUG
80 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
82 char* demangledFunctorName = 0;
83 demangledFunctorName = abi::__cxa_demangle(functorName.c_str(), 0, 0, &status);
84 functorName = demangledFunctorName;
88 KOKKOS_INLINE_FUNCTION
90 #ifdef MUELU_COALESCE_DROP_DEBUG
92 Kokkos::printf(
"\nStarting on row %d\n", rlid);
94 auto row =
A.rowConst(rlid);
96 Kokkos::printf(
"indices: ");
98 auto clid = row.colidx(k);
99 Kokkos::printf(
"%5d ", clid);
101 Kokkos::printf(
"\n");
103 Kokkos::printf(
"values: ");
105 auto val = row.value(k);
106 Kokkos::printf(
"%5f ", val);
108 Kokkos::printf(
"\n");
114 #ifdef MUELU_COALESCE_DROP_DEBUG
116 Kokkos::printf(
"%s\n", functorName.c_str());
118 auto row =
A.rowConst(rlid);
119 const size_t offset =
A.graph.row_map(rlid);
121 Kokkos::printf(
"decisions: ");
123 Kokkos::printf(
"%5d ",
results(offset + k));
125 Kokkos::printf(
"\n");
133 template <
class local_matrix_type,
class functor_type>
141 using rowptr_type =
typename local_matrix_type::row_map_type::non_const_type;
149 #ifdef MUELU_COALESCE_DROP_DEBUG
150 std::string functorName;
160 #ifdef MUELU_COALESCE_DROP_DEBUG
161 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
163 char* demangledFunctorName = 0;
164 demangledFunctorName = abi::__cxa_demangle(functorName.c_str(), 0, 0, &status);
165 functorName = demangledFunctorName;
175 #ifdef MUELU_COALESCE_DROP_DEBUG
176 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
178 char* demangledFunctorName = 0;
179 demangledFunctorName = abi::__cxa_demangle(functorName.c_str(), 0, 0, &status);
180 functorName = demangledFunctorName;
184 KOKKOS_INLINE_FUNCTION
186 #ifdef MUELU_COALESCE_DROP_DEBUG
188 Kokkos::printf(
"\nStarting on row %d\n", rlid);
190 auto row =
A.rowConst(rlid);
192 Kokkos::printf(
"indices: ");
194 auto clid = row.colidx(k);
195 Kokkos::printf(
"%5d ", clid);
197 Kokkos::printf(
"\n");
199 Kokkos::printf(
"values: ");
201 auto val = row.value(k);
202 Kokkos::printf(
"%5f ", val);
204 Kokkos::printf(
"\n");
210 #ifdef MUELU_COALESCE_DROP_DEBUG
211 Kokkos::printf(
"%s\n", functorName);
213 auto row =
A.rowConst(rlid);
214 const size_t offset =
A.graph.row_map(rlid);
216 Kokkos::printf(
"decisions: ");
218 Kokkos::printf(
"%5d ",
results(offset + k));
221 Kokkos::printf(
"\n");
222 Kokkos::printf(
"Done with row %d\n", rlid);
225 size_t start =
A.graph.row_map(rlid);
226 size_t end =
A.graph.row_map(rlid + 1);
227 for (
size_t i = start; i < end; ++i) {
245 template <
class local_matrix_type,
class local_graph_type,
bool lumping>
252 using ATS = Kokkos::ArithTraits<scalar_type>;
271 KOKKOS_INLINE_FUNCTION
273 auto rowA =
A.row(rlid);
274 size_t row_start =
A.graph.row_map(rlid);
282 if constexpr (lumping) {
289 rowFilteredA.colidx(j) = rowA.colidx(k);
290 rowFilteredA.value(j) = rowA.value(k);
292 graph.entries(graph_offset + jj) = rowA.colidx(k);
294 }
else if constexpr (lumping) {
295 diagCorrection += rowA.value(k);
296 rowFilteredA.colidx(j) = rowA.colidx(k);
297 rowFilteredA.value(j) =
zero;
300 rowFilteredA.colidx(j) = rowA.colidx(k);
301 rowFilteredA.value(j) =
zero;
305 if constexpr (lumping) {
306 rowFilteredA.value(diagOffset) += diagCorrection;
308 rowFilteredA.value(diagOffset) =
one;
320 template <
class local_matrix_type,
bool lumping>
327 using ATS = Kokkos::ArithTraits<scalar_type>;
344 KOKKOS_INLINE_FUNCTION
346 auto rowA =
A.row(rlid);
347 size_t K =
A.graph.row_map(rlid);
353 if constexpr (lumping) {
360 rowFilteredA.colidx(j) = rowA.colidx(k);
361 rowFilteredA.value(j) = rowA.value(k);
363 }
else if constexpr (lumping) {
364 diagCorrection += rowA.value(k);
367 if constexpr (lumping) {
368 rowFilteredA.value(diagOffset) += diagCorrection;
370 rowFilteredA.value(diagOffset) =
one;
375 template <
class local_matrix_type>
392 template <
class local_matrix_type2>
399 const local_matrix_type2
A;
404 KOKKOS_INLINE_FUNCTION
407 ,
offset(A_.graph.row_map(bsize_ * brlid_))
410 KOKKOS_INLINE_FUNCTION
418 KOKKOS_INLINE_FUNCTION
434 template <
class local_matrix_type,
436 class... remaining_functor_types>
446 using rowptr_type =
typename local_matrix_type::row_map_type::non_const_type;
447 using ATS = Kokkos::ArithTraits<local_ordinal_type>;
475 ,
remainingFunctors(A_, blockSize_, ghosted_point_to_block_, results_, filtered_rowptr_, graph_rowptr_, remainingFunctors_...) {
477 #ifdef MUELU_COALESCE_DROP_DEBUG
478 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
480 char* demangledFunctorName = 0;
481 demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
482 functorName = demangledFunctorName;
486 KOKKOS_INLINE_FUNCTION
487 void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest,
const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src)
const {
488 dest.first += src.first;
489 dest.second += src.second;
492 KOKKOS_INLINE_FUNCTION
498 KOKKOS_INLINE_FUNCTION
500 auto nnz_filtered = &nnz.first;
501 auto nnz_graph = &nnz.second;
503 #ifdef MUELU_COALESCE_DROP_DEBUG
504 Kokkos::printf(
"\nStarting on block row %d\n", brlid);
507 #ifdef MUELU_COALESCE_DROP_DEBUG
509 Kokkos::printf(
"\nStarting on row %d\n", rlid);
511 auto row =
A.rowConst(rlid);
513 Kokkos::printf(
"indices: ");
515 auto clid = row.colidx(k);
516 Kokkos::printf(
"%5d ", clid);
518 Kokkos::printf(
"\n");
520 Kokkos::printf(
"values: ");
522 auto val = row.value(k);
523 Kokkos::printf(
"%5f ", val);
525 Kokkos::printf(
"\n");
532 #ifdef MUELU_COALESCE_DROP_DEBUG
534 Kokkos::printf(
"%s\n", functorName.c_str());
536 auto row =
A.rowConst(rlid);
537 const size_t offset =
A.graph.row_map(rlid);
539 Kokkos::printf(
"decisions: ");
541 Kokkos::printf(
"%5d ",
results(offset + k));
543 Kokkos::printf(
"\n");
547 #ifdef MUELU_COALESCE_DROP_DEBUG
548 Kokkos::printf(
"Done with row %d\n", rlid);
551 size_t start =
A.graph.row_map(rlid);
552 size_t end =
A.graph.row_map(rlid + 1);
553 for (
size_t i = start; i < end; ++i) {
562 #ifdef MUELU_COALESCE_DROP_DEBUG
563 Kokkos::printf(
"Done with block row %d\nGraph indices ", brlid);
567 auto block_clids = Kokkos::subview(
A.graph.entries, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
570 auto block_permutation = Kokkos::subview(
permutation, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
572 for (
size_t i = 0; i < block_permutation.extent(0); ++i)
573 block_permutation(i) = i;
575 auto comparator =
comparison.getComparator(brlid);
579 bool alreadyAdded =
false;
582 auto offset =
A.graph.row_map(
blockSize * brlid);
583 for (
size_t i = 0; i < block_permutation.extent(0); ++i) {
584 auto idx = offset + block_permutation(i);
585 auto clid =
A.graph.entries(idx);
589 if (bclid > prev_bclid)
590 alreadyAdded =
false;
596 #ifdef MUELU_COALESCE_DROP_DEBUG
597 Kokkos::printf(
"%5d ", bclid);
602 #ifdef MUELU_COALESCE_DROP_DEBUG
603 Kokkos::printf(
"\n");
610 template <
class local_matrix_type,
621 using rowptr_type =
typename local_matrix_type::row_map_type::non_const_type;
622 using ATS = Kokkos::ArithTraits<local_ordinal_type>;
650 #ifdef MUELU_COALESCE_DROP_DEBUG
651 std::string mangledFunctorName =
typeid(decltype(
functor)).name();
653 char* demangledFunctorName = 0;
654 demangledFunctorName = abi::__cxa_demangle(mangledFunctorName.c_str(), 0, 0, &status);
655 functorName = demangledFunctorName;
659 KOKKOS_INLINE_FUNCTION
660 void join(Kokkos::pair<local_ordinal_type, local_ordinal_type>& dest,
const Kokkos::pair<local_ordinal_type, local_ordinal_type>& src)
const {
661 dest.first += src.first;
662 dest.second += src.second;
665 KOKKOS_INLINE_FUNCTION
670 KOKKOS_INLINE_FUNCTION
672 auto nnz_filtered = &nnz.first;
673 auto nnz_graph = &nnz.second;
675 #ifdef MUELU_COALESCE_DROP_DEBUG
676 Kokkos::printf(
"\nStarting on block row %d\n", brlid);
679 #ifdef MUELU_COALESCE_DROP_DEBUG
681 Kokkos::printf(
"\nStarting on row %d\n", rlid);
683 auto row =
A.rowConst(rlid);
685 Kokkos::printf(
"indices: ");
687 auto clid = row.colidx(k);
688 Kokkos::printf(
"%5d ", clid);
690 Kokkos::printf(
"\n");
692 Kokkos::printf(
"values: ");
694 auto val = row.value(k);
695 Kokkos::printf(
"%5f ", val);
697 Kokkos::printf(
"\n");
703 #ifdef MUELU_COALESCE_DROP_DEBUG
705 Kokkos::printf(
"%s\n", functorName.c_str());
707 auto row =
A.rowConst(rlid);
708 const size_t offset =
A.graph.row_map(rlid);
710 Kokkos::printf(
"decisions: ");
712 Kokkos::printf(
"%5d ",
results(offset + k));
714 Kokkos::printf(
"\n");
718 #ifdef MUELU_COALESCE_DROP_DEBUG
719 Kokkos::printf(
"Done with row %d\n", rlid);
722 size_t start =
A.graph.row_map(rlid);
723 size_t end =
A.graph.row_map(rlid + 1);
724 for (
size_t i = start; i < end; ++i) {
733 #ifdef MUELU_COALESCE_DROP_DEBUG
734 Kokkos::printf(
"Done with block row %d\nGraph indices ", brlid);
738 auto block_clids = Kokkos::subview(
A.graph.entries, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
741 auto block_permutation = Kokkos::subview(
permutation, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
743 for (
size_t i = 0; i < block_permutation.extent(0); ++i)
744 block_permutation(i) = i;
746 auto comparator =
comparison.getComparator(brlid);
750 bool alreadyAdded =
false;
753 auto offset =
A.graph.row_map(
blockSize * brlid);
754 for (
size_t i = 0; i < block_permutation.extent(0); ++i) {
755 auto idx = offset + block_permutation(i);
756 auto clid =
A.graph.entries(idx);
760 if (bclid > prev_bclid)
761 alreadyAdded =
false;
767 #ifdef MUELU_COALESCE_DROP_DEBUG
768 Kokkos::printf(
"%5d ", bclid);
773 #ifdef MUELU_COALESCE_DROP_DEBUG
774 Kokkos::printf(
"\n");
788 template <
class local_matrix_type,
bool lumping,
bool reuse>
796 using ATS = Kokkos::ArithTraits<scalar_type>;
797 using OTS = Kokkos::ArithTraits<local_ordinal_type>;
828 KOKKOS_INLINE_FUNCTION
831 auto rowA =
A.row(rlid);
832 size_t row_start =
A.graph.row_map(rlid);
838 if constexpr (lumping) {
845 rowFilteredA.colidx(j) = rowA.colidx(k);
846 rowFilteredA.value(j) = rowA.value(k);
848 }
else if constexpr (lumping) {
849 diagCorrection += rowA.value(k);
850 if constexpr (reuse) {
851 rowFilteredA.colidx(j) = rowA.colidx(k);
852 rowFilteredA.value(j) =
zero;
855 }
else if constexpr (reuse) {
856 rowFilteredA.colidx(j) = rowA.colidx(k);
857 rowFilteredA.value(j) =
zero;
861 if constexpr (lumping) {
862 rowFilteredA.value(diagOffset) += diagCorrection;
864 rowFilteredA.value(diagOffset) =
one;
869 auto block_clids = Kokkos::subview(
A.graph.entries, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
872 auto block_permutation = Kokkos::subview(
permutation, Kokkos::make_pair(
A.graph.row_map(
blockSize * brlid),
874 for (
size_t i = 0; i < block_permutation.extent(0); ++i)
875 block_permutation(i) = i;
877 auto comparator =
comparison.getComparator(brlid);
881 bool alreadyAdded =
false;
885 auto offset =
A.graph.row_map(
blockSize * brlid);
886 for (
size_t i = 0; i < block_permutation.extent(0); ++i) {
887 auto idx = offset + block_permutation(i);
888 auto clid =
A.graph.entries(idx);
892 if (bclid > prev_bclid)
893 alreadyAdded =
false;
897 graph.entries(j) = bclid;
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::ArithTraits< scalar_type > ATS
typename local_matrix_type::memory_space memory_space
Kokkos::View< DecisionType *, memory_space > results_view
Comparator< local_matrix_type > comparator_type
typename local_matrix_type::row_map_type::non_const_type rowptr_type
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::View< DecisionType *, memory_space > results_view
KOKKOS_INLINE_FUNCTION void operatorRow(const local_ordinal_type rlid) const
typename local_matrix_type::row_map_type::non_const_type rowptr_type
permutation_type permutation
KOKKOS_INLINE_FUNCTION comparator_type getComparator(local_ordinal_type brlid) const
magnitudeType dirichletThreshold
const local_matrix_type2 A
block_indices_view_type ghosted_point_to_block
const block_indices_view_type ghosted_point_to_block
magnitudeType dirichletThreshold
typename local_matrix_type::value_type scalar_type
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::value_type scalar_type
rowptr_type filtered_rowptr
typename local_matrix_type::value_type scalar_type
typename local_matrix_type::ordinal_type local_ordinal_type
local_ordinal_type blockSize
VectorCountingFunctor< local_matrix_type, remaining_functor_types...> remainingFunctors
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
permutation_type permutation
const local_ordinal_type offset
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
BlockRowComparison< local_matrix_type > comparison
block_indices_view_type ghosted_point_to_block
typename local_matrix_type::memory_space memory_space
Kokkos::ArithTraits< scalar_type > ATS
typename local_matrix_type::value_type scalar_type
BlockRowComparison< local_matrix_type > comparison
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
std::vector< std::string > functorNames
typename local_matrix_type::ordinal_type local_ordinal_type
typename local_matrix_type::row_map_type::non_const_type rowptr_type
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
typename local_matrix_type::row_map_type::non_const_type rowptr_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
rowptr_type filtered_rowptr
KOKKOS_INLINE_FUNCTION void serialHeapSort(view_type &v, comparator_type comparator)
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
Kokkos::ArithTraits< scalar_type > ATS
typename local_matrix_type::ordinal_type local_ordinal_type
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid) const
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_)
block_indices_view_type ghosted_point_to_block
local_matrix_type filteredA
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
typename local_matrix_type::memory_space memory_space
Kokkos::View< DecisionType *, memory_space > results_view
Functor that fills the filtered matrix while reusing the graph of the matrix before dropping...
typename local_matrix_type::ordinal_type local_ordinal_type
local_ordinal_type blockSize
block_indices_view_type ghosted_point_to_block
Kokkos::ArithTraits< local_ordinal_type > ATS
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_)
PointwiseFillNoReuseFunctor(local_matrix_type &A_, results_view &results_, local_matrix_type &filteredA_, magnitudeType dirichletThreshold_)
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_type2::ordinal_type local_ordinal_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::memory_space memory_space
local_ordinal_type blockSize
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_)
KOKKOS_INLINE_FUNCTION void operator()(const local_ordinal_type rlid, local_ordinal_type &nnz, const bool &final) const
typename local_matrix_type::memory_space memory_space
typename local_matrix_type::memory_space memory_space
std::vector< std::string > functorNames
typename ATS::magnitudeType magnitudeType
magnitudeType dirichletThreshold
typename local_matrix_type::value_type scalar_type
typename ATS::magnitudeType magnitudeType
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 does not reuse the graph of the matrix for a problem with blockSize == 1. ...
typename ATS::magnitudeType magnitudeType
local_matrix_type filteredA
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_)
typename local_matrix_type2::memory_space memory_space
Kokkos::View< local_ordinal_type *, memory_space > block_indices_view_type
permutation_type permutation
Kokkos::View< local_ordinal_type *, memory_space > permutation_type
typename local_matrix_type::ordinal_type local_ordinal_type
local_matrix_type filteredA
Kokkos::View< DecisionType *, memory_space > results_view
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
typename local_matrix_type::staticcrsgraph_type local_graph_type