評價此頁

HIP (ROCm) 語義#

創建於: 2021年5月12日 | 最後更新於: 2025年8月8日

ROCm™ 是 AMD 的開源軟體平臺,用於 GPU 加速的高效能計算和機器學習。HIP 是 ROCm 的 C++ 方言,旨在簡化 CUDA 應用程式到可移植 C++ 程式碼的轉換。在轉換現有 CUDA 應用程式(如 PyTorch)到可移植 C++ 以及需要 AMD 和 NVIDIA 之間可移植性的新專案時,都會使用 HIP。

HIP 介面重用 CUDA 介面#

PyTorch for HIP 故意重用了現有的 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#

無論您使用的是 PyTorch for CUDA 還是 HIP,呼叫 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 handle 和 HIP stream 的組合,如果該 handle 和 stream 的組合執行了需要工作區的 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://rocm.docs.amd.com/projects/HIP/en/latest/reference/api_syntax.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)

參考 CUDA 語義文件#

對於此處未列出的任何部分,請參考 CUDA 語義文件:CUDA 語義

啟用核心斷言#

ROCm 支援核心斷言,但由於效能開銷而預設停用。可以透過從原始碼重新編譯 PyTorch 來啟用它。

請在 cmake 命令引數中新增以下行:

-DROCM_FORCE_ENABLE_GPU_ASSERTS:BOOL=ON

啟用/停用 ROCm 可組合核心#

啟用 SDPA 和 GEMM 的可組合核心 (CK) 是一個分兩步的過程。首先,使用者必須在構建 PyTorch 時將相應的環境變數設定為 ‘1’:

SDPA: USE_ROCM_CK_SDPA=1

GEMMs: USE_ROCM_CK_GEMM=1

其次,使用者必須透過相應的 Python 呼叫顯式請求使用 CK 作為後端庫:

SDPA: setROCmFAPreferredBackend('<choice>')

GEMMs: setBlasPreferredBackend('<choice>')

要在這兩種情況下啟用 CK,只需將 ‘ck’ 傳遞給這些函式即可。

要將後端設定為 CK,使用者**必須**使用正確的環境變數進行構建。否則,PyTorch 將列印警告並使用“預設”後端。對於 GEMMs,這將路由到 hipblas;對於 SDPA,它將路由到 aotriton。