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.
Class to store parameters as a hierarchical key/value tree.
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.