diff --git a/.github/scripts/build-rocm.sh b/.github/scripts/build-rocm.sh index 5f507efce..7f971824a 100644 --- a/.github/scripts/build-rocm.sh +++ b/.github/scripts/build-rocm.sh @@ -40,6 +40,11 @@ if rocm_version_at_least "7.14"; then bnb_rocm_arch="${bnb_rocm_arch};gfx908;gfx1030;gfx1031;gfx1032;gfx1033;gfx1034;gfx1035;gfx1036" fi +# ROCm 7.14+ - Add CDNA5 (gfx1250). +if rocm_version_at_least "7.14"; then + bnb_rocm_arch="${bnb_rocm_arch};gfx1250" +fi + if [ "${RUNNER_OS}" == "Linux" ]; then image_suffix="complete" if rocm_version_at_least "7.14"; then diff --git a/README.md b/README.md index 4aef60d4b..5d7f2240b 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ bitsandbytes has the following minimum requirements for all platforms: 🟥 AMD GPU
cuda - CDNA: gfx908, gfx90a, gfx942, gfx950
+ CDNA: gfx908, gfx90a, gfx942, gfx950, gfx1250
RDNA: gfx103X, gfx110X, gfx115X, gfx120X ✅ diff --git a/bitsandbytes/backends/cuda/ops.py b/bitsandbytes/backends/cuda/ops.py index 0d288d82b..1f3ce82e0 100644 --- a/bitsandbytes/backends/cuda/ops.py +++ b/bitsandbytes/backends/cuda/ops.py @@ -807,18 +807,21 @@ def _gemm_4bit_use_custom_rocm(device_index, dtype, M, N, K): Fused SIMT kernel vs dequant+F.linear heuristic for ROCm. RDNA3/RDNA4 calibration keeps the SIMT kernel through ~M=8. + gfx125x (CDNA5) is Wave32 but lacks the v_dot2 SIMT + instructions, so its kernel takes the fp32-FMA CDNA math path. The crossover + below is left at the gfx12 default (M<=8) pending dedicated calibration. CDNA/gfx9 is calibrated on MI308X (gfx942): bf16/fp16 win through M<=4 after the SIMT math-path tuning, while fp32 only has a broad win through M<=2. - TODO: revisit once WMMA/MFMA kernels land. + TODO: revisit once WMMA/MFMA kernels land; calibrate the gfx125x crossover. """ if M <= _GEMM_4BIT_CUSTOM_FLOOR_M and dtype != torch.float32: return True arch = _rocm_gfx_arch(device_index) - if arch.startswith("gfx11") or arch.startswith("gfx12"): # RDNA3 / RDNA4 + if arch.startswith("gfx11") or arch.startswith("gfx12"): # RDNA3 / RDNA4 / CDNA5 (gfx125x) return M <= 8 - if arch.startswith("gfx9"): # CDNA / MI-series + if arch.startswith("gfx9"): # CDNA1-4 / MI-series (Wave64) return M <= (2 if dtype == torch.float32 else 4) return M <= 4 # unknown ROCm arch: conservative tiny-batch floor diff --git a/csrc/common.cuh b/csrc/common.cuh index 9df046903..503870124 100644 --- a/csrc/common.cuh +++ b/csrc/common.cuh @@ -20,6 +20,14 @@ #define IS_CDNA4 (defined(__gfx950__)) #define IS_CDNA (IS_CDNA1 || IS_CDNA2 || IS_CDNA3 || IS_CDNA4) +// CDNA5 (gfx1250, gfx1251). Unlike the Wave64 CDNA1-4, CDNA5 +// runs in Wave32 mode. It is deliberately kept OUT of IS_CDNA (which implies +// Wave64) so the default warp size below already resolves to 32 for it, unchanged +// from upstream. It is detected separately only so the 4-bit GEMM can opt into +// the CDNA fp32-FMA math path -- CDNA5 has no SIMT v_dot2 instruction (no +// dot12-insts). +#define IS_CDNA5 (defined(__gfx1250__) || defined(__gfx1251__)) + // Warp size #if BNB_HIP diff --git a/csrc/gemm_4bit_simt.cu b/csrc/gemm_4bit_simt.cu index c0062c4f9..d0f5354fb 100644 --- a/csrc/gemm_4bit_simt.cu +++ b/csrc/gemm_4bit_simt.cu @@ -8,12 +8,16 @@ #include "gemm_4bit_common.cuh" #include "gemm_4bit_simt.cuh" -#if IS_CDNA -// gfx9/CDNA tuning: +// gfx9/CDNA tuning (CDNA1-4 and CDNA5/gfx1250): // - use fmaf for fp32 accumulation // - accumulate fp16/bf16 pairs in fp32 via fused multiply-add // - keep 16-bit centroids unscaled and fold scale into the fp32 accumulator // - use packed fp16 accumulation +// CDNA5 (gfx1250) is Wave32, but it does NOT implement the SIMT dot instructions +// (no dot12-insts / v_dot2_f32_* builtins), so it opts into this fp32-FMA path +// rather than the v_dot2 path below. This improves bf16/fp16 accuracy relative +// to the generic fallback. +#if IS_CDNA || IS_CDNA5 #define BNB_SIMT_F32_FMAF 1 #define BNB_SIMT_16BIT_FLOAT_FMA 1 #define BNB_SIMT_BF16_UNSCALED_CENTROID 1 @@ -28,7 +32,11 @@ #endif // RDNA3/RDNA3.5/RDNA4 tuning: -// - use native packed bf16/fp16 dot2 instructions with fp32 accumulation +// - use native packed bf16/fp16 dot2 instructions with fp32 accumulation. +// Note: CDNA5 (gfx1250) is intentionally excluded here. Despite its gfx12xx +// target number, it lacks the dot12-insts v_dot2_f32_bf16 / v_dot2_f32_f16 +// builtins (they fail to compile for gfx1250), so it uses the fp32-FMA CDNA path +// above. #if IS_RDNA3 || IS_RDNA3_5 || IS_RDNA4 #define BNB_HIP_BF16_VDOT2 1 #define BNB_HIP_FP16_DOT2 1 diff --git a/docs/source/installation.mdx b/docs/source/installation.mdx index 86d50ec80..3ee3c5754 100644 --- a/docs/source/installation.mdx +++ b/docs/source/installation.mdx @@ -146,7 +146,7 @@ The currently distributed `bitsandbytes` are built with the following configurat | **Linux x86-64** | 7.0.2 | CDNA: gfx90a, gfx942, gfx950 / RDNA: gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201 | **Linux x86-64** | 7.1.1 | CDNA: gfx90a, gfx942, gfx950 / RDNA: gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201 | **Linux x86-64** | 7.2.4 | CDNA: gfx90a, gfx942, gfx950 / RDNA: gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201 -| **Linux x86-64** | 7.14.0 | CDNA: gfx908, gfx90a, gfx942, gfx950 / RDNA: gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201 +| **Linux x86-64** | 7.14.0 | CDNA: gfx908, gfx90a, gfx942, gfx950, gfx1250 / RDNA: gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1103, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201 | **Windows x86-64** | 7.2.1 | RDNA: gfx1100, gfx1101, gfx1102, gfx1150, gfx1151, gfx1200, gfx1201 | **Windows x86-64** | 7.14.0 | RDNA: gfx1030, gfx1031, gfx1032, gfx1033, gfx1034, gfx1035, gfx1036, gfx1100, gfx1101, gfx1102, gfx1150, gfx1151, gfx1152, gfx1153, gfx1200, gfx1201