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.
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.