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 #include "Kokkos_ArithTraits.hpp"
20 #include "Teuchos_Assert.hpp"
21 #include <type_traits>
22 #include "KokkosSparse_spmv_impl.hpp"
31 template<
class DVector,
38 using execution_space =
typename AMatrix::execution_space;
39 using LO =
typename AMatrix::non_const_ordinal_type;
40 using value_type =
typename AMatrix::non_const_value_type;
41 using team_policy =
typename Kokkos::TeamPolicy<execution_space>;
42 using team_member =
typename team_policy::member_type;
43 using ATV = Kokkos::ArithTraits<value_type>;
45 using magnitude_type =
typename ATV::mag_type;
46 using MATV = Kokkos::ArithTraits<magnitude_type>;
50 DiagOffsetType m_offsets;
51 magnitude_type m_L1Eta;
52 magnitude_type m_MinDiagonalValue;
56 const DiagOffsetType& m_offsets_,
57 const magnitude_type m_L1Eta_,
58 const magnitude_type m_MinDiagonalValue_) :
61 m_offsets (m_offsets_),
63 m_MinDiagonalValue (m_MinDiagonalValue_)
65 const size_t numRows = m_A.numRows ();
71 KOKKOS_INLINE_FUNCTION
72 void operator() (
const LO lclRow)
const
74 const size_t INV = Tpetra::Details::OrdinalTraits<size_t>::invalid ();
75 const value_type one = ATV::one();
78 m_d(lclRow,0) = ATV::zero();
80 if (m_offsets(lclRow) != INV) {
81 auto curRow = m_A.rowConst (lclRow);
82 value_type d = curRow.value(m_offsets(lclRow));
93 const magnitude_type half = MATV::one () / (MATV::one () + MATV::one ());
94 const LO numRows =
static_cast<LO
> (m_A.numRows ());
95 const LO row_length =
static_cast<LO
> (curRow.length);
96 magnitude_type diagonal_boost = MATV::zero();
97 for (LO iEntry = 0; iEntry < row_length; iEntry++) {
98 if (curRow.colidx(iEntry) >= numRows)
99 diagonal_boost += ATV::magnitude(curRow.value(iEntry));
101 diagonal_boost *= half;
102 if (ATV::magnitude(d) < m_L1Eta * diagonal_boost)
109 if (ATV::magnitude(d) <= m_MinDiagonalValue)
110 d = m_MinDiagonalValue;
114 m_d(lclRow,0) = one / d;
123 template<
class TpetraOperatorType>
130 template<
class TpetraOperatorType>
132 InverseDiagonalKernel<TpetraOperatorType>::
135 if (A_op_.get () != A.
get ()) {
138 using Teuchos::rcp_dynamic_cast;
139 A_crs_ = rcp_dynamic_cast<
const crs_matrix_type> (A);
142 (A_crs_.is_null(), std::logic_error,
143 "Ifpack2::Details::InverseDiagonalKernel: operator A must be a Tpetra::CrsMatrix.");
145 const size_t lclNumRows = A_crs_->getRowMap ()->getLocalNumElements ();
147 if (offsets_.extent (0) < lclNumRows) {
148 using Kokkos::view_alloc;
149 using Kokkos::WithoutInitializing;
150 using offsets_view_type = Kokkos::View<size_t*, device_type>;
152 offsets_ = offsets_view_type ();
153 auto howAlloc = view_alloc (
"offsets", WithoutInitializing);
154 offsets_ = offsets_view_type (howAlloc, lclNumRows);
157 A_crs_->getCrsGraph ()->getLocalDiagOffsets (offsets_);
161 template<
class TpetraOperatorType>
163 InverseDiagonalKernel<TpetraOperatorType>::
164 compute (vector_type& D_inv,
165 bool do_l1, magnitude_type L1Eta,
166 bool fixTinyDiagEntries, magnitude_type MinDiagonalValue)
171 using d_type =
typename vector_type::dual_view_type::t_dev;
173 using d_matrix_type =
typename crs_matrix_type::local_matrix_device_type;
175 const char kernel_label[] =
"inverse_diagonal_kernel";
176 using execution_space =
typename NT::execution_space;
177 using range_type = Kokkos::RangePolicy<execution_space, LO>;
178 const size_t lclNumRows = A_crs_->getRowMap ()->getLocalNumElements ();
179 auto policy = range_type(0, lclNumRows);
181 d_type d = D_inv.getLocalViewDevice(Tpetra::Access::OverwriteAll);
182 d_matrix_type a = A_crs_->getLocalMatrixDevice();
185 constexpr
bool do_l1_template =
true;
186 if (fixTinyDiagEntries) {
187 constexpr
bool fix_tiny_template =
true;
189 Impl::InverseDiagonalWithExtraction<d_type,
194 functor_type func (d, a, offsets_, L1Eta, MinDiagonalValue);
195 Kokkos::parallel_for (kernel_label, policy, func);
197 constexpr
bool fix_tiny_template =
false;
199 Impl::InverseDiagonalWithExtraction<d_type,
204 functor_type func (d, a, offsets_, L1Eta, MinDiagonalValue);
205 Kokkos::parallel_for (kernel_label, policy, func);
208 constexpr
bool do_l1_template =
false;
209 if (fixTinyDiagEntries) {
210 constexpr
bool fix_tiny_template =
true;
212 Impl::InverseDiagonalWithExtraction<d_type,
217 functor_type func (d, a, offsets_, L1Eta, MinDiagonalValue);
218 Kokkos::parallel_for (kernel_label, policy, func);
220 constexpr
bool fix_tiny_template =
false;
222 Impl::InverseDiagonalWithExtraction<d_type,
227 functor_type func (d, a, offsets_, L1Eta, MinDiagonalValue);
228 Kokkos::parallel_for (kernel_label, policy, func);
236 #define IFPACK2_DETAILS_INVERSEDIAGONALKERNEL_INSTANT(SC,LO,GO,NT) \
237 template class Ifpack2::Details::InverseDiagonalKernel<Tpetra::Operator<SC, LO, GO, NT> >;
239 #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)