20#pragma GCC diagnostic ignored "-Wdeprecated-copy"
21#pragma GCC diagnostic ignored "-Wint-in-bool-context"
23#include <boost/range/iterator_range.hpp>
24#include <boost/scope_exit.hpp>
26#include "arccore/alina/IO.h"
27#include "arccore/alina/Adapters.h"
28#include "arccore/alina/BuiltinBackend.h"
29#include "arccore/alina/DistributedPreconditionedSolver.h"
30#include "arccore/alina/DistributedCPRPreconditioner.h"
31#include "arccore/alina/DistributedAMG.h"
32#include "arccore/alina/DistributedCoarseningRuntime.h"
33#include "arccore/alina/DistributedRelaxationRuntime.h"
34#include "arccore/alina/DistributedSolverRuntime.h"
35#include "arccore/alina/DistributedDirectSolverRuntime.h"
36#include "arccore/alina/MatrixPartitionerRuntime.h"
37#include "arccore/alina/Profiler.h"
38#include "arccore/alina/AlinaUtils.h"
40#include "arccore/common/internal/ProgramOptions.h"
43using namespace Arcane::Alina;
45using Alina::precondition;
50 const std::string& A_file,
const std::string& rhs_file,
int block_size,
51 std::vector<ptrdiff_t>& ptr,
52 std::vector<ptrdiff_t>& col,
53 std::vector<double>& val,
54 std::vector<double>& rhs)
57 ptrdiff_t n = A_mm.rows();
59 ptrdiff_t chunk = (n + comm.size - 1) / comm.size;
60 if (chunk % block_size != 0) {
61 chunk += block_size - chunk % block_size;
64 ptrdiff_t row_beg = std::min(n, chunk * comm.rank);
65 ptrdiff_t row_end = std::min(n, row_beg + chunk);
67 chunk = row_end - row_beg;
69 A_mm(ptr, col, val, row_beg, row_end);
71 if (rhs_file.empty()) {
73 std::fill(rhs.begin(), rhs.end(), 1.0);
77 rhs_mm(rhs, row_beg, row_end);
86 const std::string& A_file,
const std::string& rhs_file,
int block_size,
87 std::vector<ptrdiff_t>& ptr,
88 std::vector<ptrdiff_t>& col,
89 std::vector<double>& val,
90 std::vector<double>& rhs)
92 ptrdiff_t n = Alina::IO::crs_size<ptrdiff_t>(A_file);
94 ptrdiff_t chunk = (n + comm.size - 1) / comm.size;
95 if (chunk % block_size != 0) {
96 chunk += block_size - chunk % block_size;
99 ptrdiff_t row_beg = std::min(n, chunk * comm.rank);
100 ptrdiff_t row_end = std::min(n, row_beg + chunk);
102 chunk = row_end - row_beg;
104 Alina::IO::read_crs(A_file, n, ptr, col, val, row_beg, row_end);
106 if (rhs_file.empty()) {
108 std::fill(rhs.begin(), rhs.end(), 1.0);
111 ptrdiff_t rows, cols;
112 Alina::IO::read_dense(rhs_file, rows, cols, rhs, row_beg, row_end);
119template <
class Backend,
class Matrix>
120std::shared_ptr<Alina::DistributedMatrix<Backend>>
123 Alina::eMatrixPartitionerType ptype,
int block_size = 1)
125 auto& prof = Alina::Profiler::globalProfiler();
128 auto A = std::make_shared<DMatrix>(comm, Astrip);
130 if (comm.size == 1 || ptype == Alina::eMatrixPartitionerType::merge)
133 prof.tic(
"partition");
135 prm.put(
"type", ptype);
138 auto I = part(*A, block_size);
139 auto J = transpose(*I);
140 A = product(*J, *product(*A, *I));
142 std::vector<double> new_rhs(J->loc_rows());
144 J->move_to_backend(bprm);
146 Alina::backend::spmv(1, *J, rhs, 0, new_rhs);
148 prof.toc(
"partition");
155int main(
int argc,
char* argv[])
157 auto& prof = Alina::Profiler::globalProfiler();
159 MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
160 BOOST_SCOPE_EXIT(
void)
169 std::cout <<
"World size: " << comm.size << std::endl;
172 namespace po = Arcane::ProgramOptions;
175 desc.add_options()(
"help,h",
"show help")(
"matrix,A",
176 po::value<std::string>(),
177 "System matrix in the MatrixMarket format. "
178 "When not specified, a Poisson problem in 3D unit cube is assembled. ")(
180 po::value<std::string>()->default_value(
""),
181 "The RHS vector in the MatrixMarket format. "
182 "When omitted, a vector of ones is used by default. "
183 "Should only be provided together with a system matrix. ")(
185 po::bool_switch()->default_value(
false),
186 "When specified, treat input files as binary instead of as MatrixMarket. "
187 "It is assumed the files were converted to binary format with mm2bin utility. ")(
189 po::value<int>()->default_value(1),
190 "The block size of the system matrix. ")(
192 po::value<Alina::eMatrixPartitionerType>()->default_value(
193#
if defined(ARCCORE_ALINA_HAVE_PARMETIS)
194 Alina::eMatrixPartitionerType::parmetis
197 "Repartition the system matrix")(
"prm-file,P",
198 po::value<std::string>(),
199 "Parameter file in json format. ")(
201 po::value<std::vector<std::string>>()->multitoken(),
202 "Parameters specified as name=value pairs. "
203 "May be provided multiple times. Examples:\n"
204 " -p solver.tol=1e-3\n"
205 " -p precond.coarse_enough=300");
208 po::store(po::parse_command_line(argc, argv, desc), vm);
211 if (vm.count(
"help")) {
213 std::cout << desc << std::endl;
218 if (vm.count(
"prm-file")) {
219 prm.read_json(vm[
"prm-file"].as<std::string>());
222 if (vm.count(
"prm")) {
223 for (
const std::string& v : vm[
"prm"].as<std::vector<std::string>>()) {
229 std::vector<ptrdiff_t> ptr;
230 std::vector<ptrdiff_t> col;
231 std::vector<double> val;
232 std::vector<double> rhs;
234 int block_size = vm[
"block-size"].as<
int>();
235 prm.put(
"precond.block_size", block_size);
238 if (vm[
"binary"].as<bool>()) {
239 n = read_binary(comm,
240 vm[
"matrix"].as<std::string>(),
241 vm[
"rhs"].as<std::string>(),
242 block_size, ptr, col, val, rhs);
245 n = read_matrix_market(comm,
246 vm[
"matrix"].as<std::string>(),
247 vm[
"rhs"].as<std::string>(),
248 block_size, ptr, col, val, rhs);
254 auto A = partition<Backend>(comm,
256 vm[
"partitioner"].as<Alina::eMatrixPartitionerType>(),
274 Solver solve(comm, A, prm);
278 std::cout << solve << std::endl;
280 std::vector<double> x(rhs.size(), 0.0);
286 if (comm.rank == 0) {
287 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
288 <<
"Error: " << r.residual() << std::endl
289 << prof << std::endl;
Algebraic multigrid method.
Distributed CPR preconditioner.
Runtime wrapper for distributed direct solvers.
Distributed Matrix using message passing.
Iterative solver wrapper for distributed linear systems.
Matrix class, to be used by user.
Describes a set of command-line options.
Stores parsed option values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Use a relaxation as a distributed preconditioner.
Alina::detail::empty_params params
Distributed memory sparse approximate inverse relaxation scheme.
Runtime-configurable wrapper around matrix partitioner.
Convenience wrapper around MPI_Comm.