21#ifndef OPM_HYPRE_PRECONDITIONER_HEADER_INCLUDED
22#define OPM_HYPRE_PRECONDITIONER_HEADER_INCLUDED
24#include <opm/common/ErrorMacros.hpp>
25#include <opm/common/TimingMacros.hpp>
26#include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
27#include <opm/simulators/linalg/PropertyTree.hpp>
28#include <opm/simulators/linalg/gpuistl/HypreInterface.hpp>
29#include <opm/simulators/linalg/gpuistl/detail/gpu_type_detection.hpp>
31#include <dune/common/fmatrix.hh>
32#include <dune/istl/bcrsmatrix.hh>
35#include <HYPRE_krylov.h>
36#include <HYPRE_parcsr_ls.h>
37#include <_hypre_utilities.h>
65template <
class M,
class X,
class Y,
class Comm>
93 OPM_TIMEBLOCK(prec_construct);
97 if constexpr (std::is_same_v<Comm, Dune::Amg::SequentialInformation>) {
98 mpi_comm = MPI_COMM_SELF;
100 mpi_comm = comm.communicator();
102 MPI_Comm_size(mpi_comm, &size);
103 MPI_Comm_rank(mpi_comm, &rank);
105 assert(size == comm.communicator().size());
106 assert(rank == comm.communicator().rank());
138 if (use_gpu_backend_) {
139#if HYPRE_USING_CUDA || HYPRE_USING_HIP
140 device_arrays_.
ncols_device = hypre_CTAlloc(HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
141 device_arrays_.rows_device = hypre_CTAlloc(HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
142 device_arrays_.cols_device = hypre_CTAlloc(HYPRE_BigInt, sparsity_pattern_.
nnz, HYPRE_MEMORY_DEVICE);
143 device_arrays_.row_indexes_device = hypre_CTAlloc(HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
144 device_arrays_.indices_device = hypre_CTAlloc(HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
150 device_arrays_.
matrix_buffer_device = hypre_CTAlloc(HYPRE_Real, A_.nonzeroes(), HYPRE_MEMORY_DEVICE);
153 hypre_TMemcpy(device_arrays_.
ncols_device, sparsity_pattern_.
ncols.data(), HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
154 hypre_TMemcpy(device_arrays_.rows_device, sparsity_pattern_.
rows.data(), HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
155 hypre_TMemcpy(device_arrays_.cols_device, sparsity_pattern_.
cols.data(), HYPRE_BigInt, sparsity_pattern_.
nnz, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
156 hypre_TMemcpy(device_arrays_.row_indexes_device, host_arrays_.
row_indexes.data(), HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
157 hypre_TMemcpy(device_arrays_.indices_device, host_arrays_.
indices.data(), HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
178 if (use_gpu_backend_) {
179#if HYPRE_USING_CUDA || HYPRE_USING_HIP
181 hypre_TFree(device_arrays_.
ncols_device, HYPRE_MEMORY_DEVICE);
183 if (device_arrays_.rows_device) {
184 hypre_TFree(device_arrays_.rows_device, HYPRE_MEMORY_DEVICE);
186 if (device_arrays_.cols_device) {
187 hypre_TFree(device_arrays_.cols_device, HYPRE_MEMORY_DEVICE);
189 if (device_arrays_.row_indexes_device) {
190 hypre_TFree(device_arrays_.row_indexes_device, HYPRE_MEMORY_DEVICE);
192 if (device_arrays_.indices_device) {
193 hypre_TFree(device_arrays_.indices_device, HYPRE_MEMORY_DEVICE);
217 OPM_TIMEBLOCK(prec_update);
221 A_, A_hypre_, sparsity_pattern_, host_arrays_, device_arrays_, use_gpu_backend_);
224 HYPRE_ParCSRMatrix parcsr_A;
225 HYPRE_SAFE_CALL(HYPRE_IJMatrixGetObject(A_hypre_,
reinterpret_cast<void**
>(&parcsr_A)));
228 HYPRE_ParVector par_x, par_b;
229 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(x_hypre_,
reinterpret_cast<void**
>(&par_x)));
230 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(b_hypre_,
reinterpret_cast<void**
>(&par_b)));
233 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetup(solver_, parcsr_A, par_b, par_x));
244 void pre(X& v, Y& )
override
246 comm_.copyOwnerToAll(v, v);
259 void apply(X& v,
const Y& d)
override
261 OPM_TIMEBLOCK(prec_apply);
268 HYPRE_ParCSRMatrix parcsr_A;
269 HYPRE_ParVector par_x, par_b;
270 HYPRE_SAFE_CALL(HYPRE_IJMatrixGetObject(A_hypre_,
reinterpret_cast<void**
>(&parcsr_A)));
271 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(x_hypre_,
reinterpret_cast<void**
>(&par_x)));
272 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(b_hypre_,
reinterpret_cast<void**
>(&par_b)));
275 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSolve(solver_, parcsr_A, par_b, par_x));
281 comm_.copyOwnerToAll(v, v);
300 Dune::SolverCategory::Category
category()
const override
302 return std::is_same_v<Comm, Dune::Amg::SequentialInformation> ? Dune::SolverCategory::sequential
303 : Dune::SolverCategory::overlapping;
331 HYPRE_Solver solver_ =
nullptr;
332 HYPRE_IJMatrix A_hypre_ =
nullptr;
333 HYPRE_IJVector x_hypre_ =
nullptr;
334 HYPRE_IJVector b_hypre_ =
nullptr;
337 bool use_gpu_backend_ =
false;
Interface class adding the update() method to the preconditioner interface.
Definition PreconditionerWithUpdate.hpp:32
Wrapper for Hypre's BoomerAMG preconditioner.
Definition HyprePreconditioner.hpp:67
M matrix_type
The matrix type the preconditioner is for.
Definition HyprePreconditioner.hpp:70
void apply(X &v, const Y &d) override
Applies the preconditioner to a vector.
Definition HyprePreconditioner.hpp:259
typename M::field_type matrix_field_type
The field type of the matrix.
Definition HyprePreconditioner.hpp:72
X domain_type
The domain type of the preconditioner.
Definition HyprePreconditioner.hpp:74
void update() override
Updates the preconditioner with the current matrix values.
Definition HyprePreconditioner.hpp:215
~HyprePreconditioner()
Destructor for HyprePreconditioner.
Definition HyprePreconditioner.hpp:175
Dune::SolverCategory::Category category() const override
Returns the solver category.
Definition HyprePreconditioner.hpp:300
typename X::field_type vector_field_type
The field type of the vectors.
Definition HyprePreconditioner.hpp:78
void pre(X &v, Y &) override
Pre-processing step before applying the preconditioner.
Definition HyprePreconditioner.hpp:244
bool hasPerfectUpdate() const override
Checks if the preconditioner has a perfect update.
Definition HyprePreconditioner.hpp:311
HyprePreconditioner(const M &A, const Opm::PropertyTree prm, const Comm &comm)
Constructor for the HyprePreconditioner class.
Definition HyprePreconditioner.hpp:89
Y range_type
The range type of the preconditioner.
Definition HyprePreconditioner.hpp:76
void post(X &) override
Post-processing step after applying the preconditioner.
Definition HyprePreconditioner.hpp:291
Hierarchical collection of key/value pairs.
Definition PropertyTree.hpp:39
T get(const std::string &key) const
Retrieve property value given hierarchical property key.
Definition PropertyTree.cpp:59
Unified interface for Hypre operations with both CPU and GPU data structures.
Definition HypreInterface.hpp:61
void destroySolver(HYPRE_Solver solver)
Destroy Hypre solver.
Definition HypreSetup.hpp:219
void transferVectorToHypre(const VectorType &vec, HYPRE_IJVector hypre_vec, HostArrays &host_arrays, const DeviceArrays &device_arrays, const ParallelInfo &par_info, bool use_gpu_backend)
Transfer vector to Hypre from any vector type (CPU or GPU)
Definition HypreInterface.hpp:164
ParallelInfo setupHypreParallelInfo(const CommType &comm, const MatrixType &matrix)
Setup parallel information for Hypre (automatically detects serial/parallel)
Definition HypreSetup.hpp:263
void destroyMatrix(HYPRE_IJMatrix matrix)
Destroy Hypre matrix.
Definition HypreSetup.hpp:233
HYPRE_Solver createAMGSolver()
Create Hypre solver (BoomerAMG)
Definition HypreSetup.hpp:117
std::vector< HYPRE_Int > computeRowIndexes(const MatrixType &matrix, const std::vector< HYPRE_Int > &ncols, const std::vector< int > &local_dune_to_local_hypre, bool owner_first)
Compute row indexes for HYPRE_IJMatrixSetValues2.
Definition HypreSetup.hpp:634
HYPRE_IJMatrix createMatrix(HYPRE_Int N, HYPRE_Int dof_offset, const CommType &comm)
Create Hypre matrix.
Definition HypreSetup.hpp:170
void updateMatrixValues(const MatrixType &matrix, HYPRE_IJMatrix hypre_matrix, const SparsityPattern &sparsity_pattern, const HostArrays &host_arrays, const DeviceArrays &device_arrays, bool use_gpu_backend)
Update matrix values in Hypre.
Definition HypreInterface.hpp:200
SparsityPattern setupSparsityPattern(const MatrixType &matrix, const ParallelInfo &par_info, bool owner_first)
Setup sparsity pattern from matrix (automatically detects CPU/GPU type)
Definition HypreSetup.hpp:465
void initialize(bool use_gpu_backend)
Initialize the Hypre library and set memory/execution policy.
Definition HypreSetup.hpp:89
HYPRE_IJVector createVector(HYPRE_Int N, HYPRE_Int dof_offset, const CommType &comm)
Create Hypre vector.
Definition HypreSetup.hpp:197
void destroyVector(HYPRE_IJVector vector)
Destroy Hypre vector.
Definition HypreSetup.hpp:247
void setSolverParameters(HYPRE_Solver solver, const PropertyTree &prm, bool use_gpu_backend)
Set solver parameters from property tree.
Definition HypreSetup.hpp:133
void transferVectorFromHypre(HYPRE_IJVector hypre_vec, VectorType &vec, HostArrays &host_arrays, const DeviceArrays &device_arrays, const ParallelInfo &par_info, bool use_gpu_backend)
Transfer vector from Hypre to any vector type (CPU or GPU)
Definition HypreInterface.hpp:182
GPU device memory arrays for HYPRE operations with GPU backend.
Definition HypreDataStructures.hpp:137
HYPRE_Real * vector_buffer_device
Device buffer for vector operations Used when input type and backend are different,...
Definition HypreDataStructures.hpp:149
HYPRE_Int * ncols_device
Mirrors host data arrays.
Definition HypreDataStructures.hpp:139
HYPRE_Real * matrix_buffer_device
Device buffer for matrix values, only needed for CPU input + GPU backend.
Definition HypreDataStructures.hpp:155
Host arrays for HYPRE matrix and vector data transfers.
Definition HypreDataStructures.hpp:106
std::vector< HYPRE_BigInt > indices
Global DOF indices for owned degrees of freedom.
Definition HypreDataStructures.hpp:120
std::vector< HYPRE_Real > continuous_vector_values
Temporary buffer for vector values in non-owner-first ordering.
Definition HypreDataStructures.hpp:128
std::vector< HYPRE_Int > row_indexes
Pre-computed row start indexes for HYPRE_IJMatrixSetValues2.
Definition HypreDataStructures.hpp:113
Parallel domain decomposition information for HYPRE-Dune interface.
Definition HypreDataStructures.hpp:37
bool owner_first
Whether owned DOFs appear first in local Dune ordering.
Definition HypreDataStructures.hpp:77
std::vector< int > local_dune_to_local_hypre
Mapping from local Dune indices to local HYPRE indices.
Definition HypreDataStructures.hpp:44
HYPRE_Int dof_offset
Global index offset for this process's owned DOFs.
Definition HypreDataStructures.hpp:69
HYPRE_Int N_owned
Number of DOFs owned by this MPI process.
Definition HypreDataStructures.hpp:62
Compressed Sparse Row (CSR) sparsity pattern for HYPRE matrix assembly.
Definition HypreDataStructures.hpp:86
std::vector< HYPRE_BigInt > rows
Global row indices for owned rows (size: N_owned)
Definition HypreDataStructures.hpp:91
std::vector< HYPRE_Int > ncols
Non-zero entries per owned row (size: N_owned)
Definition HypreDataStructures.hpp:88
HYPRE_Int nnz
Number of non-zero entries in matrix.
Definition HypreDataStructures.hpp:97
std::vector< HYPRE_BigInt > cols
Global column indices in CSR format (size: nnz)
Definition HypreDataStructures.hpp:94
Type trait to detect if a type is a GPU type.
Definition gpu_type_detection.hpp:40