device_memory_resource.hpp
转到此文件的文档。
1 /*
2  * 版权所有 (c) 2019-2025, NVIDIA CORPORATION。
3  *
4  * 根据 Apache 许可,版本 2.0(“许可”)获得许可;
5  * 除非符合许可的规定,否则不得使用此文件。
6  * 您可以在以下位置获得许可的副本:
7  *
8  * https://apache.ac.cn/licenses/LICENSE-2.0
9  *
10  * 除非适用法律要求或书面同意,否则软件
11  * 在许可下分发,按“原样”提供,
12  * 不附带任何明示或暗示的保证或条件。
13  * 请参阅许可了解特定语言的管理权限和
14  * 许可下的限制。
15  */
16 #pragma once
17 
18 #include <rmm/cuda_stream_view.hpp>
19 #include <rmm/detail/aligned.hpp>
20 #include <rmm/detail/cuda_memory_resource.hpp>
21 #include <rmm/detail/export.hpp>
22 #include <rmm/detail/nvtx/ranges.hpp>
23 
24 #include <cstddef>
25 
26 namespace RMM_NAMESPACE {
27 namespace mr {
92 /**
93  * @brief 所有 librmm 设备内存分配的基类。
94  *
95  * device_memory_resource 概念支持异步内存分配(即
96  * 不需要与 host 同步)。
97  *
98  * 与 C++ 标准库中的 `std::pmr::memory_resource` 类似,
99  * `device_memory_resource` 是多态的,它定义了分配和释放
100  * GPU 设备内存所需的接口。
101  *
102  * `device_memory_resource` 的派生类必须实现纯虚函数
103  * `do_allocate` 和 `do_deallocate`。
104  *
105  * RMM 提供了几种 `device_memory_resource` 的实现,例如
106  * `cuda_memory_resource` 和 `pool_memory_resource`。
107  *
108  * 由于所有的 `device_memory_resource` 都允许异步操作,因此它们
109  * 都支持 `cuda::mr::device_accessible` 属性。这个属性表示资源
110  * 可以从 CUDA 设备代码访问。
111  *
112  * 用户定义的内存资源只需要实现 `do_allocate` 和 `do_deallocate`
113  * 即可与 RMM 一起使用。
114  *
115  * @ingroup memory_resources
116  */
118  public
119  device_memory_resource() = default;
120  virtual ~device_memory_resource() = default;
121  /// @brief 默认拷贝构造函数。
123  /// @brief 默认移动构造函数。
125  default;
126  /// @brief 默认拷贝赋值运算符。
128  default;
129  /// @brief 默认移动赋值运算符。
130  device_memory_resource& operator=(device_memory_resource&&) noexcept =
131  default;
132 
148  /**
149  * @brief 分配至少 `bytes` 大小的内存。
150  *
151  * 请求 `bytes` 大小的内存分配。返回的指针满足 `cuda::mr::device_accessible`
152  * 属性。
153  *
154  * @throws `rmm::bad_alloc` 如果无法满足分配请求。
155  *
156  * @param bytes 请求分配的字节数。
157  * @param stream 用于分配操作的 CUDA 流。
158  * @return 指向新分配内存的指针。
159  */
160  void* allocate(std::size_t bytes, cuda_stream_view stream = cuda_stream_view{})
161  {
162  RMM_FUNC_RANGE();
163  return do_allocate(bytes, stream);
164  }
165 
182  /**
183  * @brief 释放指针 `ptr` 指向的内存。
184  *
185  * 要求 `ptr` 是之前由同一个 `device_memory_resource` 的 `allocate` 方法返回的。
186  * `bytes` 参数必须等于用于获取 `ptr` 的分配请求中的 `bytes` 参数。
187  *
188  * @param ptr 要释放的内存指针。
189  * @param bytes 要释放的字节数。
190  * @param stream 用于释放操作的 CUDA 流。
191  */
192  void deallocate(void* ptr, std::size_t bytes, cuda_stream_view stream = cuda_stream_view{})
193  {
194  RMM_FUNC_RANGE();
195  do_deallocate(ptr, bytes, stream);
196  }
197 
211  /**
212  * @brief 将此资源与另一个进行比较。
213  *
214  * @param other 要比较的 device_memory_resource。
215  * @return 如果两个资源等价,则为 true,否则为 false。
216  */
217  [[nodiscard]] bool is_equal(device_memory_resource const& other) const noexcept
218  {
219  return do_is_equal(other);
220  }
221 
234  /**
235  * @brief 分配至少 `bytes` 大小的内存,对齐到 `alignment`。
236  *
237  * @throws `rmm::bad_alloc` 如果无法满足分配请求。
238  *
239  * @param bytes 请求分配的字节数。
240  * @param alignment 内存的对齐要求。
241  * @return 指向新分配内存的指针。
242  */
243  void* allocate(std::size_t bytes, std::size_t alignment)
244  {
245  RMM_FUNC_RANGE();
246  return do_allocate(rmm::align_up(bytes, alignment), cuda_stream_view{});
247  }
248 
262  /**
263  * @brief 释放指针 `ptr` 指向的内存。
264  *
265  * 要求 `ptr` 是之前由同一个 `device_memory_resource` 的 `allocate` 方法返回的。
266  * `bytes` 和 `alignment` 参数必须等于用于获取 `ptr` 的分配请求中的参数。
267  *
268  * @param ptr 要释放的内存指针。
269  * @param bytes 要释放的字节数。
270  * @param alignment 用于获取 `ptr` 的分配请求中的对齐方式。
271  */
272  void deallocate(void* ptr, std::size_t bytes, std::size_t alignment)
262  /**
273  {
274  RMM_FUNC_RANGE();
275  do_deallocate(ptr, rmm::align_up(bytes, alignment), cuda_stream_view{});
276  }
277 
291  /**
292  * @brief 异步分配至少 `bytes` 大小的内存,对齐到 `alignment`。
276  }
293  *
294  * @throws `rmm::bad_alloc` 如果无法满足分配请求。
295  *
296  * @param bytes 请求分配的字节数。
297  * @param alignment 内存的对齐要求。
271  */
298  * @param stream 用于分配操作的 CUDA 流。
262  /**
299  * @return 指向新分配内存的指针。
247  }
300  */
262  /**
301  void* allocate_async(std::size_t bytes, std::size_t alignment, cuda_stream_view stream)
302  {
303  RMM_FUNC_RANGE();
296  * @param bytes 请求分配的字节数。
304  return do_allocate(rmm::align_up(bytes, alignment), stream);
268  * @param ptr 要释放的内存指针。
305  }
306 
291  /**
319  /**
276  }
320  * @brief 异步分配至少 `bytes` 大小的内存。
321  *
322  * @throws `rmm::bad_alloc` 如果无法满足分配请求。
323  *
324  * @param bytes 请求分配的字节数。
325  * @param stream 用于分配操作的 CUDA 流。
326  * @return 指向新分配内存的指针。
327  */
328  void* allocate_async(std::size_t bytes, cuda_stream_view stream)
329  {