19#include "arccore/alina/BuiltinBackend.h"
20#include "arccore/alina/StaticMatrix.h"
21#include "arccore/alina/Adapters.h"
22#include "arccore/alina/MessagePassingUtils.h"
23#include "arccore/alina/DistributedPreconditionedSolver.h"
24#include "arccore/alina/DistributedPreconditioner.h"
25#include "arccore/alina/DistributedSolverRuntime.h"
27#include "arccore/alina/IO.h"
28#include "arccore/alina/Profiler.h"
30#include "arccore/common/internal/ProgramOptions.h"
32#include "arccore/trace/ITraceMng.h"
34#include "AlinaSamplesCommon.h"
42namespace math = Alina::math;
47 ptrdiff_t n,
int block_size,
48 std::vector<ptrdiff_t>& ptr,
49 std::vector<ptrdiff_t>& col,
50 std::vector<double>& val,
51 std::vector<double>& rhs)
53 ptrdiff_t n3 = n * n * n;
55 ptrdiff_t chunk = (n3 + comm.size - 1) / comm.size;
56 if (chunk % block_size != 0) {
57 chunk += block_size - chunk % block_size;
59 ptrdiff_t row_beg = std::min(n3, chunk * comm.rank);
60 ptrdiff_t row_end = std::min(n3, row_beg + chunk);
61 chunk = row_end - row_beg;
64 ptr.reserve(chunk + 1);
66 col.reserve(chunk * 7);
68 val.reserve(chunk * 7);
71 std::fill(rhs.begin(), rhs.end(), 1.0);
73 const double h2i = (n - 1) * (n - 1);
76 for (ptrdiff_t idx = row_beg; idx < row_end; ++idx) {
77 ptrdiff_t k = idx / (n * n);
78 ptrdiff_t j = (idx / n) % n;
79 ptrdiff_t i = idx % n;
82 col.push_back(idx - n * n);
87 col.push_back(idx - n);
92 col.push_back(idx - 1);
97 val.push_back(6 * h2i);
100 col.push_back(idx + 1);
105 col.push_back(idx + n);
110 col.push_back(idx + n * n);
114 ptr.push_back(col.size());
121template <
class Backend,
class Matrix>
122std::shared_ptr<Alina::DistributedMatrix<Backend>>
125 Alina::eMatrixPartitionerType ptype,
int block_size = 1)
127 auto& prof = Alina::Profiler::globalProfiler();
128 typedef typename Backend::value_type val_type;
129 typedef typename Alina::math::rhs_of<val_type>::type rhs_type;
132 auto A = std::make_shared<DMatrix>(comm, Astrip);
134 if (comm.size == 1 || ptype == Alina::eMatrixPartitionerType::merge)
137 prof.tic(
"partition");
139 prm.put(
"type", ptype);
142 auto I = part(*A, block_size);
144 A = product(*J, *product(*A, *I));
148 J->move_to_backend(bprm);
150 Alina::backend::spmv(1, *J, rhs, 0, new_rhs);
152 prof.toc(
"partition");
160 const std::vector<ptrdiff_t>& ptr,
161 const std::vector<ptrdiff_t>& col,
162 const std::vector<double>& val,
164 const std::vector<double>& f,
165 Alina::eMatrixPartitionerType ptype)
167 auto& prof = Alina::Profiler::globalProfiler();
170 using BackendValueType = double;
173 std::cout <<
"Using scalar solve ptr_size=" <<
sizeof(ptrdiff_t)
174 <<
" ptr_type_size=" <<
sizeof(Backend::ptr_type)
175 <<
" col_type_size=" <<
sizeof(Backend::col_type)
176 <<
" value_type_size=" <<
sizeof(Backend::value_type)
197 auto get_distributed_matrix = [&]() {
198 auto t = prof.scoped_tic(
"distributed matrix");
199 std::shared_ptr<DMatrix> A;
201 if (ptype != Alina::eMatrixPartitionerType::merge) {
202 A = partition<Backend>(comm,
203 std::tie(chunk, ptr, col, val), rhs, bprm, ptype,
204 prm.get(
"precond.coarsening.aggr.block_size", 1));
205 chunk = A->loc_rows();
208 A = std::make_shared<DMatrix>(comm, std::tie(chunk, ptr, col, val));
214 std::shared_ptr<DMatrix> A;
215 std::shared_ptr<Solver> solve;
218 auto t = prof.scoped_tic(
"setup");
219 A = get_distributed_matrix();
220 solve = std::make_shared<Solver>(comm, A, prm, bprm);
222 solve->prm.get(prm2);
223 std::cout <<
"SOLVER parameters=" << prm2 <<
"\n";
226 if (comm.rank == 0) {
227 std::cout <<
"SolverInfo:\n";
228 std::cout << *solve << std::endl;
231 if (prm.get(
"precond.allow_rebuild",
false)) {
232 if (comm.rank == 0) {
233 std::cout <<
"Rebuilding the preconditioner..." << std::endl;
237 auto t = prof.scoped_tic(
"rebuild");
238 A = get_distributed_matrix();
239 solve->precond().rebuild(A);
242 if (comm.rank == 0) {
243 std::cout << *solve << std::endl;
253 if (comm.rank == 0) {
254 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
255 <<
"Error: " << r.residual() << std::endl
256 << prof << std::endl;
264 auto& prof = Alina::Profiler::globalProfiler();
269 tm->
info() <<
"World size: " << comm.size;
272 namespace po = Arcane::ProgramOptions;
275 auto default_partitioner_type = Alina::eMatrixPartitionerType::merge;
276#if defined(ARCCORE_ALINA_HAVE_PARMETIS)
277 default_partitioner_type = Alina::eMatrixPartitionerType::parmetis;
280 desc.add_options()(
"help,h",
"affiche l'aide")(
"matrix,A",
281 po::value<std::string>(),
282 "Matrice système au format MatrixMarket. "
283 "Si non spécifié, un problème de Poisson dans un cube unitaire 3D est assemblé. ");
284 desc.add_options()(
"partitioner,r",
285 po::value<Alina::eMatrixPartitionerType>()->default_value(
286 default_partitioner_type),
287 "Répartition de la matrice système");
288 desc.add_options()(
"size,n",
289 po::value<ptrdiff_t>()->default_value(32),
290 "taille du domaine");
291 desc.add_options()(
"prm-file,P", po::value<std::string>(),
292 "Fichier de paramètres au format json. ");
293 desc.add_options()(
"prm,p",
294 po::value<std::vector<std::string>>()->multitoken(),
295 "Paramètres spécifiés sous forme de paires nom=valeur. "
296 "Peut être fourni plusieurs fois. Exemples :\n"
297 " -p solver.tol=1e-3\n"
298 " -p precond.coarse_enough=300");
299 desc.add_options()(
"test-rebuild",
300 po::bool_switch()->default_value(
false),
301 "Lorsqu'il est spécifié, tente de reconstruire le solveur avant de résoudre. ");
310 if (vm.count(
"help")) {
312 std::cout << desc << std::endl;
317 if (vm.count(
"prm-file")) {
318 prm.read_json(vm[
"prm-file"].as<std::string>());
321 if (vm.count(
"prm")) {
322 for (
const std::string& v : vm[
"prm"].as<std::vector<std::string>>()) {
323 tm->
info() <<
"PUT_KEY_VALUE v=" << v;
329 std::vector<ptrdiff_t> ptr;
330 std::vector<ptrdiff_t> col;
331 std::vector<double> val;
332 std::vector<double> rhs;
334 Alina::eMatrixPartitionerType ptype = vm[
"partitioner"].as<Alina::eMatrixPartitionerType>();
336 prof.tic(
"assemble");
337 Int64 matrix_size = vm[
"size"].as<ptrdiff_t>();
338 tm->
info() <<
"Taille de la matrice=" << matrix_size;
339 n = assemble_poisson3d(comm, matrix_size, 1, ptr, col, val, rhs);
340 prof.toc(
"assemble");
342 if (vm[
"test-rebuild"].as<bool>()) {
343 prm.put(
"precond.allow_rebuild",
true);
346 solve_scalar(comm, n, ptr, col, val, prm, rhs, ptype);
353int main(
int argc,
char* argv[])
355 return Arcane::Alina::SampleMainContext::execMain(main2, argc, argv);
Runtime wrapper for distributed direct solvers.
Distributed Matrix using message passing.
Iterative solver wrapper for distributed linear systems.
Classe pour stocker les paramètres sous forme d'arbre hiérarchique clé/valeur.
NUMA-aware vector container.
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Matrix class, to be used by user.
Constructeur d'analyseur d'arguments en ligne de commande fluide.
Décrit un ensemble d'options en ligne de commande.
Décrit les arguments positionnels (non-options).
Stocke les valeurs d'options analysées.
Espace de nom pour les fonctions mathématiques.
__host__ __device__ Real3x3 transpose(const Real3x3 &t)
Transpose la matrice.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Alina::detail::empty_params params
Distributed smoothed aggregation coarsening scheme.
Runtime-configurable wrapper around matrix partitioner.
Wrapper de commodité autour de MPI_Comm.