31#if defined(SOLVER_BACKEND_CUDA)
40#include <boost/scope_exit.hpp>
42#if defined(SOLVER_BACKEND_CUDA)
43# include "arccore/alina/CudaBackend.h"
44# include "arccore/alina/relaxation_cusparse_ilu0.h"
47# ifndef SOLVER_BACKEND_BUILTIN
48# define SOLVER_BACKEND_BUILTIN
50#include "arccore/alina/BuiltinBackend.h"
54#include "arccore/trace/ITraceMng.h"
56#include "arccore/alina/DistributedDirectSolverRuntime.h"
57#include "arccore/alina/DistributedSolverRuntime.h"
58#include "arccore/alina/DistributedSubDomainDeflation.h"
59#include "arccore/alina/AMG.h"
60#include "arccore/alina/CoarseningRuntime.h"
61#include "arccore/alina/RelaxationRuntime.h"
62#include "arccore/alina/Profiler.h"
64#include "arccore/common/internal/ProgramOptions.h"
66#include "AlinaSamplesCommon.h"
69using namespace Arcane::Alina;
71#include "DomainPartition.h"
76 std::vector<double> x;
77 std::vector<double> y;
78 std::vector<double> z;
80 deflation_vectors(ptrdiff_t n,
size_t nv = 4)
87 size_t dim()
const {
return nv; }
89 double operator()(ptrdiff_t i,
int j)
const
107 const DomainPartition<3>& part;
108 const std::vector<ptrdiff_t>& dom;
110 renumbering(
const DomainPartition<3>& p,
111 const std::vector<ptrdiff_t>& d)
116 ptrdiff_t operator()(ptrdiff_t i, ptrdiff_t j, ptrdiff_t k)
const
118 boost::array<ptrdiff_t, 3> p = { { i, j, k } };
119 std::pair<int, ptrdiff_t> v = part.index(p);
120 return dom[v.first] + v.second;
126 auto& prof = Alina::Profiler::globalProfiler();
130 tm->
info() <<
"World size: " << world.size;
136 auto coarsening = Alina::eCoarserningType::smoothed_aggregation;
137 auto relaxation = Alina::eRelaxationType::spai0;
138 auto iterative_solver = Alina::eSolverType::bicgstabl;
139 auto direct_solver = Alina::eDistributedDirectSolverType::skyline_lu;
141 bool just_relax =
false;
142 bool symm_dirichlet =
true;
143 std::string parameter_file;
145 namespace po = Arcane::ProgramOptions;
148 desc.add_options()(
"help,h",
"show help")(
150 po::value<bool>(&symm_dirichlet)->default_value(symm_dirichlet),
151 "Use symmetric Dirichlet conditions in laplace2d")(
153 po::value<ptrdiff_t>(&n)->default_value(n),
156 po::value<Alina::eCoarserningType>(&coarsening)->default_value(coarsening),
157 "ruge_stuben, aggregation, smoothed_aggregation, smoothed_aggr_emin")(
159 po::value<Alina::eRelaxationType>(&relaxation)->default_value(relaxation),
160 "gauss_seidel, ilu0, iluk, ilut, damped_jacobi, spai0, spai1, chebyshev")(
162 po::value<Alina::eSolverType>(&iterative_solver)->default_value(iterative_solver),
163 "cg, bicgstab, bicgstabl, gmres")(
165 po::value<Alina::eDistributedDirectSolverType>(&direct_solver)->default_value(direct_solver),
167#ifdef ARCCORE_ALINA_HAVE_EIGEN
173 "Use constant deflation (linear deflation is used by default)")(
175 po::value<std::string>(¶meter_file),
176 "parameter file in json format")(
178 po::value<std::vector<std::string>>()->multitoken(),
179 "Parameters specified as name=value pairs. "
180 "May be provided multiple times. Examples:\n"
181 " -p solver.tol=1e-3\n"
182 " -p precond.coarse_enough=300")(
184 po::bool_switch(&just_relax),
185 "Do not create AMG hierarchy, use relaxation as preconditioner");
188 po::store(po::parse_command_line(argc, argv, desc), vm);
191 if (vm.count(
"help")) {
192 std::cout << desc << std::endl;
197 if (vm.count(
"params"))
198 prm.read_json(parameter_file);
200 if (vm.count(
"prm")) {
201 for (
const std::string& v : vm[
"prm"].as<std::vector<std::string>>()) {
206 prm.put(
"isolver.type", iterative_solver);
207 prm.put(
"dsolver.type", direct_solver);
209 boost::array<ptrdiff_t, 3> lo = { { 0, 0, 0 } };
210 boost::array<ptrdiff_t, 3> hi = { { n - 1, n - 1, n - 1 } };
212 prof.tic(
"partition");
213 DomainPartition<3> part(lo, hi, world.size);
214 ptrdiff_t chunk = part.size(world.rank);
216 std::vector<ptrdiff_t> domain(world.size + 1);
219 mpAllGather(world.m_message_passing_mng.get(), send_buf, receive_buf);
220 std::partial_sum(domain.begin(), domain.end(), domain.begin());
222 lo = part.domain(world.rank).min_corner();
223 hi = part.domain(world.rank).max_corner();
228 for (ptrdiff_t k = lo[2]; k <= hi[2]; ++k) {
229 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
230 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
231 boost::array<ptrdiff_t, 3> p = { { i, j, k } };
232 std::pair<int, ptrdiff_t> v = part.index(p);
234 def.x[v.second] = (i - (lo[0] + hi[0]) / 2);
235 def.y[v.second] = (j - (lo[1] + hi[1]) / 2);
236 def.z[v.second] = (k - (lo[2] + hi[2]) / 2);
240 prof.toc(
"partition");
242 prof.tic(
"assemble");
243 std::vector<ptrdiff_t> ptr;
244 std::vector<ptrdiff_t> col;
245 std::vector<double> val;
246 std::vector<double> rhs;
248 ptr.reserve(chunk + 1);
249 col.reserve(chunk * 7);
250 val.reserve(chunk * 7);
255 const double h2i = (n - 1) * (n - 1);
257 for (ptrdiff_t k = lo[2]; k <= hi[2]; ++k) {
258 for (ptrdiff_t j = lo[1]; j <= hi[1]; ++j) {
259 for (ptrdiff_t i = lo[0]; i <= hi[0]; ++i) {
261 if (!symm_dirichlet && (i == 0 || j == 0 || k == 0 || i + 1 == n || j + 1 == n || k + 1 == n)) {
262 col.push_back(renum(i, j, k));
268 col.push_back(renum(i, j, k - 1));
273 col.push_back(renum(i, j - 1, k));
278 col.push_back(renum(i - 1, j, k));
282 col.push_back(renum(i, j, k));
283 val.push_back(6 * h2i);
286 col.push_back(renum(i + 1, j, k));
291 col.push_back(renum(i, j + 1, k));
296 col.push_back(renum(i, j, k + 1));
302 ptr.push_back(col.size());
306 prof.toc(
"assemble");
310#if defined(SOLVER_BACKEND_VEXCL)
311 vex::Context ctx(vex::Filter::Env);
312 std::cout << ctx << std::endl;
314#elif defined(SOLVER_BACKEND_CUDA)
315 cusparseCreate(&bprm.cusparse_handle);
318 auto f = Backend::copy_vector(rhs, bprm);
319 auto x = Backend::create_vector(chunk, bprm);
321 Alina::backend::clear(*x);
326 std::function<double(ptrdiff_t,
unsigned)> def_vec = std::cref(def);
327 prm.put(
"num_def_vec", def.dim());
328 prm.put(
"def_vec", &def_vec);
331 prm.put(
"local.type", relaxation);
338 SDD solve(world, std::tie(chunk, ptr, col, val), prm, bprm);
342 std::tie(iters, resid) = solve(*f, *x);
346 prm.put(
"local.coarsening.type", coarsening);
347 prm.put(
"local.relax.type", relaxation);
354 SDD solve(world, std::tie(chunk, ptr, col, val), prm, bprm);
358 std::tie(iters, resid) = solve(*f, *x);
362 tm->
info() <<
"Iterations: " << iters <<
"\n"
363 <<
"Error: " << resid <<
"\n\n"
368int main(
int argc,
char* argv[])
370 return Arcane::Alina::SampleMainContext::execMain(main2, argc, argv);
Runtime wrapper for distributed direct solvers.
Distributed solver based on subdomain deflation.
Modifiable view of an array of type T.
Constant view of an array of type T.
virtual TraceMessage info()=0
Stream for an information message.
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 --
Alina::detail::empty_params params
Pointwise constant deflation vectors.
Convenience wrapper around MPI_Comm.