Arcane  4.2.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CPRDynamicRowSum.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/*---------------------------------------------------------------------------*/
9/*
10 * Ce fichier est basé sur le travail effectué sur la bibliothèque AMGCL (version mars 2026)
11 * qui peut être trouvée à https://github.com/ddemidov/amgcl.
12 *
13 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
14 * SPDX-License-Identifier: MIT
15 */
16/*---------------------------------------------------------------------------*/
17/*---------------------------------------------------------------------------*/
18
19#include <iostream>
20#include <string>
21
22#include <boost/preprocessor/seq/for_each.hpp>
23
24#if defined(SOLVER_BACKEND_CUDA)
25# include "arccore/alina/CudaBackend.h"
26# include "arccore/alina/relaxation_cusparse_ilu0.h"
28#else
29# ifndef SOLVER_BACKEND_BUILTIN
30# define SOLVER_BACKEND_BUILTIN
31# endif
32#include "arccore/alina/BuiltinBackend.h"
34#endif
35
36#if defined(SOLVER_BACKEND_BUILTIN)
37#include "arccore/alina/StaticMatrix.h"
38#include "arccore/alina/Adapters.h"
39#endif
40
41#include "arccore/alina/PreconditionedSolver.h"
42#include "arccore/alina/AMG.h"
43#include "arccore/alina/SolverRuntime.h"
44#include "arccore/alina/CoarseningRuntime.h"
45#include "arccore/alina/RelaxationRuntime.h"
46#include "arccore/alina/Relaxation.h"
47#include "arccore/alina/CPRDynamicRowSumPreconditioner.h"
48#include "arccore/alina/Adapters.h"
49#include "arccore/alina/IO.h"
50#include "arccore/alina/Profiler.h"
51
52#include "arccore/common/internal/ProgramOptions.h"
53
54using namespace Arcane;
55
56using Alina::precondition;
57
58//---------------------------------------------------------------------------
59template <class Matrix>
60void solve_cpr(const Alina::AlinaContext& context,
61 const Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
62{
63 auto& prof = Alina::Profiler::globalProfiler();
64 Backend::params bprm;
65
66#if defined(SOLVER_BACKEND_VEXCL)
67 vex::Context ctx(vex::Filter::Env);
68 std::cout << ctx << std::endl;
69 bprm.q = ctx;
70#elif defined(SOLVER_BACKEND_VIENNACL)
71 std::cout
72 << viennacl::ocl::current_device().name()
73 << " (" << viennacl::ocl::current_device().vendor() << ")\n\n";
74#elif defined(SOLVER_BACKEND_CUDA)
75 cusparseCreate(&bprm.cusparse_handle);
76 {
77 int dev;
78 cudaGetDevice(&dev);
79
80 cudaDeviceProp prop;
81 cudaGetDeviceProperties(&prop, dev);
82 std::cout << prop.name << std::endl
83 << std::endl;
84 }
85#endif
86
87 auto t1 = prof.scoped_tic("CPR");
88
90 PPrecond;
91
93
94 prof.tic("setup");
98 solve(context, K, prm, bprm);
99 prof.toc("setup");
100
101 std::cout << solve.precond() << std::endl;
102
103 auto f = Backend::copy_vector(rhs, bprm);
104 auto x = Backend::create_vector(rhs.size(), bprm);
105 Alina::backend::clear(*x);
106
107 prof.tic("solve");
108 Alina::SolverResult r = solve(*f, *x);
109 prof.toc("solve");
110
111 std::cout << "Iterations: " << r.nbIteration() << std::endl
112 << "Error: " << r.residual() << std::endl;
113}
114
115#if defined(SOLVER_BACKEND_BUILTIN)
116//---------------------------------------------------------------------------
117template <int B, class Matrix>
118void solve_block_cpr(const Alina::AlinaContext& context, const Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
119{
120 auto& prof = Alina::Profiler::globalProfiler();
121 auto t1 = prof.scoped_tic("CPR");
122
123 typedef Alina::StaticMatrix<double, B, B> val_type;
124 typedef Alina::StaticMatrix<double, B, 1> rhs_type;
125
126 typedef Alina::BuiltinBackend<val_type> SBackend;
127 typedef Alina::BuiltinBackend<double> PBackend;
128
131
132 typename SBackend::params bprm;
133
134 prof.tic("setup");
138 solve(context, Alina::adapter::block_matrix<val_type>(K), prm, bprm);
139 prof.toc("setup");
140
141 std::cout << solve.precond() << std::endl;
142
143 size_t n = Alina::backend::nbRow(K) / B;
144 auto rhs_ptr = reinterpret_cast<const rhs_type*>(rhs.data());
145
146 SmallSpan<const rhs_type> f(rhs_ptr, n);
147
148 auto x = SBackend::create_vector(n, bprm);
149 Alina::backend::clear(*x);
150
151 prof.tic("solve");
152 Alina::SolverResult r = solve(f, *x);
153 prof.toc("solve");
154
155 std::cout << "Iterations: " << r.nbIteration() << std::endl
156 << "Error: " << r.residual() << std::endl;
157}
158#endif
159
160//---------------------------------------------------------------------------
161int main(int argc, char* argv[])
162{
163 auto& prof = Alina::Profiler::globalProfiler();
164 using Alina::precondition;
165 using std::string;
166 using std::vector;
167
168 Alina::AlinaContext context;
169
170 namespace po = Arcane::ProgramOptions;
171 namespace io = Alina::IO;
172
173 po::options_description desc("Options");
174
175 desc.add_options()("help,h", "show help");
176 desc.add_options()("binary,B",
177 po::bool_switch()->default_value(false),
178 "Lorsque spécifié, traite les fichiers d'entrée en binaire au lieu de MatrixMarket. "
179 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ");
180 desc.add_options()("matrix,A",
181 po::value<string>()->required(),
182 "La matrice système au format MatrixMarket");
183 desc.add_options()("rhs,f",
184 po::value<string>(),
185 "Le côté droit en format MatrixMarket");
186 desc.add_options()("weights,w",
187 po::value<string>(),
188 "Poids des équations au format MatrixMarket");
189 desc.add_options()("runtime-block-size,b",
190 po::value<int>(),
191 "La taille de bloc de la matrice système définie à l'exécution");
192 desc.add_options()("static-block-size,c",
193 po::value<int>()->default_value(1),
194 "La taille de bloc de la matrice système définie à la compilation");
195 desc.add_options()("params,P",
196 po::value<string>(),
197 "fichier de paramètres au format json");
198 desc.add_options()("prm,p",
199 po::value<vector<string>>()->multitoken(),
200 "Paramètres spécifiés sous forme de paires nom=valeur. "
201 "Peut être fourni plusieurs fois. Exemples :\n"
202 " -p solver.tol=1e-3\n"
203 " -p precond.coarse_enough=300");
204
206 po::store(po::parse_command_line(argc, argv, desc), vm);
207
208 if (vm.count("help")) {
209 std::cout << desc << std::endl;
210 return 0;
211 }
212
213 po::notify(vm);
214
216 if (vm.count("params"))
217 prm.read_json(vm["params"].as<string>());
218
219 if (vm.count("prm")) {
220 for (const string& v : vm["prm"].as<vector<string>>()) {
221 prm.putKeyValue(v);
222 }
223 }
224
225 int cb = vm["static-block-size"].as<int>();
226
227 if (vm.count("runtime-block-size"))
228 prm.put("precond.block_size", vm["runtime-block-size"].as<int>());
229 else
230 prm.put("precond.block_size", cb);
231
232 size_t rows;
233 vector<ptrdiff_t> ptr, col;
234 vector<double> val, rhs, wgt;
235 std::vector<char> pm;
236
237 {
238 auto t = prof.scoped_tic("reading");
239
240 string Afile = vm["matrix"].as<string>();
241 bool binary = vm["binary"].as<bool>();
242
243 if (binary) {
244 io::read_crs(Afile, rows, ptr, col, val);
245 }
246 else {
247 size_t cols;
248 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
249 precondition(rows == cols, "Matrice système non carrée");
250 }
251
252 if (vm.count("rhs")) {
253 string bfile = vm["rhs"].as<string>();
254
255 size_t n, m;
256
257 if (binary) {
258 io::read_dense(bfile, n, m, rhs);
259 }
260 else {
261 std::tie(n, m) = io::mm_reader(bfile)(rhs);
262 }
263
264 precondition(n == rows && m == 1, "Le vecteur RHS a une taille incorrecte");
265 }
266 else {
267 rhs.resize(rows, 1.0);
268 }
269
270 if (vm.count("weights")) {
271 string wfile = vm["weights"].as<string>();
272
273 size_t n, m;
274
275 if (binary) {
276 io::read_dense(wfile, n, m, wgt);
277 }
278 else {
279 std::tie(n, m) = io::mm_reader(wfile)(wgt);
280 }
281
282 prm.put("precond.weights", &wgt[0]);
283 prm.put("precond.weights_size", wgt.size());
284 }
285 }
286
287#define CALL_BLOCK_SOLVER(z, data, B) \
288 case B: \
289 solve_block_cpr<B>(context, std::tie(rows, ptr, col, val), rhs, prm); \
290 break;
291
292 switch (cb) {
293 case 1:
294 solve_cpr(context, std::tie(rows, ptr, col, val), rhs, prm);
295 break;
296
297#if defined(SOLVER_BACKEND_BUILTIN) || defined(SOLVER_BACKEND_VEXCL)
298 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
299#endif
300
301 default:
302 precondition(false, "Taille de bloc non prise en charge");
303 break;
304 }
305
306 std::cout << prof << std::endl;
307}
Algebraic multigrid method.
Definition AMG.h:71
Convenience class that bundles together a preconditioner and an iterative solver.
Classe pour stocker les paramètres sous forme d'arbre hiérarchique clé/valeur.
Definition AlinaUtils.h:113
Allows to use an AMG smoother as standalone preconditioner.
Definition Relaxation.h:144
Résultat d'une solution.
Definition AlinaUtils.h:56
CPR preconditioner with Dynamic Row Sum modification.
Matrix class, to be used by user.
Décrit un ensemble d'options en ligne de commande.
Stocke les valeurs d'options analysées.
Vue d'un tableau d'éléments de type T.
Definition Span.h:802
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Runtime-configurable wrappers around iterative solvers.