AmgxPreconditioner.hpp
Go to the documentation of this file.
1/*
2 Copyright 2024 SINTEF AS
3 Copyright 2024 Equinor ASA
4
5 This file is part of the Open Porous Media project (OPM).
6
7 OPM is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 OPM is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with OPM. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#ifndef OPM_AMGX_PRECONDITIONER_HEADER_INCLUDED
22#define OPM_AMGX_PRECONDITIONER_HEADER_INCLUDED
23
24#include <opm/common/ErrorMacros.hpp>
25#include <opm/common/TimingMacros.hpp>
29
30#include <dune/common/fmatrix.hh>
31#include <dune/istl/bcrsmatrix.hh>
32
33#include <amgx_c.h>
34
35namespace Amgx
36{
37
39
45struct AmgxConfig {
49 std::string solver = "AMG";
50 std::string algorithm = "CLASSICAL";
51 std::string interpolator = "D2";
52 std::string selector = "PMIS";
53 std::string smoother = "BLOCK_JACOBI";
54 int presweeps = 3;
55 int postsweeps = 3;
56 double strength_threshold = 0.5;
57 int max_iters = 1;
58
59 explicit AmgxConfig(const Opm::PropertyTree& prm)
60 {
61 determinism_flag = prm.get<int>("determinism_flag", determinism_flag);
62 print_grid_stats = prm.get<int>("print_grid_stats", print_grid_stats);
63 print_solve_stats = prm.get<int>("print_solve_stats", print_solve_stats);
64 solver = prm.get<std::string>("solver", solver);
65 algorithm = prm.get<std::string>("algorithm", algorithm);
66 interpolator = prm.get<std::string>("interpolator", interpolator);
67 selector = prm.get<std::string>("selector", selector);
68 smoother = prm.get<std::string>("smoother", smoother);
69 presweeps = prm.get<int>("presweeps", presweeps);
70 postsweeps = prm.get<int>("postsweeps", postsweeps);
71 strength_threshold = prm.get<double>("strength_threshold", strength_threshold);
72 max_iters = prm.get<int>("max_iters", max_iters);
73 }
74
75 std::string toString() const {
76 return "config_version=2, "
77 "determinism_flag=" + std::to_string(determinism_flag) + ", "
78 "print_grid_stats=" + std::to_string(print_grid_stats) + ", "
79 "print_solve_stats=" + std::to_string(print_solve_stats) + ", "
80 "solver=" + solver + ", "
81 "algorithm=" + algorithm + ", "
82 "interpolator=" + interpolator + ", "
83 "selector=" + selector + ", "
84 "smoother=" + smoother + ", "
85 "presweeps=" + std::to_string(presweeps) + ", "
86 "postsweeps=" + std::to_string(postsweeps) + ", "
87 "strength_threshold=" + std::to_string(strength_threshold) + ", "
88 "max_iters=" + std::to_string(max_iters);
89 }
90};
91
105template <class M, class X, class Y>
107{
108public:
110 using matrix_type = M;
112 using matrix_field_type = typename M::field_type;
114 using domain_type = X;
116 using range_type = Y;
118 using vector_field_type = typename X::field_type;
119
120 static constexpr int block_size = 1;
121
131 : A_(A)
132 , setup_frequency_(prm.get<int>("setup_frequency", 30))
133 , update_counter_(0)
134 {
135 OPM_TIMEBLOCK(prec_construct);
136
137 // Create configuration
138 AmgxConfig config(prm);
139 cfg_ = AmgxInterface::createConfig(config.toString());
140 rsrc_ = AmgxInterface::createResources(cfg_);
141
142 // Determine appropriate AMGX mode based on matrix and vector types
143 amgx_mode_ = AmgxInterface::determineAmgxMode<matrix_field_type, vector_field_type>();
144
145 // Create solver, matrix, and vector handles, given the mode
146 solver_ = AmgxInterface::createSolver(rsrc_, amgx_mode_, cfg_);
147 A_amgx_ = AmgxInterface::createMatrix(rsrc_, amgx_mode_);
148 x_amgx_ = AmgxInterface::createVector(rsrc_, amgx_mode_);
149 b_amgx_ = AmgxInterface::createVector(rsrc_, amgx_mode_);
150
151 // Initialize matrix structure and values
153
154 // Initialize vectors with proper dimensions
155 const int N = A_.N();
158
159 // Perform initial update
160 update();
161 }
162
169 {
173 AmgxInterface::destroyMatrix(A_amgx_, A_);
176 }
177
186 void pre(X& /*v*/, Y& /*d*/) override
187 {
188 }
189
200 void apply(X& v, const Y& d) override
201 {
202 OPM_TIMEBLOCK(prec_apply);
203
204 // Transfer vectors to AMGX
207
208 // Apply preconditioner
209 AMGX_SAFE_CALL(AMGX_solver_solve(solver_, b_amgx_, x_amgx_));
210
211 // Transfer result back
213 }
214
222 void post(X& /*v*/) override
223 {
224 }
225
231 void update() override
232 {
233 OPM_TIMEBLOCK(prec_update);
234
236
237 // Setup or resetup the solver based on update counter
238 if (update_counter_ == 0) {
239 AMGX_SAFE_CALL(AMGX_solver_setup(solver_, A_amgx_));
240 } else {
241 AMGX_SAFE_CALL(AMGX_solver_resetup(solver_, A_amgx_));
242 }
243
244 ++update_counter_;
245 if (update_counter_ >= setup_frequency_) {
246 update_counter_ = 0;
247 }
248 }
249
255 Dune::SolverCategory::Category category() const override
256 {
257 return Dune::SolverCategory::sequential;
258 }
259
265 bool hasPerfectUpdate() const override
266 {
267 // The AMG hierarchy of the Amgx preconditioner can depend on the values of the matrix, so it must be recreated
268 // when the matrix values change, at a given frequency. Since this is handled internally, we return true.
269 return true;
270 }
271
272private:
273 // Reference to the input matrix
274 const M& A_;
275
276 // AMGX handles
277 AMGX_config_handle cfg_ = nullptr;
278 AMGX_resources_handle rsrc_ = nullptr;
279 AMGX_solver_handle solver_ = nullptr;
280 AMGX_matrix_handle A_amgx_ = nullptr;
281 AMGX_vector_handle x_amgx_ = nullptr;
282 AMGX_vector_handle b_amgx_ = nullptr;
283 AMGX_Mode amgx_mode_;
284
285 // Frequency of updating the AMG hierarchy
286 int setup_frequency_;
287 // Counter for setup updates
288 int update_counter_;
289};
290
291} // namespace Amgx
292
293#endif // OPM_AMGX_PRECONDITIONER_HEADER_INCLUDED
Wrapper for AMGX's AMG preconditioner.
Definition: AmgxPreconditioner.hpp:107
bool hasPerfectUpdate() const override
Checks if the preconditioner has a perfect update.
Definition: AmgxPreconditioner.hpp:265
Y range_type
The range type of the preconditioner.
Definition: AmgxPreconditioner.hpp:116
void update() override
Updates the preconditioner with the current matrix values.
Definition: AmgxPreconditioner.hpp:231
void apply(X &v, const Y &d) override
Applies the preconditioner to a vector.
Definition: AmgxPreconditioner.hpp:200
typename M::field_type matrix_field_type
The field type of the matrix.
Definition: AmgxPreconditioner.hpp:112
static constexpr int block_size
Definition: AmgxPreconditioner.hpp:120
AmgxPreconditioner(const M &A, const Opm::PropertyTree prm)
Constructor for AmgxPreconditioner.
Definition: AmgxPreconditioner.hpp:130
Dune::SolverCategory::Category category() const override
Returns the solver category.
Definition: AmgxPreconditioner.hpp:255
void pre(X &, Y &) override
Pre-processing step before applying the preconditioner.
Definition: AmgxPreconditioner.hpp:186
X domain_type
The domain type of the preconditioner.
Definition: AmgxPreconditioner.hpp:114
M matrix_type
The matrix type the preconditioner is for.
Definition: AmgxPreconditioner.hpp:110
typename X::field_type vector_field_type
The field type of the vectors.
Definition: AmgxPreconditioner.hpp:118
~AmgxPreconditioner()
Destructor for AmgxPreconditioner.
Definition: AmgxPreconditioner.hpp:168
void post(X &) override
Post-processing step after applying the preconditioner.
Definition: AmgxPreconditioner.hpp:222
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:32
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:39
T get(const std::string &key) const
Unified interface for AMGX operations with both CPU and GPU data structures.
Definition: AmgxInterface.hpp:122
static void destroyResources(AMGX_resources_handle resources)
Destroy an AMGX resources handle.
Definition: AmgxInterface.hpp:244
static AMGX_resources_handle createResources(AMGX_config_handle config)
Create AMGX resources from a config.
Definition: AmgxInterface.hpp:167
static void destroyVector(AMGX_vector_handle vector)
Destroy an AMGX vector handle.
Definition: AmgxInterface.hpp:292
static AMGX_solver_handle createSolver(AMGX_resources_handle resources, AMGX_Mode mode, AMGX_config_handle config)
Create an AMGX solver.
Definition: AmgxInterface.hpp:183
static void updateMatrixValues(const MatrixType &matrix, AMGX_matrix_handle amgx_matrix)
Update matrix values in AMGX.
Definition: AmgxInterface.hpp:590
static void initializeVector(int N, int block_size, AMGX_vector_handle amgx_vector)
Initialize an AMGX vector with zeros.
Definition: AmgxInterface.hpp:574
static void destroyConfig(AMGX_config_handle config)
Destroy an AMGX config handle.
Definition: AmgxInterface.hpp:226
static AMGX_config_handle createConfig(const std::string &config_string)
Create an AMGX config handle from a configuration string.
Definition: AmgxInterface.hpp:153
static void destroySolver(AMGX_solver_handle solver)
Destroy an AMGX solver handle.
Definition: AmgxInterface.hpp:257
static AMGX_matrix_handle createMatrix(AMGX_resources_handle resources, AMGX_Mode mode)
Create an AMGX matrix.
Definition: AmgxInterface.hpp:198
static void initializeMatrix(const MatrixType &matrix, AMGX_matrix_handle amgx_matrix)
Initialize an AMGX matrix from any matrix type (CPU or GPU)
Definition: AmgxInterface.hpp:515
static AMGX_vector_handle createVector(AMGX_resources_handle resources, AMGX_Mode mode)
Create an AMGX vector.
Definition: AmgxInterface.hpp:213
static void destroyMatrix(AMGX_matrix_handle amgx_matrix, const MatrixType &matrix)
Destroy an AMGX matrix handle.
Definition: AmgxInterface.hpp:272
static void transferVectorToAmgx(const VectorType &vec, AMGX_vector_handle amgx_vec)
Transfer vector to AMGX from any vector type (CPU or GPU)
Definition: AmgxInterface.hpp:370
static void transferVectorFromAmgx(AMGX_vector_handle amgx_vec, VectorType &vec)
Transfer vector from AMGX to any vector type (CPU or GPU)
Definition: AmgxInterface.hpp:396
Definition: AmgxPreconditioner.hpp:36
Opm::gpuistl::AmgxInterface AmgxInterface
Definition: AmgxPreconditioner.hpp:38
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Configuration structure for AMGX parameters.
Definition: AmgxPreconditioner.hpp:45
std::string algorithm
Definition: AmgxPreconditioner.hpp:50
std::string smoother
Definition: AmgxPreconditioner.hpp:53
std::string interpolator
Definition: AmgxPreconditioner.hpp:51
int postsweeps
Definition: AmgxPreconditioner.hpp:55
std::string solver
Definition: AmgxPreconditioner.hpp:49
int max_iters
Definition: AmgxPreconditioner.hpp:57
int presweeps
Definition: AmgxPreconditioner.hpp:54
double strength_threshold
Definition: AmgxPreconditioner.hpp:56
int determinism_flag
Definition: AmgxPreconditioner.hpp:46
int print_grid_stats
Definition: AmgxPreconditioner.hpp:47
int print_solve_stats
Definition: AmgxPreconditioner.hpp:48
std::string selector
Definition: AmgxPreconditioner.hpp:52
std::string toString() const
Definition: AmgxPreconditioner.hpp:75
AmgxConfig(const Opm::PropertyTree &prm)
Definition: AmgxPreconditioner.hpp:59