Add unified memory APIs for torch.accelerator #152932
https://github.com/pytorch/pytorch/pull/152932
为torch.accelerator增加了如下API:
- empty_cache
- max_memory_allocated
- max_memory_reserved
- memory_allocated
- memory_reserved
- memory_stats
- reset_accumulated_memory_stats
- reset_peak_memory_stats
这个pr进一步说明了PyTorch正在去CUDA化,从而转变为一系列加速器提供计算框架,即使他们的github主页仍然写着:
Tensors and Dynamic neural networks in Python with strong GPU acceleration
这些用法很长一段时间是为cuda提供的,调用方式主要为torch.cuda.empty_cache等,接口主要作用是查看device上的显存占用如memory_allocated和memory_reserved,以及清理和重置相关状态。
一起来看下相关函数的调用流程,以cuda为例,从源码分析这个接口是怎么一步一步获取底层的状态的。首先所有memory相关的数据都是从memory_stats这个字典内提取对于的value
def memory_reserved(device_index: _device_t = None, /) -> int:
r"""Return the current :ref:`accelerator<accelerators>` device memory managed by the caching allocator
in bytes for a given device index.
Args:
device_index (:class:`torch.device`, str, int, optional): the index of the device to target.
If not given, use :func:`torch.accelerator.current_device_index` by default.
If a :class:`torch.device` or str is provided, its type must match the current
:ref:`accelerator<accelerators>` device type.
"""
return memory_stats(device_index).get("reserved_bytes.all.current", 0)
而memory_stas通过底层_accelerator_getDeviceStats接口获取相关device的状态
stats = torch._C._accelerator_getDeviceStats(device_index)
torch._C._accelerator_getDeviceStats是一个pybind绑定的C接口函数
at::accelerator::getDeviceStats(device_index);
继续看调用栈
TORCH_API inline at::CachingDeviceAllocator::DeviceStats getDeviceStats(
c10::DeviceIndex device_index) {
const auto device_type = getAccelerator(true).value();
return at::getDeviceAllocator(device_type)->getDeviceStats(device_index);
}
以cuda为例
inline c10::CachingDeviceAllocator::DeviceStats getDeviceStats(
c10::DeviceIndex device) {
return get()->getDeviceStats(device);
}
其中get方法来自allocator,allocator是CUDA Cacing Allocator中的单例实现,所有方法都需要通过该接口实现
inline CUDAAllocator* get() {
return allocator.load();
}
cuda的getDeviceStats通过下面代码实现
DeviceStats getDeviceStats(c10::DeviceIndex device) override {
assertValidDevice(device);
return device_allocator[device]->getStats();
}
总之,现在,所有加速器都可以通过统一的接口返回从PyTorch申请的内存,以及对其状态进行管理,大一统进行中……