HIP (ROCm) 语义¶
ROCm™ 是 AMD 的开源软件平台,用于 GPU 加速的高性能计算和机器学习。HIP 是 ROCm 的 C++ 方言,旨在简化 CUDA 应用程序到可移植 C++ 代码的转换。在将现有 CUDA 应用程序(如 PyTorch)转换为可移植 C++ 以及需要 AMD 和 NVIDIA 之间实现可移植性的新项目中使用 HIP。
HIP 接口重用 CUDA 接口¶
面向 HIP 的 PyTorch 有意重用现有的 torch.cuda
接口。这有助于加速现有 PyTorch 代码和模型的移植,因为需要的代码更改非常少,甚至不需要更改。
来自 CUDA 语义 的示例对于 HIP 将完全相同地工作
cuda = torch.device('cuda') # Default HIP device
cuda0 = torch.device('cuda:0') # 'rocm' or 'hip' are not valid, use 'cuda'
cuda2 = torch.device('cuda:2') # GPU 2 (these are 0-indexed)
x = torch.tensor([1., 2.], device=cuda0)
# x.device is device(type='cuda', index=0)
y = torch.tensor([1., 2.]).cuda()
# y.device is device(type='cuda', index=0)
with torch.cuda.device(1):
# allocates a tensor on GPU 1
a = torch.tensor([1., 2.], device=cuda)
# transfers a tensor from CPU to GPU 1
b = torch.tensor([1., 2.]).cuda()
# a.device and b.device are device(type='cuda', index=1)
# You can also use ``Tensor.to`` to transfer a tensor:
b2 = torch.tensor([1., 2.]).to(device=cuda)
# b.device and b2.device are device(type='cuda', index=1)
c = a + b
# c.device is device(type='cuda', index=1)
z = x + y
# z.device is device(type='cuda', index=0)
# even within a context, you can specify the device
# (or give a GPU index to the .cuda call)
d = torch.randn(2, device=cuda2)
e = torch.randn(2).to(cuda2)
f = torch.randn(2).cuda(cuda2)
# d.device, e.device, and f.device are all device(type='cuda', index=2)
检查 HIP¶
无论您使用的是面向 CUDA 还是 HIP 的 PyTorch,调用 is_available()
的结果都将相同。如果您使用的是已构建 GPU 支持的 PyTorch,它将返回 True。如果您必须检查正在使用的 PyTorch 版本,请参考下面的示例
if torch.cuda.is_available() and torch.version.hip:
# do something specific for HIP
elif torch.cuda.is_available() and torch.version.cuda:
# do something specific for CUDA
ROCm 上的 TensorFloat-32(TF32)¶
ROCm 不支持 TF32。
内存管理¶
PyTorch 使用缓存内存分配器来加速内存分配。这可以在无需设备同步的情况下快速释放内存。然而,分配器管理的未使用内存仍然会在 rocm-smi
中显示为已使用。您可以使用 memory_allocated()
和 max_memory_allocated()
来监控张量占用的内存,并使用 memory_reserved()
和 max_memory_reserved()
来监控缓存分配器管理的总内存量。调用 empty_cache()
会释放 PyTorch 中所有未使用的缓存内存,以便其他 GPU 应用程序可以使用它们。然而,张量占用的 GPU 内存不会被释放,因此它不能增加可供 PyTorch 使用的 GPU 内存量。
对于更高级的用户,我们通过 memory_stats()
提供了更全面的内存基准测试。我们还提供了通过 memory_snapshot()
捕获内存分配器完整状态快照的功能,这可以帮助您理解代码产生的底层分配模式。
要调试内存错误,请在环境中设置 PYTORCH_NO_HIP_MEMORY_CACHING=1
以禁用缓存。PYTORCH_NO_CUDA_MEMORY_CACHING=1
也被接受,以方便移植。
hipBLAS 工作区¶
对于 hipBLAS 句柄和 HIP 流的每种组合,如果该句柄和流组合执行需要工作区的 hipBLAS 内核,则会分配一个 hipBLAS 工作区。为了避免重复分配工作区,除非调用 torch._C._cuda_clearCublasWorkspaces()
,否则这些工作区不会被释放;请注意,CUDA 或 HIP 都使用此函数。每次分配的工作区大小可以通过环境变量 HIPBLAS_WORKSPACE_CONFIG
指定,格式为 :[SIZE]:[COUNT]
。例如,环境变量 HIPBLAS_WORKSPACE_CONFIG=:4096:2:16:8
指定的总大小为 2 * 4096 + 8 * 16 KiB
或 8 MIB。默认工作区大小为 32 MiB;MI300 及更新版本默认为 128 MiB。要强制 hipBLAS 避免使用工作区,请设置 HIPBLAS_WORKSPACE_CONFIG=:0:0
。为了方便起见,CUBLAS_WORKSPACE_CONFIG
也被接受。
hipFFT/rocFFT 计划缓存¶
不支持设置 hipFFT/rocFFT 计划缓存的大小。
torch.distributed 后端¶
目前,ROCm 仅支持 torch.distributed 的“nccl”和“gloo”后端。
C++ 中的 CUDA API 到 HIP API 映射¶
请参阅:https://rocmdocs.amd.com/en/latest/Programming_Guides/HIP_API_Guide.html
注意:CUDA_VERSION
宏、cudaRuntimeGetVersion
和 cudaDriverGetVersion
API 在语义上与 HIP_VERSION
宏、hipRuntimeGetVersion
和 hipDriverGetVersion
API 的值不相同。在进行版本检查时,请勿混用它们。
例如:与其使用
#if defined(CUDA_VERSION) && CUDA_VERSION >= 11000
来隐式排除 ROCm/HIP,
不如使用以下方式来避免 ROCm/HIP 的代码路径
#if defined(CUDA_VERSION) && CUDA_VERSION >= 11000 && !defined(USE_ROCM)
或者,如果希望采用 ROCm/HIP 的代码路径
#if (defined(CUDA_VERSION) && CUDA_VERSION >= 11000) || defined(USE_ROCM)
或者,如果希望仅针对特定 HIP 版本采用 ROCm/HIP 的代码路径
#if (defined(CUDA_VERSION) && CUDA_VERSION >= 11000) || (defined(USE_ROCM) && ROCM_VERSION >= 40300)
启用内核断言¶
ROCm 支持内核断言,但由于性能开销而被禁用。可以通过从源代码重新编译 PyTorch 来启用它。
请将下面这行作为参数添加到 cmake 命令参数中
-DROCM_FORCE_ENABLE_GPU_ASSERTS:BOOL=ON