opm-simulators
GpuOwnerOverlapCopy.hpp
1 /*
2  Copyright 2022-2023 SINTEF AS, 2025 Equinor ASA
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_GPUISTL_GPUOWNEROVERLAPCOPY_HPP
20 #define OPM_GPUISTL_GPUOWNEROVERLAPCOPY_HPP
21 
22 #include <dune/istl/owneroverlapcopy.hh>
23 
24 #include <opm/simulators/linalg/FlowLinearSolverParameters.hpp>
25 #include <opm/simulators/linalg/gpuistl/GpuAwareMPISender.hpp>
26 #include <opm/simulators/linalg/gpuistl/GpuObliviousMPISender.hpp>
27 #include <opm/simulators/linalg/gpuistl/GpuVector.hpp>
28 
29 #include <mpi.h>
30 
31 #include <memory>
32 
33 #ifdef OPEN_MPI
34 #if OPEN_MPI
35 #include "mpi-ext.h"
36 #endif
37 #endif
38 
39 namespace Opm::gpuistl
40 {
41 
53 template <class field_type, class OwnerOverlapCopyCommunicationType>
55 {
56 public:
57  using X = GpuVector<field_type>;
58 
60  : m_sender(sender)
61  {
62  }
63 
64  void copyOwnerToAll(const X& source, X& dest) const
65  {
66  m_sender->copyOwnerToAll(source, dest);
67  }
68 
69  void dot(const X& x, const X& y, field_type& output) const
70  {
71  m_sender->dot(x, y, output);
72  }
73 
74  field_type norm(const X& x) const
75  {
76  return m_sender->norm(x);
77  }
78 
79  void project(X& x) const
80  {
81  m_sender->project(x);
82  }
83 
88  const ::Dune::Communication<MPI_Comm>& communicator() const
89  {
90  return m_sender->communicator();
91  }
92 
93 private:
94  std::shared_ptr<GPUSender<field_type, OwnerOverlapCopyCommunicationType>> m_sender;
95 };
96 
97 template <class field_type, int block_size, class OwnerOverlapCopyCommunicationType>
98 std::shared_ptr<GpuOwnerOverlapCopy<field_type, OwnerOverlapCopyCommunicationType>>
99 makeGpuOwnerOverlapCopy(const OwnerOverlapCopyCommunicationType& cpuOwnerOverlapCopy)
100 {
101 
102  const auto useGPUAwareMPI = Opm::Parameters::Get<Opm::Parameters::GpuAwareMpi>();
103  const auto verifyGPUAwareMPI = Opm::Parameters::Get<Opm::Parameters::VerifyGpuAwareMpi>();
104  std::shared_ptr<Opm::gpuistl::GPUSender<field_type, OwnerOverlapCopyCommunicationType>> gpuComm;
105 
106  if (useGPUAwareMPI) {
107  if (verifyGPUAwareMPI) {
108 
109  // Temporary solution use the GPU Direct communication solely based on these prepcrosessor statements
110  bool mpiSupportsCudaAwareAtCompileTime = false;
111  bool mpiSupportsCudaAwareAtRunTime = false;
112 
113 #if defined(MPIX_CUDA_AWARE_SUPPORT) && MPIX_CUDA_AWARE_SUPPORT
114  mpiSupportsCudaAwareAtCompileTime = true;
115 #endif /* MPIX_CUDA_AWARE_SUPPORT */
116 
117 #if defined(MPIX_CUDA_AWARE_SUPPORT)
118  if (1 == MPIX_Query_cuda_support()) {
119  mpiSupportsCudaAwareAtRunTime = true;
120  }
121 #endif /* MPIX_CUDA_AWARE_SUPPORT */
122 
123  if (!mpiSupportsCudaAwareAtCompileTime || !mpiSupportsCudaAwareAtRunTime) {
124  OPM_THROW(std::runtime_error,
125  fmt::format(fmt::runtime("The GPU-aware MPI support is not available. "
126  "CUDA aware support at compile time: {}, "
127  "CUDA aware support at runtime: {}. "
128  "Please check your MPI installation and the OPM configuration "
129  "or run with --gpu-aware-mpi=false. If you are sure that your MPI "
130  "implementation supports GPU aware MPI, you can disable this check "
131  "by setting --verify-gpu-aware-mpi=false."),
132  mpiSupportsCudaAwareAtCompileTime ? "yes" : "no",
133  mpiSupportsCudaAwareAtRunTime ? "yes" : "no"));
134  }
135  }
136  gpuComm = std::make_shared<
138  cpuOwnerOverlapCopy);
139 
140  } else {
141  gpuComm = std::make_shared<
143  cpuOwnerOverlapCopy);
144  }
145 
146  using CudaCommunication = GpuOwnerOverlapCopy<field_type, OwnerOverlapCopyCommunicationType>;
147 
148  return std::make_shared<CudaCommunication>(gpuComm);
149 }
150 } // namespace Opm::gpuistl
151 
152 #endif
CUDA compatiable variant of Dune::OwnerOverlapCopyCommunication.
Definition: GpuOwnerOverlapCopy.hpp:54
Derived class of GPUSender that handles MPI calls that should NOT use GPU direct communicatoin The im...
Definition: GpuObliviousMPISender.hpp:43
GPUSender is a wrapper class for classes which will implement copOwnerToAll This is implemented with ...
Definition: GpuSender.hpp:43
const ::Dune::Communication< MPI_Comm > & communicator() const
communicator returns the MPI communicator used by this GpuOwnerOverlapCopy
Definition: GpuOwnerOverlapCopy.hpp:88
A small, fixed‑dimension MiniVector class backed by std::array that can be used in both host and CUD...
Definition: AmgxInterface.hpp:37
Derived class of GPUSender that handles MPI made with CUDA aware MPI The copOwnerToAll function uses ...
Definition: GpuAwareMPISender.hpp:45