Arcane  4.2.1.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 Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
61{
62 auto& prof = Alina::Profiler::globalProfiler();
63 Backend::params bprm;
64
65#if defined(SOLVER_BACKEND_VEXCL)
66 vex::Context ctx(vex::Filter::Env);
67 std::cout << ctx << std::endl;
68 bprm.q = ctx;
69#elif defined(SOLVER_BACKEND_VIENNACL)
70 std::cout
71 << viennacl::ocl::current_device().name()
72 << " (" << viennacl::ocl::current_device().vendor() << ")\n\n";
73#elif defined(SOLVER_BACKEND_CUDA)
74 cusparseCreate(&bprm.cusparse_handle);
75 {
76 int dev;
77 cudaGetDevice(&dev);
78
79 cudaDeviceProp prop;
80 cudaGetDeviceProperties(&prop, dev);
81 std::cout << prop.name << std::endl
82 << std::endl;
83 }
84#endif
85
86 auto t1 = prof.scoped_tic("CPR");
87
89 PPrecond;
90
92
93 prof.tic("setup");
97 solve(K, prm, bprm);
98 prof.toc("setup");
99
100 std::cout << solve.precond() << std::endl;
101
102 auto f = Backend::copy_vector(rhs, bprm);
103 auto x = Backend::create_vector(rhs.size(), bprm);
104 Alina::backend::clear(*x);
105
106 prof.tic("solve");
107 Alina::SolverResult r = solve(*f, *x);
108 prof.toc("solve");
109
110 std::cout << "Iterations: " << r.nbIteration() << std::endl
111 << "Error: " << r.residual() << std::endl;
112}
113
114#if defined(SOLVER_BACKEND_BUILTIN)
115//---------------------------------------------------------------------------
116template <int B, class Matrix>
117void solve_block_cpr(const Matrix& K, const std::vector<double>& rhs, Alina::PropertyTree& prm)
118{
119 auto& prof = Alina::Profiler::globalProfiler();
120 auto t1 = prof.scoped_tic("CPR");
121
122 typedef Alina::StaticMatrix<double, B, B> val_type;
123 typedef Alina::StaticMatrix<double, B, 1> rhs_type;
124
125 typedef Alina::BuiltinBackend<val_type> SBackend;
126 typedef Alina::BuiltinBackend<double> PBackend;
127
130
131 typename SBackend::params bprm;
132
133 prof.tic("setup");
137 solve(Alina::adapter::block_matrix<val_type>(K), prm, bprm);
138 prof.toc("setup");
139
140 std::cout << solve.precond() << std::endl;
141
142 size_t n = Alina::backend::nbRow(K) / B;
143 auto rhs_ptr = reinterpret_cast<const rhs_type*>(rhs.data());
144
145 SmallSpan<const rhs_type> f(rhs_ptr, n);
146
147 auto x = SBackend::create_vector(n, bprm);
148 Alina::backend::clear(*x);
149
150 prof.tic("solve");
151 Alina::SolverResult r = solve(f, *x);
152 prof.toc("solve");
153
154 std::cout << "Iterations: " << r.nbIteration() << std::endl
155 << "Error: " << r.residual() << std::endl;
156}
157#endif
158
159//---------------------------------------------------------------------------
160int main(int argc, char* argv[])
161{
162 auto& prof = Alina::Profiler::globalProfiler();
163 using Alina::precondition;
164 using std::string;
165 using std::vector;
166
167 namespace po = Arcane::ProgramOptions;
168 namespace io = Alina::IO;
169
170 po::options_description desc("Options");
171
172 desc.add_options()("help,h", "show help")(
173 "binary,B",
174 po::bool_switch()->default_value(false),
175 "Lorsque spécifié, traite les fichiers d'entrée en binaire au lieu de MatrixMarket. "
176 "Il est supposé que les fichiers ont été convertis au format binaire avec l'utilitaire mm2bin. ")(
177 "matrix,A",
178 po::value<string>()->required(),
179 "La matrice système au format MatrixMarket")(
180 "rhs,f",
181 po::value<string>(),
182 "Le côté droit en format MatrixMarket")(
183 "weights,w",
184 po::value<string>(),
185 "Poids des équations au format MatrixMarket")(
186 "runtime-block-size,b",
187 po::value<int>(),
188 "La taille de bloc de la matrice système définie à l'exécution")(
189 "static-block-size,c",
190 po::value<int>()->default_value(1),
191 "La taille de bloc de la matrice système définie à la compilation")(
192 "params,P",
193 po::value<string>(),
194 "fichier de paramètres au format json")(
195 "prm,p",
196 po::value<vector<string>>()->multitoken(),
197 "Paramètres spécifiés sous forme de paires nom=valeur. "
198 "Peut être fourni plusieurs fois. Exemples :\n"
199 " -p solver.tol=1e-3\n"
200 " -p precond.coarse_enough=300");
201
203 po::store(po::parse_command_line(argc, argv, desc), vm);
204
205 if (vm.count("help")) {
206 std::cout << desc << std::endl;
207 return 0;
208 }
209
210 po::notify(vm);
211
213 if (vm.count("params"))
214 prm.read_json(vm["params"].as<string>());
215
216 if (vm.count("prm")) {
217 for (const string& v : vm["prm"].as<vector<string>>()) {
218 prm.putKeyValue(v);
219 }
220 }
221
222 int cb = vm["static-block-size"].as<int>();
223
224 if (vm.count("runtime-block-size"))
225 prm.put("precond.block_size", vm["runtime-block-size"].as<int>());
226 else
227 prm.put("precond.block_size", cb);
228
229 size_t rows;
230 vector<ptrdiff_t> ptr, col;
231 vector<double> val, rhs, wgt;
232 std::vector<char> pm;
233
234 {
235 auto t = prof.scoped_tic("reading");
236
237 string Afile = vm["matrix"].as<string>();
238 bool binary = vm["binary"].as<bool>();
239
240 if (binary) {
241 io::read_crs(Afile, rows, ptr, col, val);
242 }
243 else {
244 size_t cols;
245 std::tie(rows, cols) = io::mm_reader(Afile)(ptr, col, val);
246 precondition(rows == cols, "Matrice système non carrée");
247 }
248
249 if (vm.count("rhs")) {
250 string bfile = vm["rhs"].as<string>();
251
252 size_t n, m;
253
254 if (binary) {
255 io::read_dense(bfile, n, m, rhs);
256 }
257 else {
258 std::tie(n, m) = io::mm_reader(bfile)(rhs);
259 }
260
261 precondition(n == rows && m == 1, "Le vecteur RHS a une taille incorrecte");
262 }
263 else {
264 rhs.resize(rows, 1.0);
265 }
266
267 if (vm.count("weights")) {
268 string wfile = vm["weights"].as<string>();
269
270 size_t n, m;
271
272 if (binary) {
273 io::read_dense(wfile, n, m, wgt);
274 }
275 else {
276 std::tie(n, m) = io::mm_reader(wfile)(wgt);
277 }
278
279 prm.put("precond.weights", &wgt[0]);
280 prm.put("precond.weights_size", wgt.size());
281 }
282 }
283
284#define CALL_BLOCK_SOLVER(z, data, B) \
285 case B: \
286 solve_block_cpr<B>(std::tie(rows, ptr, col, val), rhs, prm); \
287 break;
288
289 switch (cb) {
290 case 1:
291 solve_cpr(std::tie(rows, ptr, col, val), rhs, prm);
292 break;
293
294#if defined(SOLVER_BACKEND_BUILTIN) || defined(SOLVER_BACKEND_VEXCL)
295 BOOST_PP_SEQ_FOR_EACH(CALL_BLOCK_SOLVER, ~, ARCCORE_ALINA_BLOCK_SIZES)
296#endif
297
298 default:
299 precondition(false, "Taille de bloc non prise en charge");
300 break;
301 }
302
303 std::cout << prof << std::endl;
304}
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:112
Allows to use an AMG smoother as standalone preconditioner.
Definition Relaxation.h:144
Résultat d'une solution.
Definition AlinaUtils.h:53
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.