system_memory_resource.hpp
转到此文件的文档。
1 /*
2  * 版权所有 (c) 2024-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_device.hpp>
19 #include <rmm/cuda_stream_view.hpp>
20 #include <rmm/detail/error.hpp>
21 #include <rmm/detail/export.hpp>
22 #include <rmm/detail/format.hpp>
24 
25 #include <cstddef>
26 #include <string>
27 
28 namespace RMM_NAMESPACE {
29 namespace mr {
30 
31 namespace detail {
38 // 检查指定设备上是否支持系统分配内存 (SAM)。static bool is_system_memory_supported(cuda_device_id device_id)
39 {
40  int pageableMemoryAccess;
41  RMM_CUDA_TRY(cudaDeviceGetAttribute(
42  &pageableMemoryAccess, cudaDevAttrPageableMemoryAccess, device_id.value()));
43  return pageableMemoryAccess == 1;
44 }
45 } // namespace detail
46 
74 // system_memory_resource 是 device_memory_resource 的派生类,使用 malloc/free 进行分配/释放。class system_memory_resource final : public device_memory_resource {
75  public
77  {
78  RMM_EXPECTS(rmm::mr::detail::is_system_memory_supported(rmm::get_current_cuda_device()),
79  "此硬件/软件版本不支持系统内存分配器。");
80  }
81  ~system_memory_resource() override = default;
82  // 默认拷贝构造函数。system_memory_resource(system_memory_resource const&) = default;
84  // 默认拷贝赋值运算符。system_memory_resource& operator=(system_memory_resource const&) =
85  default;
86  // 默认移动赋值运算符。system_memory_resource& operator=(system_memory_resource&&) =
87  default;
88 
89  private
101  // 使用 `malloc` 分配内存并返回指向已分配内存的指针。void* do_allocate(std::size_t bytes, [[maybe_unused]] cuda_stream_view stream) override
102  {
103  try {
104  return rmm::detail::aligned_host_allocate(
105  bytes, CUDA_ALLOCATION_ALIGNMENT, [](std::size_t size) { return ::operator new(size); });
106  } catch (std::bad_alloc const& e) {
107  auto const msg = std::string("分配失败 ") + rmm::detail::format_bytes(bytes) +
108  std::string("内存:") + e.what();
109  RMM_FAIL(msg.c_str(), rmm::out_of_memory);
110  }
111  }
112 
123  // 使用 `free` 释放由 `do_allocate` 分配的内存。void do_deallocate(void* ptr,
124  [[maybe_unused]] std::size_t bytes,
125  cuda_stream_view stream) override
126  {
127  // 使用 cudaFree 时,CUDA 运行时会跟踪相关的操作并进行隐式同步。然而,对于 SAM,由于 free 是即时的,我们需要等待进行中的
128  // CUDA 操作完成后再释放内存,以避免潜在的 use-after-free 错误或竞态条件。
129  //
130  // In `cudaFree`, the CUDA runtime keeps track of dependent operations and does implicit synchronization. However, with SAM, since `free` is immediate, we need to wait for in-flight CUDA operations to finish before freeing the memory, to avoid potential use-after-free errors or race conditions.stream.synchronize();
131 
132 
133  rmm::detail::aligned_host_deallocate(
134  ptr, bytes, CUDA_ALLOCATION_ALIGNMENT, [](void* ptr) { ::operator delete(ptr); });
135  }
136 
147  // 比较是否相等。system_memory_resource 对象仅当它们是同一类型时才相等。[[nodiscard]] bool do_is_equal(device_memory_resource const& other) const noexcept override
148  {
149  return dynamic_cast<system_memory_resource const*>(&other) != nullptr;
150  }
156  // 启用 cuda::mr::device_accessible 属性。friend void get_property(system_memory_resource const&, cuda::mr::device_accessible) noexcept {}
157 
163  // 启用 cuda::mr::host_accessible 属性。friend void get_property(system_memory_resource const&, cuda::mr::host_accessible) noexcept {}
164 };
165 
166 // 静态属性检查
167 static_assert(cuda::mr::async_resource_with<system_memory_resource, cuda::mr::device_accessible>);
168 static_assert(cuda::mr::async_resource_with<system_memory_resource, cuda::mr::host_accessible>); // end of group
170 } // namespace mr
171 } // namespace RMM_NAMESPACE
CUDA stream 的强类型非拥有包装器,带默认构造函数。
定义: cuda_stream_view.hpp:39
void synchronize() const
同步视图化的 CUDA stream。
定义: cuda_stream_view.hpp:106
librmm 设备内存分配的基类。
定义: device_memory_resource.hpp:92
device_memory_resource 的派生类,使用 malloc/free 进行分配/释放。
定义: system_memory_resource.hpp:74
system_memory_resource(system_memory_resource const &)=default
默认拷贝构造函数。
system_memory_resource(system_memory_resource &&)=default
默认拷贝构造函数。
system_memory_resource & operator=(system_memory_resource const &)=default
默认拷贝赋值运算符。
friend void get_property(system_memory_resource const &, cuda::mr::device_accessible) noexcept
启用 cuda::mr::device_accessible 属性。
定义: system_memory_resource.hpp:156
friend void get_property(system_memory_resource const &, cuda::mr::host_accessible) noexcept
启用 cuda::mr::host_accessible 属性。
定义: system_memory_resource.hpp:163
system_memory_resource & operator=(system_memory_resource &&)=default
默认移动赋值运算符。
RMM 内存不足时抛出的异常。
定义: error.hpp:87
cuda_device_id get_current_cuda_device()
返回当前设备的 cuda_device_id。
定义: cuda_device.hpp:99
static constexpr std::size_t CUDA_ALLOCATION_ALIGNMENT
CUDA 内存分配使用的默认对齐方式。
定义: aligned.hpp:43
用于 CUDA 设备标识符的强类型。
定义: cuda_device.hpp:41
constexpr value_type value() const noexcept
包装的整数值。
定义: cuda_device.hpp:57
static bool is_system_memory_supported(cuda_device_id device_id)
检查指定设备上是否支持系统分配内存 (SAM)。
定义: system_memory_resource.hpp:38