20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
31#include <boost/range/iterator_range.hpp>
33#if defined(SOLVER_BACKEND_CUDA)
34# include "arccore/alina/CudaBackend.h"
35# include "arccore/alina/relaxation_cusparse_ilu0.h"
38# ifndef SOLVER_BACKEND_BUILTIN
39# define SOLVER_BACKEND_BUILTIN
41#include "arccore/alina/BuiltinBackend.h"
45#include "arccore/alina/IO.h"
46#include "arccore/alina/Adapters.h"
47#include "arccore/alina/AMG.h"
48#include "arccore/alina/CoarseningRuntime.h"
49#include "arccore/alina/RelaxationRuntime.h"
50#include "arccore/alina/DistributedPreconditionedSolver.h"
51#include "arccore/alina/DistributedSchurPressureCorrection.h"
52#include "arccore/alina/DistributedPreconditioner.h"
53#include "arccore/alina/DistributedSubDomainDeflation.h"
54#include "arccore/alina/DistributedSolverRuntime.h"
55#include "arccore/alina/DistributedDirectSolverRuntime.h"
56#include "arccore/alina/Profiler.h"
58#include "arccore/common/internal/ProgramOptions.h"
61using namespace Arcane::Alina;
63using Alina::precondition;
68 const std::string& A_file,
69 const std::string& rhs_file,
70 const std::string& part_file,
71 std::vector<ptrdiff_t>& ptr,
72 std::vector<ptrdiff_t>& col,
73 std::vector<double>& val,
74 std::vector<double>& rhs)
78 std::vector<ptrdiff_t> domain(world.size + 1, 0);
79 std::vector<int> part;
84 precondition(p < world.size,
"MPI world does not correspond to partition");
86 std::partial_sum(domain.begin(), domain.end(), domain.begin());
88 ptrdiff_t chunk_beg = domain[world.rank];
89 ptrdiff_t chunk_end = domain[world.rank + 1];
90 ptrdiff_t chunk = chunk_end - chunk_beg;
93 std::vector<ptrdiff_t> order(n);
94 for (ptrdiff_t i = 0; i < n; ++i)
95 order[i] = domain[part[i]]++;
97 std::rotate(domain.begin(), domain.end() - 1, domain.end());
102 using namespace Arcane::Alina::IO;
104 std::ifstream A(A_file.c_str(), std::ios::binary);
105 precondition(A,
"Failed to open matrix file (" + A_file +
")");
107 std::ifstream b(rhs_file.c_str(), std::ios::binary);
108 precondition(b,
"Failed to open rhs file (" + rhs_file +
")");
111 precondition(read(A, rows),
"File I/O error");
112 precondition(rows == n,
"Matrix and partition have incompatible sizes");
115 ptr.reserve(chunk + 1);
118 std::vector<ptrdiff_t> gptr(n + 1);
119 precondition(read(A, gptr),
"File I/O error");
121 size_t col_beg =
sizeof(rows) +
sizeof(gptr[0]) * (n + 1);
122 size_t val_beg = col_beg +
sizeof(col[0]) * gptr.back();
123 size_t rhs_beg = 2 *
sizeof(ptrdiff_t);
126 for (ptrdiff_t i = 0; i < n; ++i)
127 if (part[i] == world.rank)
128 ptr.push_back(gptr[i + 1] - gptr[i]);
130 std::partial_sum(ptr.begin(), ptr.end(), ptr.begin());
133 col.reserve(ptr.back());
135 val.reserve(ptr.back());
140 for (ptrdiff_t i = 0; i < n; ++i) {
141 if (part[i] != world.rank)
145 A.seekg(col_beg + gptr[i] *
sizeof(c));
146 for (ptrdiff_t j = gptr[i], e = gptr[i + 1]; j < e; ++j) {
147 precondition(read(A, c),
"File I/O error (1)");
148 col.push_back(order[c]);
152 for (ptrdiff_t i = 0; i < n; ++i) {
153 if (part[i] != world.rank)
157 A.seekg(val_beg + gptr[i] *
sizeof(v));
158 for (ptrdiff_t j = gptr[i], e = gptr[i + 1]; j < e; ++j) {
159 precondition(read(A, v),
"File I/O error (2)");
164 for (ptrdiff_t i = 0; i < n; ++i) {
165 if (part[i] != world.rank)
169 b.seekg(rhs_beg + i *
sizeof(f));
170 precondition(read(b, f),
"File I/O error (3)");
179int main(
int argc,
char* argv[])
181 auto& prof = Alina::Profiler::globalProfiler();
183 auto mpm = StandaloneMpi::createAndInitializeMPI(&argc, &argv, MPI_THREAD_MULTIPLE);
187 std::cout <<
"World size: " << world.size << std::endl;
190 namespace po = Arcane::ProgramOptions;
194 desc.add_options()(
"help,h",
"show help")(
196 po::value<string>()->required(),
197 "La matrice du système au format binaire")(
200 "Le membre de droite au format binaire")(
202 po::value<string>()->required(),
203 "Partitionnement du problème au format MatrixMarket")(
206 "Le masque de pression au format binaire. Ou, si le paramètre a "
207 "la forme '%n:m', alors chaque variable (n+i*m)-ième est traitée comme une pression.")(
210 "fichier de paramètres au format json")(
212 po::value<std::vector<string>>()->multitoken(),
213 "Paramètres spécifiés sous forme de paires nom=valeur. "
214 "Peut être fourni plusieurs fois. Exemples :\n"
215 " -p solver.tol=1e-3\n"
216 " -p precond.coarse_enough=300");
219 po::store(po::parse_command_line(argc, argv, desc), vm);
221 if (vm.count(
"help")) {
223 std::cout << desc << std::endl;
230 if (vm.count(
"params"))
231 prm.read_json(vm[
"params"].as<string>());
233 if (vm.count(
"prm")) {
234 for (
const string& v : vm[
"prm"].as<std::vector<string>>()) {
239 prof.tic(
"read problem");
240 std::vector<ptrdiff_t> ptr;
241 std::vector<ptrdiff_t> col;
242 std::vector<double> val;
243 std::vector<double> rhs;
245 std::vector<ptrdiff_t> domain = read_problem(
247 vm[
"matrix"].as<string>(), vm[
"rhs"].as<string>(), vm[
"part"].as<string>(),
250 ptrdiff_t chunk = domain[world.rank + 1] - domain[world.rank];
251 prof.toc(
"read problem");
253 std::vector<char> pm;
254 if (vm.count(
"pmask")) {
255 std::string pmask = vm[
"pmask"].as<
string>();
256 prm.put(
"precond.pmask_size", chunk);
262 prm.put(
"precond.pmask_pattern", pmask);
265 precondition(
false,
"Pressure mask may only be set with a pattern");
270 prm.put(
"precond.psolver.num_def_vec", 1);
271 prm.put(
"precond.psolver.def_vec", &dv);
275#if defined(SOLVER_BACKEND_VEXCL)
276 vex::Context ctx(vex::Filter::Env);
277 std::cout << ctx << std::endl;
279#elif defined(SOLVER_BACKEND_CUDA)
280 cusparseCreate(&bprm.cusparse_handle);
283 auto f = Backend::copy_vector(rhs, bprm);
284 auto x = Backend::create_vector(chunk, bprm);
286 Alina::backend::clear(*x);
304 Solver solve(context, world, std::tie(chunk, ptr, col, val), prm, bprm);
305 double tm_setup = prof.toc(
"setup");
309 double tm_solve = prof.toc(
"solve");
311 if (world.rank == 0) {
312 std::cout <<
"Iters: " << r.nbIteration() << std::endl
313 <<
"Error: " << r.residual() << std::endl
314 << prof << std::endl;
Algebraic multigrid method.
Distributed block preconditioner.
Runtime wrapper for distributed direct solvers.
Iterative solver wrapper for distributed linear systems.
Préconditionneur de correction de pression par complément de Schur distribué.
Solveur distribué basé sur la déflation de sous-domaines.
Classe pour stocker les paramètres sous forme d'arbre hiérarchique clé/valeur.
Allows to use an AMG smoother as standalone preconditioner.
Version autonome de IMessagePassingMng associée à un communicateur MPI.
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.
Alina::detail::empty_params params
Vecteurs de déflation constants ponctuels.