23#include <ginkgo/ginkgo.hpp>
33#define MFEM_GINKGO_VERSION \
34 ((GKO_VERSION_MAJOR*100 + GKO_VERSION_MINOR)*100 + GKO_VERSION_PATCH)
41template <
typename T>
using gko_array = gko::array<T>;
42#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
45 std::conditional_t<
sizeof(HYPRE_Int) ==
sizeof(std::int32_t), std::int32_t,
46 std::conditional_t<
sizeof(HYPRE_Int) ==
sizeof(std::int64_t), std::int64_t,
void>>;
48 std::conditional_t<
sizeof(
HYPRE_BigInt) ==
sizeof(std::int32_t), std::int32_t,
49 std::conditional_t<
sizeof(
HYPRE_BigInt) ==
sizeof(std::int64_t), std::int64_t,
void>>;
50static_assert(!std::is_void_v<gko_hypre_int>,
51 "HYPRE_Int type is incompatible with Ginkgo");
52static_assert(!std::is_void_v<gko_hypre_bigint>,
53 "HYPRE_BigInt type is incompatible with Ginkgo");
91 gko::size_type size,
Vector *mfem_vec,
92 bool ownership =
false)
93 : gko::matrix::Dense<
real_t>(
95 gko::
dim<2> {size, 1},
99 exec != exec->get_master() ?
true : false)),
110 wrapped_vec = std::unique_ptr<
Vector,
111 std::function<void(
Vector *)>>(
112 mfem_vec, deleter{});
116 using deleter = gko::null_deleter<Vector>;
117 wrapped_vec = std::unique_ptr<Vector,
118 std::function<void(Vector *)>>(
119 mfem_vec, deleter{});
123 static std::unique_ptr<VectorWrapper>
create(
124 std::shared_ptr<const gko::Executor> exec,
127 bool ownership =
false)
129 return std::unique_ptr<VectorWrapper>(
141 std::unique_ptr<gko::matrix::Dense<real_t>>
146 this->wrapped_vec.get()->GetMemory().GetMemoryType());
148 mfem_vec->
UseDevice(this->wrapped_vec.get()->UseDevice());
164 std::shared_ptr<const gko::Executor> exec,
165 const gko::dim<2> &size,
166 gko::size_type stride)
const override
173 "VectorWrapper cannot be created with stride > 1");
176 gko::size_type total_size = size[0]*size[1];
179 this->wrapped_vec.get()->GetMemory().GetMemoryType());
181 mfem_vec->
UseDevice(this->wrapped_vec.get()->UseDevice());
187 this->get_executor(), total_size, mfem_vec,
194 const gko::span &rows,
195 const gko::span &columns,
196 const gko::size_type stride)
override
199 gko::size_type num_rows = rows.end - rows.begin;
200 gko::size_type num_cols = columns.end - columns.begin;
204 if (num_cols > 1 || stride > 1)
206 throw gko::BadDimension(
207 __FILE__, __LINE__, __func__,
"new_submatrix", num_rows,
209 "VectorWrapper submatrix must have one column and stride = 1");
211 int data_size =
static_cast<int>(num_rows * num_cols);
212 int start =
static_cast<int>(rows.begin);
215 mfem_vec->
MakeRef(*(this->wrapped_vec.get()), start, data_size);
216 mfem_vec->
UseDevice(this->wrapped_vec.get()->UseDevice());
223 this->get_executor(), data_size, mfem_vec,
228 std::unique_ptr<
Vector, std::function<void(
Vector *)>> wrapped_vec;
240 :
public gko::EnableLinOp<OperatorWrapper>,
241 public gko::EnableCreateMethod<OperatorWrapper>
245 gko::size_type size = 0,
248 gko::EnableCreateMethod<OperatorWrapper>()
250 this->wrapped_oper = oper;
254 void apply_impl(
const gko::LinOp *
b, gko::LinOp *x)
const override;
256 const gko::LinOp *beta, gko::LinOp *x)
const override;
262#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
265 :
public gko::EnableLinOp<ParallelOperatorWrapper>,
266 public gko::experimental::distributed::DistributedBase,
267 public gko::EnableCreateMethod<ParallelOperatorWrapper>
271 gko::experimental::mpi::communicator comm,
272 gko::size_type size = 0,
275 gko::experimental::distributed::DistributedBase(comm),
276 gko::EnableCreateMethod<ParallelOperatorWrapper>()
278 this->wrapped_oper = oper;
282 void apply_impl(
const gko::LinOp *
b, gko::LinOp *x)
const override;
284 const gko::LinOp *beta, gko::LinOp *x)
const override;
291 gko::experimental::distributed::Vector<real_t>
295 gko::experimental::mpi::communicator comm,
301 gko::
dim<2>(global_rows, global_cols),
302 gko::make_dense_view(gko::as<gko::matrix::Dense<
real_t>>
303 (wrapped_local_mfem_vec))
306 this->local_wrapped_vec = std::unique_ptr<Ginkgo::VectorWrapper>
307 (wrapped_local_mfem_vec);
310 static std::unique_ptr<ParallelVectorWrapper>
create(
311 std::shared_ptr<const gko::Executor> exec,
312 gko::experimental::mpi::communicator comm,
316 return std::unique_ptr<ParallelVectorWrapper>(
329 std::unique_ptr<gko::experimental::distributed::Vector<real_t>>
333 this->get_local_vector()->get_size()[0],
334 (this->local_wrapped_vec.get()->get_mfem_vec_const_ref()).GetMemory().GetMemoryType());
337 this->local_wrapped_vec.get()->get_mfem_vec_const_ref()).UseDevice());
339 this->get_executor(),
340 this->get_local_vector()->get_size()[0],
345 this->get_communicator(),
348 this->get_size()[1]);
356 std::unique_ptr<gko::experimental::distributed::Vector<real_t>>
358 std::shared_ptr<const gko::Executor> exec,
359 const gko::dim<2> &global_size,
360 const gko::dim<2> &local_size,
361 gko::size_type stride)
const override
368 "ParallelVectorWrapper cannot be created with stride > 1");
371 gko::size_type total_local_size = local_size[0]*local_size[1];
374 (this->local_wrapped_vec.get()->get_mfem_vec_const_ref()).GetMemory().GetMemoryType());
376 this->local_wrapped_vec.get()->get_mfem_vec_const_ref().UseDevice());
379 this->get_executor(),
385 this->get_communicator(),
394 std::unique_ptr<gko::experimental::distributed::Vector<real_t>>
396 gko::local_span rows, gko::local_span columns,
397 gko::dim<2> global_size)
override
399 gko::size_type num_rows = rows.end - rows.begin;
400 gko::size_type num_cols = columns.end - columns.begin;
405 throw gko::BadDimension(
406 __FILE__, __LINE__, __func__,
"new_submatrix", num_rows,
408 "ParallelVectorWrapper submatrix must have one column");
410 int data_size =
static_cast<int>(num_rows * num_cols);
411 int start =
static_cast<int>(rows.begin);
414 local_mfem_vec->
MakeRef(this->local_wrapped_vec.get()->get_mfem_vec_ref(),
417 this->local_wrapped_vec.get()->get_mfem_vec_const_ref().UseDevice());
420 this->get_executor(),
426 this->get_communicator(),
435 std::unique_ptr<Ginkgo::VectorWrapper> local_wrapped_vec;
441template <
typename ValueType=real_t>
445 auto cpu_norm = clone(
norm->get_executor()->get_master(),
norm);
447 return cpu_norm->at(0, 0);
450#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
453template <
typename ValueType=real_t>
457 auto cpu_norm = clone(
norm->get_executor()->get_master(),
458 norm->get_local_vector());
460 return cpu_norm->at(0, 0);
466template <
typename VecType,
typename ValueType=real_t>
470 auto exec =
b->get_executor();
472 auto b_norm = gko::initialize<gko::matrix::Dense<ValueType>>({0.0}, exec);
474 b->compute_norm2(b_norm);
505 const gko::size_type &iteration,
506 const gko::LinOp *residual,
507 const gko::LinOp *solution,
508 const gko::LinOp *residual_norm)
const override
510 MFEM_ABORT(
"Error: Ginkgo logging function for v1.5 or older was called");
514 const gko::size_type &iteration,
515 const gko::LinOp *residual,
516 const gko::LinOp *solution,
517 const gko::LinOp *residual_norm,
518 const gko::LinOp *implicit_sq_residual_norm)
const override
520 MFEM_ABORT(
"Error: Ginkgo logging function for v1.5 or older was called");
524 const gko::LinOp *rhs,
525 const gko::LinOp *solution,
526 const gko::size_type &iteration,
527 const gko::LinOp *residual,
528 const gko::LinOp *residual_norm,
529 const gko::LinOp *implicit_sq_residual_norm,
530 const gko::array<gko::stopping_status>* status,
531 bool stopped)
const override
537 implicit_sq_residual_norm, status);
544 gko::log::Logger(gko::log::Logger::iteration_complete_mask) {}
549 const gko::LinOp *residual,
550 const gko::LinOp *solution,
551 const gko::LinOp *residual_norm,
552 const gko::LinOp *implicit_sq_residual_norm,
553 const gko::array<gko::stopping_status>* status)
const = 0;
569template <
typename VecType>
575 const gko::LinOp *matrix,
const VecType *b,
576 bool compute_real_residual=
false)
581 compute_real_residual{compute_real_residual} {}
586 void convergence_iteration_complete_core(
const gko::size_type &iteration,
587 const gko::LinOp *residual,
588 const gko::LinOp *solution,
589 const gko::LinOp *residual_norm,
590 const gko::LinOp *implicit_sq_residual_norm,
591 const gko::array<gko::stopping_status>* status)
const override
593 gko::array<gko::stopping_status> tmp(status->get_executor()->get_master(),
596 for (
int i = 0; i < status->get_size(); i++)
598 if (!tmp.get_data()[i].has_converged())
607 bool has_residual_or_norm = (residual || residual_norm ||
608 implicit_sq_residual_norm);
609 if ((solution && compute_real_residual) || (solution && !has_residual_or_norm))
611 res = std::move(VecType::create_with_config_of(b).release());
613 auto exec = matrix->get_executor();
616 matrix->apply(solution, res);
618 auto neg_one = gko::initialize<gko::matrix::Dense<real_t>>({-1.0}, exec);
619 res->add_scaled(neg_one, b);
626 if (implicit_sq_residual_norm)
628 auto dense_norm = gko::as<gko::matrix::Dense<real_t>>
629 (implicit_sq_residual_norm);
634 else if (residual_norm)
636 auto dense_norm = gko::as<gko::matrix::Dense<real_t>>(residual_norm);
642 auto dense_residual = gko::as<VecType>(residual);
649 const gko::LinOp *matrix;
653 mutable VecType *res;
656 const bool compute_real_residual;
679 mfem::out <<
"Iteration log with real residual norms:" << std::endl;
683 mfem::out <<
"Iteration log with residual norms:" << std::endl;
685 mfem::out <<
'|' << std::setw(10) <<
"Iteration" <<
'|' << std::setw(25)
686 <<
"Residual Norm" <<
'|' << std::endl;
689 mfem::out <<
'|' << std::setfill(
'-') << std::setw(11) <<
'|' <<
690 std::setw(26) <<
'|' << std::setfill(
' ') << std::endl;
693 for (std::size_t i = 0; i <
iterations.size(); i++)
700 mfem::out.unsetf(std::ios_base::floatfield);
702 mfem::out <<
'|' << std::setfill(
'-') << std::setw(11) <<
'|' <<
703 std::setw(26) <<
'|' << std::setfill(
' ') << std::endl;
708 const gko::size_type &iteration,
709 const gko::LinOp *residual,
710 const gko::LinOp *solution,
711 const gko::LinOp *residual_norm)
const override
718 const gko::size_type &iteration,
719 const gko::LinOp *residual,
720 const gko::LinOp *solution,
721 const gko::LinOp *residual_norm,
722 const gko::LinOp *implicit_sq_residual_norm)
const override
725 implicit_sq_residual_norm);
729 const gko::LinOp *rhs,
730 const gko::LinOp *solution,
731 const gko::size_type &iteration,
732 const gko::LinOp *residual,
733 const gko::LinOp *residual_norm,
734 const gko::LinOp *implicit_sq_residual_norm,
735 const gko::array<gko::stopping_status>* status,
736 bool stopped)
const override
739 implicit_sq_residual_norm);
745 gko::log::Logger(gko::log::Logger::iteration_complete_mask),
750 const gko::LinOp *residual,
751 const gko::LinOp *solution,
752 const gko::LinOp *residual_norm,
753 const gko::LinOp *implicit_sq_residual_norm)
const = 0;
769template <
typename VecType>
775 const gko::LinOp *matrix,
const VecType *b,
784 res = std::move(VecType::create_with_config_of(
b).release());
795 void iteration_complete_core(
const gko::size_type &iteration,
796 const gko::LinOp *residual,
797 const gko::LinOp *solution,
798 const gko::LinOp *residual_norm,
799 const gko::LinOp *implicit_sq_residual_norm)
const override
803 bool has_residual_or_norm = (residual || residual_norm ||
804 implicit_sq_residual_norm);
810 res = std::move(VecType::create_with_config_of(b).release());
813 auto exec = matrix->get_executor();
816 matrix->apply(solution, res);
818 auto neg_one = gko::initialize<gko::matrix::Dense<real_t>>({-1.0}, exec);
819 res->add_scaled(neg_one, b);
827 if (implicit_sq_residual_norm)
829 auto dense_norm = gko::as<gko::matrix::Dense<real_t>>
830 (implicit_sq_residual_norm);
835 else if (residual_norm)
837 auto dense_norm = gko::as<gko::matrix::Dense<real_t>>(residual_norm);
844 auto dense_residual = gko::as<VecType>(residual);
855 const gko::LinOp *matrix;
859 mutable VecType *res;
929 return this->executor;
933 std::shared_ptr<gko::Executor> executor;
974#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1045#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1049 std::shared_ptr<gko::experimental::mpi::communicator>
gko_comm;
1131#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1164 std::shared_ptr<gko::stop::ResidualNorm<real_t>::Factory>
1171 std::shared_ptr<gko::stop::ResidualNorm<real_t>::Factory>
1178 std::shared_ptr<gko::stop::ImplicitResidualNorm<real_t>::Factory>
1185 std::shared_ptr<gko::stop::ImplicitResidualNorm<real_t>::Factory>
1211#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1215 std::shared_ptr<gko::experimental::mpi::communicator>
gko_comm;
1248 initialize_ginkgo_log(gko::matrix::Dense<real_t>*
b)
const;
1250#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1259 std::shared_ptr<gko::LinOp> system_oper;
1269template<
typename SolverType>
1276#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1286 auto current_params = gko::as<typename SolverType::Factory>
1300 auto current_params = gko::as<typename SolverType::Factory>
1314 auto current_params = gko::as<typename SolverType::Factory>
1324#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1330 bool needs_sorted_diag =
false;
1331 auto current_params = gko::as<typename SolverType::Factory>
1334 gko::experimental::distributed::preconditioner::Schwarz<real_t, int, gko_hypre_bigint>;
1335 auto schwarz_factory = gko::as<typename schwarz::Factory>
1336 (current_params.preconditioner);
1337 if (schwarz_factory != NULL)
1339 auto schwarz_factory_params = schwarz_factory->get_parameters();
1340 if (schwarz_factory_params.l1_smoother ==
true)
1342 needs_sorted_diag =
true;
1345 return needs_sorted_diag;
1366#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1385#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1415#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1434#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1465#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1484#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1523#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1542#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1572#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1596#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1621using gko::solver::cb_gmres::storage_precision;
1652 storage_precision prec = storage_precision::reduce1);
1671 storage_precision prec = storage_precision::reduce1);
1701#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1720#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1754 const std::string &storage_opt =
"none",
1755 const real_t accuracy = 1.e-1,
1756 const int max_block_size = 32
1788 const std::string &factorization_type =
"exact",
1789 const int sweeps = 0,
1790 const bool skip_sort =
false
1830 const std::string &factorization_type =
"exact",
1831 const int sweeps = 0,
1832 const int sparsity_power = 1,
1833 const bool skip_sort =
false
1865 const std::string &factorization_type =
"exact",
1866 const int sweeps = 0,
1867 const bool skip_sort =
false
1907 const std::string &factorization_type =
"exact",
1908 const int sweeps = 0,
1909 const int sparsity_power = 1,
1910 const bool skip_sort =
false
1914#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1947 const bool l1_smoother =
false
1981 const Solver &mfem_precond
1984#if defined(MFEM_USE_MPI) && GINKGO_BUILD_MPI
1995 const Solver &mfem_precond,
2007 MFEM_ABORT(
"Ginkgo::MFEMPreconditioner must be constructed "
2008 "with the MFEM Operator that it will wrap as an argument;\n"
2009 "calling SetOperator() is not allowed.");
The MFEM Device class abstracts hardware devices such as GPUs, as well as programming models such as ...
BICGSTABSolver(GinkgoExecutor &exec)
CBGMRESSolver(GinkgoExecutor &exec, int dim=0, storage_precision prec=storage_precision::reduce1)
CGSSolver(GinkgoExecutor &exec)
CGSolver(GinkgoExecutor &exec)
void on_iteration_complete(const gko::LinOp *op, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm) const override
real_t final_residual_norm
void on_iteration_complete(const gko::LinOp *op, const gko::LinOp *rhs, const gko::LinOp *solution, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm, const gko::array< gko::stopping_status > *status, bool stopped) const override
real_t get_final_residual_norm()
void on_iteration_complete(const gko::LinOp *op, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm) const override
gko::size_type num_iterations
virtual void convergence_iteration_complete_core(const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm, const gko::array< gko::stopping_status > *status) const =0
EnableConvergenceLogger(std::shared_ptr< const gko::Executor > exec, const gko::LinOp *matrix, const VecType *b, bool compute_real_residual=false)
void SetRelTol(real_t rtol)
EnableGinkgoSolver(GinkgoExecutor &exec, MPI_Comm comm, bool use_implicit_res_norm)
void SetAbsTol(real_t atol)
bool check_needs_sorted_diagonal_mat()
void SetMaxIter(int max_it)
EnableGinkgoSolver(GinkgoExecutor &exec, bool use_implicit_res_norm)
EnableResidualLogger(std::shared_ptr< const gko::Executor > exec, const gko::LinOp *matrix, const VecType *b, bool compute_real_residual=false)
FCGSolver(GinkgoExecutor &exec)
GMRESSolver(GinkgoExecutor &exec, int dim=0)
std::shared_ptr< gko::Executor > GetExecutor() const
GinkgoExecutor(ExecType exec_type)
virtual ~GinkgoExecutor()=default
@ REFERENCE
Reference CPU Executor.
@ OMP
OpenMP CPU Executor.
void SetOperator(const Operator &op) override
bool sub_op_needs_wrapped_vecs
bool UsesVectorWrappers() const
void Mult(const Vector &x, Vector &y) const override
void update_stop_factory()
bool use_implicit_res_norm
std::shared_ptr< gko::stop::Combined::Factory > combined_factory
std::shared_ptr< gko::experimental::mpi::communicator > gko_comm
std::shared_ptr< gko::stop::ResidualNorm< real_t >::Factory > abs_criterion
std::shared_ptr< gko::stop::ImplicitResidualNorm< real_t >::Factory > imp_abs_criterion
std::shared_ptr< ConvergenceLogger > convergence_logger
real_t GetFinalNorm() const
std::shared_ptr< gko::stop::ResidualNorm< real_t >::Factory > rel_criterion
int GetNumIterations() const
bool needs_sorted_diagonal_mat
const std::shared_ptr< gko::LinOpFactory > GetFactory() const
std::shared_ptr< ResidualLogger > residual_logger
GinkgoIterativeSolver(GinkgoExecutor &exec, bool use_implicit_res_norm)
void SetPrintLevel(int print_lvl)
std::shared_ptr< gko::stop::ImplicitResidualNorm< real_t >::Factory > imp_rel_criterion
std::shared_ptr< gko::LinOpFactory > solver_gen
virtual ~GinkgoIterativeSolver()=default
std::shared_ptr< gko::Executor > executor
std::shared_ptr< gko::LinOp > solver
void SetOperator(const Operator &op) override
std::shared_ptr< gko::Executor > executor
const std::shared_ptr< gko::LinOpFactory > GetFactory() const
void Mult(const Vector &x, Vector &y) const override
virtual ~GinkgoPreconditioner()=default
std::shared_ptr< gko::LinOp > generated_precond
bool HasGeneratedPreconditioner() const
std::shared_ptr< gko::experimental::mpi::communicator > gko_comm
bool has_generated_precond
GinkgoPreconditioner(GinkgoExecutor &exec)
std::shared_ptr< gko::LinOpFactory > precond_gen
const std::shared_ptr< gko::LinOp > GetGeneratedPreconditioner() const
IRSolver(GinkgoExecutor &exec)
IcIsaiPreconditioner(GinkgoExecutor &exec, const std::string &factorization_type="exact", const int sweeps=0, const int sparsity_power=1, const bool skip_sort=false)
IcPreconditioner(GinkgoExecutor &exec, const std::string &factorization_type="exact", const int sweeps=0, const bool skip_sort=false)
IluIsaiPreconditioner(GinkgoExecutor &exec, const std::string &factorization_type="exact", const int sweeps=0, const int sparsity_power=1, const bool skip_sort=false)
IluPreconditioner(GinkgoExecutor &exec, const std::string &factorization_type="exact", const int sweeps=0, const bool skip_sort=false)
JacobiPreconditioner(GinkgoExecutor &exec, const std::string &storage_opt="none", const real_t accuracy=1.e-1, const int max_block_size=32)
MFEMPreconditioner(GinkgoExecutor &exec, const Solver &mfem_precond)
void SetOperator(const Operator &op) override
OperatorWrapper(std::shared_ptr< const gko::Executor > exec, gko::size_type size=0, const Operator *oper=NULL)
void apply_impl(const gko::LinOp *b, gko::LinOp *x) const override
ParallelOperatorWrapper(std::shared_ptr< const gko::Executor > exec, gko::experimental::mpi::communicator comm, gko::size_type size=0, const Operator *oper=NULL)
void apply_impl(const gko::LinOp *b, gko::LinOp *x) const override
std::unique_ptr< gko::experimental::distributed::Vector< real_t > > create_submatrix_impl(gko::local_span rows, gko::local_span columns, gko::dim< 2 > global_size) override
static std::unique_ptr< ParallelVectorWrapper > create(std::shared_ptr< const gko::Executor > exec, gko::experimental::mpi::communicator comm, Ginkgo::VectorWrapper *wrapped_local_mfem_vec, HYPRE_BigInt global_rows, HYPRE_BigInt global_cols)
const Ginkgo::VectorWrapper * get_local_wrapped_vec_const() const
std::unique_ptr< gko::experimental::distributed::Vector< real_t > > create_with_same_config() const override
Ginkgo::VectorWrapper * get_local_wrapped_vec()
ParallelVectorWrapper(std::shared_ptr< const gko::Executor > exec, gko::experimental::mpi::communicator comm, Ginkgo::VectorWrapper *wrapped_local_mfem_vec, HYPRE_BigInt global_rows, HYPRE_BigInt global_cols)
std::unique_ptr< gko::experimental::distributed::Vector< real_t > > create_with_type_of_impl(std::shared_ptr< const gko::Executor > exec, const gko::dim< 2 > &global_size, const gko::dim< 2 > &local_size, gko::size_type stride) const override
ResidualLogger(bool compute_real_residual)
void on_iteration_complete(const gko::LinOp *op, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm) const override
const bool compute_real_residual
virtual void iteration_complete_core(const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm) const =0
void on_iteration_complete(const gko::LinOp *op, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *solution, const gko::LinOp *residual_norm) const override
void on_iteration_complete(const gko::LinOp *op, const gko::LinOp *rhs, const gko::LinOp *solution, const gko::size_type &iteration, const gko::LinOp *residual, const gko::LinOp *residual_norm, const gko::LinOp *implicit_sq_residual_norm, const gko::array< gko::stopping_status > *status, bool stopped) const override
std::vector< std::size_t > iterations
std::vector< real_t > residual_norms
void SetOperator(const Operator &op) override
SchwarzPreconditioner(GinkgoExecutor &exec, MPI_Comm comm, Solver &local_solver, const bool l1_smoother=false)
static std::unique_ptr< VectorWrapper > create(std::shared_ptr< const gko::Executor > exec, gko::size_type size, Vector *mfem_vec, bool ownership=false)
Vector & get_mfem_vec_ref()
std::unique_ptr< gko::matrix::Dense< real_t > > create_with_same_config() const override
std::unique_ptr< gko::matrix::Dense< real_t > > create_submatrix_impl(const gko::span &rows, const gko::span &columns, const gko::size_type stride) override
std::unique_ptr< gko::matrix::Dense< real_t > > create_with_type_of_impl(std::shared_ptr< const gko::Executor > exec, const gko::dim< 2 > &size, gko::size_type stride) const override
VectorWrapper(std::shared_ptr< const gko::Executor > exec, gko::size_type size, Vector *mfem_vec, bool ownership=false)
const Vector & get_mfem_vec_const_ref() const
void operator()(pointer ptr) const noexcept
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void MakeRef(Vector &base, int offset, int size)
Reset the Vector to be a reference to a sub-vector of base.
real_t get_norm(const gko::matrix::Dense< ValueType > *norm)
std::conditional_t< sizeof(HYPRE_BigInt)==sizeof(std::int32_t), std::int32_t, std::conditional_t< sizeof(HYPRE_BigInt)==sizeof(std::int64_t), std::int64_t, void > > gko_hypre_bigint
std::conditional_t< sizeof(HYPRE_Int)==sizeof(std::int32_t), std::int32_t, std::conditional_t< sizeof(HYPRE_Int)==sizeof(std::int64_t), std::int64_t, void > > gko_hypre_int
gko::array< T > gko_array
real_t compute_norm(const VecType *b)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
struct schwarz_common schwarz
MFEM_HOST_DEVICE real_t norm(const Complex &z)