20 #ifndef OPM_HYPRE_SETUP_HPP 21 #define OPM_HYPRE_SETUP_HPP 23 #include <opm/simulators/linalg/PropertyTree.hpp> 24 #include <opm/simulators/linalg/hypreinterface/HypreDataStructures.hpp> 25 #include <opm/simulators/linalg/hypreinterface/HypreErrorHandling.hpp> 27 #include <dune/istl/owneroverlapcopy.hh> 28 #include <dune/istl/paamg/graph.hh> 29 #include <dune/istl/paamg/pinfo.hh> 30 #include <dune/istl/repartition.hh> 33 #include <opm/simulators/linalg/gpuistl/detail/gpu_type_detection.hpp> 34 #include <opm/simulators/linalg/gpuistl/GpuSparseMatrixWrapper.hpp> 35 #include <opm/simulators/linalg/gpuistl/hypreinterface/HypreSetup.hpp> 37 #include <opm/simulators/linalg/gpuistl_hip/detail/gpu_type_detection.hpp> 38 #include <opm/simulators/linalg/gpuistl_hip/GpuSparseMatrixWrapper.hpp> 39 #include <opm/simulators/linalg/gpuistl_hip/hypreinterface/HypreSetup.hpp> 43 #include <HYPRE_parcsr_ls.h> 44 #include <_hypre_utilities.h> 57 template <
typename CommType,
typename MatrixType>
61 template <
typename MatrixType>
64 const ParallelInfo& par_info,
67 template <
typename MatrixType>
68 std::vector<HYPRE_Int> computeRowIndexesWithMappingCpu(
const MatrixType& matrix,
69 const std::vector<HYPRE_Int>& ncols,
70 const std::vector<int>& local_dune_to_local_hypre,
73 template <
typename MatrixType>
74 std::vector<HYPRE_Int> computeRowIndexesWithMappingCpu(
const MatrixType& matrix,
75 const std::vector<int>& local_dune_to_local_hypre);
87 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 88 if (use_gpu_backend) {
89 OPM_HYPRE_SAFE_CALL(HYPRE_SetMemoryLocation(HYPRE_MEMORY_DEVICE));
90 OPM_HYPRE_SAFE_CALL(HYPRE_SetExecutionPolicy(HYPRE_EXEC_DEVICE));
92 OPM_HYPRE_SAFE_CALL(HYPRE_SetSpGemmUseVendor(
false));
94 OPM_HYPRE_SAFE_CALL(HYPRE_SetUseGpuRand(1));
95 OPM_HYPRE_SAFE_CALL(HYPRE_DeviceInitialize());
96 OPM_HYPRE_SAFE_CALL(HYPRE_PrintDeviceInfo());
100 OPM_HYPRE_SAFE_CALL(HYPRE_SetMemoryLocation(HYPRE_MEMORY_HOST));
101 OPM_HYPRE_SAFE_CALL(HYPRE_SetExecutionPolicy(HYPRE_EXEC_HOST));
115 OPM_HYPRE_SAFE_CALL(HYPRE_BoomerAMGCreate(&solver));
131 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetPrintLevel(solver, prm.
get<
int>(
"print_level", 0)));
132 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetMaxIter(solver, prm.
get<
int>(
"max_iter", 1)));
133 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetStrongThreshold(solver, prm.
get<
double>(
"strong_threshold", 0.5)));
134 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetAggTruncFactor(solver, prm.
get<
double>(
"agg_trunc_factor", 0.3)));
135 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetInterpType(solver, prm.
get<
int>(
"interp_type", 6)));
136 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetMaxLevels(solver, prm.
get<
int>(
"max_levels", 15)));
137 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetTol(solver, prm.
get<
double>(
"tolerance", 0.0)));
139 if (use_gpu_backend) {
140 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetRelaxType(solver, prm.
get<
int>(
"relax_type", 16)));
141 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetCoarsenType(solver, prm.
get<
int>(
"coarsen_type", 8)));
142 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetAggNumLevels(solver, prm.
get<
int>(
"agg_num_levels", 0)));
143 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetAggInterpType(solver, prm.
get<
int>(
"agg_interp_type", 6)));
145 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetKeepTranspose(solver,
true));
147 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetRelaxType(solver, prm.
get<
int>(
"relax_type", 13)));
148 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetCoarsenType(solver, prm.
get<
int>(
"coarsen_type", 10)));
149 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetAggNumLevels(solver, prm.
get<
int>(
"agg_num_levels", 1)));
150 HYPRE_SAFE_CALL(HYPRE_BoomerAMGSetAggInterpType(solver, prm.
get<
int>(
"agg_interp_type", 4)));
163 template <
typename CommType>
167 HYPRE_IJMatrix matrix;
169 if constexpr (std::is_same_v<CommType, Dune::Amg::SequentialInformation>) {
170 mpi_comm = MPI_COMM_SELF;
172 mpi_comm = comm.communicator();
175 HYPRE_IJMatrixCreate(mpi_comm, dof_offset, dof_offset + (N - 1), dof_offset, dof_offset + (N - 1), &matrix));
176 OPM_HYPRE_SAFE_CALL(HYPRE_IJMatrixSetObjectType(matrix, HYPRE_PARCSR));
177 OPM_HYPRE_SAFE_CALL(HYPRE_IJMatrixInitialize(matrix));
190 template <
typename CommType>
194 HYPRE_IJVector vector;
196 if constexpr (std::is_same_v<CommType, Dune::Amg::SequentialInformation>) {
197 mpi_comm = MPI_COMM_SELF;
199 mpi_comm = comm.communicator();
201 OPM_HYPRE_SAFE_CALL(HYPRE_IJVectorCreate(mpi_comm, dof_offset, dof_offset + (N - 1), &vector));
202 OPM_HYPRE_SAFE_CALL(HYPRE_IJVectorSetObjectType(vector, HYPRE_PARCSR));
203 OPM_HYPRE_SAFE_CALL(HYPRE_IJVectorInitialize(vector));
217 OPM_HYPRE_SAFE_CALL(HYPRE_BoomerAMGDestroy(solver));
231 OPM_HYPRE_SAFE_CALL(HYPRE_IJMatrixDestroy(matrix));
245 OPM_HYPRE_SAFE_CALL(HYPRE_IJVectorDestroy(vector));
256 template <
typename CommType,
typename MatrixType>
260 if constexpr (std::is_same_v<CommType, Dune::Amg::SequentialInformation>) {
356 template <
typename CommType,
typename MatrixType>
361 const auto& collective_comm = comm.communicator();
368 if (!(matrix.N() == comm.indexSet().size())) {
371 const_cast<CommType&
>(comm).buildGlobalLookup(matrix.N());
372 Dune::Amg::MatrixGraph<MatrixType> graph(const_cast<MatrixType&>(matrix));
373 Dune::fillIndexSetHoles(graph, const_cast<CommType&>(comm));
374 assert(matrix.N() == comm.indexSet().size());
380 for (
const auto& ind : comm.indexSet()) {
381 int local_ind = ind.local().local();
382 if (ind.local().attribute() == Dune::OwnerOverlapCopyAttributeSet::owner) {
394 bool owner_first =
true;
395 bool visited_ghost =
false;
396 std::size_t count = 0;
400 visited_ghost =
true;
408 owner_first = owner_first && !visited_ghost;
422 std::vector<HYPRE_Int> dof_counts_per_process(collective_comm.size());
423 collective_comm.allgather(&info.
N_owned, 1, dof_counts_per_process.data());
426 info.
dof_offset = std::accumulate(dof_counts_per_process.begin(),
427 dof_counts_per_process.begin() + collective_comm.rank(),
441 if (collective_comm.rank() > 0) {
460 template <
typename MatrixType>
466 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 468 return gpuistl::HypreInterface::setupSparsityPatternFromGpuMatrix(matrix, par_info, owner_first);
484 template <
typename MatrixType>
494 std::size_t cols_size = 0;
496 for (
auto row = matrix.begin(); row != matrix.end(); ++row) {
497 const int rowIdx = row.index();
499 cols_size += row->size();
502 pattern.
nnz = cols_size;
505 pattern.
nnz = matrix.nonzeroes();
511 pattern.
cols.resize(pattern.
nnz);
514 for (
auto row = matrix.begin(); row != matrix.end(); ++row) {
515 const int rind = row.index();
520 if (owner_first && local_rowIdx < 0) {
524 if (local_rowIdx >= 0) {
527 pattern.
rows[local_rowIdx] = global_rowIdx;
528 pattern.
ncols[local_rowIdx] = row->size();
532 for (
auto col = row->begin(); col != row->end(); ++col) {
534 assert(global_colIdx >= 0);
535 pattern.
cols[pos++] = global_colIdx;
555 template <
typename MatrixType>
556 std::vector<HYPRE_Int>
558 const std::vector<HYPRE_Int>& ncols,
559 const std::vector<int>& local_dune_to_local_hypre,
564 std::vector<HYPRE_Int> row_indexes(ncols.size());
566 for (std::size_t i = 1; i < ncols.size(); ++i) {
567 row_indexes[i] = row_indexes[i - 1] + ncols[i - 1];
572 #if HYPRE_USING_CUDA || HYPRE_USING_HIP 574 return gpuistl::HypreInterface::computeRowIndexesWithMappingGpu(matrix, local_dune_to_local_hypre);
576 #endif // HYPRE_USING_CUDA || HYPRE_USING_HIP 578 return computeRowIndexesWithMappingCpu(matrix, local_dune_to_local_hypre);
602 template <
typename MatrixType>
603 std::vector<HYPRE_Int>
604 computeRowIndexesWithMappingCpu(
const MatrixType& matrix,
const std::vector<int>& local_dune_to_local_hypre)
606 const int N = std::count_if(
607 local_dune_to_local_hypre.begin(), local_dune_to_local_hypre.end(), [](
int val) {
return val >= 0; });
608 std::vector<HYPRE_Int> row_indexes(N);
609 int data_position = 0;
611 for (
auto row = matrix.begin(); row != matrix.end(); ++row) {
612 const int dune_row_idx = row.index();
613 const int hypre_row_idx = local_dune_to_local_hypre[dune_row_idx];
615 if (hypre_row_idx >= 0) {
618 row_indexes[hypre_row_idx] = data_position;
621 data_position += row->size();
628 #endif // OPM_HYPRE_SETUP_HPP 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
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
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< int > local_dune_to_global_hypre
Mapping from local Dune indices to global HYPRE indices.
Definition: HypreDataStructures.hpp:51
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
std::vector< int > local_hypre_to_local_dune
Mapping from local HYPRE indices to local Dune indices.
Definition: HypreDataStructures.hpp:59
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 initialize(bool use_gpu_backend)
Initialize the Hypre library and set memory/execution policy.
std::vector< int > local_dune_to_local_hypre
Mapping from local Dune indices to local HYPRE indices.
Definition: HypreDataStructures.hpp:44
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
ParallelInfo setupHypreParallelInfoParallel(const CommType &comm, const MatrixType &matrix)
Create mappings between Dune and HYPRE indexing for parallel decomposition.
Definition: HypreSetup.hpp:358
HYPRE_Solver createAMGSolver()
Create Hypre solver (BoomerAMG)
Definition: HypreSetup.hpp:112
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
Unified interface for Hypre operations with both CPU and GPU data structures.
Definition: HypreCpuTransfers.hpp:35
bool owner_first
Whether owned DOFs appear first in local Dune ordering.
Definition: HypreDataStructures.hpp:77
ParallelInfo setupHypreParallelInfoSerial(HYPRE_Int N)
Setup parallel information for Hypre in serial case.
Definition: HypreSetup.hpp:274
HYPRE_Int N_owned
Number of DOFs owned by this MPI process.
Definition: HypreDataStructures.hpp:62
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
SparsityPattern setupSparsityPatternFromCpuMatrix(const MatrixType &matrix, const ParallelInfo &par_info, bool owner_first)
Setup sparsity pattern from CPU matrix (BCRSMatrix)
Definition: HypreSetup.hpp:486