17 #ifndef OPM_STANDARDPRECONDITIONERS_GPU_SERIAL_HEADER 18 #define OPM_STANDARDPRECONDITIONERS_GPU_SERIAL_HEADER 20 #include <opm/simulators/linalg/gpuistl/detail/gpu_preconditioner_utils.hpp> 22 #include <dune/istl/bcrsmatrix.hh> 24 #include <type_traits> 32 template <
class Operator>
34 Dune::Amg::SequentialInformation,
35 typename std::enable_if_t<Opm::is_gpu_operator_v<Operator>>>
39 using C = Dune::Amg::SequentialInformation;
42 using V =
typename F::Vector;
46 using field_type =
typename V::field_type;
48 static constexpr
int maxblocksize = 6;
51 F::addCreator(
"ilu0", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
52 const double w = prm.
get<
double>(
"relaxation", 1.0);
55 return std::make_shared<GpuILU0>(op.getmat(), w);
58 F::addCreator(
"jac", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
59 const double w = prm.
get<
double>(
"relaxation", 1.0);
61 return std::make_shared<GPUJac>(op.getmat(), w);
70 F::addCreator(
"opmilu0", [](
const O& op, [[maybe_unused]]
const P& prm,
const std::function<V()>&, std::size_t) -> PrecPtr {
71 return op.getmat().dispatchOnBlocksize([&](
auto blockSizeVal) -> PrecPtr {
72 constexpr
int blockSize = decltype(blockSizeVal)::value;
73 const auto cpuMatrix = gpuistl::detail::makeCPUMatrix<O, Dune::FieldMatrix<field_type, blockSize, blockSize>>(op);
74 const bool split_matrix = prm.get<
bool>(
"split_matrix",
true);
75 const bool tune_gpu_kernels = prm.get<
bool>(
"tune_gpu_kernels",
true);
76 const int mixed_precision_scheme = prm.get<
int>(
"mixed_precision_scheme", 0);
77 using CPUMatrixType = std::remove_const_t<std::remove_reference_t<decltype(cpuMatrix)>>;
81 return std::make_shared<GPUILU0>(op.getmat(), cpuMatrix, split_matrix, tune_gpu_kernels, mixed_precision_scheme);
85 F::addCreator(
"dilu", [](
const O& op, [[maybe_unused]]
const P& prm,
const std::function<V()>&, std::size_t) -> PrecPtr {
86 return op.getmat().dispatchOnBlocksize([&](
auto blockSizeVal) -> PrecPtr {
87 constexpr
int blockSize = decltype(blockSizeVal)::value;
88 const auto cpuMatrix = gpuistl::detail::makeCPUMatrix<O, Dune::FieldMatrix<field_type, blockSize, blockSize>>(op);
89 const bool split_matrix = prm.get<
bool>(
"split_matrix",
true);
90 const bool tune_gpu_kernels = prm.get<
bool>(
"tune_gpu_kernels",
true);
91 const int mixed_precision_scheme = prm.get<
int>(
"mixed_precision_scheme", 0);
92 const bool reorder = prm.get<
bool>(
"reorder",
true);
93 using CPUMatrixType = std::remove_const_t<std::remove_reference_t<decltype(cpuMatrix)>>;
96 return std::make_shared<GPUDILU>(op.getmat(), cpuMatrix, split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder);
102 if constexpr (std::is_same_v<O, Dune::MatrixAdapter<M, V, V>>) {
105 F::addCreator(
"amgx", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
107 if (op.getmat().blockSize() == 1) {
109 prm_copy.
put(
"setup_frequency", Opm::Parameters::Get<Opm::Parameters::CprReuseInterval>());
110 return std::make_shared<Amgx::AmgxPreconditioner<M, V, V>>(op.getmat(), prm_copy);
112 OPM_THROW(std::logic_error,
"AMGX preconditioner only works with scalar matrices (block size 1)");
117 #if HAVE_HYPRE && HYPRE_USING_CUDA || HYPRE_USING_HIP 119 if constexpr (std::is_same_v<HYPRE_Real, typename V::field_type>) {
120 F::addCreator(
"hypre", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
122 if (op.getmat().blockSize() == 1) {
123 return std::make_shared<Hypre::HyprePreconditioner<M, V, V, Dune::Amg::SequentialInformation>>(op.getmat(), prm, Dune::Amg::SequentialInformation());
125 OPM_THROW(std::logic_error,
"Hypre preconditioner only works with scalar matrices (block size 1).");
132 F::addCreator(
"cpr", [](
const O& op,
const P& prm,
const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
133 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
134 OPM_THROW(std::logic_error,
"Pressure index out of bounds. It needs to specified for CPR");
136 using Scalar =
typename V::field_type;
139 return std::make_shared<Dune::OwningTwoLevelPreconditioner<O, GpuVector, LevelTransferPolicy>>(op, prm, weightsCalculator, pressureIndex);
142 F::addCreator(
"cprt", [](
const O& op,
const P& prm,
const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
143 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
144 OPM_THROW(std::logic_error,
"Pressure index out of bounds. It needs to specified for CPR");
146 using Scalar =
typename V::field_type;
149 return std::make_shared<Dune::OwningTwoLevelPreconditioner<O, GpuVector, LevelTransferPolicy>>(op, prm, weightsCalculator, pressureIndex);
159 #endif // OPM_STANDARDPRECONDITIONERS_GPU_SERIAL_HEADER T get(const std::string &key) const
Retrieve property value given hierarchical property key.
Definition: PropertyTree.cpp:59
void put(const std::string &key, const T &data)
Insert key/value pair into property tree.
Definition: PropertyTree.cpp:71
Definition: fvbaseprimaryvariables.hh:161
typename Operator::matrix_type Matrix
Linear algebra types.
Definition: PreconditionerFactory.hpp:67
Definition: GpuPressureTransferPolicy.hpp:52
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
ILU0 preconditioner on the GPU.
Definition: OpmGpuILU0.hpp:50
DILU preconditioner on the GPU.
Definition: GpuDILU.hpp:52
Sequential ILU0 preconditioner on the GPU through the CuSparse library.
Definition: GpuSeqILU0.hpp:51
Jacobi preconditioner on the GPU.
Definition: GpuJac.hpp:46
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:38
Definition: StandardPreconditioners_mpi.hpp:134
This is an object factory for creating preconditioners.
Definition: OwningTwoLevelPreconditioner.hpp:43
std::shared_ptr< Dune::PreconditionerWithUpdate< Vector, Vector > > PrecPtr
The type of pointer returned by create().
Definition: PreconditionerFactory.hpp:71