20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
23#include <boost/range/iterator_range.hpp>
25#include "arccore/alina/IO.h"
26#include "arccore/alina/Adapters.h"
27#include "arccore/alina/BuiltinBackend.h"
28#include "arccore/alina/DistributedPreconditionedSolver.h"
29#include "arccore/alina/DistributedCPRPreconditioner.h"
30#include "arccore/alina/DistributedAMG.h"
31#include "arccore/alina/DistributedCoarseningRuntime.h"
32#include "arccore/alina/DistributedRelaxationRuntime.h"
33#include "arccore/alina/DistributedSolverRuntime.h"
34#include "arccore/alina/DistributedDirectSolverRuntime.h"
35#include "arccore/alina/MatrixPartitionerRuntime.h"
36#include "arccore/alina/Profiler.h"
37#include "arccore/alina/AlinaUtils.h"
39#include "arccore/common/internal/ProgramOptions.h"
42using namespace Arcane::Alina;
44using Alina::precondition;
49 const std::string& A_file,
const std::string& rhs_file,
int block_size,
50 std::vector<ptrdiff_t>& ptr,
51 std::vector<ptrdiff_t>& col,
52 std::vector<double>& val,
53 std::vector<double>& rhs)
56 ptrdiff_t n = A_mm.rows();
58 ptrdiff_t chunk = (n + comm.size - 1) / comm.size;
59 if (chunk % block_size != 0) {
60 chunk += block_size - chunk % block_size;
63 ptrdiff_t row_beg = std::min(n, chunk * comm.rank);
64 ptrdiff_t row_end = std::min(n, row_beg + chunk);
66 chunk = row_end - row_beg;
68 A_mm(ptr, col, val, row_beg, row_end);
70 if (rhs_file.empty()) {
72 std::fill(rhs.begin(), rhs.end(), 1.0);
76 rhs_mm(rhs, row_beg, row_end);
85 const std::string& A_file,
const std::string& rhs_file,
int block_size,
86 std::vector<ptrdiff_t>& ptr,
87 std::vector<ptrdiff_t>& col,
88 std::vector<double>& val,
89 std::vector<double>& rhs)
91 ptrdiff_t n = Alina::IO::crs_size<ptrdiff_t>(A_file);
93 ptrdiff_t chunk = (n + comm.size - 1) / comm.size;
94 if (chunk % block_size != 0) {
95 chunk += block_size - chunk % block_size;
98 ptrdiff_t row_beg = std::min(n, chunk * comm.rank);
99 ptrdiff_t row_end = std::min(n, row_beg + chunk);
101 chunk = row_end - row_beg;
103 Alina::IO::read_crs(A_file, n, ptr, col, val, row_beg, row_end);
105 if (rhs_file.empty()) {
107 std::fill(rhs.begin(), rhs.end(), 1.0);
110 ptrdiff_t rows, cols;
111 Alina::IO::read_dense(rhs_file, rows, cols, rhs, row_beg, row_end);
118template <
class Backend,
class Matrix>
119std::shared_ptr<Alina::DistributedMatrix<Backend>>
122 Alina::eMatrixPartitionerType ptype,
int block_size = 1)
124 auto& prof = Alina::Profiler::globalProfiler();
127 auto A = std::make_shared<DMatrix>(comm, Astrip);
129 if (comm.size == 1 || ptype == Alina::eMatrixPartitionerType::merge)
132 prof.tic(
"partition");
134 prm.put(
"type", ptype);
137 auto I = part(*A, block_size);
138 auto J = transpose(*I);
139 A = product(*J, *product(*A, *I));
141 std::vector<double> new_rhs(J->loc_rows());
143 J->move_to_backend(bprm);
145 Alina::backend::spmv(1, *J, rhs, 0, new_rhs);
147 prof.toc(
"partition");
154int main(
int argc,
char* argv[])
156 auto& prof = Alina::Profiler::globalProfiler();
162 std::cout <<
"World size: " << comm.size << std::endl;
165 namespace po = Arcane::ProgramOptions;
168 desc.add_options()(
"help,h",
"affiche l'aide");
169 desc.add_options()(
"matrix,A",
170 po::value<std::string>(),
171 "Matrice du système au format MatrixMarket. "
172 "Si non spécifié, un problème de Poisson dans un cube unitaire 3D est assemblé. ");
173 desc.add_options()(
"rhs,f",
174 po::value<std::string>()->default_value(
""),
175 "Le vecteur du membre de droite (RHS) au format MatrixMarket. "
176 "S'il est omis, un vecteur de uns est utilisé par défaut. "
177 "Ne doit être fourni qu'avec une matrice de système. ");
178 desc.add_options()(
"binary,B",
179 po::bool_switch()->default_value(
false),
180 "Si spécifié, traiter les fichiers d'entrée comme binaires au lieu de MatrixMarket. "
181 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ");
182 desc.add_options()(
"block-size,b",
183 po::value<int>()->default_value(1),
184 "La taille de bloc de la matrice de système. ");
185 desc.add_options()(
"partitioner,r",
186 po::value<Alina::eMatrixPartitionerType>()->default_value(
187#
if defined(ARCCORE_ALINA_HAVE_PARMETIS)
188 Alina::eMatrixPartitionerType::parmetis
191 "Répartition de la matrice de système");
192 desc.add_options()(
"prm-file,P",
193 po::value<std::string>(),
194 "Fichier de paramètres au format json. ");
195 desc.add_options()(
"prm,p",
196 po::value<std::vector<std::string>>()->multitoken(),
197 "Paramètres spécifiés sous forme de paires nom=valeur. "
198 "Peut être fourni plusieurs fois. Exemples :\n"
199 " -p solver.tol=1e-3\n"
200 " -p precond.coarse_enough=300");
203 po::store(po::parse_command_line(argc, argv, desc), vm);
206 if (vm.count(
"help")) {
208 std::cout << desc << std::endl;
213 if (vm.count(
"prm-file")) {
214 prm.read_json(vm[
"prm-file"].as<std::string>());
217 if (vm.count(
"prm")) {
218 for (
const std::string& v : vm[
"prm"].as<std::vector<std::string>>()) {
224 std::vector<ptrdiff_t> ptr;
225 std::vector<ptrdiff_t> col;
226 std::vector<double> val;
227 std::vector<double> rhs;
229 int block_size = vm[
"block-size"].as<
int>();
230 prm.put(
"precond.block_size", block_size);
233 if (vm[
"binary"].as<bool>()) {
234 n = read_binary(comm,
235 vm[
"matrix"].as<std::string>(),
236 vm[
"rhs"].as<std::string>(),
237 block_size, ptr, col, val, rhs);
240 n = read_matrix_market(comm,
241 vm[
"matrix"].as<std::string>(),
242 vm[
"rhs"].as<std::string>(),
243 block_size, ptr, col, val, rhs);
249 auto A = partition<Backend>(comm,
251 vm[
"partitioner"].as<Alina::eMatrixPartitionerType>(),
269 Solver solve(context, comm, A, prm);
273 std::cout << solve << std::endl;
275 std::vector<double> x(rhs.size(), 0.0);
281 if (comm.rank == 0) {
282 std::cout <<
"Itérations: " << r.nbIteration() << std::endl
283 <<
"Erreur: " << r.residual() << std::endl
284 << prof << std::endl;
Algebraic multigrid method.
Distributed CPR preconditioner.
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.
Matrix class, to be used by user.
static Ref< IMessagePassingMng > createAndInitializeMPI(int *argc, char **argv[], int wanted_thread_level)
Initialise MPI et créé un gestionnaire associé au communicateur MPI_WORLD_COMM.
Décrit un ensemble d'options en ligne de commande.
Stocke les valeurs d'options analysées.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Wrapper de commodité autour de MPI_Comm.
Use a relaxation as a distributed preconditioner.
Alina::detail::empty_params params
Distributed memory sparse approximate inverse relaxation scheme.
Runtime-configurable wrapper around matrix partitioner.