Go to the documentation of this file.
21#ifndef OPM_STANDARDPRECONDITIONERS_SERIAL_HPP
22#define OPM_STANDARDPRECONDITIONERS_SERIAL_HPP
26#include <opm/simulators/linalg/gpuistl_hip/PreconditionerCPUMatrixToGPUMatrix.hpp>
36#if HAVE_AVX2_EXTENSION
42template < class X, class Y>
49 void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& y) override {};
50 void post ([[maybe_unused]] X& x) override {};
51 void apply ([[maybe_unused]] X& x, [[maybe_unused]] const Y& y) override {};
52 Dune::SolverCategory::Category category() const override { return Dune::SolverCategory::sequential; };
56template < class Operator>
63 using C = Dune::Amg::SequentialInformation;
65 using M = typename F::Matrix;
66 using V = typename F::Vector;
68 F::addCreator( "ilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
69 const double w = prm.get< double>( "relaxation", 1.0);
70 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
73 F::addCreator( "duneilu", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
74 const double w = prm.get< double>( "relaxation", 1.0);
75 const int n = prm.get< int>( "ilulevel", 0);
76 const bool resort = prm.get< bool>( "resort", false);
77 return getRebuildOnUpdateWrapper<Dune::SeqILU<M, V, V>>(std::cref(op.getmat()), n, w, resort);
79 F::addCreator( "paroverilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
80 const double w = prm.get< double>( "relaxation", 1.0);
81 const int n = prm.get< int>( "ilulevel", 0);
82 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
85 F::addCreator( "ilun", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
86 const int n = prm.get< int>( "ilulevel", 0);
87 const double w = prm.get< double>( "relaxation", 1.0);
88 return std::make_shared<ParallelOverlappingILU0<M, V, V, C>>(
91 F::addCreator( "dilu", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
92 DUNE_UNUSED_PARAMETER(prm);
93 return std::make_shared<MultithreadDILU<M, V, V>>(op.getmat());
95#if HAVE_AVX2_EXTENSION
96 F::addCreator( "mixed-ilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
97 DUNE_UNUSED_PARAMETER(prm);
98 if constexpr (std::is_same_v<typename V::field_type, float>) {
99 OPM_THROW(std::logic_error, "mixed-ilu0 is not available for floats");
102 return std::make_shared<MixedPreconditioner<M,V,V>>(op.getmat());
105 F::addCreator( "mixed-dilu", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
106 DUNE_UNUSED_PARAMETER(prm);
107 if constexpr (std::is_same_v<typename V::field_type, float>) {
108 OPM_THROW(std::logic_error, "mixed-dilu is not available for floats");
111 return std::make_shared<MixedPreconditioner<M,V,V>>(op.getmat(), true);
115 F::addCreator( "legacy-mixed-ilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
116 DUNE_UNUSED_PARAMETER(prm);
117 DUNE_UNUSED_PARAMETER(op);
118 return std::make_shared<TrivialPreconditioner<V,V>>();
120 F::addCreator( "legacy-mixed-dilu", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
121 DUNE_UNUSED_PARAMETER(prm);
122 DUNE_UNUSED_PARAMETER(op);
123 return std::make_shared<TrivialPreconditioner<V,V>>();
125 F::addCreator( "jac", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
126 const int n = prm.get< int>( "repeats", 1);
127 const double w = prm.get< double>( "relaxation", 1.0);
128 return getDummyUpdateWrapper<SeqJac<M, V, V>>(op.getmat(), n, w);
130 F::addCreator( "gs", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
131 const int n = prm.get< int>( "repeats", 1);
132 const double w = prm.get< double>( "relaxation", 1.0);
133 return getDummyUpdateWrapper<SeqGS<M, V, V>>(op.getmat(), n, w);
135 F::addCreator( "sor", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
136 const int n = prm.get< int>( "repeats", 1);
137 const double w = prm.get< double>( "relaxation", 1.0);
138 return getDummyUpdateWrapper<SeqSOR<M, V, V>>(op.getmat(), n, w);
140 F::addCreator( "ssor", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
141 const int n = prm.get< int>( "repeats", 1);
142 const double w = prm.get< double>( "relaxation", 1.0);
143 return getDummyUpdateWrapper<SeqSSOR<M, V, V>>(op.getmat(), n, w);
148 if constexpr (std::is_same_v<O, Dune::MatrixAdapter<M, V, V>>) {
149 F::addCreator( "amg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
150 std::string smoother = prm.get<std::string>( "smoother", "paroverilu0");
152 std::ranges::transform(smoother, smoother.begin(), ::tolower);
153 if (smoother == "ilu0" || smoother == "paroverilu0") {
154 using Smoother = SeqILU<M, V, V>;
156 } else if (smoother == "jac") {
157 using Smoother = SeqJac<M, V, V>;
159 } else if (smoother == "gs") {
160 using Smoother = SeqGS<M, V, V>;
162 } else if (smoother == "dilu") {
165 } else if (smoother == "sor") {
166 using Smoother = SeqSOR<M, V, V>;
168 } else if (smoother == "ssor") {
169 using Smoother = SeqSSOR<M, V, V>;
171 } else if (smoother == "ilun") {
172 using Smoother = SeqILU<M, V, V>;
175 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
178 F::addCreator( "kamg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
179 std::string smoother = prm.get<std::string>( "smoother", "paroverilu0");
181 std::ranges::transform(smoother, smoother.begin(), ::tolower);
182 if (smoother == "ilu0" || smoother == "paroverilu0") {
183 using Smoother = SeqILU<M, V, V>;
185 } else if (smoother == "jac") {
186 using Smoother = SeqJac<M, V, V>;
188 } else if (smoother == "sor") {
189 using Smoother = SeqSOR<M, V, V>;
191 } else if (smoother == "gs") {
192 using Smoother = SeqGS<M, V, V>;
194 } else if (smoother == "ssor") {
195 using Smoother = SeqSSOR<M, V, V>;
197 } else if (smoother == "ilun") {
198 using Smoother = SeqILU<M, V, V>;
201 OPM_THROW(std::invalid_argument, "Properties: No smoother with name " + smoother + ".");
204 F::addCreator( "famg", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
205 if constexpr (std::is_same_v<typename V::field_type, float>) {
206 OPM_THROW(std::logic_error, "famg requires UMFPack which is not available for floats");
210 Dune::Amg::Parameters parms;
211 parms.setNoPreSmoothSteps(1);
212 parms.setNoPostSmoothSteps(1);
213 return getRebuildOnUpdateWrapper<Dune::Amg::FastAMG<O, V>>(op, crit, parms);
219 if constexpr (M::block_type::rows == 1 && M::block_type::cols == 1) {
220 F::addCreator( "amgx", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
222 prm_copy.put( "setup_frequency", Opm::Parameters::Get<Opm::Parameters::CprReuseInterval>());
223 return std::make_shared<Amgx::AmgxPreconditioner<M, V, V>>(op.getmat(), prm_copy);
230 if constexpr (M::block_type::rows == 1 && M::block_type::cols == 1 &&
231 std::is_same_v<HYPRE_Real, typename V::field_type>) {
232 F::addCreator( "hypre", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
233 return std::make_shared<linalg::HyprePreconditioner<M, V, V, Dune::Amg::SequentialInformation>>(op.getmat(), prm, Dune::Amg::SequentialInformation());
243 if constexpr (std::is_same_v<O, WellModelMatrixAdapter<M, V, V>>) {
246 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
247 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
248 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
250 using Scalar = typename V::field_type;
251 using LevelTransferPolicy
253 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
254 op, prm, weightsCalculator, pressureIndex);
260 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
261 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
262 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
264 using Scalar = typename V::field_type;
266 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
267 op, prm, weightsCalculator, pressureIndex);
271 []( const O& op, const P& prm, const std::function<V()>& weightsCalculator, std::size_t pressureIndex) {
272 if (pressureIndex == std::numeric_limits<std::size_t>::max()) {
273 OPM_THROW(std::logic_error, "Pressure index out of bounds. It needs to specified for CPR");
275 using Scalar = typename V::field_type;
277 return std::make_shared<OwningTwoLevelPreconditioner<O, V, LevelTransferPolicy>>(
278 op, prm, weightsCalculator, pressureIndex);
287 F::addCreator( "gpuilu0", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
288 const double w = prm.get< double>( "relaxation", 1.0);
289 using field_type = typename V::field_type;
290 using GpuILU0 = typename gpuistl::
292 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, GpuILU0>>(
293 std::make_shared<GpuILU0>(op.getmat(), w));
296 F::addCreator( "gpuilu0float", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
297 const double w = prm.get< double>( "relaxation", 1.0);
298 using block_type = typename V::block_type;
299 using VTo = Dune::BlockVector<Dune::FieldVector<float, block_type::dimension>>;
300 using matrix_type_to =
301 typename Dune::BCRSMatrix<Dune::FieldMatrix<float, block_type::dimension, block_type::dimension>>;
302 using GpuILU0 = typename gpuistl::
306 auto converted = std::make_shared<Converter>(op.getmat());
307 auto adapted = std::make_shared<Adapter>(std::make_shared<GpuILU0>(converted->getConvertedMatrix(), w));
308 converted->setUnderlyingPreconditioner(adapted);
312 F::addCreator( "gpujac", []( const O& op, const P& prm, const std::function<V()>&, std::size_t) {
313 const double w = prm.get< double>( "relaxation", 1.0);
314 using field_type = typename V::field_type;
321 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(
322 std::make_shared<MatrixOwner>(op.getmat(), w));
325 F::addCreator( "opmgpuilu0", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
326 const bool split_matrix = prm.get< bool>( "split_matrix", true);
327 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
328 const int mixed_precision_scheme = prm.get< int>( "mixed_precision_scheme", 0);
330 using field_type = typename V::field_type;
334 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(
337 std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme));
341 F::addCreator( "gpudilu", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
342 const bool split_matrix = prm.get< bool>( "split_matrix", true);
343 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
344 const int mixed_precision_scheme = prm.get< int>( "mixed_precision_scheme", 0);
345 const bool reorder = prm.get< bool>( "reorder", true);
346 using field_type = typename V::field_type;
350 return std::make_shared<gpuistl::PreconditionerAdapter<V, V, MatrixOwner>>(
353 std::make_shared<MatrixOwner>(op.getmat(), op.getmat(), split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder));
356 F::addCreator( "gpudilufloat", []( const O& op, [[maybe_unused]] const P& prm, const std::function<V()>&, std::size_t) {
357 const bool split_matrix = prm.get< bool>( "split_matrix", true);
358 const bool tune_gpu_kernels = prm.get< bool>( "tune_gpu_kernels", true);
359 const int mixed_precision_scheme = prm.get< int>( "mixed_precision_scheme", 0);
360 const bool reorder = prm.get< bool>( "reorder", true);
362 using block_type = typename V::block_type;
363 using VTo = Dune::BlockVector<Dune::FieldVector<float, block_type::dimension>>;
364 using matrix_type_to = typename Dune::BCRSMatrix<Dune::FieldMatrix<float, block_type::dimension, block_type::dimension>>;
372 auto converted = std::make_shared<Converter>(op.getmat());
375 auto adapted = std::make_shared<Adapter>(std::make_shared<MatrixOwner>(
376 converted->getConvertedMatrix(), converted->getConvertedMatrix(),
377 split_matrix, tune_gpu_kernels, mixed_precision_scheme, reorder));
378 converted->setUnderlyingPreconditioner(adapted);
The OpenMP thread parallelized DILU preconditioner. Definition: DILU.hpp:53
Interface class adding the update() method to the preconditioner interface. Definition: PreconditionerWithUpdate.hpp:34
Definition: PreconditionerFactory.hpp:64
Definition: PressureBhpTransferPolicy.hpp:99
Definition: PressureTransferPolicy.hpp:55
Hierarchical collection of key/value pairs. Definition: PropertyTree.hpp:39
Definition: StandardPreconditioners_serial.hpp:44
void update() override Definition: StandardPreconditioners_serial.hpp:47
void apply(X &x, const Y &y) override Definition: StandardPreconditioners_serial.hpp:51
Dune::SolverCategory::Category category() const override Definition: StandardPreconditioners_serial.hpp:52
void post(X &x) override Definition: StandardPreconditioners_serial.hpp:50
void pre(X &x, Y &y) override Definition: StandardPreconditioners_serial.hpp:49
bool hasPerfectUpdate() const override Definition: StandardPreconditioners_serial.hpp:48
TrivialPreconditioner() Definition: StandardPreconditioners_serial.hpp:46
DILU preconditioner on the GPU. Definition: GpuDILU.hpp:53
Jacobi preconditioner on the GPU. Definition: GpuJac.hpp:47
ILU0 preconditioner on the GPU. Definition: OpmGpuILU0.hpp:51
Makes a CUDA preconditioner available to a CPU simulator. Definition: PreconditionerAdapter.hpp:43
Convert a CPU matrix to a GPU matrix and use a CUDA preconditioner on the GPU. Definition: PreconditionerCPUMatrixToGPUMatrix.hpp:42
Converts the field type (eg. double to float) to benchmark single precision preconditioners. Definition: PreconditionerConvertFieldTypeAdapter.hpp:86
Definition: fvbaseprimaryvariables.hh:161
Definition: blackoilbioeffectsmodules.hh:45
@ ILU Do not perform modified ILU.
Definition: PreconditionerFactory.hpp:43
static Criterion criterion(const PropertyTree &prm) Definition: StandardPreconditioners_mpi.hpp:94
Definition: StandardPreconditioners_mpi.hpp:139
|