20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
31#include <boost/program_options.hpp>
32#include <boost/range/iterator_range.hpp>
33#include <boost/scope_exit.hpp>
35#if defined(SOLVER_BACKEND_CUDA)
36# include "arccore/alina/CudaBackend.h"
37# include "arccore/alina/relaxation_cusparse_ilu0.h"
40# ifndef SOLVER_BACKEND_BUILTIN
41# define SOLVER_BACKEND_BUILTIN
43#include "arccore/alina/BuiltinBackend.h"
47#include "arccore/alina/IO.h"
48#include "arccore/alina/Adapters.h"
49#include "arccore/alina/AMG.h"
50#include "arccore/alina/CoarseningRuntime.h"
51#include "arccore/alina/RelaxationRuntime.h"
52#include "arccore/alina/DistributedPreconditionedSolver.h"
53#include "arccore/alina/DistributedSchurPressureCorrection.h"
54#include "arccore/alina/DistributedPreconditioner.h"
55#include "arccore/alina/DistributedSubDomainDeflation.h"
56#include "arccore/alina/DistributedSolverRuntime.h"
57#include "arccore/alina/DistributedDirectSolverRuntime.h"
58#include "arccore/alina/Profiler.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();
184 MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
185 BOOST_SCOPE_EXIT(
void)
194 std::cout <<
"World size: " << world.size << std::endl;
197 namespace po = boost::program_options;
199 po::options_description desc(
"Options");
201 desc.add_options()(
"help,h",
"show help")(
203 po::value<string>()->required(),
204 "The system matrix in binary format")(
207 "The right-hand side in binary format")(
209 po::value<string>()->required(),
210 "Partitioning of the problem in MatrixMarket format")(
213 "The pressure mask in binary format. Or, if the parameter has "
214 "the form '%n:m', then each (n+i*m)-th variable is treated as pressure.")(
217 "parameter file in json format")(
219 po::value<std::vector<string>>()->multitoken(),
220 "Parameters specified as name=value pairs. "
221 "May be provided multiple times. Examples:\n"
222 " -p solver.tol=1e-3\n"
223 " -p precond.coarse_enough=300");
225 po::variables_map vm;
226 po::store(po::parse_command_line(argc, argv, desc), vm);
228 if (vm.count(
"help")) {
230 std::cout << desc << std::endl;
237 if (vm.count(
"params"))
238 prm.read_json(vm[
"params"].as<string>());
240 if (vm.count(
"prm")) {
241 for (
const string& v : vm[
"prm"].as<std::vector<string>>()) {
246 prof.tic(
"read problem");
247 std::vector<ptrdiff_t> ptr;
248 std::vector<ptrdiff_t> col;
249 std::vector<double> val;
250 std::vector<double> rhs;
252 std::vector<ptrdiff_t> domain = read_problem(
254 vm[
"matrix"].as<string>(), vm[
"rhs"].as<string>(), vm[
"part"].as<string>(),
257 ptrdiff_t chunk = domain[world.rank + 1] - domain[world.rank];
258 prof.toc(
"read problem");
260 std::vector<char> pm;
261 if (vm.count(
"pmask")) {
262 std::string pmask = vm[
"pmask"].as<
string>();
263 prm.put(
"precond.pmask_size", chunk);
269 prm.put(
"precond.pmask_pattern", pmask);
272 precondition(
false,
"Pressure mask may only be set with a pattern");
277 prm.put(
"precond.psolver.num_def_vec", 1);
278 prm.put(
"precond.psolver.def_vec", &dv);
282#if defined(SOLVER_BACKEND_VEXCL)
283 vex::Context ctx(vex::Filter::Env);
284 std::cout << ctx << std::endl;
286#elif defined(SOLVER_BACKEND_CUDA)
287 cusparseCreate(&bprm.cusparse_handle);
290 auto f = Backend::copy_vector(rhs, bprm);
291 auto x = Backend::create_vector(chunk, bprm);
293 Alina::backend::clear(*x);
311 Solver solve(world, std::tie(chunk, ptr, col, val), prm, bprm);
312 double tm_setup = prof.toc(
"setup");
316 double tm_solve = prof.toc(
"solve");
318 if (world.rank == 0) {
319 std::cout <<
"Iters: " << r.nbIteration() << std::endl
320 <<
"Error: " << r.residual() << std::endl
321 << prof << std::endl;
Algebraic multigrid method.
Distributed block preconditioner.
Runtime wrapper for distributed direct solvers.
Iterative solver wrapper for distributed linear systems.
Distributed Schur complement pressure correction preconditioner.
Distributed solver based on subdomain deflation.
Allows to use an AMG smoother as standalone preconditioner.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Alina::detail::empty_params params
Pointwise constant deflation vectors.
Convenience wrapper around MPI_Comm.