14#include "AlinaUtils.h"
15#include "arccore/alina/RelaxationRuntime.h"
16#include "arccore/alina/CoarseningRuntime.h"
17#include "arccore/alina/SolverRuntime.h"
18#include "arccore/alina/PreconditionedSolver.h"
19#include "arccore/alina/PreconditionerRuntime.h"
20#include "arccore/alina/DistributedSolverRuntime.h"
21#include "arccore/alina/DistributedPreconditioner.h"
22#include "arccore/alina/BuiltinBackend.h"
23#include "arccore/alina/AlinaLib.h"
24#include "arccore/alina/DistributedPreconditionedSolver.h"
26#include "arccore/message_passing/IMessagePassingMng.h"
28#include "arccore/trace/ITraceMng.h"
30#include "arccore/base/NotSupportedException.h"
31#include "arccore/base/NotImplementedException.h"
39namespace Arcane::AlinaLib
41using Arcane::IMessagePassingMng;
47using Backend = Alina::BuiltinBackend<double, Int32, Int32>;
48using PreconditionerType = Alina::PreconditionerRuntime<Backend>;
49using SequentialSolverType = Alina::PreconditionedSolver<PreconditionerType, Alina::SolverRuntime<Backend>>;
53using DistributedSolverType = Alina::DistributedPreconditionedSolver<Alina::DistributedPreconditioner<Backend>,
54 Alina::DistributedSolverRuntime<Backend>>;
56typedef double (*AlinaDefVecFunction)(
int vec, ptrdiff_t coo,
void* data);
67 _toConvInfo(
const Alina::SolverResult& r)
70 x.iterations = r.nbIteration();
71 x.residual = r.residual();
79void AlinaCSRMatrixView::
80dump(std::ostream& o)
const
82 const AlinaCSRMatrixView& matrix_view = *
this;
83 Int32 nb_row = matrix_view.nbRow();
84 const auto default_precision{ o.precision() };
85 constexpr auto max_precision{ std::numeric_limits<long double>::digits10 + 1 };
86 o << std::setprecision(max_precision);
87 o <<
"MATRIX nb_row=" << nb_row <<
"\n";
88 auto rows_index = matrix_view.rowIndexes();
89 auto columns = matrix_view.columns();
90 auto values = matrix_view.values();
91 for (
Int32 i = 0; i < nb_row; ++i) {
92 Int32 begin = rows_index[i];
93 Int32 end = rows_index[i + 1];
94 o <<
"ROW I=" << i <<
" index0=" << begin <<
" index1=" << end <<
"\n";
95 for (
Int32 z = begin; z < end; ++z) {
96 o <<
" C=" << std::setw(8) << columns[z] <<
" V=" << values[z] <<
"\n";
99 o << std::setprecision(default_precision);
126 m_p->m_properties.put(name, value);
132 m_p->m_properties.put(name, value);
138 m_p->m_properties.put(name, value);
142setString(
const char* name,
const char* value)
144 m_p->m_properties.put(name, value);
157class AlinaSolverParametersImpl
164 m_message_passing_mng =
makeRef(mpm);
166 tm = arccoreCreateDefaultTraceMng();
183 m_p = std::make_shared<AlinaSolverParametersImpl>(
nullptr,
nullptr);
192 m_p = std::make_shared<AlinaSolverParametersImpl>(mpm,tm);
198AlinaSolverParameters::
199~AlinaSolverParameters()
209 return m_p->m_trace_mng.get();
218 m_p->m_properties.put(name, value);
224 m_p->m_properties.put(name, value);
230 m_p->m_properties.put(name, value);
234setString(
const char* name,
const char* value)
236 m_p->m_properties.put(name, value);
249void AlinaSolverParameters::
252 m_p->m_properties.put(
"solver.abstol", value);
254void AlinaSolverParameters::
257 m_p->m_properties.put(
"solver.tol", value);
259void AlinaSolverParameters::
262 m_p->m_properties.put(
"solver.maxiter", value);
264void AlinaSolverParameters::
267 m_p->m_properties.put(
"solver.verbose", value);
273void AlinaSolverParameters::
274setSolverPreconditioner(eAlinaPreconditionerType v)
276 auto& x = m_p->m_properties;
278 case eAlinaPreconditionerType::AMG:
279 x.put(
"precond.class",
"amg");
281 case eAlinaPreconditionerType::Diagonal:
282 x.put(
"precond.class",
"relaxation");
283 x.put(
"precond.relax.type",
"spai0");
291void AlinaSolverParameters::
292setSolverType(eAlinaSolverType v)
294 const char* name =
nullptr;
296 case eAlinaSolverType::ConjugateGradient:
299 case eAlinaSolverType::BiCGStab:
302 case eAlinaSolverType::GMRES:
307 ARCCORE_THROW(NotSupportedException,
"Invalid value '{0}' for solver type",
static_cast<int>(v));
308 m_p->m_properties.put(
"solver.type", name);
317 Int32 nb_row = nbRow();
318 Int32 n1 = m_row_indexes.size();
319 if (n1 != (nb_row + 1))
320 ARCCORE_FATAL(
"Bad size '{0}' for rowIndexes() (expected value = {1})", n1, nb_row + 1);
321 Int32 nb_value = m_row_indexes[nb_row];
322 Int32 n2 = m_columns.size();
323 Int32 n3 = m_values.size();
325 ARCCORE_FATAL(
"Bad size '{0}' for columns() (expected value = {1})", n2, nb_value);
327 ARCCORE_FATAL(
"Bad size '{0}' for values() (expected value = {1})", n3, nb_value);
336class AlinaPreconditionerImpl
340 explicit AlinaPreconditionerImpl(PreconditionerType* preconditioner)
341 : m_preconditioner(preconditioner)
343 ~AlinaPreconditionerImpl()
345 delete m_preconditioner;
348 PreconditionerType* m_preconditioner =
nullptr;
355AlinaPreconditioner(
int n,
365 auto A = std::make_tuple(n, ptr_range, col_range, val_range);
367 PreconditionerType* amg =
nullptr;
370 amg =
new PreconditionerType(context, A, prm->m_p->m_properties);
372 amg =
new PreconditionerType(context, A);
373 m_p = std::make_shared<AlinaPreconditionerImpl>(amg);
380apply(
const double* rhs,
double* x)
382 PreconditionerType* amg = m_p->m_preconditioner;
384 size_t n = Alina::backend::nbRow(amg->system_matrix());
389 amg->apply(rhs_range, x_range);
398 std::cout << *(m_p->m_preconditioner) << std::endl;
420 virtual void report(std::ostream& o) = 0;
428class AlinaSequentialSolverImpl
438 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
439 matrix_view.columns(), matrix_view.values());
442 m_solver =
new SequentialSolverType(context, A, prm.m_p->m_properties);
444 tm->
info() <<
"Printing solver infos\n"
445 << (*m_solver) <<
"\n"
446 <<
"PARAMS: " << prm.m_p->m_properties;
448 m_solver->prm.get(ptree);
449 tm->
info() <<
"SOLVER_PARAMS: " << ptree;
451 ~AlinaSequentialSolverImpl()
override
459 return _toConvInfo(r);
465 SequentialSolverType* slv = m_solver;
470 if (n != matrix_view.nbRow())
471 ARCCORE_FATAL(
"Bad number of rows v={0} expected={1}", matrix_view.nbRow(), n);
473 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
474 matrix_view.columns(), matrix_view.values());
478 return _toConvInfo(r);
480 void report(std::ostream& o)
override
482 o << m_solver->precond() <<
"\n";
487 SequentialSolverType* m_solver =
nullptr;
495class AlinaDistributedSolverImpl
508 auto A = std::make_tuple(matrix_view.nbRow(), matrix_view.rowIndexes(),
509 matrix_view.columns(), matrix_view.values());
513 m_solver =
new DistributedSolverType(context, mpi_comm, A, prm);
516 tm->
info() <<
"Printing solver infos\n"
517 << (*m_solver) <<
"\n"
518 <<
"PARAMS: " << params.m_p->m_properties;
520 m_solver->prm.get(ptree);
521 tm->
info() <<
"SOLVER_PARAMS: " << ptree;
523 ~AlinaDistributedSolverImpl()
536 return _toConvInfo(r);
545 void report([[maybe_unused]] std::ostream& o)
override
551 DistributedSolverType* m_solver =
nullptr;
565 m_p = std::make_shared<AlinaDistributedSolverImpl>(matrix_view, parameters);
568 m_p = std::make_shared<AlinaSequentialSolverImpl>(matrix_view, parameters);
577 m_p->report(std::cout);
586 return m_p->solve(rhs, x);
597 return m_p->solveMatrix(matrix_view, rhs, x);
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_THROW(exception_class,...)
Macro to throw an exception with formatting.
CSR Matrix view used in AlinaLib.
void checkSizes() const
Check that sizes are valid:
Handle parameters for Alina.
void setInt64(const char *name, Int64 value)
Set Int64 parameter in the parameter list.
void setString(const char *name, const char *value)
Set floating point parameter in the parameter list.
void setInt32(const char *name, Int32 value)
Set Int32 parameter in the parameter list.
void readFromJSON(const char *fname)
Read parameters from a JSON file.
void setReal(const char *name, Real value)
Set floating point parameter in the parameter list.
void report()
Printout preconditioner structure.
void apply(const double *rhs, double *x)
Apply AMG preconditioner (x = M^(-1) * rhs).
Handle parameters for solvers.
void readFromJSON(const char *fname)
Read parameters from a JSON file.
void setString(const char *name, const char *value)
Set floating point parameter in the parameter list.
void setInt32(const char *name, Int32 value)
Set Int32 parameter in the parameter list.
void setReal(const char *name, Real value)
Set floating point parameter in the parameter list.
void setInt64(const char *name, Int64 value)
Set Int64 parameter in the parameter list.
AlinaSolverParameters()
Create a sequential solver.
AlinaSolver(const AlinaSolverParameters ¶ms, const AlinaCSRMatrixView &matrix_view)
Create a solver.
void report()
Printout solver structure.
AlinaConvergenceInfo solveMatrix(const AlinaCSRMatrixView &matrix_view, SmallSpan< const double > rhs, SmallSpan< double > x)
Solve the problem for the given matrix and the right-hand side.
AlinaConvergenceInfo solve(SmallSpan< const double > rhs, SmallSpan< double > x)
Find solution for the given RHS.
size_t size() const
Returns the size of the system matrix.
Class to store parameters as a hierarchical key/value tree.
virtual TraceMessage info()=0
Stream for an information message.
Interface of the message passing manager.
Exception when a function is not implemented.
Reference to an instance.
View of an array of elements of type T.
std::int64_t Int64
Signed integer type of 64 bits.
double Real
Type representing a real number.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.
Convenience wrapper around MPI_Comm.