17 #ifndef OPM_STANDARDPRECONDITIONERS_GPU_SERIAL_HEADER 18 #define OPM_STANDARDPRECONDITIONERS_GPU_SERIAL_HEADER 21 #include <opm/simulators/linalg/gpuistl_hip/detail/gpu_preconditioner_utils.hpp> 23 #include <opm/simulators/linalg/gpuistl/detail/gpu_preconditioner_utils.hpp> 26 #include <dune/istl/bcrsmatrix.hh> 28 #include <type_traits> 36 template <
class Operator>
38 Dune::Amg::SequentialInformation,
39 typename std::enable_if_t<Opm::is_gpu_operator_v<Operator>>>
43 using C = Dune::Amg::SequentialInformation;
46 using V =
typename F::Vector;
50 using field_type =
typename V::field_type;
52 static constexpr
int maxblocksize = 6;
55 F::addCreator(
"ilu0", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
56 const double w = prm.
get<
double>(
"relaxation", 1.0);
59 return std::make_shared<GpuILU0>(op.getmat(), w);
62 F::addCreator(
"jac", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
63 const double w = prm.
get<
double>(
"relaxation", 1.0);
65 return std::make_shared<GPUJac>(op.getmat(), w);
74 F::addCreator(
"opmilu0", [](
const O& op, [[maybe_unused]]
const P& prm,
const std::function<V()>&, std::size_t) -> PrecPtr {
75 return op.getmat().dispatchOnBlocksize([&](
auto blockSizeVal) -> PrecPtr {
76 constexpr
int blockSize = decltype(blockSizeVal)::value;
77 const auto cpuMatrix = gpuistl::detail::makeCPUMatrix<O, Dune::FieldMatrix<field_type, blockSize, blockSize>>(op);
78 const bool split_matrix = prm.get<
bool>(
"split_matrix",
true);
79 const bool tune_gpu_kernels = prm.get<
bool>(
"tune_gpu_kernels",
true);
80 const int mixed_precision_scheme = prm.get<
int>(
"mixed_precision_scheme", 0);
81 using CPUMatrixType = std::remove_const_t<std::remove_reference_t<decltype(cpuMatrix)>>;
85 return std::make_shared<GPUILU0>(op.getmat(), cpuMatrix, split_matrix, tune_gpu_kernels, mixed_precision_scheme);
89 F::addCreator(
"dilu", [](
const O& op, [[maybe_unused]]
const P& prm,
const std::function<V()>&, std::size_t) -> PrecPtr {
90 return op.getmat().dispatchOnBlocksize([&](
auto blockSizeVal) -> PrecPtr {
91 constexpr
int blockSize = decltype(blockSizeVal)::value;
92 const auto cpuMatrix = gpuistl::detail::makeCPUMatrix<O, Dune::FieldMatrix<field_type, blockSize, blockSize>>(op);
93 const bool split_matrix = prm.get<
bool>(
"split_matrix",
true);
94 const bool tune_gpu_kernels = prm.get<
bool>(
"tune_gpu_kernels",
true);
95 const int mixed_precision_scheme = prm.get<
int>(
"mixed_precision_scheme", 0);
96 const bool reorder = prm.get<
bool>(
"reorder",
true);
97 using CPUMatrixType = std::remove_const_t<std::remove_reference_t<decltype(cpuMatrix)>>;
100 return std::make_shared<GPUDILU>(op.getmat(), cpuMatrix, split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder);
106 if constexpr (std::is_same_v<O, Dune::MatrixAdapter<M, V, V>>) {
109 F::addCreator(
"amgx", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
111 if (op.getmat().blockSize() == 1) {
113 prm_copy.
put(
"setup_frequency", Opm::Parameters::Get<Opm::Parameters::CprReuseInterval>());
114 return std::make_shared<Amgx::AmgxPreconditioner<M, V, V>>(op.getmat(), prm_copy);
116 OPM_THROW(std::logic_error,
"AMGX preconditioner only works with scalar matrices (block size 1)");
121 #if HAVE_HYPRE && (HYPRE_USING_CUDA || HYPRE_USING_HIP) 123 if constexpr (std::is_same_v<HYPRE_Real, typename V::field_type>) {
124 F::addCreator(
"hypre", [](
const O& op,
const P& prm,
const std::function<V()>&, std::size_t) {
126 if (op.getmat().blockSize() == 1) {
127 return std::make_shared<linalg::HyprePreconditioner<M, V, V, Dune::Amg::SequentialInformation>>(op.getmat(), prm, Dune::Amg::SequentialInformation());
129 OPM_THROW(std::logic_error,
"Hypre preconditioner only works with scalar matrices (block size 1).");
136 F::addCreator(
"cpr", [](
const O& op,
const P& prm,
const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
137 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
138 OPM_THROW(std::logic_error,
"Pressure index out of bounds. It needs to specified for CPR");
140 using Scalar =
typename V::field_type;
143 return std::make_shared<Dune::OwningTwoLevelPreconditioner<O, GpuVector, LevelTransferPolicy>>(op, prm, weightsCalculator, pressureIndex);
146 F::addCreator(
"cprt", [](
const O& op,
const P& prm,
const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
147 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
148 OPM_THROW(std::logic_error,
"Pressure index out of bounds. It needs to specified for CPR");
150 using Scalar =
typename V::field_type;
153 return std::make_shared<Dune::OwningTwoLevelPreconditioner<O, GpuVector, LevelTransferPolicy>>(op, prm, weightsCalculator, pressureIndex);
163 #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
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
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