25#include <boost/range/iterator_range.hpp>
26#include <boost/scope_exit.hpp>
28#include "arccore/alina/BuiltinBackend.h"
29#include "arccore/alina/PreconditionerRuntime.h"
30#include "arccore/alina/Adapters.h"
31#include "arccore/alina/DistributedPreconditionedSolver.h"
32#include "arccore/alina/DistributedSolverRuntime.h"
33#include "arccore/alina/DistributedPreconditioner.h"
34#include "arccore/alina/Profiler.h"
35#include "arccore/alina/AlinaUtils.h"
38#include "arccore/alina/DistributedSolver.h"
41#include "arccore/alina/DistributedRelaxationRuntime.h"
43#include "arccore/common/internal/ProgramOptions.h"
45#include "DomainPartition.h"
48using namespace Arcane::Alina;
50using Alina::precondition;
55 const DomainPartition<2>& part;
56 const std::vector<ptrdiff_t>& dom;
58 renumbering(
const DomainPartition<2>& p,
59 const std::vector<ptrdiff_t>& d)
64 ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j)
const
66 boost::array<ptrdiff_t, 2> p = { { i, j } };
67 std::pair<int, ptrdiff_t> v = part.index(p);
68 return dom[v.first] + v.second;
74template <
template <
class>
class Precond,
class Matrix>
80 auto& prof = Alina::Profiler::globalProfiler();
86 const size_t n = Alina::backend::nbRow(A);
88 std::vector<double> rhs(n, 1), x(n, 0);
91 Solver solve(comm, A, prm);
95 auto t2 = prof.scoped_tic(
"solve");
102int main(
int argc,
char* argv[])
104 auto& prof = Alina::Profiler::globalProfiler();
105 namespace po = Arcane::ProgramOptions;
112 desc.add_options()(
"help,h",
"Show this help.")(
"prm-file,P",
114 "Parameter file in json format. ")(
116 po::value<vector<string>>()->multitoken(),
117 "Parameters specified as name=value pairs. "
118 "May be provided multiple times. Examples:\n"
119 " -p solver.tol=1e-3\n"
120 " -p precond.coarse_enough=300")(
122 po::value<int>()->default_value(1024),
123 "The size of the Poisson problem to solve. "
124 "Specified as number of grid nodes along each dimension of a unit square. "
125 "The resulting system will have n*n unknowns. ")(
127 po::bool_switch()->default_value(
false),
128 "When specified, the AMG hierarchy is not constructed. "
129 "Instead, the problem is solved using a single-level smoother as preconditioner. ")(
131 po::value<double>()->default_value(0),
132 "Value to use as initial approximation. ");
135 po::store(po::parse_command_line(argc, argv, desc), vm);
138 if (vm.count(
"help")) {
139 std::cout << desc << std::endl;
144 if (vm.count(
"prm-file")) {
145 prm.read_json(vm[
"prm-file"].as<string>());
148 if (vm.count(
"prm")) {
154 MPI_Init(&argc, &argv);
155 BOOST_SCOPE_EXIT(
void)
164 std::cout <<
"World size: " << world.size << std::endl;
166 const ptrdiff_t n = vm[
"size"].as<
int>();
167 const double h2i = (n - 1) * (n - 1);
169 boost::array<ptrdiff_t, 2> lo = { { 0, 0 } };
170 boost::array<ptrdiff_t, 2> hi = { { n - 1, n - 1 } };
172 prof.tic(
"partition");
173 DomainPartition<2> part(lo, hi, world.size);
174 ptrdiff_t chunk = part.size(world.rank);
176 std::vector<ptrdiff_t> domain(world.size + 1);
179 mpAllGather(world.m_message_passing_mng.get(),send_buf,receive_buf);
180 std::partial_sum(domain.begin(), domain.end(), domain.begin());
182 lo = part.domain(world.rank).min_corner();
183 hi = part.domain(world.rank).max_corner();
184 prof.toc(
"partition");
188 prof.tic(
"assemble");
189 std::vector<ptrdiff_t> ptr;
190 std::vector<ptrdiff_t> col;
191 std::vector<double> val;
192 std::vector<double> rhs;
194 ptr.reserve(chunk + 1);
195 col.reserve(chunk * 5);
196 val.reserve(chunk * 5);
200 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
201 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
203 col.push_back(renum(i, j - 1));
208 col.push_back(renum(i - 1, j));
212 col.push_back(renum(i, j));
213 val.push_back(4 * h2i);
216 col.push_back(renum(i + 1, j));
221 col.push_back(renum(i, j + 1));
225 ptr.push_back(col.size());
228 prof.toc(
"assemble");
230 bool single_level = vm[
"single-level"].as<
bool>();
233 prm.put(
"precond.class",
"relaxation");
235 Alina::SolverResult r = solve<Alina::PreconditionerRuntime>(world, prm, std::tie(chunk, ptr, col, val));
237 if (world.rank == 0) {
238 std::cout <<
"Iterations: " << r.nbIteration() << std::endl
239 <<
"Error: " << r.residual() << std::endl
241 << prof << std::endl;
Iterative solver wrapper for distributed linear systems.
Class to store parameters as a hierarchical key/value tree.
Modifiable view of an array of type T.
Constant view of an array of type T.
Matrix class, to be used by user.
Describes a set of command-line options.
Stores parsed option values.
void mpAllGather(IMessagePassingMng *pm, const ISerializer *send_serializer, ISerializer *receive_serialize)
allGather() message for serialization
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Convenience wrapper around MPI_Comm.