10 #ifndef IFPACK2_DETAILS_INVERSEDIAGONALKERNEL_DEF_HPP
11 #define IFPACK2_DETAILS_INVERSEDIAGONALKERNEL_DEF_HPP
13 #include "Tpetra_CrsMatrix.hpp"
14 #include "Tpetra_MultiVector.hpp"
15 #include "Tpetra_Operator.hpp"
16 #include "Tpetra_Vector.hpp"
17 #include "Tpetra_Export_decl.hpp"
18 #include "Tpetra_Import_decl.hpp"
19 #if KOKKOS_VERSION >= 40799
20 #include "KokkosKernels_ArithTraits.hpp"
22 #include "Kokkos_ArithTraits.hpp"
24 #include "Teuchos_Assert.hpp"
25 #include <type_traits>
26 #include "KokkosSparse_spmv_impl.hpp"
35 template <
class DVector,
41 using execution_space =
typename AMatrix::execution_space;
42 using LO =
typename AMatrix::non_const_ordinal_type;
43 using value_type =
typename AMatrix::non_const_value_type;
44 using team_policy =
typename Kokkos::TeamPolicy<execution_space>;
45 using team_member =
typename team_policy::member_type;
46 #if KOKKOS_VERSION >= 40799
47 using ATV = KokkosKernels::ArithTraits<value_type>;
49 using ATV = Kokkos::ArithTraits<value_type>;
52 using magnitude_type =
typename ATV::mag_type;
53 #if KOKKOS_VERSION >= 40799
54 using MATV = KokkosKernels::ArithTraits<magnitude_type>;
56 using MATV = Kokkos::ArithTraits<magnitude_type>;
61 DiagOffsetType m_offsets;
62 magnitude_type m_L1Eta;
63 magnitude_type m_MinDiagonalValue;
67 const DiagOffsetType& m_offsets_,
68 const magnitude_type m_L1Eta_,
69 const magnitude_type m_MinDiagonalValue_)
72 , m_offsets(m_offsets_)
74 , m_MinDiagonalValue(m_MinDiagonalValue_) {
75 const size_t numRows = m_A.numRows();
81 KOKKOS_INLINE_FUNCTION
82 void operator()(
const LO lclRow)
const {
83 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid();
84 const value_type one = ATV::one();
87 m_d(lclRow, 0) = ATV::zero();
89 if (m_offsets(lclRow) != INV) {
90 auto curRow = m_A.rowConst(lclRow);
91 value_type d = curRow.value(m_offsets(lclRow));
102 const magnitude_type half = MATV::one() / (MATV::one() + MATV::one());
103 const LO numRows =
static_cast<LO
>(m_A.numRows());
104 const LO row_length =
static_cast<LO
>(curRow.length);
105 magnitude_type diagonal_boost = MATV::zero();
106 for (LO iEntry = 0; iEntry < row_length; iEntry++) {
107 if (curRow.colidx(iEntry) >= numRows)
108 diagonal_boost += ATV::magnitude(curRow.value(iEntry));
110 diagonal_boost *= half;
111 if (ATV::magnitude(d) < m_L1Eta * diagonal_boost)
118 if (ATV::magnitude(d) <= m_MinDiagonalValue)
119 d = m_MinDiagonalValue;
123 m_d(lclRow, 0) = one / d;
130 template <
class TpetraOperatorType>
136 template <
class TpetraOperatorType>
137 void InverseDiagonalKernel<TpetraOperatorType>::
139 if (A_op_.get() != A.
get()) {
142 using Teuchos::rcp_dynamic_cast;
143 A_crs_ = rcp_dynamic_cast<
const crs_matrix_type>(A);
146 "Ifpack2::Details::InverseDiagonalKernel: operator A must be a Tpetra::CrsMatrix.");
148 const size_t lclNumRows = A_crs_->getRowMap()->getLocalNumElements();
150 if (offsets_.extent(0) < lclNumRows) {
151 using Kokkos::view_alloc;
152 using Kokkos::WithoutInitializing;
153 using offsets_view_type = Kokkos::View<size_t*, device_type>;
155 offsets_ = offsets_view_type();
156 auto howAlloc = view_alloc(
"offsets", WithoutInitializing);
157 offsets_ = offsets_view_type(howAlloc, lclNumRows);
160 A_crs_->getCrsGraph()->getLocalDiagOffsets(offsets_);
164 template <
class TpetraOperatorType>
165 void InverseDiagonalKernel<TpetraOperatorType>::
166 compute(vector_type& D_inv,
167 bool do_l1, magnitude_type L1Eta,
168 bool fixTinyDiagEntries, magnitude_type MinDiagonalValue) {
170 using d_type =
typename vector_type::dual_view_type::t_dev;
172 using d_matrix_type =
typename crs_matrix_type::local_matrix_device_type;
174 const char kernel_label[] =
"inverse_diagonal_kernel";
175 using execution_space =
typename NT::execution_space;
176 using range_type = Kokkos::RangePolicy<execution_space, LO>;
177 const size_t lclNumRows = A_crs_->getRowMap()->getLocalNumElements();
178 auto policy = range_type(0, lclNumRows);
180 d_type d = D_inv.getLocalViewDevice(Tpetra::Access::OverwriteAll);
181 d_matrix_type a = A_crs_->getLocalMatrixDevice();
184 constexpr
bool do_l1_template =
true;
185 if (fixTinyDiagEntries) {
186 constexpr
bool fix_tiny_template =
true;
188 Impl::InverseDiagonalWithExtraction<d_type,
193 functor_type func(d, a, offsets_, L1Eta, MinDiagonalValue);
194 Kokkos::parallel_for(kernel_label, policy, func);
196 constexpr
bool fix_tiny_template =
false;
198 Impl::InverseDiagonalWithExtraction<d_type,
203 functor_type func(d, a, offsets_, L1Eta, MinDiagonalValue);
204 Kokkos::parallel_for(kernel_label, policy, func);
207 constexpr
bool do_l1_template =
false;
208 if (fixTinyDiagEntries) {
209 constexpr
bool fix_tiny_template =
true;
211 Impl::InverseDiagonalWithExtraction<d_type,
216 functor_type func(d, a, offsets_, L1Eta, MinDiagonalValue);
217 Kokkos::parallel_for(kernel_label, policy, func);
219 constexpr
bool fix_tiny_template =
false;
221 Impl::InverseDiagonalWithExtraction<d_type,
226 functor_type func(d, a, offsets_, L1Eta, MinDiagonalValue);
227 Kokkos::parallel_for(kernel_label, policy, func);
235 #define IFPACK2_DETAILS_INVERSEDIAGONALKERNEL_INSTANT(SC, LO, GO, NT) \
236 template class Ifpack2::Details::InverseDiagonalKernel<Tpetra::Operator<SC, LO, GO, NT> >;
238 #endif // IFPACK2_DETAILS_INVERSEDIAGONALKERNEL_DEF_HPP
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Compute scaled damped residual for Chebyshev.
Definition: Ifpack2_Details_InverseDiagonalKernel_decl.hpp:45
#define TEUCHOS_ASSERT(assertion_test)