内存资源
-
namespace mr
- group 内存资源
类型别名
-
using device_resource_ref = cuda::mr::resource_ref<cuda::mr::device_accessible>
cuda::mr::resource_ref
的别名,具有属性cuda::mr::device_accessible
。
-
using device_async_resource_ref = cuda::mr::async_resource_ref<cuda::mr::device_accessible>
cuda::mr::async_resource_ref
的别名,具有属性cuda::mr::device_accessible
。
-
using host_resource_ref = cuda::mr::resource_ref<cuda::mr::host_accessible>
cuda::mr::resource_ref
的别名,具有属性cuda::mr::host_accessible
。
-
using host_async_resource_ref = cuda::mr::async_resource_ref<cuda::mr::host_accessible>
cuda::mr::async_resource_ref
的别名,具有属性cuda::mr::host_accessible
。
-
using host_device_resource_ref = cuda::mr::resource_ref<cuda::mr::host_accessible, cuda::mr::device_accessible>
cuda::mr::resource_ref
的别名,具有属性cuda::mr::host_accessible
和cuda::mr::device_accessible
。
-
using host_device_async_resource_ref = cuda::mr::async_resource_ref<cuda::mr::host_accessible, cuda::mr::device_accessible>
cuda::mr::async_resource_ref
的别名,具有属性cuda::mr::host_accessible
和cuda::mr::device_accessible
。
函数
-
inline device_memory_resource *get_per_device_resource(cuda_device_id device_id)
获取指定设备的资源。
返回指定设备的
device_memory_resource
的指针。初始资源是cuda_memory_resource
。device_id.value()
必须在范围[0, cudaGetDeviceCount())
内,否则行为未定义。此函数在并行调用
set_per_device_resource
、get_per_device_resource
、get_current_device_resource
和set_current_device_resource
时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
返回的
device_memory_resource
仅应在 CUDA 设备device_id
是当前设备时使用(例如使用cudaSetDevice()
设置)。如果在活动 CUDA 设备与创建device_memory_resource
时活动设备不同时使用device_memory_resource
,则其行为未定义。- 参数:
device_id – 目标设备的 id
- 返回:
设备
device_id
的当前device_memory_resource
指针
-
inline device_memory_resource *set_per_device_resource(cuda_device_id device_id, device_memory_resource *new_mr)
设置指定设备的
device_memory_resource
。如果
new_mr
不是nullptr
,则将由id
指定的设备的内存资源指针设置为new_mr
。否则,将id
的资源重置为初始的cuda_memory_resource
。id.value()
必须在范围[0, cudaGetDeviceCount())
内,否则行为未定义。new_mr
指向的对象必须在资源最后一次使用之后仍然存在,否则行为未定义。调用方负责维护资源对象的生命周期。此函数在并行调用
set_per_device_resource
、get_per_device_resource
、get_current_device_resource
和set_current_device_resource
时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
传入
new_mr
的资源必须在设备id
是当前 CUDA 设备时创建(例如使用cudaSetDevice()
设置)。如果在活动 CUDA 设备与创建 device_memory_resource 时活动设备不同时使用 device_memory_resource,则其行为未定义。- 参数:
device_id – 目标设备的 id
new_mr – 如果不是
nullptr
,则为新的device_memory_resource
指针,用作id
的新资源
- 返回:
id
的先前内存资源指针
-
inline device_memory_resource *get_current_device_resource()
获取当前设备的内存资源。
返回为当前设备设置的资源的指针。初始资源是
cuda_memory_resource
。“当前设备”是
cudaGetDevice
返回的设备。此函数在并行调用
set_per_device_resource
、get_per_device_resource
、get_current_device_resource
和set_current_device_resource
时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
返回的
device_memory_resource
仅应与当前 CUDA 设备一起使用。更改当前设备(例如使用cudaSetDevice()
)然后使用返回的资源可能导致未定义的行为。如果在活动 CUDA 设备与创建 device_memory_resource 时活动设备不同时使用 device_memory_resource,则其行为未定义。- 返回:
当前设备的资源指针
-
inline device_memory_resource *set_current_device_resource(device_memory_resource *new_mr)
设置当前设备的内存资源。
如果
new_mr
不是nullptr
,则将当前设备的资源指针设置为new_mr
。否则,将资源重置为初始的cuda_memory_resource
。“当前设备”是
cudaGetDevice
返回的设备。new_mr
指向的对象必须在资源最后一次使用之后仍然存在,否则行为未定义。调用方负责维护资源对象的生命周期。此函数在并行调用
set_per_device_resource
、get_per_device_resource
、get_current_device_resource
和set_current_device_resource
时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
传入
new_mr
的资源必须为当前 CUDA 设备创建。如果在活动 CUDA 设备与创建 device_memory_resource 时活动设备不同时使用 device_memory_resource,则其行为未定义。- 参数:
new_mr – 如果不是
nullptr
,则为新的资源指针,用作当前设备的资源- 返回:
当前设备的先前资源指针
-
inline device_async_resource_ref get_per_device_resource_ref(cuda_device_id device_id)
获取指定设备的
device_async_resource_ref
。返回指定设备的
device_async_resource_ref
。初始的 resource_ref 引用一个cuda_memory_resource
。device_id.value()
必须在范围[0, cudaGetDeviceCount())
内,否则行为未定义。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
返回的
device_async_resource_ref
仅应在 CUDA 设备device_id
是当前设备时使用(例如使用cudaSetDevice()
设置)。如果在活动 CUDA 设备与创建内存资源时活动设备不同时使用device_async_resource_ref
,则其行为未定义。- 参数:
device_id – 目标设备的 id
- 返回:
设备
device_id
的当前device_async_resource_ref
-
inline device_async_resource_ref set_per_device_resource_ref(cuda_device_id device_id, device_async_resource_ref new_resource_ref)
将指定设备的
device_async_resource_ref
设置为new_resource_ref
device_id.value()
必须在范围[0, cudaGetDeviceCount())
内,否则行为未定义。new_resource_ref
引用的对象必须在资源最后一次使用之后仍然存在,否则行为未定义。调用方负责维护资源对象的生命周期。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
传入
new_resource_ref
的资源必须在设备device_id
是当前 CUDA 设备时创建(例如使用cudaSetDevice()
设置)。如果在活动 CUDA 设备与创建内存资源时活动设备不同时使用device_async_resource_ref
,则其行为未定义。- 参数:
device_id – 目标设备的 id
new_resource_ref – 用于
device_id
的新的device_async_resource_ref
- 返回:
设备
device_id
的先前的device_async_resource_ref
-
inline device_async_resource_ref get_current_device_resource_ref()
获取当前设备的
device_async_resource_ref
。返回为当前设备设置的
device_async_resource_ref
。初始的 resource_ref 引用一个cuda_memory_resource
。“当前设备”是
cudaGetDevice
返回的设备。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
返回的
device_async_resource_ref
仅应与当前 CUDA 设备一起使用。更改当前设备(例如使用cudaSetDevice()
)然后使用返回的resource_ref
可能导致未定义的行为。如果在活动 CUDA 设备与创建内存资源时活动设备不同时使用device_async_resource_ref
,则其行为未定义。- 返回:
当前设备的活动
device_async_resource_ref
-
inline device_async_resource_ref set_current_device_resource_ref(device_async_resource_ref new_resource_ref)
设置当前设备的
device_async_resource_ref
。“当前设备”是
cudaGetDevice
返回的设备。new_resource_ref
引用的对象必须在资源最后一次使用之后仍然存在,否则行为未定义。调用方负责维护资源对象的生命周期。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。注意
传入
new_resource
的资源必须为当前 CUDA 设备创建。如果在活动 CUDA 设备与创建内存资源时活动设备不同时使用device_async_resource_ref
,则其行为未定义。- 参数:
new_resource_ref – 用于当前设备的新的
device_async_resource_ref
- 返回:
当前设备的先前的
device_async_resource_ref
-
inline device_async_resource_ref reset_per_device_resource_ref(cuda_device_id device_id)
将指定设备的
device_async_resource_ref
重置为初始资源。重置为对初始
cuda_memory_resource
的引用。device_id.value()
必须在范围[0, cudaGetDeviceCount())
内,否则行为未定义。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。- 参数:
device_id – 目标设备的 id
- 返回:
设备
device_id
的先前的device_async_resource_ref
-
inline device_async_resource_ref reset_current_device_resource_ref()
将当前设备的
device_async_resource_ref
重置为初始资源。重置为对初始
cuda_memory_resource
的引用。“当前设备”是cudaGetDevice
返回的设备。此函数在并行调用
set_per_device_resource_ref
、get_per_device_resource_ref
、get_current_device_resource_ref
、set_current_device_resource_ref
和 `reset_current_device_resource_ref 时是线程安全的。对这些函数中任何一个的并行调用将导致有效状态,但执行顺序未定义。- 返回:
设备
device_id
的先前的device_async_resource_ref
-
template<class Resource>
device_async_resource_ref to_device_async_resource_ref_checked(Resource *res) 将内存资源指针转换为
device_async_resource_ref
,并检查是否为nullptr
- 模板参数:
Resource – 内存资源的类型。
- 参数:
res – 内存资源的指针。
- 抛出:
std::logic_error – 如果内存资源指针为空。
- 返回:
一个指向内存资源的
device_async_resource_ref
。
变量
-
template<class Resource, class = void>
constexpr bool is_resource_adaptor = false 通过检查是否存在
get_upstream_resource
来检查资源是否为资源适配器的概念。
-
class pinned_host_memory_resource
- #include <pinned_host_memory_resource.hpp>
用于分配固定主机内存的内存资源类。
此类使用 CUDA 的
cudaHostAlloc
分配固定主机内存。它实现了cuda::mr::memory_resource
和cuda::mr::device_memory_resource
概念,以及cuda::mr::host_accessible
和cuda::mr::device_accessible
属性。公共函数
-
inline bool operator==(const pinned_host_memory_resource&) const
如果指定的资源与此资源类型相同,则为 true。
- 返回:
如果指定的资源与此资源类型相同,则为 true。
-
inline bool operator!=(const pinned_host_memory_resource&) const
如果指定的资源与此资源类型不同,则为 true,否则为 false。
- 返回:
如果指定的资源与此资源类型不同,则为 true,否则为 false。
公共静态函数
-
static inline void *allocate(std::size_t bytes, [[maybe_unused]] std::size_t alignment = rmm::RMM_DEFAULT_HOST_ALIGNMENT)
分配至少
bytes
字节的固定主机内存。- 抛出:
rmm::out_of_memory – 如果由于 CUDA 内存不足错误而无法满足请求的分配。
- 参数:
bytes – 分配的大小,以字节为单位。
alignment – 对齐方式,以字节为单位。如果未指定,则使用默认对齐方式。
- 返回:
指向新分配内存的指针。
-
static inline void *deallocate(void *ptr, std::size_t bytes, std::size_t alignment = rmm::RMM_DEFAULT_HOST_ALIGNMENT) noexcept
释放由
ptr
指向的大小为bytes
字节的内存。- 参数:
ptr – 要释放的指针。
bytes – 分配的大小。
alignment – 对齐方式,以字节为单位。如果未指定,则使用默认对齐方式。
-
static inline void *allocate_async(std::size_t bytes, [[maybe_unused]] cuda::stream_ref stream)
分配至少
bytes
字节的固定主机内存。注意
流参数被忽略,行为与 allocate 相同。
- 抛出:
rmm::out_of_memory – 如果由于 CUDA 内存不足错误而无法满足请求的分配。
- 参数:
bytes – 分配的大小,以字节为单位。
stream – 在其上执行分配的 CUDA 流(被忽略)。
- 返回:
指向新分配内存的指针。
-
static inline void *allocate_async(std::size_t bytes, std::size_t alignment, [[maybe_unused]] cuda::stream_ref stream)
分配至少
bytes
字节且对齐方式为alignment
的固定主机内存。注意
流参数被忽略,行为与 allocate 相同。
- 抛出:
rmm::out_of_memory – 如果由于 CUDA 内存不足错误而无法满足请求的分配。
- 参数:
bytes – 分配的大小,以字节为单位。
alignment – 对齐方式,以字节为单位。
stream – 在其上执行分配的 CUDA 流(被忽略)。
- 返回:
指向新分配内存的指针。
-
static inline void *deallocate_async(void *ptr, std::size_t bytes, [[maybe_unused]] cuda::stream_ref stream) noexcept
释放由
ptr
指向的大小为bytes
字节的内存。注意
流参数被忽略,行为与 deallocate 相同。
- 参数:
ptr – 要释放的指针。
bytes – 分配的大小。
stream – 在其上执行释放的 CUDA 流(被忽略)。
-
static inline void *deallocate_async(void *ptr, std::size_t bytes, std::size_t alignment, [[maybe_unused]] cuda::stream_ref stream) noexcept
释放由
ptr
指向的大小为bytes
字节且对齐方式为alignment
字节的内存。注意
流参数被忽略,行为与 deallocate 相同。
- 参数:
ptr – 要释放的指针。
bytes – 分配的大小。
alignment – 对齐方式,以字节为单位。
stream – 在其上执行释放的 CUDA 流(被忽略)。
友元
-
inline friend void get_property(pinned_host_memory_resource const&, cuda::mr::device_accessible) noexcept
启用
cuda::mr::device_accessible
属性。此属性声明
pinned_host_memory_resource
提供设备可访问内存
-
inline friend void get_property(pinned_host_memory_resource const&, cuda::mr::host_accessible) noexcept
启用
cuda::mr::host_accessible
属性。此属性声明
pinned_host_memory_resource
提供主机可访问内存
-
inline bool operator==(const pinned_host_memory_resource&) const
-
using device_resource_ref = cuda::mr::resource_ref<cuda::mr::device_accessible>
- group 设备内存资源
类型别名
-
using allocate_callback_t = std::function<void*(std::size_t, cuda_stream_view, void*)>
回调内存资源用于分配的回调函数类型。
回调函数的签名是:`void* allocate_callback_t(std::size_t bytes, cuda_stream_view stream, void* arg);`
返回一个指针,指向在
stream
上可立即使用的至少bytes
字节的分配。流有序行为要求与device_memory_resource::allocate
相同。此签名与
do_allocate
兼容,但添加了额外的函数参数arg
。arg
提供给callback_memory_resource
的构造函数,并将被转发到每次回调函数调用。
-
using deallocate_callback_t = std::function<void(void*, std::size_t, cuda_stream_view, void*)>
callback_memory_resource 用于释放的回调函数类型。
回调函数的签名是:`void deallocate_callback_t(void* ptr, std::size_t bytes, cuda_stream_view stream, void* arg);`
释放由
ptr
指向的内存。bytes
指定分配的大小(以字节为单位),并且必须等于传递给分配回调函数时的bytes
值。流有序行为要求与device_memory_resource::deallocate
相同。此签名与
do_deallocate
兼容,但添加了额外的函数参数arg
。arg
提供给callback_memory_resource
的构造函数,并将被转发到每次回调函数调用。
函数
-
template<typename T, typename U>
bool operator==(polymorphic_allocator<T> const &lhs, polymorphic_allocator<U> const &rhs) 比较两个
polymorphic_allocator
是否相等。如果两个
polymorphic_allocator
的底层内存资源比较相等,则它们相等。- 模板参数:
T – 第一个分配器的类型
U – 第二个分配器的类型
- 参数:
lhs – 要比较的第一个分配器
rhs – 要比较的第二个分配器
- 返回:
如果两个分配器相等,则为 true,否则为 false
-
template<typename T, typename U>
bool operator!=(polymorphic_allocator<T> const &lhs, polymorphic_allocator<U> const &rhs) 比较两个
polymorphic_allocator
是否不相等。如果两个
polymorphic_allocator
的底层内存资源比较不相等,则它们不相等。- 模板参数:
T – 第一个分配器的类型
U – 第二个分配器的类型
- 参数:
lhs – 要比较的第一个分配器
rhs – 要比较的第二个分配器
- 返回:
如果两个分配器不相等,则为 true,否则为 false
-
template<typename A, typename O>
bool operator==(stream_allocator_adaptor<A> const &lhs, stream_allocator_adaptor<O> const &rhs) 比较两个
stream_allocator_adaptor
是否相等。如果两个
stream_allocator_adaptor
的底层分配器比较相等,则它们相等。- 模板参数:
A – 第一个分配器的类型
O – 第二个分配器的类型
- 参数:
lhs – 要比较的第一个分配器
rhs – 要比较的第二个分配器
- 返回:
如果两个分配器相等,则为 true,否则为 false
-
template<typename A, typename O>
bool operator!=(stream_allocator_adaptor<A> const &lhs, stream_allocator_adaptor<O> const &rhs) 比较两个
stream_allocator_adaptor
是否不相等。如果两个
stream_allocator_adaptor
的底层分配器比较不相等,则它们不相等。- 模板参数:
A – 第一个分配器的类型
O – 第二个分配器的类型
- 参数:
lhs – 要比较的第一个分配器
rhs – 要比较的第二个分配器
- 返回:
如果两个分配器不相等,则为 true,否则为 false
-
template<typename Upstream>
class arena_memory_resource : public rmm::mr::device_memory_resource - #include <arena_memory_resource.hpp>
一种子分配器,强调避免碎片和可伸缩的并发支持。
分配 (
do_allocate()
) 和释放 (do_deallocate()
) 是线程安全的。此外,此类与 CUDA 每线程默认流兼容。GPU 内存被划分为一个全局 arena、用于默认流的每线程 arena 以及用于非默认流的每流 arena。每个 arena 从全局 arena 中以称为 superblocks 的块分配内存。
每个 arena 中的块使用地址排序的首次适应法进行分配。当块被释放时,如果地址是连续的,则与相邻的空闲块合并。空闲的 superblocks 返回到全局 arena。
在实际应用中,分配大小倾向于遵循幂律分布,其中大型分配很少见,但小型分配相当常见。通过在每线程 arena 中处理小型分配,可以在高并发下获得足够的性能而不会引入过多的内存碎片。
此设计受到几个针对多线程应用的现有 CPU 内存分配器(glibc malloc、Hoard、jemalloc、TCMalloc)的启发,尽管形式更简单。未来可能的改进包括使用大小类、分配缓存以及更细粒度的锁定或无锁方法。
另请参阅
Wilson, P. R., Johnstone, M. S., Neely, M., & Boles, D. (1995, September). Dynamic storage allocation: A survey and critical review. In International Workshop on Memory Management (pp. 1-116). Springer, Berlin, Heidelberg.
另请参阅
Berger, E. D., McKinley, K. S., Blumofe, R. D., & Wilson, P. R. (2000). Hoard: A scalable memory allocator for multithreaded applications. ACM Sigplan Notices, 35(11), 117-128.
另请参阅
Evans, J. (2006, April). A scalable concurrent malloc (3) implementation for FreeBSD. In Proc. of the bsdcan conference, ottawa, canada.
另请参阅
另请参阅
- 模板参数:
上游资源 – 用于为全局 arena 分配内存的内存资源。实现
rmm::mr::device_memory_resource
接口。
公共函数
-
inline explicit arena_memory_resource(device_async_resource_ref upstream_mr, std::optional<std::size_t> arena_size = std::nullopt, bool dump_log_on_failure = false)
构造一个
arena_memory_resource
。- 参数:
upstream_mr
– 用于为全局 arena 分配块的内存资源。arena_size
– 全局 arena 的大小,以字节为单位。默认为当前设备可用内存的一半。dump_log_on_failure
– 如果为 true,则在内存不足时转储内存日志。
-
inline explicit arena_memory_resource(Upstream *upstream_mr, std::optional<std::size_t> arena_size = std::nullopt, bool dump_log_on_failure = false)
构造一个
arena_memory_resource
。- 抛出:
rmm::logic_error – 如果
upstream_mr == nullptr
。- 参数:
upstream_mr
– 用于为全局 arena 分配块的内存资源。arena_size
– 全局 arena 的大小,以字节为单位。默认为当前设备可用内存的一半。dump_log_on_failure
– 如果为 true,则在内存不足时转储内存日志。
-
template<typename Upstream>
class binning_memory_resource : public rmm::mr::device_memory_resource - #include <binning_memory_resource.hpp>
从与 bin 大小相关的上游资源分配内存。
- 模板参数:
UpstreamResource
– 用于分配不属于任何配置 bin 大小的内存的 memory_resource。实现rmm::mr::device_memory_resource
接口。
公共函数
-
inline explicit binning_memory_resource(device_async_resource_ref upstream_resource)
构造一个新的 binning memory resource 对象。
最初没有 bins,因此只需使用 upstream_resource,直到使用
add_bin
添加 bin 资源。- 参数:
upstream_resource
– 用于分配 bin 池的上游内存资源。
-
inline explicit binning_memory_resource(Upstream *upstream_resource)
构造一个新的 binning memory resource 对象。
最初没有 bins,因此只需使用 upstream_resource,直到使用
add_bin
添加 bin 资源。- 抛出:
rmm::logic_error – 如果 upstream_resource 为 nullptr
- 参数:
upstream_resource
– 用于分配 bin 池的上游内存资源。
-
inline binning_memory_resource(device_async_resource_ref upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
构造一个带有一系列初始 bin 的 binning memory resource 对象。
构造一个新的 binning memory resource 并添加由范围 [2^min_size_exponent, 2^max_size_exponent] 内的
fixed_size_memory_resource
支持的 bin。例如,如果min_size_exponent==18
且max_size_exponent==22
,则创建大小为 256KiB, 512KiB, 1024KiB, 2048KiB 和 4096KiB 的 bin。- 参数:
upstream_resource
– 用于分配 bin 池的上游内存资源。min_size_exponent
– 最小的基数为 2 的指数 bin 大小。max_size_exponent
– 最大的基数为 2 的指数 bin 大小。
-
inline binning_memory_resource(Upstream *upstream_resource, int8_t min_size_exponent, int8_t max_size_exponent)
构造一个带有一系列初始 bin 的 binning memory resource 对象。
构造一个新的 binning memory resource 并添加由范围 [2^min_size_exponent, 2^max_size_exponent] 内的
fixed_size_memory_resource
支持的 bin。例如,如果min_size_exponent==18
且max_size_exponent==22
,则创建大小为 256KiB, 512KiB, 1024KiB, 2048KiB 和 4096KiB 的 bin。- 抛出:
rmm::logic_error – 如果 upstream_resource 为 nullptr
- 参数:
upstream_resource
– 用于分配 bin 池的上游内存资源。min_size_exponent
– 最小的基数为 2 的指数 bin 大小。max_size_exponent
– 最大的基数为 2 的指数 bin 大小。
-
~binning_memory_resource() override = default
销毁
binning_memory_resource
并释放从上游资源分配的所有内存。
-
inline device_async_resource_ref get_upstream_resource() const noexcept
指向的上游资源的 device_async_resource_ref
- 返回:
指向的上游资源的 device_async_resource_ref
-
inline void add_bin(std::size_t allocation_size, std::optional<device_async_resource_ref> bin_resource = std::nullopt)
向此资源添加一个 bin 分配器。
如果提供了
bin_resource
,则添加它;否则构造并添加一个fixed_size_memory_resource
。这个 bin 将用于任何小于
allocation_size
且大于下一个较小 bin 分配大小的分配。如果已经存在指定大小的 bin,则不进行任何更改。
此函数不是线程安全的。
- 参数:
allocation_size
– 此 bin 分配的最大大小bin_resource
– bin 的内存资源
-
class callback_memory_resource : public rmm::mr::device_memory_resource
- #include <callback_memory_resource.hpp>
使用提供的回调函数进行内存分配和释放的设备内存资源。
公共函数
-
inline callback_memory_resource(allocate_callback_t allocate_callback, deallocate_callback_t deallocate_callback, void *allocate_callback_arg = nullptr, void *deallocate_callback_arg = nullptr) noexcept
构造一个新的 callback memory resource。
构造一个 callback memory resource,它使用用户提供的回调函数
allocate_callback
进行分配,使用deallocate_callback
进行释放。- 参数:
allocate_callback
– 用于分配的回调函数deallocate_callback
– 用于释放的回调函数allocate_callback_arg
– 传递给allocate_callback
的附加上下文。调用者有责任在callback_memory_resource
的生命周期内维护指向的数据的生命周期。deallocate_callback_arg
– 传递给deallocate_callback
的附加上下文。调用者有责任在callback_memory_resource
的生命周期内维护指向的数据的生命周期。
-
callback_memory_resource(callback_memory_resource&&) noexcept = default
默认移动构造函数。
-
callback_memory_resource &operator=(callback_memory_resource&&) noexcept = default
默认移动赋值运算符。
- 返回:
callback_memory_resource
& 对赋值对象的引用
-
inline callback_memory_resource(allocate_callback_t allocate_callback, deallocate_callback_t deallocate_callback, void *allocate_callback_arg = nullptr, void *deallocate_callback_arg = nullptr) noexcept
-
class cuda_async_memory_resource : public rmm::mr::device_memory_resource
- #include <cuda_async_memory_resource.hpp>
使用
cudaMallocAsync
/cudaFreeAsync
进行分配/释放的device_memory_resource
派生类。公共类型
-
enum class allocation_handle_type
用于指定内存分配句柄类型的标志。
注意
这些值完全复制自
cudaMemAllocationHandleType
。我们需要在此定义自己的枚举,因为支持异步内存池的最早 CUDA 运行时版本 (CUDA 11.2) 不支持这些标志,所以我们需要一个占位符,以便在 CUDA >= 11.2 的所有版本中都能在cuda_async_memory_resource
的构造函数中一致地使用。请参阅 https://docs.nvda.net.cn/cuda/cuda-runtime-api/group__CUDART__TYPES.html 上的cudaMemAllocationHandleType
文档,并确保枚举值与 CUDA 文档保持同步。值
-
enumerator none
不允许任何导出机制。
-
enumerator posix_file_descriptor
允许使用文件描述符进行导出。仅在 POSIX 系统上允许。
-
enumerator win32
允许使用 Win32 NT 句柄进行导出。(HANDLE)
-
enumerator win32_kmt
允许使用 Win32 KMT 句柄进行导出。(D3DKMT_HANDLE)
-
enumerator fabric
允许使用 fabric 句柄进行导出。(cudaMemFabricHandle_t)
-
enumerator none
公共函数
-
inline cuda_async_memory_resource(std::optional<std::size_t> initial_pool_size = {}, std::optional<std::size_t> release_threshold = {}, std::optional<allocation_handle_type> export_handle_type = {})
构造一个
cuda_async_memory_resource
,带有所选的初始池大小和释放阈值。如果池大小超出释放阈值,则池持有的未使用内存将在下一个同步事件时释放。
- 抛出:
rmm::logic_error – 如果 CUDA 版本不支持
cudaMallocAsync
- 参数:
initial_pool_size
– 可选的池初始大小,以字节为单位。如果未提供值,初始池大小为可用 GPU 内存的一半。release_threshold
– 可选的池释放阈值大小,以字节为单位。如果未提供值,释放阈值将设置为当前设备上的总内存量。export_handle_type
– 可选的cudaMemAllocationHandleType
,表示从此资源进行的分配应支持进程间通信 (IPC)。默认为cudaMemHandleTypeNone
,不支持 IPC。
-
inline cudaMemPool_t pool_handle() const noexcept
返回底层本地 CUDA 池的句柄。
- 返回:
cudaMemPool_t 底层 CUDA 池的句柄
-
enum class allocation_handle_type
-
class cuda_async_view_memory_resource : public rmm::mr::device_memory_resource
- #include <cuda_async_view_memory_resource.hpp>
使用
cudaMallocAsync
/cudaFreeAsync
进行分配/释放的device_memory_resource
派生类。公共函数
-
inline cuda_async_view_memory_resource(cudaMemPool_t pool_handle)
构造一个
cuda_async_view_memory_resource
,它使用现有的 CUDA 内存池。提供的池不由cuda_async_view_memory_resource
拥有,并且必须在内存资源的生命周期内保持有效。- 抛出:
rmm::logic_error – 如果 CUDA 版本不支持
cudaMallocAsync
- 参数:
pool_handle
– 用于服务分配请求的 CUDA 内存池句柄。
-
inline cudaMemPool_t pool_handle() const noexcept
返回底层本地 CUDA 池的句柄。
- 返回:
cudaMemPool_t 底层 CUDA 池的句柄
-
cuda_async_view_memory_resource(cuda_async_view_memory_resource const&) = default
默认拷贝构造函数。
-
cuda_async_view_memory_resource(cuda_async_view_memory_resource&&) = default
默认移动构造函数。
-
cuda_async_view_memory_resource &operator=(cuda_async_view_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
cuda_async_view_memory_resource
& 对赋值对象的引用
-
cuda_async_view_memory_resource &operator=(cuda_async_view_memory_resource&&) = default
默认移动赋值运算符。
- 返回:
cuda_async_view_memory_resource
& 对赋值对象的引用
-
inline cuda_async_view_memory_resource(cudaMemPool_t pool_handle)
-
class cuda_memory_resource : public rmm::mr::device_memory_resource
- #include <cuda_memory_resource.hpp>
使用 cudaMalloc/Free 进行分配/释放的
device_memory_resource
派生类。公共函数
-
cuda_memory_resource(cuda_memory_resource const&) = default
默认拷贝构造函数。
-
cuda_memory_resource(cuda_memory_resource&&) = default
默认移动构造函数。
-
cuda_memory_resource &operator=(cuda_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
cuda_memory_resource
& 对赋值对象的引用
-
cuda_memory_resource &operator=(cuda_memory_resource&&) = default
默认移动赋值运算符。
- 返回:
cuda_memory_resource
& 对赋值对象的引用
-
cuda_memory_resource(cuda_memory_resource const&) = default
-
class device_memory_resource
- #include <device_memory_resource.hpp>
所有 librmm 设备内存分配的基类。
这个类是所有自定义设备内存实现必须满足的接口。
所有派生类必须实现两个私有的纯虚函数:
do_allocate
和do_deallocate
。可选地,派生类还可以重写is_equal
。默认情况下,is_equal
仅执行身份比较。公共的非虚函数
allocate
、deallocate
和is_equal
只是简单地调用私有虚函数。这样做的原因是允许在基类中实现共享的默认行为。例如,基类的allocate
函数可能会记录每一次分配,无论使用哪种派生类实现。allocate
和deallocate
API 和实现提供了流有序的内存分配。这允许优化,例如在同一流上重新使用已释放的内存,而无需流同步的开销。调用
allocate(bytes, stream_a)
(在任何派生类上)返回一个指针,该指针在stream_a
上使用是有效的。在不同的流(例如stream_b
)上使用内存是未定义行为,除非这两个流首先同步,例如使用cudaStreamSynchronize(stream_a)
或在stream_a
上记录一个 CUDA 事件,然后在stream_b
上调用cudaStreamWaitEvent(stream_b, event)
。传递给
deallocate()
的流应该是可以在其上立即使用已释放内存进行另一次分配的流。通常这是在调用deallocate()
之前最后使用该分配的流。传入的流可以由device_memory_resource
在内部用于以最少的同步管理可用内存,并且也可以在稍后时间同步,例如使用调用cudaStreamSynchronize()
。因此,销毁传递给
deallocate()
的 CUDA 流是未定义行为。如果在调用deallocate()
之前最后使用该分配的流已被销毁,或者已知该流将被销毁,那么最好同步该流(在销毁之前),然后将不同的流传递给deallocate()
(例如,默认流)。仅当活动 CUDA 设备与创建
device_memory_resource
时活动的设备相同时,才应使用device_memory_resource
。否则行为未定义。为每个设备创建
device_memory_resource
需要小心地在创建每个资源之前设置当前设备,并在资源被设置为每个设备资源时维持其生命周期。下面是一个示例循环,它为每个设备创建指向pool_memory_resource
对象的unique_ptr
,并将它们设置为该设备的每个设备资源。using pool_mr = rmm::mr::pool_memory_resource<rmm::mr::cuda_memory_resource>; std::vector<unique_ptr<pool_mr>> per_device_pools; for(int i = 0; i < N; ++i) { cudaSetDevice(i); // Note: for brevity, omitting creation of upstream and computing initial_size per_device_pools.push_back(std::make_unique<pool_mr>(upstream, initial_size)); set_per_device_resource(cuda_device_id{i}, &per_device_pools.back()); }
派生自
rmm::mr::aligned_resource_adaptor< Upstream >
,rmm::mr::arena_memory_resource< Upstream >
,rmm::mr::binning_memory_resource< Upstream >
,rmm::mr::callback_memory_resource
,rmm::mr::cuda_async_memory_resource
,rmm::mr::cuda_async_view_memory_resource
,rmm::mr::cuda_memory_resource
,rmm::mr::failure_callback_resource_adaptor< Upstream, ExceptionType >
,rmm::mr::limiting_resource_adaptor< Upstream >
,rmm::mr::logging_resource_adaptor< Upstream >
,rmm::mr::managed_memory_resource
,rmm::mr::owning_wrapper< Resource, Upstreams >
,rmm::mr::prefetch_resource_adaptor< Upstream >
,rmm::mr::sam_headroom_memory_resource
,rmm::mr::statistics_resource_adaptor< Upstream >
,rmm::mr::system_memory_resource
,rmm::mr::thread_safe_resource_adaptor< Upstream >
,rmm::mr::tracking_resource_adaptor< Upstream >
公共函数
-
device_memory_resource(device_memory_resource const&) = default
默认拷贝构造函数。
-
device_memory_resource(device_memory_resource&&) noexcept = default
默认移动构造函数。
-
device_memory_resource &operator=(device_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
device_memory_resource
& 对赋值对象的引用
-
device_memory_resource &operator=(device_memory_resource&&) noexcept = default
默认移动赋值运算符。
- 返回:
device_memory_resource
& 对赋值对象的引用
-
inline void *allocate(std::size_t bytes, cuda_stream_view stream = cuda_stream_view{})
分配至少
bytes
大小的内存。返回的指针将至少具有 256 字节对齐。
如果支持,此操作可以选择在流上执行。否则,流将被忽略,使用空流。
-
inline void deallocate(void *ptr, std::size_t bytes, cuda_stream_view stream = cuda_stream_view{})
释放
p
指向的内存。p
必须是由先前在与*this
比较相等的device_memory_resource
上调用allocate(bytes, stream)
返回的,并且其指向的存储空间尚未被释放,否则行为未定义。如果支持,此操作可以选择在流上执行。否则,流将被忽略,使用空流。
- 参数:
ptr
– 要释放的指针bytes
– 分配的大小,以字节为单位。这必须等于返回p
的allocate
调用中传递的bytes
值。stream
– 执行释放的流
-
inline bool is_equal(device_memory_resource const &other) const noexcept
将此资源与另一个资源进行比较。
两个 device_memory_resource 仅当一个
device_memory_resource
分配的内存可以从另一个释放,反之亦然时才相等。默认情况下,仅检查
*this
和other
是否指向同一对象,即不检查它们是否是同一类的两个对象。- 参数:
other
– 要比较的另一个资源- 返回:
如果两个资源等效
-
inline void *allocate(std::size_t bytes, std::size_t alignment)
分配至少
bytes
大小的内存。返回的指针将至少具有 256 字节对齐。
-
inline void *deallocate(void *ptr, std::size_t bytes, std::size_t alignment)
释放
p
指向的内存。p
必须是由先前在与*this
比较相等的device_memory_resource
上调用allocate(bytes, stream)
返回的,并且其指向的存储空间尚未被释放,否则行为未定义。- 参数:
ptr
– 要释放的指针bytes
– 分配的大小,以字节为单位。这必须等于返回p
的allocate
调用中传递的bytes
值。alignment
– 返回p
的allocate
调用中传递的对齐方式
-
inline void *allocate_async(std::size_t bytes, std::size_t alignment, cuda_stream_view stream)
分配至少
bytes
大小的内存。返回的指针将至少具有 256 字节对齐。
-
inline void *allocate_async(std::size_t bytes, cuda_stream_view stream)
分配至少
bytes
大小的内存。返回的指针将至少具有 256 字节对齐。
-
inline void *deallocate_async(void *ptr, std::size_t bytes, std::size_t alignment, cuda_stream_view stream)
释放
p
指向的内存。p
必须是由先前在与*this
比较相等的device_memory_resource
上调用allocate(bytes, stream)
返回的,并且其指向的存储空间尚未被释放,否则行为未定义。- 参数:
ptr
– 要释放的指针bytes
– 分配的大小,以字节为单位。这必须等于返回p
的allocate
调用中传递的bytes
值。alignment
– 返回p
的allocate
调用中传递的对齐方式stream
– 执行分配的流
-
inline void *deallocate_async(void *ptr, std::size_t bytes, cuda_stream_view stream)
释放
p
指向的内存。p
必须是由先前在与*this
比较相等的device_memory_resource
上调用allocate(bytes, stream)
返回的,并且其指向的存储空间尚未被释放,否则行为未定义。- 参数:
ptr
– 要释放的指针bytes
– 分配的大小,以字节为单位。这必须等于返回p
的allocate
调用中传递的bytes
值。stream
– 执行分配的流
-
inline bool operator==(device_memory_resource const &other) const noexcept
与另一个
device_memory_resource
的比较运算符。- 参数:
other
– 要比较的另一个资源- 返回:
true 如果两个资源等效
- 返回:
false 如果两个资源不等效
-
inline bool operator!=(device_memory_resource const &other) const noexcept
与另一个
device_memory_resource
的比较运算符。- 参数:
other
– 要比较的另一个资源- 返回:
false 如果两个资源等效
- 返回:
true 如果两个资源不等效
友元
-
inline friend void get_property(device_memory_resource const&, cuda::mr::device_accessible) noexcept
启用
cuda::mr::device_accessible
属性。此属性声明
device_memory_resource
提供设备可访问的内存
-
device_memory_resource(device_memory_resource const&) = default
-
template<typename Upstream>
class fixed_size_memory_resource : public detail::stream_ordered_memory_resource<fixed_size_memory_resource<Upstream>, detail::fixed_size_free_list> - #include <fixed_size_memory_resource.hpp>
一种
device_memory_resource
,它分配单个固定大小的内存块。仅支持小于配置的 block_size 的分配。
公共函数
-
inline explicit fixed_size_memory_resource(device_async_resource_ref upstream_mr, std::size_t block_size = default_block_size, std::size_t blocks_to_preallocate = default_blocks_to_preallocate)
构造一个新的
fixed_size_memory_resource
,它从upstream_mr
分配内存。当块池全部被分配时,通过从
upstream_mr
分配blocks_to_preallocate
个更多块来扩大池。- 参数:
upstream_mr
– 用于为池分配块的 device_async_resource_ref。block_size
– 要分配的块大小。blocks_to_preallocate
– 初始化池要分配的块数。
-
inline explicit fixed_size_memory_resource(Upstream *upstream_mr, std::size_t block_size = default_block_size, std::size_t blocks_to_preallocate = default_blocks_to_preallocate)
构造一个新的
fixed_size_memory_resource
,它从upstream_mr
分配内存。当块池全部被分配时,通过从
upstream_mr
分配blocks_to_preallocate
个更多块来扩大池。- 参数:
upstream_mr
– 用于为池分配块的 memory_resource。block_size
– 要分配的块大小。blocks_to_preallocate
– 初始化池要分配的块数。
-
inline ~fixed_size_memory_resource() override
销毁
fixed_size_memory_resource
并释放所有从上游分配的内存。
-
inline device_async_resource_ref get_upstream_resource() const noexcept
指向的上游资源的 device_async_resource_ref
- 返回:
指向的上游资源的 device_async_resource_ref
-
inline std::size_t get_block_size() const noexcept
获取此内存资源分配的块的大小。
- 返回:
已分配块的大小(字节),类型为 std::size_t。
-
inline explicit fixed_size_memory_resource(device_async_resource_ref upstream_mr, std::size_t block_size = default_block_size, std::size_t blocks_to_preallocate = default_blocks_to_preallocate)
-
class managed_memory_resource : public rmm::mr::device_memory_resource
- #include <managed_memory_resource.hpp>
device_memory_resource
派生类,使用 cudaMallocManaged/Free 进行分配/释放。公共函数
-
managed_memory_resource(managed_memory_resource const&) = default
默认拷贝构造函数。
-
managed_memory_resource(managed_memory_resource&&) = default
默认移动构造函数。
-
managed_memory_resource &operator=(managed_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
managed_memory_resource& 对赋值对象的引用
-
managed_memory_resource &operator=(managed_memory_resource&&) = default
默认移动赋值运算符。
- 返回:
managed_memory_resource& 对赋值对象的引用
-
managed_memory_resource(managed_memory_resource const&) = default
-
template<typename T>
class polymorphic_allocator - #include <polymorphic_allocator.hpp>
一个使用
rmm::mr::device_memory_resource
执行(解)分配的流序 Allocator。类似于
std::pmr::polymorphic_allocator
,利用device_memory_resource
的运行时多态性,允许将polymorphic_allocator
作为静态分配器类型的容器可以互操作,但根据使用的资源表现出不同的行为。与 STL 分配器不同,
polymorphic_allocator
的allocate
和deallocate
函数是流序的。使用stream_allocator_adaptor
允许与需要标准、非流序 `Allocator` 接口的接口进行互操作。- 模板参数:
T – 分配器的值类型。
公共函数
-
polymorphic_allocator() = default
使用
rmm::mr::get_current_device_resource_ref()
的返回值作为底层内存资源构造一个polymorphic_allocator
。
-
inline polymorphic_allocator(device_async_resource_ref mr)
使用提供的内存资源构造一个
polymorphic_allocator
。此构造函数提供了从
device_async_resource_ref
的隐式转换。- 参数:
mr – 用于分配的上游内存资源。
-
template<typename U>
inline polymorphic_allocator(polymorphic_allocator<U> const &other) noexcept 使用 `other` 的底层内存资源构造一个
polymorphic_allocator
。- 参数:
other – 其内存资源将用作新的
polymorphic_allocator
的底层资源的polymorphic_allocator
。
-
inline value_type *allocate(std::size_t num, cuda_stream_view stream)
使用底层内存资源为 `num` 个类型为 `T` 的对象分配存储空间。
- 参数:
num – 要分配存储空间的对象数量
stream – 执行分配所在的流
- 返回:
指向已分配存储空间的指针
-
inline void deallocate(value_type *ptr, std::size_t num, cuda_stream_view stream)
释放 `ptr` 指向的存储空间。
`ptr` 必须是从一个内存资源 `r` 分配的,该资源使用 `r.allocate(n * sizeof(T))` 与
get_upstream_resource()
比较相等。- 参数:
ptr – 指向要释放的内存的指针
num – 最初分配的对象数量
stream – 执行释放所在的流
-
template<typename Allocator>
class stream_allocator_adaptor - #include <polymorphic_allocator.hpp>
适配一个流序分配器以提供标准的 `Allocator` 接口。
流序分配器(即 `allocate/deallocate` 使用
cuda_stream_view
)不能用于期望标准 C++ `Allocator` 接口的接口中。stream_allocator_adaptor
包装了一个流序分配器和一个流,以提供标准的 `Allocator` 接口。此适配器在调用底层分配器的 `allocate` 和 `deallocate` 函数时使用包装的流。示例
my_stream_ordered_allocator<int> a{...}; cuda_stream_view s = // create stream; auto adapted = stream_allocator_adaptor(a, s); // Allocates storage for `n` int's on stream `s` int * p = std::allocator_traits<decltype(adapted)>::allocate(adapted, n);
- 模板参数:
Allocator – 要适配的流序分配器类型
公共函数
-
inline stream_allocator_adaptor(Allocator const &allocator, cuda_stream_view stream)
使用 `a` 作为底层分配器构造一个
stream_allocator_adaptor
。注意
: 在
stream_allocator_adaptor
被销毁之前,`stream` 不能被销毁,否则行为是未定义的。- 参数:
allocator – 用作底层分配器的流序分配器
stream – 与底层分配器一起使用的流
-
template<typename OtherAllocator>
inline stream_allocator_adaptor(stream_allocator_adaptor<OtherAllocator> const &other) 使用 `other.underlying_allocator()` 和 `other.stream()` 作为底层分配器和流构造一个
stream_allocator_adaptor
。- 模板参数:
OtherAllocator – `other` 的底层分配器类型
- 参数:
other – 其底层分配器和流将被复制的另一个
stream_allocator_adaptor
-
inline value_type *allocate(std::size_t num)
在
stream()
上使用底层分配器为 `num` 个类型为 `T` 的对象分配存储空间。- 参数:
num – 要分配存储空间的对象数量
- 返回:
指向已分配存储空间的指针
-
inline void deallocate(value_type *ptr, std::size_t num)
在
stream()
上使用底层分配器释放 `ptr` 指向的存储空间。`ptr` 必须是由一个分配器 `a` 分配的,该分配器使用 `a.allocate(n)` 与
underlying_allocator()
比较相等。- 参数:
ptr – 指向要释放的内存的指针
num – 最初分配的对象数量
-
inline cuda_stream_view stream() const noexcept
对底层分配器进行调用时所在的流。
- 返回:
对底层分配器进行调用时所在的流
-
template<typename T>
struct rebind - #include <polymorphic_allocator.hpp>
将分配器重新绑定到指定的类型。
- 模板参数:
T – 重新绑定后的分配器类型所需的值类型 `value_type`
公共类型
-
using other = stream_allocator_adaptor<typename std::allocator_traits<Allocator>::template rebind_alloc<T>>
要绑定的类型。
-
template<typename Upstream>
class pool_memory_resource : public detail::maybe_remove_property<pool_memory_resource<Upstream>, Upstream, cuda::mr::device_accessible>, public detail::stream_ordered_memory_resource<pool_memory_resource<Upstream>, detail::coalescing_free_list>, public cuda::forward_property<pool_memory_resource<Upstream>, Upstream> - #include <pool_memory_resource.hpp>
一个合并式的最佳匹配子分配器,它使用从上游 `memory_resource` 分配的内存池。
分配 (
do_allocate()
) 和释放 (do_deallocate()
) 是线程安全的。此外,此类与 CUDA 每线程默认流兼容。- 模板参数:
UpstreamResource – 用于分配内存池的 `memory_resource`。实现了 rmm::mr::device_memory_resource 接口。
公共函数
-
inline explicit pool_memory_resource(device_async_resource_ref upstream_mr, std::size_t initial_pool_size, std::optional<std::size_t> maximum_pool_size = std::nullopt)
构造一个
pool_memory_resource
并使用 `upstream_mr` 分配初始设备内存池。- 抛出:
rmm::logic_error – 如果 `initial_pool_size` 未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
rmm::logic_error – 如果 `maximum_pool_size` 既非默认值也未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
- 参数:
upstream_mr
– 用于为池分配块的 memory_resource。initial_pool_size – 初始池的最小大小(字节)。
maximum_pool_size – 池可以增长到的最大大小(字节)。默认为上游资源可用的所有内存。
-
inline explicit pool_memory_resource(Upstream *upstream_mr, std::size_t initial_pool_size, std::optional<std::size_t> maximum_pool_size = std::nullopt)
构造一个
pool_memory_resource
并使用 `upstream_mr` 分配初始设备内存池。- 抛出:
rmm::logic_error – 如果 `upstream_mr == nullptr`
rmm::logic_error – 如果 `initial_pool_size` 未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
rmm::logic_error – 如果 `maximum_pool_size` 既非默认值也未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
- 参数:
upstream_mr
– 用于为池分配块的 memory_resource。initial_pool_size – 初始池的最小大小(字节)。
maximum_pool_size – 池可以增长到的最大大小(字节)。默认为上游资源可用的所有内存。
-
template<typename Upstream2 = Upstream, cuda::std::enable_if_t<cuda::mr::async_resource<Upstream2>, int> = 0>
inline explicit pool_memory_resource(Upstream2 &upstream_mr, std::size_t initial_pool_size, std::optional<std::size_t> maximum_pool_size = std::nullopt) 构造一个
pool_memory_resource
并使用 `upstream_mr` 分配初始设备内存池。- 抛出:
rmm::logic_error – 如果 `upstream_mr == nullptr`
rmm::logic_error – 如果 `initial_pool_size` 未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
rmm::logic_error – 如果 `maximum_pool_size` 既非默认值也未按 pool_memory_resource::allocation_alignment 字节的倍数对齐。
- 参数:
upstream_mr
– 用于为池分配块的 memory_resource。initial_pool_size – 初始池的最小大小(字节)。
maximum_pool_size – 池可以增长到的最大大小(字节)。默认为上游资源可用的所有内存。
-
inline ~pool_memory_resource() override
销毁
pool_memory_resource
并使用上游资源释放其分配的所有内存。
-
inline device_async_resource_ref get_upstream_resource() const noexcept
rmm::device_async_resource_ref,指向(或引用)上游资源
- 返回:
rmm::device_async_resource_ref,指向(或引用)上游资源
-
inline std::size_t pool_size() const noexcept
计算当前内存池的大小。
包含已分配和空闲的内存。
- 返回:
std::size_t 当前已分配内存池的总大小。
-
class sam_headroom_memory_resource : public rmm::mr::device_memory_resource
- #include <sam_headroom_memory_resource.hpp>
使用系统内存资源分配带预留空间的内存的资源。
系统分配内存(SAM)可以迁移到 GPU,但不会迁移回主机。如果 GPU 内存超额预订,这可能导致其他 CUDA 调用因内存不足而失败。为了解决这个问题,在使用系统内存资源时,我们预留一些 GPU 内存作为其他 CUDA 调用的预留空间,并且仅在分配不会占用预留空间时才将其首选位置条件性地设置为 GPU。
由于在每次分配时执行此检查可能开销很大,调用者可以选择使用其他分配器(例如
binning_memory_resource
)进行小额分配,而仅对大额分配使用此分配器。公共函数
-
inline explicit sam_headroom_memory_resource(std::size_t headroom)
构造一个预留空间内存资源。
- 参数:
headroom – 作为预留空间的预留 GPU 内存的大小
-
inline explicit sam_headroom_memory_resource(std::size_t headroom)
-
class system_memory_resource : public rmm::mr::device_memory_resource
- #include <system_memory_resource.hpp>
使用 malloc/free 进行分配/释放的
device_memory_resource
派生类。有两种硬件/软件环境支持从 GPU 访问系统分配内存(SAM):HMM 和 ATS。
异构内存管理 (HMM) 是针对 x86 系统上通过 PCIe 连接的 GPU 的基于软件的解决方案。要求
NVIDIA CUDA 12.2 以及开源 r535_00 驱动或更新版本。
足够新的 Linux 内核:6.1.24+、6.2.11+ 或 6.3+。
支持以下架构之一的 GPU:NVIDIA Turing、NVIDIA Ampere、NVIDIA Ada Lovelace、NVIDIA Hopper 或更新版本。
64 位 x86 CPU。
更多信息,请参阅 https://developer.nvidia.com/blog/simplifying-gpu-application-development-with-heterogeneous-memory-management/。
地址转换服务 (ATS) 是 Grace Hopper Superchip 的硬件/软件解决方案,它使用 NVLink Chip-2-Chip (C2C) 互连提供一致性内存。更多信息,请参阅 https://developer.nvidia.com/blog/nvidia-grace-hopper-superchip-architecture-in-depth/。
公共函数
-
system_memory_resource(system_memory_resource const&) = default
默认拷贝构造函数。
-
system_memory_resource(system_memory_resource&&) = default
默认拷贝构造函数。
-
system_memory_resource &operator=(system_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
system_memory_resource& 对赋值对象的引用
-
system_memory_resource &operator=(system_memory_resource&&) default
默认移动赋值运算符。
- 返回:
system_memory_resource& 对赋值对象的引用
-
using allocate_callback_t = std::function<void*(std::size_t, cuda_stream_view, void*)>
- group 主机内存资源
-
class host_memory_resource
- #include <host_memory_resource.hpp>
主机内存分配的基类。
这基于
std::pmr::memory_resource
:https://cppreference.cn/w/cpp/memory/memory_resource当 C++17 可用于 RMM 时,`rmm::host_memory_resource` 应该继承自 `std::pmr::memory_resource`。
此类作为所有主机内存资源实现必须满足的接口。
所有派生类必须实现两个私有的纯虚函数:
do_allocate
和do_deallocate
。可选地,派生类还可以重写is_equal
。默认情况下,is_equal
仅执行身份比较。公共的非虚函数
allocate
、deallocate
和is_equal
只是简单地调用私有虚函数。这样做的原因是允许在基类中实现共享的默认行为。例如,基类的allocate
函数可能会记录每一次分配,无论使用哪种派生类实现。子类包括 rmm::mr::new_delete_resource, rmm::mr::pinned_memory_resource
公共函数
-
host_memory_resource(host_memory_resource const&) = default
默认拷贝构造函数。
-
host_memory_resource(host_memory_resource&&) noexcept = default
默认移动构造函数。
-
host_memory_resource &operator=(host_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
host_memory_resource& 对赋值对象的引用
-
host_memory_resource &operator=(host_memory_resource&&) noexcept = default
默认移动赋值运算符。
- 返回:
host_memory_resource& 对赋值对象的引用
-
inline void *allocate(std::size_t bytes, std::size_t alignment = alignof(std::max_align_t))
在主机上分配至少 `bytes` 字节大小的内存。
如果支持,返回的存储空间将按照指定的 `alignment` 对齐;否则,将按照 `alignof(std::max_align_t)` 对齐。
- 抛出:
std::bad_alloc – 当请求的 `bytes` 和 `alignment` 无法分配时。
- 参数:
bytes
– 分配的大小alignment – 分配的对齐方式
- 返回:
void* 指向新分配内存的指针
-
inline void deallocate(void *ptr, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t))
释放 `ptr` 指向的内存。
`ptr` 必须是通过之前调用 `allocate(bytes,alignment)` 从一个与 `*this` 比较相等
host_memory_resource
返回的,并且其指向的存储空间尚未被释放,否则行为是未定义的。- 参数:
ptr
– 要释放的指针bytes – 分配的大小(字节)。这必须等于返回 `ptr` 的 `allocate` 调用中传递的 `bytes` 值。
alignment – 分配的对齐方式。这必须等于返回 `ptr` 的 `allocate` 调用中传递的 `alignment` 值。
-
inline bool is_equal(host_memory_resource const &other) const noexcept
将此资源与另一个资源进行比较。
当且仅当从一个
host_memory_resource
分配的内存可以从另一个释放,反之亦然时,两个host_memory_resource
比较相等。默认情况下,仅检查
*this
和other
是否指向同一对象,即不检查它们是否是同一类的两个对象。- 参数:
other
– 要比较的另一个资源- 返回:
如果两个资源等价,则为 true
-
inline bool operator==(host_memory_resource const &other) const noexcept
与另一个 host_memory_resource 的比较运算符。
- 参数:
other
– 要比较的另一个资源- 返回:
true 如果两个资源等效
- 返回:
false 如果两个资源不等效
-
inline bool operator!=(host_memory_resource const &other) const noexcept
与另一个 host_memory_resource 的比较运算符。
- 参数:
other
– 要比较的另一个资源- 返回:
false 如果两个资源等效
- 返回:
true 如果两个资源不等效
友元
-
inline friend void get_property(host_memory_resource const&, cuda::mr::host_accessible) noexcept
启用
cuda::mr::host_accessible
属性。此属性声明
host_memory_resource
提供主机可访问的内存。
-
host_memory_resource(host_memory_resource const&) = default
-
class new_delete_resource : public rmm::mr::host_memory_resource
- #include <new_delete_resource.hpp>
使用全局 `operator new` 和 `operator delete` 分配主机内存的
host_memory_resource
。公共函数
-
new_delete_resource(new_delete_resource const&) = default
默认拷贝构造函数。
-
new_delete_resource(new_delete_resource&&) = default
默认移动构造函数。
-
new_delete_resource &operator=(new_delete_resource const&) = default
默认拷贝赋值运算符。
- 返回:
new_delete_resource& 对赋值对象的引用
-
new_delete_resource &operator=(new_delete_resource&&) default
默认移动赋值运算符。
- 返回:
new_delete_resource& 对赋值对象的引用
-
new_delete_resource(new_delete_resource const&) = default
-
class pinned_memory_resource : public rmm::mr::host_memory_resource
- #include <pinned_memory_resource.hpp>
使用 `cudaMallocHost` 分配固定/页锁定主机内存的
host_memory_resource
。请参阅 https://devblogs.nvidia.com/how-optimize-data-transfers-cuda-cc/
公共函数
-
pinned_memory_resource(pinned_memory_resource const&) = default
默认拷贝构造函数。
-
pinned_memory_resource(pinned_memory_resource&&) = default
默认移动构造函数。
-
pinned_memory_resource &operator=(pinned_memory_resource const&) = default
默认拷贝赋值运算符。
- 返回:
pinned_memory_resource& 对被赋值对象的引用
-
pinned_memory_resource &operator=(pinned_memory_resource&&) = default
默认移动赋值运算符。
- 返回:
pinned_memory_resource& 对被赋值对象的引用
-
inline void *allocate_async(std::size_t bytes, std::size_t alignment, cuda_stream_view)
假装支持 allocate_async 接口,实际回退到 stream 0。
-
inline void *allocate_async(std::size_t bytes, cuda_stream_view)
假装支持 allocate_async 接口,实际回退到 stream 0。
-
inline void deallocate_async(void *ptr, std::size_t bytes, std::size_t alignment, cuda_stream_view)
假装支持 deallocate_async 接口,实际回退到 stream 0。
- 参数:
ptr
– 要释放的指针bytes
– 分配的大小,以字节为单位。这必须等于返回p
的allocate
调用中传递的bytes
值。alignment
– 返回p
的allocate
调用中传递的对齐方式
友元
-
inline friend void get_property(pinned_memory_resource const&, cuda::mr::device_accessible) noexcept
启用
cuda::mr::device_accessible
属性。此属性声明
pinned_memory_resource
提供设备可访问的内存
-
pinned_memory_resource(pinned_memory_resource const&) = default
-
class host_memory_resource
- group 设备资源适配器
类型别名
-
using failure_callback_t = std::function<bool(std::size_t, void*)>
failure_callback_resource_adaptor 使用的回调函数类型。
当内存分配抛出指定类型的异常时,资源适配器会调用此函数。函数决定资源适配器是应尝试再次分配内存还是重新抛出异常。
回调函数签名是:
bool failure_callback_t(std::size_t bytes, void* callback_arg)
回调函数传递两个参数:
bytes
是失败的内存分配大小,arg
是传递给failure_callback_resource_adaptor
构造函数的额外参数。回调函数返回一个布尔值,其中 true 表示重试内存分配,false 表示重新抛出异常。
函数
使用
upstreams
作为上游资源,并使用args
作为构造Resource
的额外参数,构造一个类型为Resource
并包装在owning_wrapper
中的资源。template <typename Upstream1, typename Upstream2> class example_resource{ example_resource(Upstream1 * u1, Upstream2 * u2, int n, float f); }; auto cuda_mr = std::make_shared<rmm::mr::cuda_memory_resource>(); auto cuda_upstreams = std::make_tuple(cuda_mr, cuda_mr); // Constructs an `example_resource<rmm::mr::cuda_memory_resource, rmm::mr::cuda_memory_resource>` // wrapped by an `owning_wrapper` taking shared ownership of `cuda_mr` and using it as both of // `example_resource`s upstream resources. Forwards the arguments `42` and `3.14` to the // additional `n` and `f` arguments of `example_resource` constructor. auto wrapped_example = rmm::mr::make_owning_wrapper<example_resource>(cuda_upstreams, 42, 3.14);
- 模板参数:
Resource – 指定要构造的包装资源的类型的模板模板参数
Upstreams – 上游资源的类型
Args – 在
Resource
的构造函数中使用的参数类型
- 参数:
upstreams –
std::shared_ptr
的元组,指向包装资源使用的上游,顺序与Resource
的构造函数期望的顺序相同。args – 要转发给包装资源的构造函数的函数参数包
- 返回:
一个
owning_wrapper
,包装了一个新构造的Resource<Upstreams...>
和upstreams
。
当
Resource
只有一个上游资源时,owning_wrapper
的额外便利工厂函数。当一个资源只有一个上游时,构造上游资源的
std::tuple
可能不方便。此工厂函数允许将单个上游指定为仅一个std::shared_ptr
。- 模板参数:
Resource – 要构造的包装资源的类型
Upstream – 单个上游资源的类型
Args – 在
Resource
的构造函数中使用的参数类型
- 参数:
upstream – 指向 上游资源的
std::shared_ptr
args – 要转发给包装资源的构造函数的函数参数包
- 返回:
一个
owning_wrapper
,包装了一个新构造的Resource<Upstream>
和upstream
。
-
template<typename Upstream>
class aligned_resource_adaptor : public rmm::mr::device_memory_resource - #include <aligned_resource_adaptor.hpp>
使
Upstream
内存资源以指定的对齐大小分配内存的资源。此资源的一个实例可以使用现有的上游资源来构造,以满足分配请求。此适配器使用给定的对齐大小包装来自 Upstream 的分配和释放。
默认情况下,CUDA 驱动程序或运行时 API 的内存分配例程返回的任何地址始终至少对齐到 256 字节。对于某些用例,例如 GPUDirect Storage (GDS),为了避免额外的复制到 bounce buffer,分配需要对齐到更大的大小(GDS 为 4 KiB)。
由于更大的对齐大小会带来一些额外的开销,用户可以指定一个阈值大小。如果分配大小低于该阈值,则按默认大小对齐。只有大小超过阈值的分配才会按自定义对齐大小对齐。
- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共函数
-
inline explicit aligned_resource_adaptor(device_async_resource_ref upstream, std::size_t alignment = rmm::CUDA_ALLOCATION_ALIGNMENT, std::size_t alignment_threshold = default_alignment_threshold)
构造一个对齐资源适配器,使用
upstream
来满足分配请求。- 抛出:
rmm::logic_error – 如果
allocation_alignment
不是 2 的幂- 参数:
upstream – 用于分配/释放设备内存的资源。
alignment – 用于分配对齐的大小。
alignment_threshold – 只有大小大于或等于此阈值的分配才会被对齐。
-
inline explicit aligned_resource_adaptor(Upstream *upstream, std::size_t alignment = rmm::CUDA_ALLOCATION_ALIGNMENT, std::size_t alignment_threshold = default_alignment_threshold)
构造一个对齐资源适配器,使用
upstream
来满足分配请求。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
rmm::logic_error – 如果
alignment
不是 2 的幂
- 参数:
upstream – 用于分配/释放设备内存的资源。
alignment – 用于分配对齐的大小。
alignment_threshold – 只有大小大于或等于此阈值的分配才会被对齐。
公共静态属性
-
static constexpr std::size_t default_alignment_threshold = 0
适配器使用的默认对齐方式。
-
template<typename Upstream, typename ExceptionType = rmm::out_of_memory>
class failure_callback_resource_adaptor : public rmm::mr::device_memory_resource - #include <failure_callback_resource_adaptor.hpp>
一种设备内存资源,在分配抛出指定的异常类型时调用回调函数。
此资源的一个实例必须使用现有上游资源构造,以满足分配请求。
回调函数接受分配大小和回调参数,并返回一个布尔值,表示是否应重试分配 (true) 或重新抛出捕获到的异常 (false)。
在实现分配重试的回调函数时,必须注意避免无限循环。以下示例确保仅重试分配一次
using failure_callback_adaptor = rmm::mr::failure_callback_resource_adaptor<rmm::mr::device_memory_resource>; bool failure_handler(std::size_t bytes, void* arg) { bool& retried = *reinterpret_cast<bool*>(arg); if (!retried) { retried = true; return true; // First time we request an allocation retry } return false; // Second time we let the adaptor throw std::bad_alloc } int main() { bool retried{false}; failure_callback_adaptor mr{ rmm::mr::get_current_device_resource_ref(), failure_handler, &retried }; rmm::mr::set_current_device_resource_ref(mr); }
- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
ExceptionType – 此适配器应响应的异常类型
公共类型
-
using exception_type = ExceptionType
此对象捕获/抛出的异常类型。
公共函数
-
inline failure_callback_resource_adaptor(device_async_resource_ref upstream, failure_callback_t callback, void *callback_arg)
构造一个新的
failure_callback_resource_adaptor
,使用upstream
来满足分配请求。另请参阅
failure_callback_t
- 参数:
upstream – 用于分配/释放设备内存的资源
callback – 回调函数
callback_arg – 传递给
callback
的额外参数
-
inline failure_callback_resource_adaptor(Upstream *upstream, failure_callback_t callback, void *callback_arg)
构造一个新的
failure_callback_resource_adaptor
,使用upstream
来满足分配请求。另请参阅
failure_callback_t
- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
callback – 回调函数
callback_arg – 传递给
callback
的额外参数
-
failure_callback_resource_adaptor(failure_callback_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
failure_callback_resource_adaptor &operator=(failure_callback_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
failure_callback_resource_adaptor& 对被赋值对象的引用
-
template<typename Upstream>
class limiting_resource_adaptor : public rmm::mr::device_memory_resource - #include <limiting_resource_adaptor.hpp>
使用
Upstream
分配内存并限制总分配量的资源。此资源的一个实例可以使用现有的上游资源构造,以满足分配请求,但任何现有分配将不被跟踪。使用原子操作使此线程安全,但请注意,
get_allocated_bytes
可能不包含正在进行的分配。- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共函数
-
inline limiting_resource_adaptor(device_async_resource_ref upstream, std::size_t allocation_limit, std::size_t alignment = CUDA_ALLOCATION_ALIGNMENT)
构造一个新的限制资源适配器,使用
upstream
来满足分配请求,并限制总分配量。- 参数:
upstream – 用于分配/释放设备内存的资源
allocation_limit – 此分配器允许的最大内存量
alignment – 每个分配缓冲区的起始地址的对齐字节数
-
inline limiting_resource_adaptor(Upstream *upstream, std::size_t allocation_limit, std::size_t alignment = CUDA_ALLOCATION_ALIGNMENT)
构造一个新的限制资源适配器,使用
upstream
来满足分配请求,并限制总分配量。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
allocation_limit – 此分配器允许的最大内存量
alignment – 每个分配缓冲区的起始地址的对齐字节数
-
limiting_resource_adaptor(limiting_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
limiting_resource_adaptor &operator=(limiting_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
limiting_resource_adaptor& 对被赋值对象的引用
-
inline device_async_resource_ref get_upstream_resource() const noexcept
指向的上游资源的 device_async_resource_ref
- 返回:
指向的上游资源的 device_async_resource_ref
-
inline std::size_t get_allocated_bytes() const
查询已分配的字节数。注意,这不能用于了解可能分配的大小,因为可能存在碎片以及此分配器未跟踪的内部页面大小和对齐。
- 返回:
std::size_t 已通过此分配器分配的字节数。
-
inline std::size_t get_allocation_limit() const
查询此分配器允许分配的最大字节数。这是对分配器的限制,而不是底层设备的表示。设备可能无法支持此限制。
- 返回:
std::size_t 此分配器允许的最大字节数
-
template<typename Upstream>
class logging_resource_adaptor : public rmm::mr::device_memory_resource - #include <logging_resource_adaptor.hpp>
使用
Upstream
分配内存并记录有关请求的分配/释放信息的资源。此资源的一个实例可以使用现有的上游资源构造,以满足分配请求并记录分配/释放活动。
- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共函数
-
inline logging_resource_adaptor(Upstream *upstream, std::string const &filename = get_default_filename(), bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到filename
指定的文件中。日志文件将使用 CSV 格式写入。
如果
filename
已存在,则清除其内容。创建多个具有相同
filename
的logging_resource_adaptor
将导致未定义行为。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
spdlog::spdlog_ex – 如果打开
filename
失败
- 参数:
upstream – 用于分配/释放设备内存的资源
filename – 写入日志信息的文件名。如果未指定,则从环境变量 “RMM_LOG_FILE” 中获取文件名。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
inline logging_resource_adaptor(Upstream *upstream, std::ostream &stream, bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到stream
指定的 ostream。日志文件将使用 CSV 格式写入。
- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
stream – 写入日志信息的 ostream。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
inline logging_resource_adaptor(Upstream *upstream, std::initializer_list<rapids_logger::sink_ptr> sinks, bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到stream
指定的 ostream。日志文件将使用 CSV 格式写入。
- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
sinks – 将日志输出写入的日志接收器列表。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
inline logging_resource_adaptor(device_async_resource_ref upstream, std::string const &filename = get_default_filename(), bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到filename
指定的文件中。日志文件将使用 CSV 格式写入。
如果
filename
已存在,则清除其内容。创建多个具有相同
filename
的logging_resource_adaptor
将导致未定义行为。- 抛出:
spdlog::spdlog_ex – 如果打开
filename
失败- 参数:
upstream – 用于分配/释放设备内存的 resource_ref。
filename – 写入日志信息的文件名。如果未指定,则从环境变量 “RMM_LOG_FILE” 中获取文件名。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
inline logging_resource_adaptor(device_async_resource_ref upstream, std::ostream &stream, bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到stream
指定的 ostream。日志文件将使用 CSV 格式写入。
- 参数:
upstream – 用于分配/释放设备内存的 resource_ref。
stream – 写入日志信息的 ostream。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
inline logging_resource_adaptor(device_async_resource_ref upstream, std::initializer_list<rapids_logger::sink_ptr> sinks, bool auto_flush = false)
构造一个新的日志资源适配器,使用
upstream
来满足分配请求,并将每个分配/释放的信息记录到stream
指定的 ostream。日志文件将使用 CSV 格式写入。
- 参数:
upstream – 用于分配/释放设备内存的 resource_ref。
sinks – 将日志输出写入的日志接收器列表。
auto_flush – 如果为 true,则每次分配/释放时都会刷新日志。警告:这会降低性能。
-
logging_resource_adaptor(logging_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
logging_resource_adaptor &operator=(logging_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
logging_resource_adaptor& 对被赋值对象的引用
-
inline rmm::device_async_resource_ref get_upstream_resource() const noexcept
rmm::device_async_resource_ref,指向(或引用)上游资源
- 返回:
rmm::device_async_resource_ref,指向(或引用)上游资源
-
inline void flush()
刷新记录器内容。
-
inline std::string header() const
返回 CSV 头部字符串。
- 返回:
列名的 CSV 格式头部字符串
公共静态函数
-
static inline std::string get_default_filename()
返回环境变量 RMM_LOG_FILE 的值。
- 抛出:
rmm::logic_error – 如果未设置
RMM_LOG_FILE
。- 返回:
RMM_LOG_FILE 的值,类型为
std::string
。
-
template<typename Resource, typename ...Upstreams>
class owning_wrapper : public rmm::mr::device_memory_resource - #include <owning_wrapper.hpp>
维护上游资源生命周期的资源适配器。
许多派生自
device_memory_resource
的类型从另一个“上游”资源分配内存。例如,pool_memory_resource
从上游资源分配其池。通常,资源不拥有其上游,因此用户有责任维护上游资源的生命周期。这可能很不方便且容易出错,特别是对于具有复杂上游资源(其自身也可能有上游)的资源。owning_wrapper
通过std::shared_ptr
共享所有上游资源的 ownership 来简化包装资源wrapped
的生命周期管理。为了方便起见,建议使用
make_owning_wrapper
工厂函数,而不是直接构造owning_wrapper
。示例
auto cuda = std::make_shared<rmm::mr::cuda_memory_resource>(); auto pool = rmm::mr::make_owning_wrapper<rmm::mr::pool_memory_resource>(cuda,initial_pool_size, max_pool_size); // The `cuda` resource will be kept alive for the lifetime of `pool` and automatically be // destroyed after `pool` is destroyed
- 模板参数:
Resource – 包装资源的类型
Upstreams –
Resource
使用的上游资源类型的模板参数包
公共函数
-
template<typename ...Args>
inline owning_wrapper(upstream_tuple upstreams, Args&&... args) 使用提供的上游资源和转发给包装资源构造函数的任何额外参数来构造包装资源。
要求
Resource
具有一个构造函数,其第一个参数是其上游资源的原始指针,顺序与upstreams
中的顺序相同,后跟与args
中顺序相同的任何额外参数。示例
template <typename Upstream1, typename Upstream2> class example_resource{ example_resource(Upstream1 * u1, Upstream2 * u2, int n, float f); }; using cuda = rmm::mr::cuda_memory_resource; using example = example_resource<cuda,cuda>; using wrapped_example = rmm::mr::owning_wrapper<example, cuda, cuda>; auto cuda_mr = std::make_shared<cuda>(); // Constructs an `example_resource` wrapped by an `owning_wrapper` taking shared ownership of //`cuda_mr` and using it as both of `example_resource`s upstream resources. Forwards the // arguments `42` and `3.14` to the additional `n` and `f` arguments of `example_resources` // constructor. wrapped_example w{std::make_tuple(cuda_mr,cuda_mr), 42, 3.14};
- 模板参数:
Args – 要转发到包装资源构造函数的模板参数包
- 参数:
upstreams –
std::shared_ptr
的元组,指向包装资源使用的上游,顺序与Resource
的构造函数期望的顺序相同。args – 要转发给包装资源的构造函数的函数参数包
-
template<typename Upstream>
class prefetch_resource_adaptor : public rmm::mr::device_memory_resource - #include <prefetch_resource_adaptor.hpp>
预取所有内存分配的资源。
- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共函数
-
inline prefetch_resource_adaptor(device_async_resource_ref upstream)
使用
upstream
构造新的预取资源适配器以满足分配请求。- 参数:
upstream – 用于分配/释放设备内存的 `resource_ref`
-
inline prefetch_resource_adaptor(Upstream *upstream)
使用
upstream
构造新的预取资源适配器以满足分配请求。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
-
prefetch_resource_adaptor(prefetch_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
prefetch_resource_adaptor &operator=(prefetch_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
prefetch_resource_adaptor& 对分配的对象的引用
-
template<typename Upstream>
class statistics_resource_adaptor : public rmm::mr::device_memory_resource - #include <statistics_resource_adaptor.hpp>
使用
Upstream
分配内存并跟踪内存分配统计信息的资源。可以使用现有的上游资源构造此资源的一个实例,以满足分配请求,但任何现有分配将不受跟踪。跟踪统计信息会存储内存资源的字节数和调用次数的当前、峰值和总分配内存量。
此资源支持嵌套统计信息,可以跟踪代码块的统计信息。使用
.push_counters()
开始跟踪代码块的统计信息,使用.pop_counters()
停止跟踪。嵌套统计信息是层叠的,因此代码块跟踪的统计信息包括其所有跟踪的子代码块中跟踪的统计信息。statistics_resource_adaptor
用作调试适配器,不应在性能敏感的代码中使用。- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共类型
-
using read_lock_t = std::shared_lock<std::shared_mutex>
用于同步读访问的锁类型。
-
using write_lock_t = std::unique_lock<std::shared_mutex>
用于同步写访问的锁类型。
公共函数
-
inline statistics_resource_adaptor(device_async_resource_ref upstream)
使用
upstream
构造新的统计信息资源适配器以满足分配请求。- 参数:
upstream – 用于分配/释放设备内存的 resource_ref。
-
inline statistics_resource_adaptor(Upstream *upstream)
使用
upstream
构造新的统计信息资源适配器以满足分配请求。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源。
-
statistics_resource_adaptor(statistics_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
statistics_resource_adaptor &operator=(statistics_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
statistics_resource_adaptor& 对分配的对象的引用
-
inline rmm::device_async_resource_ref get_upstream_resource() const noexcept
rmm::device_async_resource_ref,指向(或引用)上游资源
- 返回:
rmm::device_async_resource_ref,指向(或引用)上游资源
-
inline counter get_bytes_counter() const noexcept
返回此适配器的
counter
结构体,其中包含自创建以来此适配器分配的字节数的当前、峰值和总数。- 返回:
包含字节计数的
counter
结构体
-
inline counter get_allocations_counter() const noexcept
返回此适配器的
counter
结构体,其中包含自创建以来此适配器的分配次数的当前、峰值和总数。- 返回:
包含分配计数的
counter
结构体
-
inline std::pair<counter, counter> push_counters()
在堆栈上推送一对零计数器,这将成为
get_bytes_counter()
和get_allocations_counter()
返回的新计数器。- 返回:
推送之前堆栈中的顶部计数器对
-
struct counter
- #include <statistics_resource_adaptor.hpp>
用于计数数字的当前值、峰值和总值的实用结构体。
公共函数
-
template<typename Upstream>
class thread_safe_resource_adaptor : public rmm::mr::device_memory_resource - #include <thread_safe_resource_adaptor.hpp>
将
Upstream
内存资源适配器调整为线程安全的资源。可以使用现有的上游资源构造此资源的一个实例,以满足分配请求。此适配器将 Upstream 的分配和释放操作包装在互斥锁中。
- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共类型
-
using lock_t = std::lock_guard<std::mutex>
用于同步访问的锁类型。
公共函数
-
inline thread_safe_resource_adaptor(device_async_resource_ref upstream)
使用
upstream
构造新的线程安全资源适配器以满足分配请求。所有分配和释放都受互斥锁保护
- 参数:
upstream – 用于分配/释放设备内存的资源。
-
inline thread_safe_resource_adaptor(Upstream *upstream)
使用
upstream
构造新的线程安全资源适配器以满足分配请求。所有分配和释放都受互斥锁保护
- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源。
-
template<typename T>
class thrust_allocator : public thrust::device_malloc_allocator<T> - #include <thrust_allocator_adaptor.hpp>
兼容 Thrust 容器和算法的
allocator
,使用device_async_resource_ref
进行内存分配/释放。与
device_async_resource_ref
不同,thrust_allocator
是类型化的,绑定用于分配特定类型T
的对象,但可以自由地重新绑定到其他类型。该分配器记录当前的 cuda 设备,并且只能与对同一设备有效的底层
device_async_resource_ref
一起使用。- 模板参数:
T – 此分配器将分配的对象的类型
公共类型
公共函数
-
thrust_allocator() = default
默认构造函数使用默认内存资源和默认流创建分配器。
-
inline explicit thrust_allocator(cuda_stream_view stream)
使用默认设备内存资源和指定流构造
thrust_allocator
。- 参数:
stream – 用于设备内存分配/释放的流
-
inline thrust_allocator(cuda_stream_view stream, rmm::device_async_resource_ref mr)
使用设备内存资源和流构造
thrust_allocator
。- 参数:
mr – 用于设备内存分配的资源
stream – 用于设备内存分配/释放的流
-
template<typename U>
inline thrust_allocator(thrust_allocator<U> const &other) 复制构造函数。复制资源指针和流。
- 参数:
other – 要复制的
thrust_allocator
-
inline void deallocate(pointer ptr, size_type num)
释放类型
T
的对象- 参数:
ptr – 由先前对
allocate
的调用返回的指针num – 元素数量,必须等于生成
p
的先前allocate
调用传递的参数
-
inline rmm::device_async_resource_ref get_upstream_resource() const noexcept
rmm::device_async_resource_ref,指向(或引用)上游资源
- 返回:
rmm::device_async_resource_ref,指向(或引用)上游资源
-
inline cuda_stream_view stream() const noexcept
此分配器使用的流。
- 返回:
此分配器使用的流
友元
-
inline friend void get_property(thrust_allocator const&, cuda::mr::device_accessible) noexcept
启用
cuda::mr::device_accessible
属性。此属性声明
thrust_allocator
提供设备可访问的内存
-
template<typename U>
struct rebind - #include <thrust_allocator_adaptor.hpp>
提供用另一种类型实例化的
thrust_allocator
的类型。- 模板参数:
U – 用于实例化的另一种类型
公共类型
-
using other = thrust_allocator<U>
要绑定的类型。
-
template<typename Upstream>
class tracking_resource_adaptor : public rmm::mr::device_memory_resource - #include <tracking_resource_adaptor.hpp>
使用
Upstream
分配内存并跟踪分配的资源。可以使用现有的上游资源构造此资源的一个实例,以满足分配请求,但任何现有分配将不受跟踪。如果
capture_stacks
为 true,跟踪会存储每个分配的大小和指针以及堆栈帧,因此可能会增加显著的开销。tracking_resource_adaptor
用作调试适配器,不应在性能敏感的代码中使用。请注意,除非项目与-rdynamic
链接,否则调用堆栈可能不包含所有符号。这可以通过在 cmake 中使用add_link_options(-rdynamic)
来实现。- 模板参数:
Upstream – 用于分配/释放的上游资源的类型。
公共类型
-
using read_lock_t = std::shared_lock<std::shared_mutex>
用于同步读访问的锁类型。
-
using write_lock_t = std::unique_lock<std::shared_mutex>
用于同步写访问的锁类型。
公共函数
-
inline tracking_resource_adaptor(device_async_resource_ref upstream, bool capture_stacks = false)
使用
upstream
构造新的跟踪资源适配器以满足分配请求。- 参数:
upstream – 用于分配/释放设备内存的资源
capture_stacks – 如果为 true,则捕获分配调用的堆栈
-
inline tracking_resource_adaptor(Upstream *upstream, bool capture_stacks = false)
使用
upstream
构造新的跟踪资源适配器以满足分配请求。- 抛出:
rmm::logic_error – 如果
upstream == nullptr
- 参数:
upstream – 用于分配/释放设备内存的资源
capture_stacks – 如果为 true,则捕获分配调用的堆栈
-
tracking_resource_adaptor(tracking_resource_adaptor&&) noexcept = default
默认移动构造函数。
-
tracking_resource_adaptor &operator=(tracking_resource_adaptor&&) noexcept = default
默认移动赋值运算符。
- 返回:
tracking_resource_adaptor& 对分配的对象的引用
-
inline rmm::device_async_resource_ref get_upstream_resource() const noexcept
rmm::device_async_resource_ref,指向(或引用)上游资源
- 返回:
rmm::device_async_resource_ref,指向(或引用)上游资源
-
inline std::map<void*, allocation_info> const &get_outstanding_allocations() const noexcept
获取未完成分配映射。
- 返回:
一个
std::map<void*, allocation_info> const&
,包含分配的映射。键是分配的内存指针,值是 allocation_info 结构体,其中包含大小以及(可能)堆栈跟踪。
-
inline std::size_t get_allocated_bytes() const noexcept
查询已分配的字节数。注意,这不能用于了解可能分配的大小,因为可能存在碎片以及此分配器未跟踪的内部页面大小和对齐。
- 返回:
std::size_t 已通过此分配器分配的字节数。
-
inline std::string get_outstanding_allocations_str() const
获取一个字符串,其中包含未完成分配的指针、它们的大小,以及可选地包含分配每个指针时的堆栈跟踪。
仅当此资源适配器使用
capture_stack == true
创建时,才包含堆栈跟踪。否则,未完成分配的指针将显示其大小和空堆栈跟踪。- 返回:
std::string
包含未完成分配指针的字符串。
-
inline void log_outstanding_allocations() const
通过 RMM_LOG_DEBUG 记录任何未完成的分配。
-
struct allocation_info
- #include <tracking_resource_adaptor.hpp>
关于分配存储的信息。包括大小,如果
tracking_resource_adaptor
初始化为捕获堆栈,则还包括堆栈跟踪。公共函数
-
inline allocation_info(std::size_t size, bool capture_stack)
构造新的分配信息对象。
- 参数:
size – 分配的大小
capture_stack – 如果为 true,则捕获分配的堆栈跟踪
-
inline allocation_info(std::size_t size, bool capture_stack)
-
using failure_callback_t = std::function<bool(std::size_t, void*)>