20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
23#include "arccore/alina/AMG.h"
24#include "arccore/alina/CoarseningRuntime.h"
25#include "arccore/alina/RelaxationRuntime.h"
26#include "arccore/alina/DistributedSubDomainDeflation.h"
27#include "arccore/alina/DistributedSolverRuntime.h"
28#include "arccore/alina/DistributedDirectSolverRuntime.h"
29#include "arccore/alina/Profiler.h"
31#include "arccore/common/internal/ProgramOptions.h"
44using namespace Arcane::Alina;
46using Alina::precondition;
51 const std::string& A_file,
52 const std::string& rhs_file,
53 const std::string& part_file,
55 std::vector<ptrdiff_t>& ptr,
56 std::vector<ptrdiff_t>& col,
57 std::vector<double>& val,
58 std::vector<double>& rhs)
61 std::vector<int> part;
62 std::vector<ptrdiff_t> domain(world.size + 1, 0);
67 std::ifstream f(part_file.c_str());
68 precondition(f,
"Failed to open part file (" + part_file +
")");
70 while (std::getline(f, line)) {
73 std::istringstream is(line);
75 precondition(is >> n >> cols,
"Unsupported format in matrix file");
79 precondition(n,
"Zero sized partition vector");
80 precondition(n % block_size == 0,
"Matrix size is not divisible by block_size");
84 while (std::getline(f, line)) {
87 std::istringstream is(line);
89 precondition(is >> p,
"Unsupported format in part file");
90 precondition(p < world.size,
"MPI world does not correspond to partition");
96 std::partial_sum(domain.begin(), domain.end(), domain.begin());
99 ptrdiff_t chunk_beg = domain[world.rank];
100 ptrdiff_t chunk_end = domain[world.rank + 1];
101 ptrdiff_t chunk = chunk_end - chunk_beg;
104 std::vector<ptrdiff_t> order(n);
106 for (ptrdiff_t i = 0; i < n; ++i) {
113 std::rotate(domain.begin(), domain.end() - 1, domain.end());
119 std::ifstream A(A_file.c_str());
120 precondition(A,
"Failed to open matrix file (" + A_file +
")");
123 while (std::getline(A, line)) {
126 std::istringstream is(line);
128 precondition(is >> rows >> m >> nnz,
"Unsupported format in matrix file");
129 precondition(rows == n,
"Matrix and partition have incompatible sizes");
130 precondition(n == m,
"Non-square matrix in matrix file");
135 std::vector<ptrdiff_t> I, J;
136 std::vector<double> V;
139 ptr.resize(chunk + 1, 0);
141 while (std::getline(A, line)) {
144 std::istringstream is(line);
147 precondition(is >> i >> j >> v,
"Unsupported format in matrix file");
151 if (part[i] != world.rank)
154 ++ptr[order[i] + 1 - chunk_beg];
156 I.push_back(order[i] - chunk_beg);
157 J.push_back(order[j]);
161 std::partial_sum(ptr.begin(), ptr.end(), ptr.begin());
163 ptrdiff_t loc_nnz = ptr.back();
170 for (ptrdiff_t i = 0; i < loc_nnz; ++i) {
171 ptrdiff_t row = I[i];
172 col[ptr[row]] = J[i];
173 val[ptr[row]] = V[i];
176 std::rotate(ptr.begin(), ptr.end() - 1, ptr.end());
183 std::ifstream f(rhs_file.c_str());
184 precondition(f,
"Failed to open rhs file (" + rhs_file +
")");
186 while (std::getline(f, line)) {
189 std::istringstream is(line);
190 ptrdiff_t rows, cols;
191 precondition(is >> rows >> cols,
"Unsupported format in matrix file");
192 precondition(rows == n,
"RHS size should coincide with matrix size");
200 while (std::getline(f, line)) {
203 std::istringstream is(line);
205 precondition(is >> v,
"Unsupported format in RHS file");
207 if (part[pos++] != world.rank)
213 assert(rhs.size() + 1 == ptr.size());
220int main(
int argc,
char* argv[])
222 auto& prof = Alina::Profiler::globalProfiler();
228 std::cout <<
"World size: " << world.size << std::endl;
231 auto coarsening = Alina::eCoarserningType::smoothed_aggregation;
232 auto relaxation = Alina::eRelaxationType::spai0;
233 auto iterative_solver = Alina::eSolverType::bicgstabl;
234 auto direct_solver = Alina::eDistributedDirectSolverType::skyline_lu;
235 std::string parameter_file;
236 std::string A_file =
"A.mtx";
237 std::string rhs_file =
"b.mtx";
238 std::string part_file =
"partition.mtx";
239 std::string out_file;
241 namespace po = Arcane::ProgramOptions;
244 desc.add_options()(
"help,h",
"show help");
245 desc.add_options()(
"coarsening,c",
246 po::value<Alina::eCoarserningType>(&coarsening)->default_value(coarsening),
247 "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin");
248 desc.add_options()(
"relaxation,r",
249 po::value<Alina::eRelaxationType>(&relaxation)->default_value(relaxation),
250 "gauss_seidel, ilu0, damped_jacobi, spai0, chebyshev");
251 desc.add_options()(
"iter_solver,i",
252 po::value<Alina::eSolverType>(&iterative_solver)->default_value(iterative_solver),
253 "cg, bicgstab, bicgstabl, gmres");
254 desc.add_options()(
"dir_solver,d",
255 po::value<Alina::eDistributedDirectSolverType>(&direct_solver)->default_value(direct_solver),
257 desc.add_options()(
"params,p",
258 po::value<std::string>(¶meter_file),
259 "parameter file in json format");
260 desc.add_options()(
"matrix,A",
261 po::value<std::string>(&A_file)->default_value(A_file),
262 "The system matrix in MatrixMarket format");
263 desc.add_options()(
"rhs,b",
264 po::value<std::string>(&rhs_file)->default_value(rhs_file),
265 "The right-hand side in MatrixMarket format");
266 desc.add_options()(
"part,s",
267 po::value<std::string>(&part_file)->default_value(part_file),
268 "Partitioning of the problem in MatrixMarket format");
269 desc.add_options()(
"output,o",
270 po::value<std::string>(&out_file),
271 "The output file (saved in MatrixMarket format)");
274 po::store(po::parse_command_line(argc, argv, desc), vm);
277 if (vm.count(
"help")) {
279 std::cout << desc << std::endl;
284 if (vm.count(
"params"))
285 prm.read_json(parameter_file);
287 prm.put(
"local.coarsening.type", coarsening);
288 prm.put(
"local.relax.type", relaxation);
289 prm.put(
"isolver.type", iterative_solver);
290 prm.put(
"dsolver.type", direct_solver);
292 int block_size = prm.get(
"precond.coarsening.aggr.block_size", 1);
294 prof.tic(
"read problem");
295 std::vector<ptrdiff_t> ptr;
296 std::vector<ptrdiff_t> col;
297 std::vector<double> val;
298 std::vector<double> rhs;
300 std::vector<ptrdiff_t> domain = read_problem(
301 world, A_file, rhs_file, part_file, block_size, ptr, col, val, rhs);
303 ptrdiff_t chunk = domain[world.rank + 1] - domain[world.rank];
304 prof.toc(
"read problem");
316 prm.put(
"num_def_vec", block_size);
317 prm.put(
"def_vec", &dv);
319 SDD solve(context, world, std::tie(chunk, ptr, col, val), prm);
320 double tm_setup = prof.toc(
"setup");
322 std::vector<double> x(chunk, 0);
327 std::tie(iters, resid) = solve(rhs, x);
328 double tm_solve = prof.toc(
"solve");
330 if (vm.count(
"output")) {
332 for (
int r = 0; r < world.size; ++r) {
333 if (r == world.rank) {
334 std::ofstream f(out_file.c_str(), r == 0 ? std::ios::trunc : std::ios::app);
337 f <<
"%%MatrixMarket matrix array real general\n"
338 << domain.back() <<
" 1\n";
341 std::ostream_iterator<double> oi(f,
"\n");
342 std::copy(x.begin(), x.end(), oi);
349 if (world.rank == 0) {
350 std::cout <<
"Iterations: " << iters << std::endl
351 <<
"Error: " << resid << std::endl
353 << prof << std::endl;
Algebraic multigrid method.
Runtime wrapper for distributed direct solvers.
Distributed solver based on subdomain deflation.
Class to store parameters as a hierarchical key/value tree.
static Ref< IMessagePassingMng > createAndInitializeMPI(int *argc, char **argv[], int wanted_thread_level)
Initialize MPI and creates a manager associated with the MPI_WORLD_COMM communicator.
Describes a set of command-line options.
Stores parsed option values.
Reference to an instance.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Convenience wrapper around MPI_Comm.
Runtime configurable relaxation.
Pointwise constant deflation vectors.