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 "The system matrix in binary format")(
200 "The right-hand side in binary format")(
202 po::value<string>()->required(),
203 "Partitioning of the problem in MatrixMarket format")(
206 "The pressure mask in binary format. Or, if the parameter has "
207 "the form '%n:m', then each (n+i*m)-th variable is treated as pressure.")(
210 "parameter file in json format")(
212 po::value<std::vector<string>>()->multitoken(),
213 "Parameters specified as name=value pairs. "
214 "May be provided multiple times. Examples:\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.
Distributed Schur complement pressure correction preconditioner.
Distributed solver based on subdomain deflation.
Class to store parameters as a hierarchical key/value tree.
Allows to use an AMG smoother as standalone preconditioner.
Standalone version of IMessagePassingMng associated to a MPI Communicator.
Describes a set of command-line options.
Stores parsed option values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Convenience wrapper around MPI_Comm.
Alina::detail::empty_params params
Pointwise constant deflation vectors.