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/hypreinterface/HypreInterface.hpp> 31 #include <opm/simulators/linalg/gpuistl/detail/gpu_type_detection.hpp> 33 #include <opm/simulators/linalg/gpuistl_hip/detail/gpu_type_detection.hpp> 36 #include <dune/common/fmatrix.hh> 37 #include <dune/istl/bcrsmatrix.hh> 40 #include <HYPRE_krylov.h> 41 #include <HYPRE_parcsr_ls.h> 42 #include <_hypre_utilities.h> 68 template <
class M,
class X,
class Y,
class Comm>
96 OPM_TIMEBLOCK(prec_construct);
100 if constexpr (std::is_same_v<Comm, Dune::Amg::SequentialInformation>) {
101 mpi_comm = MPI_COMM_SELF;
103 mpi_comm = comm.communicator();
105 MPI_Comm_size(mpi_comm, &size);
106 MPI_Comm_rank(mpi_comm, &rank);
108 assert(size == comm.communicator().size());
109 assert(rank == comm.communicator().rank());
112 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 131 sparsity_pattern_.
ncols,
145 if (use_gpu_backend_) {
146 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 147 device_arrays_.
ncols_device = hypre_CTAlloc(HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
148 device_arrays_.rows_device = hypre_CTAlloc(HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
149 device_arrays_.cols_device = hypre_CTAlloc(HYPRE_BigInt, sparsity_pattern_.
nnz, HYPRE_MEMORY_DEVICE);
150 device_arrays_.row_indexes_device = hypre_CTAlloc(HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
151 device_arrays_.indices_device = hypre_CTAlloc(HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE);
157 device_arrays_.
matrix_buffer_device = hypre_CTAlloc(HYPRE_Real, A_.nonzeroes(), HYPRE_MEMORY_DEVICE);
160 hypre_TMemcpy(device_arrays_.
ncols_device, sparsity_pattern_.
ncols.data(), HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
161 hypre_TMemcpy(device_arrays_.rows_device, sparsity_pattern_.
rows.data(), HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
162 hypre_TMemcpy(device_arrays_.cols_device, sparsity_pattern_.
cols.data(), HYPRE_BigInt, sparsity_pattern_.
nnz, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
163 hypre_TMemcpy(device_arrays_.row_indexes_device, host_arrays_.
row_indexes.data(), HYPRE_Int, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
164 hypre_TMemcpy(device_arrays_.indices_device, host_arrays_.
indices.data(), HYPRE_BigInt, par_info_.
N_owned, HYPRE_MEMORY_DEVICE, HYPRE_MEMORY_HOST);
185 if (use_gpu_backend_) {
186 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 188 hypre_TFree(device_arrays_.
ncols_device, HYPRE_MEMORY_DEVICE);
190 if (device_arrays_.rows_device) {
191 hypre_TFree(device_arrays_.rows_device, HYPRE_MEMORY_DEVICE);
193 if (device_arrays_.cols_device) {
194 hypre_TFree(device_arrays_.cols_device, HYPRE_MEMORY_DEVICE);
196 if (device_arrays_.row_indexes_device) {
197 hypre_TFree(device_arrays_.row_indexes_device, HYPRE_MEMORY_DEVICE);
199 if (device_arrays_.indices_device) {
200 hypre_TFree(device_arrays_.indices_device, HYPRE_MEMORY_DEVICE);
224 OPM_TIMEBLOCK(prec_update);
228 host_arrays_, device_arrays_, use_gpu_backend_);
231 HYPRE_ParCSRMatrix parcsr_A;
232 HYPRE_SAFE_CALL(HYPRE_IJMatrixGetObject(A_hypre_, reinterpret_cast<void**>(&parcsr_A)));
235 HYPRE_ParVector par_x, par_b;
236 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(x_hypre_, reinterpret_cast<void**>(&par_x)));
237 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(b_hypre_, reinterpret_cast<void**>(&par_b)));
240 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetup(solver_, parcsr_A, par_b, par_x));
251 void pre(X& v, Y& )
override 253 comm_.copyOwnerToAll(v, v);
266 void apply(X& v,
const Y& d)
override 268 OPM_TIMEBLOCK(prec_apply);
272 device_arrays_, par_info_, use_gpu_backend_);
274 device_arrays_, par_info_, use_gpu_backend_);
277 HYPRE_ParCSRMatrix parcsr_A;
278 HYPRE_ParVector par_x, par_b;
279 HYPRE_SAFE_CALL(HYPRE_IJMatrixGetObject(A_hypre_, reinterpret_cast<void**>(&parcsr_A)));
280 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(x_hypre_, reinterpret_cast<void**>(&par_x)));
281 HYPRE_SAFE_CALL(HYPRE_IJVectorGetObject(b_hypre_, reinterpret_cast<void**>(&par_b)));
284 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSolve(solver_, parcsr_A, par_b, par_x));
288 device_arrays_, par_info_, use_gpu_backend_);
291 comm_.copyOwnerToAll(v, v);
310 Dune::SolverCategory::Category
category()
const override 312 return std::is_same_v<Comm, Dune::Amg::SequentialInformation> ? Dune::SolverCategory::sequential
313 : Dune::SolverCategory::overlapping;
341 HYPRE_Solver solver_ =
nullptr;
342 HYPRE_IJMatrix A_hypre_ =
nullptr;
343 HYPRE_IJVector x_hypre_ =
nullptr;
344 HYPRE_IJVector b_hypre_ =
nullptr;
347 bool use_gpu_backend_ =
false;
HYPRE_Real * vector_buffer_device
Device buffer for vector operations Used when input type and backend are different, for transferring values between host and device.
Definition: HypreDataStructures.hpp:149
HyprePreconditioner(const M &A, const Opm::PropertyTree prm, const Comm &comm)
Constructor for the HyprePreconditioner class.
Definition: HyprePreconditioner.hpp:92
std::vector< HYPRE_BigInt > rows
Global row indices for owned rows (size: N_owned)
Definition: HypreDataStructures.hpp:91
HYPRE_Int nnz
Number of non-zero entries in matrix.
Definition: HypreDataStructures.hpp:97
void transferVectorFromHypre(HYPRE_IJVector hypre_vec, VectorType &vec, HostDataArrays &host_arrays, const DeviceDataArrays &device_arrays, const ParallelInfo &par_info, bool use_gpu_backend)
Transfer vector from Hypre to any vector type (CPU or GPU)
Definition: HypreInterface.hpp:186
Type trait to detect if a type is a GPU type.
Definition: gpu_type_detection.hpp:40
Parallel domain decomposition information for HYPRE-Dune interface.
Definition: HypreDataStructures.hpp:37
Y range_type
The range type of the preconditioner.
Definition: HyprePreconditioner.hpp:79
HYPRE_Int * ncols_device
Mirrors host data arrays.
Definition: HypreDataStructures.hpp:139
std::vector< HYPRE_BigInt > cols
Global column indices in CSR format (size: nnz)
Definition: HypreDataStructures.hpp:94
T get(const std::string &key) const
Retrieve property value given hierarchical property key.
Definition: PropertyTree.cpp:59
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:557
void destroySolver(HYPRE_Solver solver)
Destroy Hypre solver.
Definition: HypreSetup.hpp:214
Compressed Sparse Row (CSR) sparsity pattern for HYPRE matrix assembly.
Definition: HypreDataStructures.hpp:86
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:462
void apply(X &v, const Y &d) override
Applies the preconditioner to a vector.
Definition: HyprePreconditioner.hpp:266
HYPRE_IJMatrix createMatrix(HYPRE_Int N, HYPRE_Int dof_offset, const CommType &comm)
Create Hypre matrix.
Definition: HypreSetup.hpp:165
void destroyMatrix(HYPRE_IJMatrix matrix)
Destroy Hypre matrix.
Definition: HypreSetup.hpp:228
std::vector< HYPRE_Int > ncols
Non-zero entries per owned row (size: N_owned)
Definition: HypreDataStructures.hpp:88
void transferVectorToHypre(const VectorType &vec, HYPRE_IJVector hypre_vec, HostDataArrays &host_arrays, const DeviceDataArrays &device_arrays, const ParallelInfo &par_info, bool use_gpu_backend)
Transfer vector to Hypre from any vector type (CPU or GPU)
Definition: HypreInterface.hpp:166
Host arrays for HYPRE matrix and vector data transfers.
Definition: HypreDataStructures.hpp:106
bool hasPerfectUpdate() const override
Checks if the preconditioner has a perfect update.
Definition: HyprePreconditioner.hpp:321
void initialize(bool use_gpu_backend)
Initialize the Hypre library and set memory/execution policy.
X domain_type
The domain type of the preconditioner.
Definition: HyprePreconditioner.hpp:77
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:33
std::vector< int > local_dune_to_local_hypre
Mapping from local Dune indices to local HYPRE indices.
Definition: HypreDataStructures.hpp:44
Wrapper for Hypre's BoomerAMG preconditioner.
Definition: HyprePreconditioner.hpp:69
void destroyVector(HYPRE_IJVector vector)
Destroy Hypre vector.
Definition: HypreSetup.hpp:242
HYPRE_IJVector createVector(HYPRE_Int N, HYPRE_Int dof_offset, const CommType &comm)
Create Hypre vector.
Definition: HypreSetup.hpp:192
HYPRE_Solver createAMGSolver()
Create Hypre solver (BoomerAMG)
Definition: HypreSetup.hpp:112
Dune::SolverCategory::Category category() const override
Returns the solver category.
Definition: HyprePreconditioner.hpp:310
M matrix_type
The matrix type the preconditioner is for.
Definition: HyprePreconditioner.hpp:73
ParallelInfo setupHypreParallelInfo(const CommType &comm, const MatrixType &matrix)
Setup parallel information for Hypre (automatically detects serial/parallel)
Definition: HypreSetup.hpp:258
void setSolverParameters(HYPRE_Solver solver, const PropertyTree &prm, bool use_gpu_backend)
Set solver parameters from property tree.
Definition: HypreSetup.hpp:128
void update() override
Updates the preconditioner with the current matrix values.
Definition: HyprePreconditioner.hpp:222
HYPRE_Real * matrix_buffer_device
Device buffer for matrix values, only needed for CPU input + GPU backend.
Definition: HypreDataStructures.hpp:155
typename M::field_type matrix_field_type
The field type of the matrix.
Definition: HyprePreconditioner.hpp:75
bool owner_first
Whether owned DOFs appear first in local Dune ordering.
Definition: HypreDataStructures.hpp:77
GPU device memory arrays for HYPRE operations with GPU backend.
Definition: HypreDataStructures.hpp:137
std::vector< HYPRE_Real > continuous_vector_values
Temporary buffer for vector values in non-owner-first ordering.
Definition: HypreDataStructures.hpp:128
HYPRE_Int N_owned
Number of DOFs owned by this MPI process.
Definition: HypreDataStructures.hpp:62
std::vector< HYPRE_Int > row_indexes
Pre-computed row start indexes for HYPRE_IJMatrixSetValues2.
Definition: HypreDataStructures.hpp:113
void updateMatrixValues(const MatrixType &matrix, HYPRE_IJMatrix hypre_matrix, const SparsityPattern &sparsity_pattern, const HostDataArrays &host_arrays, const DeviceDataArrays &device_arrays, bool use_gpu_backend)
Update matrix values in Hypre.
Definition: HypreInterface.hpp:206
void post(X &) override
Post-processing step after applying the preconditioner.
Definition: HyprePreconditioner.hpp:301
std::vector< HYPRE_BigInt > indices
Global DOF indices for owned degrees of freedom.
Definition: HypreDataStructures.hpp:120
~HyprePreconditioner()
Destructor for HyprePreconditioner.
Definition: HyprePreconditioner.hpp:182
HYPRE_Int dof_offset
Global index offset for this process's owned DOFs.
Definition: HypreDataStructures.hpp:69
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:38
typename X::field_type vector_field_type
The field type of the vectors.
Definition: HyprePreconditioner.hpp:81
void pre(X &v, Y &) override
Pre-processing step before applying the preconditioner.
Definition: HyprePreconditioner.hpp:251