Gyselalib++
 
Loading...
Searching...
No Matches
matrix_batch_ell.hpp
1#pragma once
2
3#include <sll/matrix_batch.hpp>
4#include <sll/matrix_utils.hpp>
5
6#include <ginkgo/extensions/kokkos.hpp>
7#include <ginkgo/ginkgo.hpp>
8
9#include <Kokkos_Core.hpp>
10
22template <class ExecSpace>
23class MatrixBatchEll : public MatrixBatch<ExecSpace>
24{
25public:
27 using MatrixBatch<ExecSpace>::size;
28 using MatrixBatch<ExecSpace>::batch_size;
29
30private:
31 using batch_sparse_type = gko::batch::matrix::Ell<double, int>;
32 using solver_type = gko::batch::solver::Bicgstab<double>;
33
34 std::shared_ptr<batch_sparse_type> m_batch_matrix_ell;
35 std::shared_ptr<solver_type> m_solver;
36 int m_max_iter;
37 double m_tol;
38 bool m_with_logger;
39
40
41public:
54 const int batch_size,
55 const int mat_size,
56 const int non_zeros_per_row,
57 std::optional<int> max_iter = std::nullopt,
58 std::optional<double> res_tol = std::nullopt,
59 std::optional<bool> logger = std::nullopt)
60 : MatrixBatch<ExecSpace>(batch_size, mat_size)
61 , m_max_iter(max_iter.value_or(500))
62 , m_tol(res_tol.value_or(1e-15))
63 , m_with_logger(logger.value_or(false))
64 {
65 std::shared_ptr const gko_exec = gko::ext::kokkos::create_executor(ExecSpace());
66 m_batch_matrix_ell = gko::share(
67 batch_sparse_type::
68 create(gko_exec,
69 gko::batch_dim<2>(batch_size, gko::dim<2>(mat_size, mat_size)),
70 non_zeros_per_row));
71 }
72
85 Kokkos::View<int**, Kokkos::LayoutLeft, ExecSpace> cols_idx,
86 Kokkos::View<double***, Kokkos::LayoutStride, ExecSpace> batch_values,
87 std::optional<int> max_iter = std::nullopt,
88 std::optional<double> res_tol = std::nullopt,
89 std::optional<bool> logger = std::nullopt)
90 : MatrixBatch<ExecSpace>(batch_values.extent(0), batch_values.extent(1))
91 , m_max_iter(max_iter.value_or(500))
92 , m_tol(res_tol.value_or(1e-15))
93 , m_with_logger(logger.value_or(false))
94
95
96 {
97 std::shared_ptr const gko_exec = gko::ext::kokkos::create_executor(ExecSpace());
98 m_batch_matrix_ell = gko::share(
99 gko::batch::matrix::Ell<double>::
100 create(gko_exec,
101 gko::batch_dim<2>(batch_size(), gko::dim<2>(size(), size())),
102 batch_values.extent(2),
103 gko::array<double>::
104 view(gko_exec, batch_values.span(), batch_values.data()),
105 gko::array<int>::view(gko_exec, cols_idx.span(), cols_idx.data())));
106 }
107
114 std::pair<
115 Kokkos::View<int**, Kokkos::LayoutLeft, ExecSpace>,
116 Kokkos::View<double***, Kokkos::LayoutStride, ExecSpace>>
118 {
119 int* idx_buffer = m_batch_matrix_ell->get_col_idxs();
120 double* vals_buffer = m_batch_matrix_ell->get_values();
121 Kokkos::LayoutStride values_layout(
122 batch_size(),
123 m_batch_matrix_ell->get_num_stored_elements_per_row() * size(),
124 size(),
125 1,
126 m_batch_matrix_ell->get_num_stored_elements_per_row(),
127 size());
128 Kokkos::View<int**, Kokkos::LayoutLeft, ExecSpace>
129 idx_view(idx_buffer, size(), m_batch_matrix_ell->get_num_stored_elements_per_row());
130 Kokkos::View<double***, Kokkos::LayoutStride, ExecSpace>
131 vals_view(vals_buffer, values_layout);
132 return {idx_view, vals_view};
133 }
134
142 double get_ell_element(int batch_idx, int line_idx, int non_zero_col_idx) const
143 {
144 // Checks index of column according to the sparsity pattern.
145 assert(non_zero_col_idx >= 0
146 && non_zero_col_idx <= m_batch_matrix_ell->get_num_stored_elements_per_row());
147 return m_batch_matrix_ell->get_const_values()
148 [batch_idx * size() * m_batch_matrix_ell->get_num_stored_elements_per_row()
149 + non_zero_col_idx * size() + line_idx];
150 }
151
159 void set_ell_element(int batch_idx, int line_idx, int non_zero_col_idx, double aij)
160 {
161 // Checks index of column according to the sparsity pattern.
162 assert(non_zero_col_idx >= 0
163 && non_zero_col_idx <= m_batch_matrix_ell->get_num_stored_elements_per_row());
164 m_batch_matrix_ell->get_values()
165 [batch_idx * size() * m_batch_matrix_ell->get_num_stored_elements_per_row()
166 + non_zero_col_idx * size() + line_idx]
167 = aij;
168 }
169
177 void setup_solver() final
178 {
179 std::shared_ptr const gko_exec = m_batch_matrix_ell->get_executor();
180 gko::batch::stop::tolerance_type tol_type = gko::batch::stop::tolerance_type::relative;
181
182 std::shared_ptr solver_factory = solver_type::build()
183 .with_max_iterations(m_max_iter)
184 .with_tolerance(m_tol)
185 .with_tolerance_type(tol_type)
186 .on(gko_exec);
187 m_solver = solver_factory->generate(m_batch_matrix_ell);
188 gko_exec->synchronize();
189 }
190
196 void solve(BatchedRHS const b) const final
197 {
198 std::shared_ptr const gko_exec = m_solver->get_executor();
199 BatchedRHS x_view("x_view", batch_size(), size());
200
201 // Create a logger to obtain the iteration counts and "implicit" residual norms for every system after the solve.
202 std::shared_ptr<const gko::batch::log::BatchConvergence<double>> logger
203 = gko::batch::log::BatchConvergence<double>::create();
204 m_solver->add_logger(logger);
205 gko_exec->synchronize();
206
207 Kokkos::deep_copy(x_view, b);
208 m_solver->apply(to_gko_multivector(gko_exec, b), to_gko_multivector(gko_exec, x_view));
209 m_solver->remove_logger(logger);
210 // save logger data
211 if (m_with_logger) {
212 std::fstream log_file("ell_log.txt", std::ios::out | std::ios::app);
213 save_logger(log_file, m_batch_matrix_ell, x_view, b, logger, m_tol);
214 log_file.close();
215 }
216 //check convergence
217 check_conv(batch_size(), m_tol, gko_exec, logger);
218
219 Kokkos::deep_copy(b, x_view);
220 }
221
227 double norm(int batch_idx) const
228 {
229 int const tmp_mat_size = size();
230 int const tmp_batch_size = batch_size();
231 int const non_zeros = m_batch_matrix_ell->get_num_stored_elements_per_row();
232 double* vals_proxy = m_batch_matrix_ell->get_values();
233 Kokkos::LayoutStride values_layout(
234 tmp_batch_size,
235 non_zeros * tmp_mat_size,
236 tmp_mat_size,
237 1,
238 non_zeros,
239 tmp_mat_size);
240 Kokkos::View<double***, Kokkos::LayoutStride, typename ExecSpace::memory_space>
241 vals_view(vals_proxy, values_layout);
242
243 double result = 0;
244 Kokkos::parallel_reduce(
245 "L-infinitty norm",
246 Kokkos::RangePolicy<ExecSpace>(0, tmp_mat_size),
247 KOKKOS_LAMBDA(int i, double& res) {
248 double row_sum = 0.;
249 for (int k = 0; k < non_zeros; k++) {
250 row_sum += Kokkos::abs(vals_view(batch_idx, i, k));
251 }
252 if (row_sum > res) {
253 res = row_sum;
254 }
255 },
256 Kokkos::Max<double>(result));
257 return result;
258 }
259};
Matrix class which is able to manage and solve a batch of sparse linear systems.
Definition matrix_batch_ell.hpp:24
MatrixBatchEll(Kokkos::View< int **, Kokkos::LayoutLeft, ExecSpace > cols_idx, Kokkos::View< double ***, Kokkos::LayoutStride, ExecSpace > batch_values, std::optional< int > max_iter=std::nullopt, std::optional< double > res_tol=std::nullopt, std::optional< bool > logger=std::nullopt)
Constructor for MatrixBatchEll class.
Definition matrix_batch_ell.hpp:84
void setup_solver() final
Perform a pre-process operation on the solver.
Definition matrix_batch_ell.hpp:177
void solve(BatchedRHS const b) const final
Solve the batched linear problem Ax=b.
Definition matrix_batch_ell.hpp:196
double norm(int batch_idx) const
A function returns the norm of a matrix located at batch_idx.
Definition matrix_batch_ell.hpp:227
void set_ell_element(int batch_idx, int line_idx, int non_zero_col_idx, double aij)
A setter function to modify a value located at a specified place.
Definition matrix_batch_ell.hpp:159
MatrixBatchEll(const int batch_size, const int mat_size, const int non_zeros_per_row, std::optional< int > max_iter=std::nullopt, std::optional< double > res_tol=std::nullopt, std::optional< bool > logger=std::nullopt)
The constructor for MatrixBatchEll class.
Definition matrix_batch_ell.hpp:53
std::pair< Kokkos::View< int **, Kokkos::LayoutLeft, ExecSpace >, Kokkos::View< double ***, Kokkos::LayoutStride, ExecSpace > > get_batch_ell()
A function to get information about values and indices for the whole batch.
Definition matrix_batch_ell.hpp:117
double get_ell_element(int batch_idx, int line_idx, int non_zero_col_idx) const
A getter function for a value located at a specified place.
Definition matrix_batch_ell.hpp:142
MatrixBatch superclass for managing a collection of linear systems.
Definition matrix_batch.hpp:23
std::size_t batch_size() const
Get the batch size of the linear problem.
Definition matrix_batch.hpp:76
std::size_t size() const
Get the size of the square matrix corresponding to a single batch in one of its dimensions.
Definition matrix_batch.hpp:66
Kokkos::View< double **, Kokkos::LayoutRight, ExecSpace > BatchedRHS
The type of a Kokkos::View storing batched right-hand sides. Second dimenion is batch dimension.
Definition matrix_batch.hpp:26