opm-simulators
PreconditionerAdapter.hpp
1 /*
2  Copyright 2022-2023 SINTEF AS
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef OPM_PRECONDITIONERADAPTER_HPP
20 #define OPM_PRECONDITIONERADAPTER_HPP
21 #include <cusparse.h>
22 #include <dune/istl/preconditioner.hh>
23 #include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
24 #include <opm/simulators/linalg/gpuistl/GpuVector.hpp>
25 #include <opm/simulators/linalg/gpuistl/PreconditionerHolder.hpp>
26 #include <opm/simulators/linalg/gpuistl/detail/preconditioner_should_call_post_pre.hpp>
27 
28 
29 namespace Opm::gpuistl
30 {
39 template <class X, class Y, class CudaPreconditionerType>
41  : public Dune::PreconditionerWithUpdate<X, Y>,
42  public PreconditionerHolder<GpuVector<typename X::field_type>, GpuVector<typename Y::field_type>>
43 {
44 public:
46  using domain_type = X;
48  using range_type = Y;
50  using field_type = typename X::field_type;
51 
57  explicit PreconditionerAdapter(std::shared_ptr<CudaPreconditionerType> preconditioner)
58  : m_underlyingPreconditioner(preconditioner)
59  {
60  }
61 
62 
66  virtual void pre([[maybe_unused]] X& x, [[maybe_unused]] Y& b) override
67  {
68  static_assert(!detail::shouldCallPreconditionerPre<CudaPreconditionerType>(),
69  "We currently do not support Preconditioner::pre().");
70  }
71 
72 
76  virtual void apply(X& v, const Y& d) override
77  {
78  if (!m_inputBuffer) {
79  m_inputBuffer.reset(new GpuVector<field_type>(v.dim()));
80  m_outputBuffer.reset(new GpuVector<field_type>(v.dim()));
81  }
82  m_inputBuffer->copyFromHost(d);
83  m_underlyingPreconditioner->apply(*m_outputBuffer, *m_inputBuffer);
84  m_outputBuffer->copyToHost(v);
85  }
86 
87 
91  virtual void post([[maybe_unused]] X& x) override
92  {
93  static_assert(!detail::shouldCallPreconditionerPost<CudaPreconditionerType>(),
94  "We currently do not support Preconditioner::post().");
95  }
96 
97 
99  Dune::SolverCategory::Category category() const override
100  {
101  return m_underlyingPreconditioner->category();
102  }
103 
105  virtual void update() override
106  {
107  m_underlyingPreconditioner->update();
108  }
109 
110  static constexpr bool shouldCallPre()
111  {
112  return detail::shouldCallPreconditionerPost<CudaPreconditionerType>();
113  }
114  static constexpr bool shouldCallPost()
115  {
116  return detail::shouldCallPreconditionerPre<CudaPreconditionerType>();
117  }
118 
119  virtual std::shared_ptr<Dune::PreconditionerWithUpdate<GpuVector<field_type>, GpuVector<field_type>>>
121  {
122  return m_underlyingPreconditioner;
123  }
124 
125  virtual bool hasPerfectUpdate() const override {
126  return m_underlyingPreconditioner->hasPerfectUpdate();
127  }
128 
129 private:
131  std::shared_ptr<CudaPreconditionerType> m_underlyingPreconditioner;
132 
133  std::unique_ptr<GpuVector<field_type>> m_inputBuffer;
134  std::unique_ptr<GpuVector<field_type>> m_outputBuffer;
135 };
136 } // end namespace Opm::gpuistl
137 
138 #endif
Y range_type
The range type of the preconditioner.
Definition: PreconditionerAdapter.hpp:48
virtual void apply(X &v, const Y &d) override
Apply the preconditoner.
Definition: PreconditionerAdapter.hpp:76
typename X::field_type field_type
The field type of the preconditioner.
Definition: PreconditionerAdapter.hpp:50
virtual void pre([[maybe_unused]] X &x, [[maybe_unused]] Y &b) override
Prepare the preconditioner.
Definition: PreconditionerAdapter.hpp:66
Common interface for adapters that hold preconditioners.
Definition: PreconditionerHolder.hpp:33
Dune::SolverCategory::Category category() const override
Category of the preconditioner (see SolverCategory::Category)
Definition: PreconditionerAdapter.hpp:99
virtual void update() override
Calls update on the underlying CUDA preconditioner.
Definition: PreconditionerAdapter.hpp:105
Makes a CUDA preconditioner available to a CPU simulator.
Definition: PreconditionerAdapter.hpp:40
X domain_type
The domain type of the preconditioner.
Definition: PreconditionerAdapter.hpp:46
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:33
virtual std::shared_ptr< Dune::PreconditionerWithUpdate< GpuVector< field_type >, GpuVector< field_type > > > getUnderlyingPreconditioner() override
getUnderlyingPreconditioner gets the underlying preconditioner (preconditioner being held) ...
Definition: PreconditionerAdapter.hpp:120
PreconditionerAdapter(std::shared_ptr< CudaPreconditionerType > preconditioner)
Constructor.
Definition: PreconditionerAdapter.hpp:57
A small, fixed‑dimension MiniVector class backed by std::array that can be used in both host and CUD...
Definition: AmgxInterface.hpp:37
virtual void post([[maybe_unused]] X &x) override
Clean up.
Definition: PreconditionerAdapter.hpp:91