2#include <ginkgo/ginkgo.hpp>
4#include <Kokkos_Core.hpp>
13template <
class KokkosViewType>
14auto to_gko_multivector(
15 std::shared_ptr<const gko::Executor>
const& gko_exec,
16 KokkosViewType
const& view)
18 static_assert((Kokkos::is_view_v<KokkosViewType> && KokkosViewType::rank == 2));
19 using value_type =
typename KokkosViewType::traits::value_type;
21 assert(view.stride_1() == 1);
23 gko::batch::MultiVector<value_type>::
25 gko::batch_dim<2>(view.extent(0), gko::dim<2>(view.extent(1), 1)),
26 gko::array<value_type>::view(gko_exec, view.span(), view.data())));
38inline void check_conv(
41 std::shared_ptr<const gko::Executor> gko_exec,
42 std::shared_ptr<
const gko::batch::log::BatchConvergence<double>> logger)
44 auto logger_residual_host
45 = gko::make_temporary_clone(gko_exec->get_master(), &logger->get_residual_norm());
46 bool has_converged =
false;
47 Kokkos::parallel_reduce(
49 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(0, batch_size),
50 [&](
int batch_idx,
bool& check_tol) {
51 check_tol = check_tol && (logger_residual_host->get_const_data()[batch_idx] <= tol);
53 Kokkos::LAnd<bool>(has_converged));
55 throw ::std::runtime_error(
"Ginkgo did not converge");
71 std::fstream& log_file,
72 int const batch_index,
73 int const num_iterations,
74 double const implicit_res_norm,
75 double const true_res_norm,
79 log_file <<
" System no. " << batch_index <<
":" << std::endl;
80 log_file <<
" Number of iterations = " << num_iterations << std::endl;
81 log_file <<
" Implicit residual norm = " << implicit_res_norm << std::endl;
82 log_file <<
" True (Ax-b) residual norm = " << true_res_norm << std::endl;
83 log_file <<
" Right-hand side (b) norm = " << b_norm << std::endl;
84 if (!(true_res_norm <= tol)) {
85 log_file <<
" --- System " << batch_index <<
" did not converge! ---" << std::endl;
87 log_file <<
"------------------------------------------------" << std::endl;
99template <
class sparse_type>
101 std::fstream& log_file,
102 int const batch_index,
103 std::unique_ptr<sparse_type> matrix,
104 Kokkos::View<double*, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace>
const x_view,
105 Kokkos::View<double*, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace>
const b_view,
106 std::shared_ptr<
const gko::log::Convergence<double>> logger,
109 std::shared_ptr
const gko_exec = matrix->get_executor();
111 auto x = gko::matrix::Dense<double>::
113 gko::dim<2>(x_view.extent(0), 1),
114 gko::array<double>::view(gko_exec, x_view.span(), x_view.data()),
116 auto b = gko::matrix::Dense<double>::
118 gko::dim<2>(b_view.extent(0), 1),
119 gko::array<double>::view(gko_exec, b_view.span(), b_view.data()),
123 auto res = gko::matrix::Dense<double>::create(gko_exec, gko::dim<2>(b_view.extent(0), 1));
126 auto norm_dim = gko::dim<2>(1, 1);
128 auto b_norm_host = gko::matrix::Dense<double>::create(gko_exec->get_master(), norm_dim);
129 b_norm_host->fill(0.0);
131 auto res_norm_host = gko::matrix::Dense<double>::create(gko_exec->get_master(), norm_dim);
132 res_norm_host->fill(0.0);
134 b->compute_norm2(b_norm_host);
136 auto one = gko::matrix::Dense<double>::create(gko_exec, norm_dim);
138 auto neg_one = gko::matrix::Dense<double>::create(gko_exec, norm_dim);
141 matrix->apply(one, x, neg_one, res);
143 res->compute_norm2(res_norm_host);
145 int const log_iters_host = logger->get_num_iterations();
146 double const log_resid_host
147 = gko::make_temporary_clone(
148 gko_exec->get_master(),
149 gko::as<gko::matrix::Dense<double>>(logger->get_residual_norm()))
157 res_norm_host->at(0, 0),
158 b_norm_host->at(0, 0),
171template <
class batch_sparse_type>
173 std::fstream& log_file,
174 std::shared_ptr<batch_sparse_type> batch_matrix,
175 Kokkos::View<double**, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace>
const x_view,
176 Kokkos::View<double**, Kokkos::LayoutRight, Kokkos::DefaultExecutionSpace>
const b_view,
177 std::shared_ptr<
const gko::batch::log::BatchConvergence<double>> logger,
180 std::shared_ptr
const gko_exec = batch_matrix->get_executor();
181 int const batch_size = x_view.extent(0);
183 auto x = to_gko_multivector(gko_exec, x_view);
184 auto b = to_gko_multivector(gko_exec, b_view);
187 auto res = gko::batch::MultiVector<double>::
188 create(gko_exec, gko::batch_dim<2>(batch_size, gko::dim<2>(b_view.extent(1), 1)));
191 auto norm_dim = gko::batch_dim<2>(batch_size, gko::dim<2>(1, 1));
193 auto b_norm_host = gko::batch::MultiVector<double>::create(gko_exec->get_master(), norm_dim);
194 b_norm_host->fill(0.0);
196 auto res_norm_host = gko::batch::MultiVector<double>::create(gko_exec->get_master(), norm_dim);
197 res_norm_host->fill(0.0);
199 b->compute_norm2(b_norm_host);
201 auto one = gko::batch::MultiVector<double>::create(gko_exec, norm_dim);
203 auto neg_one = gko::batch::MultiVector<double>::create(gko_exec, norm_dim);
206 batch_matrix->apply(one, x, neg_one, res);
208 res->compute_norm2(res_norm_host);
211 = gko::make_temporary_clone(gko_exec->get_master(), &logger->get_num_iterations());
213 = gko::make_temporary_clone(gko_exec->get_master(), &logger->get_residual_norm());
217 for (
int i = 0; i < batch_size; ++i) {
221 log_iters_host->get_const_data()[i],
222 log_resid_host->get_const_data()[i],
223 res_norm_host->create_const_view_for_item(i)->at(0, 0),
224 b_norm_host->create_const_view_for_item(i)->at(0, 0),
229template <
class ExecSpace>
230unsigned int default_preconditionner_max_block_size() noexcept
232#ifdef KOKKOS_ENABLE_SERIAL
233 if (std::is_same_v<ExecSpace, Kokkos::Serial>) {
237#ifdef KOKKOS_ENABLE_OPENMP
238 if (std::is_same_v<ExecSpace, Kokkos::OpenMP>) {
242#ifdef KOKKOS_ENABLE_CUDA
243 if (std::is_same_v<ExecSpace, Kokkos::Cuda>) {
247#ifdef KOKKOS_ENABLE_HIP
248 if (std::is_same_v<ExecSpace, Kokkos::HIP>) {