PinnedMemoryHolder.hpp
Go to the documentation of this file.
1/*
2 Copyright 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
20#ifndef OPM_SIMULATORS_LINALG_GPUISTL_PINNEDMEMORYHOLDER_HPP
21#define OPM_SIMULATORS_LINALG_GPUISTL_PINNEDMEMORYHOLDER_HPP
22
23
25
26#include <cuda_runtime.h>
27
28#include <fmt/format.h>
29
30namespace Opm
31{
32namespace gpuistl
33{
34
44 template <class T>
46 {
47 public:
56 PinnedMemoryHolder(T* ptr, std::size_t numberOfElements, unsigned int flags = cudaHostRegisterDefault)
57 : m_ptr(ptr)
58 , m_numberOfElements(numberOfElements)
59 {
60 if (m_ptr && m_numberOfElements > 0) {
61 std::size_t sizeInBytes = numberOfElements * sizeof(T);
62 OPM_GPU_SAFE_CALL(cudaHostRegister(static_cast<void*>(m_ptr), sizeInBytes, flags));
63 }
64 }
65
70 {
71 if (m_ptr && m_numberOfElements > 0)
72 OPM_GPU_SAFE_CALL(cudaHostUnregister(static_cast<void*>(m_ptr)));
73 }
74
75 // Disable copy constructor and copy assignment operator
78
79 // Enable move constructor and move assignment operator
81 : m_ptr(other.m_ptr)
82 , m_numberOfElements(other.m_numberOfElements)
83 {
84 other.m_ptr = nullptr;
85 other.m_numberOfElements = 0;
86 }
87
89 {
90 if (this != &other) {
91 // Unregister existing memory, if any
92 if (m_ptr && m_numberOfElements > 0) {
93 OPM_GPU_SAFE_CALL(cudaHostUnregister(static_cast<void*>(m_ptr)));
94 }
95
96 // Transfer ownership
97 m_ptr = other.m_ptr;
98 m_numberOfElements = other.m_numberOfElements;
99
100 // Leave other in a valid but empty state
101 other.m_ptr = nullptr;
102 other.m_numberOfElements = 0;
103 }
104 return *this;
105 }
106
111 T* get() const
112 {
113 return m_ptr;
114 }
115
120 std::size_t numberOfElements() const
121 {
122 return m_numberOfElements;
123 }
124
125 private:
126 T* m_ptr;
127 std::size_t m_numberOfElements;
128 };
129
130} // namespace gpuistl
131} // namespace Opm
132
133#endif // OPM_SIMULATORS_LINALG_GPUISTL_PINNEDMEMORYHOLDER_HPP
RAII class for pinning host memory using cudaHostRegister.
Definition: PinnedMemoryHolder.hpp:46
T * get() const
Gets the pointer to the pinned memory.
Definition: PinnedMemoryHolder.hpp:111
PinnedMemoryHolder(T *ptr, std::size_t numberOfElements, unsigned int flags=cudaHostRegisterDefault)
Constructs a PinnedMemoryHolder and registers the host memory.
Definition: PinnedMemoryHolder.hpp:56
PinnedMemoryHolder(const PinnedMemoryHolder &)=delete
~PinnedMemoryHolder()
Destructor. Unregisters the host memory.
Definition: PinnedMemoryHolder.hpp:69
PinnedMemoryHolder & operator=(PinnedMemoryHolder &&other) noexcept
Definition: PinnedMemoryHolder.hpp:88
PinnedMemoryHolder & operator=(const PinnedMemoryHolder &)=delete
PinnedMemoryHolder(PinnedMemoryHolder &&other) noexcept
Definition: PinnedMemoryHolder.hpp:80
std::size_t numberOfElements() const
Gets the number of elements in the pinned memory region.
Definition: PinnedMemoryHolder.hpp:120
#define OPM_GPU_SAFE_CALL(expression)
OPM_GPU_SAFE_CALL checks the return type of the GPU expression (function call) and throws an exceptio...
Definition: gpu_safe_call.hpp:150
Definition: blackoilboundaryratevector.hh:39