19#include "arccore/alina/BuiltinBackend.h"
20#include "arccore/alina/RelaxationRuntime.h"
21#include "arccore/alina/CoarseningRuntime.h"
22#include "arccore/alina/SolverRuntime.h"
23#include "arccore/alina/PreconditionerRuntime.h"
24#include "arccore/alina/DeflatedSolver.h"
25#include "arccore/alina/AMG.h"
26#include "arccore/alina/Adapters.h"
27#include "arccore/alina/IO.h"
28#include "arccore/alina/Profiler.h"
30#include "arccore/common/internal/ProgramOptions.h"
37using Alina::precondition;
40int main(
int argc,
char* argv[])
42 auto& prof = Alina::Profiler::globalProfiler();
44 namespace po = Arcane::ProgramOptions;
45 namespace io = Alina::IO;
53 desc.add_options()(
"help,h",
"Show this help.");
54 desc.add_options()(
"prm-file,P",
56 "Parameter file in json format. ");
57 desc.add_options()(
"prm,p",
58 po::value<vector<string>>()->multitoken(),
59 "Parameters specified as name=value pairs. "
60 "May be provided multiple times. Examples:\n"
61 " -p solver.tol=1e-3\n"
62 " -p precond.coarse_enough=300");
63 desc.add_options()(
"matrix,A",
64 po::value<string>()->required(),
65 "System matrix in the MatrixMarket format.");
66 desc.add_options()(
"rhs,f",
68 "The RHS vector in the MatrixMarket format. "
69 "When omitted, a vector of ones is used by default. "
70 "Should only be provided together with a system matrix. ");
71 desc.add_options()(
"scale,s",
72 po::bool_switch()->default_value(
false),
73 "Scale the matrix so that the diagonal is unit. ");
74 desc.add_options()(
"null,N",
76 "Starting null-vectors in the MatrixMarket format. ");
77 desc.add_options()(
"numvec,n",
78 po::value<int>()->default_value(3),
79 "The number of near nullspace vectors to search for. ");
80 desc.add_options()(
"binary,B",
81 po::bool_switch()->default_value(
false),
82 "When specified, treat input files as binary instead of as MatrixMarket. "
83 "It is assumed the files were converted to binary format with mm2bin utility. ");
84 desc.add_options()(
"output,o",
86 "Output the computed nullspace to the MatrixMarket file.");
95 if (vm.count(
"help")) {
96 std::cout << desc << std::endl;
100 for (
int i = 0; i < argc; ++i) {
103 std::cout << argv[i];
105 std::cout << std::endl;
108 if (vm.count(
"prm-file")) {
109 prm.read_json(vm[
"prm-file"].as<string>());
112 if (vm.count(
"prm")) {
113 for (
const string& v : vm[
"prm"].as<vector<string>>()) {
118 ptrdiff_t rows, nv = 0, numvec = vm[
"numvec"].as<
int>();
119 vector<ptrdiff_t> ptr, col;
120 vector<double> val, rhs;
121 std::list<std::vector<double>> Z;
124 auto t = prof.scoped_tic(
"read");
126 string Afile = vm[
"matrix"].as<
string>();
127 bool binary = vm[
"binary"].as<
bool>();
130 io::read_crs(Afile, rows, ptr, col, val);
134 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
135 precondition(rows == cols,
"Non-square system matrix");
138 if (vm.count(
"rhs")) {
139 string bfile = vm[
"rhs"].as<
string>();
144 io::read_dense(bfile, n, m, rhs);
147 std::tie(n, m) = io::mm_reader(bfile)(rhs);
150 precondition(n == rows && m == 1,
"The RHS vector has wrong size");
153 rhs.resize(rows, 1.0);
156 if (vm.count(
"null")) {
157 string nfile = vm[
"null"].as<
string>();
159 std::vector<double> null;
163 io::read_dense(nfile, m, nv, null);
166 std::tie(m, nv) = io::mm_reader(nfile)(null);
169 precondition(m == rows,
"Near null-space vectors have wrong size");
171 for (ptrdiff_t i = 0; i < nv; ++i) {
172 Z.emplace_back(rows);
173 for (ptrdiff_t j = 0; j < rows; ++j) {
174 Z.back()[j] = null[j * nv + i];
180 if (vm[
"scale"].as<bool>()) {
181 auto t = prof.scoped_tic(
"scaling");
182 std::vector<double> dia(rows, 1.0);
184 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
186 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
188 d = 1 /
sqrt(val[j]);
195 for (ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(rows); ++i) {
197 for (ptrdiff_t j = ptr[i], e = ptr[i + 1]; j < e; ++j) {
198 val[j] *= dia[i] * dia[col[j]];
208 std::uniform_real_distribution<double> rnd(-1, 1);
209 std::vector<double> x(rows), zero(rows, 0.0);
211 auto A = std::tie(rows, ptr, col, val);
213 prm.put(
"solver.ns_search",
true);
216 for (
int k = nv; k < numvec; ++k) {
217 auto t = prof.scoped_tic(std::string(
"vector ") + std::to_string(k));
218 std::vector<double> N;
223 for (
const auto& z : Z) {
224 for (ptrdiff_t i = 0; i < rows; ++i) {
230 prm.put(
"precond.coarsening.nullspace.rows", rows);
231 prm.put(
"precond.coarsening.nullspace.cols", k);
232 prm.put(
"precond.coarsening.nullspace.B", N.data());
236 Solver S(context, A, prm);
239 std::cout << std::endl
240 <<
"-------------------------" << std::endl
241 <<
"-- Searching for vector " << k << std::endl
242 <<
"-------------------------" << std::endl
252 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
253 <<
"Error: " << r.residual() << std::endl;
256 for (
const auto& z : Z) {
257 double c = Alina::backend::inner_product(x, z) / Alina::backend::inner_product(z, z);
258 Alina::backend::axpby(-c, z, 1, x);
261 double nx =
sqrt(Alina::backend::inner_product(x, x));
269 std::vector<double> N(numvec * rows);
271 auto t = prof.scoped_tic(
"apply");
274 for (
const auto& z : Z) {
275 for (ptrdiff_t i = 0; i < rows; ++i) {
276 N[i * numvec + j] = z[i];
281 prm.put(
"precond.coarsening.nullspace.rows", rows);
282 prm.put(
"precond.coarsening.nullspace.cols", numvec);
283 prm.put(
"precond.coarsening.nullspace.B", N.data());
286 Solver S(context, A, prm);
289 std::cout << std::endl
290 <<
"-------------------------" << std::endl
291 <<
"-- Solving the system " << std::endl
292 <<
"-------------------------" << std::endl
295 Alina::backend::clear(x);
301 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
302 <<
"Error: " << r.residual() << std::endl;
305 if (vm.count(
"output")) {
306 auto t = prof.scoped_tic(
"write");
307 Alina::IO::mm_write(vm[
"output"].as<string>(), N.data(), rows, numvec);
310 std::cout << prof << std::endl;
Convenience class that bundles together a preconditioner and an iterative solver.
Class to store parameters as a hierarchical key/value tree.
Fluent command-line parser builder.
Describes a set of command-line options.
Describes positional (non-option) arguments.
Stores parsed option values.
apfloat sqrt(apfloat v)
Square root of v.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Runtime-configurable wrappers around iterative solvers.