20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
33#include <boost/scope_exit.hpp>
35#include <boost/program_options.hpp>
37#include "arccore/alina/AMG.h"
38#include "arccore/alina/CoarseningRuntime.h"
39#include "arccore/alina/RelaxationRuntime.h"
40#include "arccore/alina/DistributedSubDomainDeflation.h"
41#include "arccore/alina/DistributedSolverRuntime.h"
42#include "arccore/alina/DistributedDirectSolverRuntime.h"
43#include "arccore/alina/Profiler.h"
46using namespace Arcane::Alina;
48using Alina::precondition;
53 const std::string& A_file,
54 const std::string& rhs_file,
55 const std::string& part_file,
57 std::vector<ptrdiff_t>& ptr,
58 std::vector<ptrdiff_t>& col,
59 std::vector<double>& val,
60 std::vector<double>& rhs)
63 std::vector<int> part;
64 std::vector<ptrdiff_t> domain(world.size + 1, 0);
69 std::ifstream f(part_file.c_str());
70 precondition(f,
"Failed to open part file (" + part_file +
")");
72 while (std::getline(f, line)) {
75 std::istringstream is(line);
77 precondition(is >> n >> cols,
"Unsupported format in matrix file");
81 precondition(n,
"Zero sized partition vector");
82 precondition(n % block_size == 0,
"Matrix size is not divisible by block_size");
86 while (std::getline(f, line)) {
89 std::istringstream is(line);
91 precondition(is >> p,
"Unsupported format in part file");
92 precondition(p < world.size,
"MPI world does not correspond to partition");
98 std::partial_sum(domain.begin(), domain.end(), domain.begin());
101 ptrdiff_t chunk_beg = domain[world.rank];
102 ptrdiff_t chunk_end = domain[world.rank + 1];
103 ptrdiff_t chunk = chunk_end - chunk_beg;
106 std::vector<ptrdiff_t> order(n);
108 for (ptrdiff_t i = 0; i < n; ++i) {
115 std::rotate(domain.begin(), domain.end() - 1, domain.end());
121 std::ifstream A(A_file.c_str());
122 precondition(A,
"Failed to open matrix file (" + A_file +
")");
125 while (std::getline(A, line)) {
128 std::istringstream is(line);
130 precondition(is >> rows >> m >> nnz,
"Unsupported format in matrix file");
131 precondition(rows == n,
"Matrix and partition have incompatible sizes");
132 precondition(n == m,
"Non-square matrix in matrix file");
137 std::vector<ptrdiff_t> I, J;
138 std::vector<double> V;
141 ptr.resize(chunk + 1, 0);
143 while (std::getline(A, line)) {
146 std::istringstream is(line);
149 precondition(is >> i >> j >> v,
"Unsupported format in matrix file");
153 if (part[i] != world.rank)
156 ++ptr[order[i] + 1 - chunk_beg];
158 I.push_back(order[i] - chunk_beg);
159 J.push_back(order[j]);
163 std::partial_sum(ptr.begin(), ptr.end(), ptr.begin());
165 ptrdiff_t loc_nnz = ptr.back();
172 for (ptrdiff_t i = 0; i < loc_nnz; ++i) {
173 ptrdiff_t row = I[i];
174 col[ptr[row]] = J[i];
175 val[ptr[row]] = V[i];
178 std::rotate(ptr.begin(), ptr.end() - 1, ptr.end());
185 std::ifstream f(rhs_file.c_str());
186 precondition(f,
"Failed to open rhs file (" + rhs_file +
")");
188 while (std::getline(f, line)) {
191 std::istringstream is(line);
192 ptrdiff_t rows, cols;
193 precondition(is >> rows >> cols,
"Unsupported format in matrix file");
194 precondition(rows == n,
"RHS size should coincide with matrix size");
202 while (std::getline(f, line)) {
205 std::istringstream is(line);
207 precondition(is >> v,
"Unsupported format in RHS file");
209 if (part[pos++] != world.rank)
215 assert(rhs.size() + 1 == ptr.size());
222int main(
int argc,
char* argv[])
224 auto& prof = Alina::Profiler::globalProfiler();
226 MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
227 BOOST_SCOPE_EXIT(
void)
236 std::cout <<
"World size: " << world.size << std::endl;
239 auto coarsening = Alina::eCoarserningType::smoothed_aggregation;
240 auto relaxation = Alina::eRelaxationType::spai0;
241 auto iterative_solver = Alina::eSolverType::bicgstabl;
242 auto direct_solver = Alina::eDistributedDirectSolverType::skyline_lu;
243 std::string parameter_file;
244 std::string A_file =
"A.mtx";
245 std::string rhs_file =
"b.mtx";
246 std::string part_file =
"partition.mtx";
247 std::string out_file;
249 namespace po = boost::program_options;
250 po::options_description desc(
"Options");
252 desc.add_options()(
"help,h",
"show help")(
254 po::value<Alina::eCoarserningType>(&coarsening)->default_value(coarsening),
255 "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin")(
257 po::value<Alina::eRelaxationType>(&relaxation)->default_value(relaxation),
258 "gauss_seidel, ilu0, damped_jacobi, spai0, chebyshev")(
260 po::value<Alina::eSolverType>(&iterative_solver)->default_value(iterative_solver),
261 "cg, bicgstab, bicgstabl, gmres")(
263 po::value<Alina::eDistributedDirectSolverType>(&direct_solver)->default_value(direct_solver),
265#ifdef ARCCORE_ALINA_HAVE_PASTIX
270 po::value<std::string>(¶meter_file),
271 "parameter file in json format")(
273 po::value<std::string>(&A_file)->default_value(A_file),
274 "The system matrix in MatrixMarket format")(
276 po::value<std::string>(&rhs_file)->default_value(rhs_file),
277 "The right-hand side in MatrixMarket format")(
279 po::value<std::string>(&part_file)->default_value(part_file),
280 "Partitioning of the problem in MatrixMarket format")(
282 po::value<std::string>(&out_file),
283 "The output file (saved in MatrixMarket format)");
285 po::variables_map vm;
286 po::store(po::parse_command_line(argc, argv, desc), vm);
289 if (vm.count(
"help")) {
291 std::cout << desc << std::endl;
296 if (vm.count(
"params"))
297 prm.read_json(parameter_file);
299 prm.put(
"local.coarsening.type", coarsening);
300 prm.put(
"local.relax.type", relaxation);
301 prm.put(
"isolver.type", iterative_solver);
302 prm.put(
"dsolver.type", direct_solver);
304 int block_size = prm.get(
"precond.coarsening.aggr.block_size", 1);
306 prof.tic(
"read problem");
307 std::vector<ptrdiff_t> ptr;
308 std::vector<ptrdiff_t> col;
309 std::vector<double> val;
310 std::vector<double> rhs;
312 std::vector<ptrdiff_t> domain = read_problem(
313 world, A_file, rhs_file, part_file, block_size, ptr, col, val, rhs);
315 ptrdiff_t chunk = domain[world.rank + 1] - domain[world.rank];
316 prof.toc(
"read problem");
327 prm.put(
"num_def_vec", block_size);
328 prm.put(
"def_vec", &dv);
330 SDD solve(world, std::tie(chunk, ptr, col, val), prm);
331 double tm_setup = prof.toc(
"setup");
333 std::vector<double> x(chunk, 0);
338 std::tie(iters, resid) = solve(rhs, x);
339 double tm_solve = prof.toc(
"solve");
341 if (vm.count(
"output")) {
343 for (
int r = 0; r < world.size; ++r) {
344 if (r == world.rank) {
345 std::ofstream f(out_file.c_str(), r == 0 ? std::ios::trunc : std::ios::app);
348 f <<
"%%MatrixMarket matrix array real general\n"
349 << domain.back() <<
" 1\n";
352 std::ostream_iterator<double> oi(f,
"\n");
353 std::copy(x.begin(), x.end(), oi);
360 if (world.rank == 0) {
361 std::cout <<
"Iterations: " << iters << std::endl
362 <<
"Error: " << resid << std::endl
364 << prof << std::endl;
Algebraic multigrid method.
Runtime wrapper for distributed direct solvers.
Distributed solver based on subdomain deflation.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Runtime configurable relaxation.
Pointwise constant deflation vectors.
Convenience wrapper around MPI_Comm.