Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
Ifpack2_BlockComputeResidualAndSolve_decl.hpp
1// @HEADER
2// *****************************************************************************
3// Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4//
5// Copyright 2009 NTESS and the Ifpack2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef IFPACK2_BLOCKCOMPUTERES_AND_SOLVE_DECL_HPP
11#define IFPACK2_BLOCKCOMPUTERES_AND_SOLVE_DECL_HPP
12
13#include <KokkosBatched_Util.hpp>
14#include <KokkosBatched_Vector.hpp>
15#include <Tpetra_BlockMultiVector.hpp>
16#include <Tpetra_BlockCrsMatrix_decl.hpp>
17#include "Ifpack2_BlockHelper.hpp"
18#include "Ifpack2_BlockHelper_ETI.hpp"
19
20namespace Ifpack2::BlockHelperDetails {
21
22template <typename ExecSpace, typename DiagOffsets, typename Rowptrs,
23 typename Entries>
24DiagOffsets findDiagOffsets(const Rowptrs& rowptrs, const Entries& entries,
25 size_t nrows, int blocksize) {
26 DiagOffsets diag_offsets(do_not_initialize_tag("btdm.diag_offsets"), nrows);
27 int err1 = 0;
28 Kokkos::parallel_reduce(
29 Kokkos::RangePolicy<ExecSpace>(0, nrows),
30 KOKKOS_LAMBDA(size_t row, int& err2) {
31 auto rowBegin = rowptrs(row);
32 auto rowEnd = rowptrs(row + 1);
33 for (size_t j = rowBegin; j < rowEnd; j++) {
34 if (size_t(entries(j)) == row) {
35 diag_offsets(row) = j * blocksize * blocksize;
36 return;
37 }
38 }
39 err2++;
40 },
41 err1);
42 TEUCHOS_TEST_FOR_EXCEPT_MSG(
43 err1, "Ifpack2 BTD: at least one row has no diagonal entry");
44 return diag_offsets;
45}
46
47template <typename MatrixType,
48 typename ImplTagType = typename BlockTriDiContainerDetails::ImplTag<typename MatrixType::scalar_type>::type>
49struct ComputeResidualAndSolve;
50
51template <typename MatrixType>
52struct ComputeResidualAndSolve<MatrixType, BlockTriDiContainerDetails::ImplSimdTag> {
53 using impl_type = BlockHelperDetails::ImplType<MatrixType>;
54 using node_device_type = typename impl_type::node_device_type;
55 using execution_space = typename impl_type::execution_space;
56 using memory_space = typename impl_type::memory_space;
57
58 using local_ordinal_type = typename impl_type::local_ordinal_type;
59 using size_type = typename impl_type::size_type;
60 using impl_scalar_type = typename impl_type::impl_scalar_type;
61 using magnitude_type = typename impl_type::magnitude_type;
63 using local_ordinal_type_1d_view =
64 typename impl_type::local_ordinal_type_1d_view;
65 using size_type_1d_view = typename impl_type::size_type_1d_view;
66 using tpetra_block_access_view_type =
67 typename impl_type::tpetra_block_access_view_type; // block crs (layout
68 // right)
69 using impl_scalar_type_1d_view = typename impl_type::impl_scalar_type_1d_view;
70 using impl_scalar_type_2d_view_tpetra =
71 typename impl_type::impl_scalar_type_2d_view_tpetra; // block multivector
72 // (layout left)
73 using btdm_scalar_type_3d_view = typename impl_type::btdm_scalar_type_3d_view;
74 using btdm_scalar_type_4d_view = typename impl_type::btdm_scalar_type_4d_view;
75 using i64_3d_view = typename impl_type::i64_3d_view;
76
78 using member_type = typename Kokkos::TeamPolicy<execution_space>::member_type;
79
80 ComputeResidualAndSolve(const AmD<MatrixType>& amd_,
81 const btdm_scalar_type_3d_view& d_inv_,
82 const impl_scalar_type_1d_view& W_,
83 const local_ordinal_type& blocksize_requested_,
84 const impl_scalar_type& damping_factor_)
85 : amd(amd_)
86 , blocksize_requested(blocksize_requested_)
87 , d_inv(d_inv_)
88 , W(W_)
89 , damping_factor(damping_factor_) {}
90
91 void run_y_zero(
92 const Const<impl_scalar_type_2d_view_tpetra>& b_,
93 const impl_scalar_type_2d_view_tpetra& y_);
94 void run_single_pass(
95 const Const<impl_scalar_type_2d_view_tpetra>& b_,
96 const impl_scalar_type_2d_view_tpetra& x_,
97 const impl_scalar_type_2d_view_tpetra& x_remote_,
98 const impl_scalar_type_2d_view_tpetra& y_);
99 void run_pass1_of_2(
100 const Const<impl_scalar_type_2d_view_tpetra>& b_,
101 const impl_scalar_type_2d_view_tpetra& x_,
102 const impl_scalar_type_2d_view_tpetra& y_);
103 void run_pass2_of_2(
104 const impl_scalar_type_2d_view_tpetra& x_,
105 const impl_scalar_type_2d_view_tpetra& x_remote_,
106 const impl_scalar_type_2d_view_tpetra& y_);
107
108 private:
109 // AmD information
110 const AmD<MatrixType> amd;
111
112 // blocksize
113 const local_ordinal_type blocksize_requested;
114
115 // diagonal block inverses
116 const btdm_scalar_type_3d_view d_inv;
117
118 // squared update norms
119 const impl_scalar_type_1d_view W;
120
121 impl_scalar_type damping_factor;
122};
123
124template <typename MatrixType>
125struct ComputeResidualAndSolve<MatrixType, BlockTriDiContainerDetails::ImplNotAvailTag> {
126 using impl_type = BlockHelperDetails::ImplType<MatrixType>;
127 using node_device_type = typename impl_type::node_device_type;
128 using execution_space = typename impl_type::execution_space;
129 using memory_space = typename impl_type::memory_space;
130
131 using local_ordinal_type = typename impl_type::local_ordinal_type;
132 using size_type = typename impl_type::size_type;
133 using impl_scalar_type = typename impl_type::impl_scalar_type;
134 using magnitude_type = typename impl_type::magnitude_type;
136 using local_ordinal_type_1d_view =
137 typename impl_type::local_ordinal_type_1d_view;
138 using size_type_1d_view = typename impl_type::size_type_1d_view;
139 using tpetra_block_access_view_type =
140 typename impl_type::tpetra_block_access_view_type; // block crs (layout
141 // right)
142 using impl_scalar_type_1d_view = typename impl_type::impl_scalar_type_1d_view;
143 using impl_scalar_type_2d_view_tpetra =
144 typename impl_type::impl_scalar_type_2d_view_tpetra; // block multivector
145 // (layout left)
146 using btdm_scalar_type_3d_view = typename impl_type::btdm_scalar_type_3d_view;
147 using btdm_scalar_type_4d_view = typename impl_type::btdm_scalar_type_4d_view;
148 using i64_3d_view = typename impl_type::i64_3d_view;
149
151 using member_type = typename Kokkos::TeamPolicy<execution_space>::member_type;
152
153 ComputeResidualAndSolve(const AmD<MatrixType>& amd_,
154 const btdm_scalar_type_3d_view& d_inv_,
155 const impl_scalar_type_1d_view& W_,
156 const local_ordinal_type& blocksize_requested_,
157 const impl_scalar_type& damping_factor_)
158 : amd(amd_)
159 , blocksize_requested(blocksize_requested_)
160 , d_inv(d_inv_)
161 , W(W_)
162 , damping_factor(damping_factor_) {
163 TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "Error: BlockTriDiContainer and related classes are not available for this scalar_type");
164 }
165
166 void run_y_zero(
167 const Const<impl_scalar_type_2d_view_tpetra>& b_,
168 const impl_scalar_type_2d_view_tpetra& y_) {}
169 void run_single_pass(
170 const Const<impl_scalar_type_2d_view_tpetra>& b_,
171 const impl_scalar_type_2d_view_tpetra& x_,
172 const impl_scalar_type_2d_view_tpetra& x_remote_,
173 const impl_scalar_type_2d_view_tpetra& y_) {}
174 void run_pass1_of_2(
175 const Const<impl_scalar_type_2d_view_tpetra>& b_,
176 const impl_scalar_type_2d_view_tpetra& x_,
177 const impl_scalar_type_2d_view_tpetra& y_) {}
178 void run_pass2_of_2(
179 const impl_scalar_type_2d_view_tpetra& x_,
180 const impl_scalar_type_2d_view_tpetra& x_remote_,
181 const impl_scalar_type_2d_view_tpetra& y_) {}
182
183 private:
184 // AmD information
185 const AmD<MatrixType> amd;
186
187 // blocksize
188 const local_ordinal_type blocksize_requested;
189
190 // diagonal block inverses
191 const btdm_scalar_type_3d_view d_inv;
192
193 // squared update norms
194 const impl_scalar_type_1d_view W;
195
196 impl_scalar_type damping_factor;
197};
198
199} // namespace Ifpack2::BlockHelperDetails
200
201#endif