Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
8335488
enable blockwise FP8 quantization on rocm
asdfvg123 Jun 1, 2026
6226301
enable blockwise FP8 C++ tests on ROCm, fix wave64 bugs, remove redun…
asdfvg123 Jun 4, 2026
bdf905e
fix constexpr chain, arch guard
asdfvg123 Jun 4, 2026
676d1f0
guard kThreadsPerWarp for wave32, derive fp8 max on AMD host
asdfvg123 Jun 9, 2026
f8a0fc5
revert unnecessary guard, add license
asdfvg123 Jun 9, 2026
231e381
use non-sync __shfl on ROCm, drop kFullWarpMask
asdfvg123 Jun 10, 2026
e158d3e
fix fp32 LDS overflow in vector blockwise on gfx942
asdfvg123 Jun 10, 2026
70c35df
drop WarpSyncMask, use __shfl_xor reduce, guard gfx1250 wave32, minor…
asdfvg123 Jun 15, 2026
7ede21d
use explicit gfx942/host guard
asdfvg123 Jun 15, 2026
8895166
fix guard
asdfvg123 Jun 19, 2026
da49b3c
Merge remote-tracking branch 'origin/dev' into yeonsoo/blockwise_fp8
asdfvg123 Jun 19, 2026
64f92a6
use shared rocm_subwarp_allreduce for warp amax reduction
asdfvg123 Jun 19, 2026
21c4f10
guard blockwise fp8 GEMM
asdfvg123 Jun 25, 2026
96ab7d0
add hipkittens blockwise fp8 GEMM for gfx942
asdfvg123 Jun 25, 2026
b542efc
revert the blockwise fp8 gemm guard
asdfvg123 Jun 26, 2026
1a5c4a5
optimize kernel
asdfvg123 Jun 30, 2026
039ff90
Merge remote-tracking branch 'origin/dev' into yeonsoo/blockwise_fp8
asdfvg123 Jun 30, 2026
0c4e2dd
rename submodule
asdfvg123 Jun 30, 2026
53787a5
Merge branch 'yeonsoo/blockwise_fp8' into yeonsoo/blockwise_fp8_gemm_…
asdfvg123 Jun 30, 2026
0803cc4
integrate gfx950 blockwise fp8 gemm
asdfvg123 Jun 30, 2026
812fb91
refactor gemm dispatch, optimize kernel
asdfvg123 Jul 1, 2026
29b2605
refactor dispatch for gfx942
asdfvg123 Jul 1, 2026
a07f0b3
refactor code
asdfvg123 Jul 1, 2026
37f1e2f
refactor code
asdfvg123 Jul 6, 2026
34720d5
support e5m2, fp32 output, add 1d1d kernel
asdfvg123 Jul 6, 2026
9c8a379
refactor code
asdfvg123 Jul 6, 2026
1f14306
refactor code
asdfvg123 Jul 6, 2026
8224e6b
Merge remote-tracking branch 'origin/dev' into yeonsoo/blockwise_fp8_…
asdfvg123 Jul 6, 2026
3b3bb80
handle gemm skips
asdfvg123 Jul 6, 2026
65af26b
add hipkittens cdna3 branch submodule
asdfvg123 Jul 7, 2026
a9f2129
refactor code
asdfvg123 Jul 7, 2026
2199903
drop orphan composable_kernel submodule gitlink in hipkittens_cdna3 s…
asdfvg123 Jul 8, 2026
e7241e8
guard fix
asdfvg123 Jul 9, 2026
0ddeefb
optimize kernel
asdfvg123 Jul 13, 2026
71c02a8
add pow2 scale blockwise gemm kernel
asdfvg123 Jul 14, 2026
c502029
fix spill issue
asdfvg123 Jul 14, 2026
f6a9ae0
clean code
asdfvg123 Jul 14, 2026
cb96f47
clean code
asdfvg123 Jul 15, 2026
449d620
clean code
asdfvg123 Jul 15, 2026
1c172ca
add guard for blockwise group gemm
asdfvg123 Jul 15, 2026
562c6fe
clean code remove debug guard
asdfvg123 Jul 16, 2026
6fb0712
fix OOM
asdfvg123 Jul 20, 2026
1f3ee3c
refactor code
asdfvg123 Jul 21, 2026
bd4e737
switch gemm dispatch
asdfvg123 Jul 21, 2026
d6b2005
merge 1d2d and 1d1d kernel for mi300
asdfvg123 Jul 21, 2026
7687bde
replace arch namespaces with virtual backend class
asdfvg123 Jul 21, 2026
d3ef59c
fix guard
asdfvg123 Jul 22, 2026
12acc6b
merge 1d2d and 1d1d kernel for mi355
asdfvg123 Jul 22, 2026
4e9f19b
add hip guard, strict atol rtol
asdfvg123 Jul 22, 2026
139331e
support blockwise FP8 GEMM on gfx94x/gfx95x with runtime scale selection
asdfvg123 Jul 23, 2026
6626387
refactor rtne and store for mi300
asdfvg123 Jul 23, 2026
f5a8756
fix gfx94x gfx95x explanation
asdfvg123 Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/rocm-wheels-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ jobs:
3rdparty/ck_jit \
3rdparty/hipify_torch \
3rdparty/hipkittens \
3rdparty/hipkittens_cdna3 \
3rdparty/composable_kernel

- name: Derive Docker image tag
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@
[submodule "3rdparty/ck_jit"]
path = 3rdparty/ck_jit
url = https://github.com/ROCm/ck-jit.git
[submodule "3rdparty/hipkittens_cdna3"]
path = 3rdparty/hipkittens_cdna3
url = https://github.com/asdfvg123/HipKittens.git
branch = yeonsoo/cdna3_fp8
Comment on lines +36 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submodule points to a personal user fork on an unreleased branch — must be relocated before merge.

  • url = https://github.com/asdfvg123/HipKittens.git is a personal repo, not a canonical one. The sibling 3rdparty/hipkittens correctly points at HazyResearch/HipKittens.git. Anyone cloning ROCm/TransformerEngine will fail git submodule update --init the moment this repo goes private or gets renamed. It also blocks reproducible ROCm CI wheel builds (this submodule is now in the init list in .github/workflows/rocm-wheels-build.yml).
  • The pinned branch yeonsoo/cdna3_fp8 is likewise a personal in-flight branch; the CDNA3 kittens sources need to land in a persistent upstream branch (HazyResearch or a ROCm-owned mirror) and this URL/branch should be updated before merge.

1 change: 1 addition & 0 deletions 3rdparty/hipkittens_cdna3
Submodule hipkittens_cdna3 added at 17d808
15 changes: 15 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,21 @@ To enable MXFP8 support, use NVTE_ROCM_ENABLE_MXFP8 environment variable which c
* 1 - enable MXFP8 support in fp8;
* 2 - make MXFP8 a default fp8 recipe.

Blockwise FP8 GEMM support on ROCm (gfx942 and gfx950)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Blockwise FP8 GEMM is supported on gfx942 and gfx950 GPUs through the HipKittens backend and is enabled by default.
It supports 1Dx2D and 1Dx1D scaling, e4m3/e5m2 inputs in any combination except e5m2 x e5m2, bf16/fp32/fp16 output, and bias/beta/DGELU epilogues.
The K and N dimensions must be multiples of 16.
The backend shares the existing USE_HIPKITTENS_GEMM build option with MXFP8:

* OFF - disable the HipKittens blockwise FP8 and MXFP8 GEMM backend;
* ON - enable the HipKittens GEMM backend (default).

On gfx950 there are two blockwise FP8 GEMM kernels, selected at runtime by the NVTE_BLOCKWISE_FP8_POWER_OF_2_SCALE environment variable:

* 0 - compute the GEMM with the FP32 scales directly;
* 1 - cast the incoming FP32 scales to E8M0 (power-of-2) and compute the GEMM with those scales (default).

Two-stage amax Kernel
^^^^^^^^^^^^^^^^^^^^^

Expand Down
151 changes: 126 additions & 25 deletions tests/pytorch/test_float8_blockwise_gemm_exact.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# This file was modified for portability to AMDGPU
# Copyright (c) 2026, Advanced Micro Devices, Inc. All rights reserved.
# Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# See LICENSE for license information.
Expand All @@ -6,21 +8,46 @@
import torch
import transformer_engine.pytorch as te
import transformer_engine_torch as tex
from torch.utils.cpp_extension import IS_HIP_EXTENSION

from transformer_engine.pytorch.constants import TE_DType
from transformer_engine.pytorch import (
Float8BlockQuantizer,
get_device_compute_capability,
)
from transformer_engine.pytorch.utils import (
get_torch_float8_e4m3_type,
get_torch_float8_e5m2_type,
)
from references.blockwise_quantizer_reference import CuBLASScaleMunger
from references.blockwise_fp8_gemm_reference import CuBLASRefBlockwiseGemm

fp8_e4m3_type = get_torch_float8_e4m3_type()
fp8_e5m2_type = get_torch_float8_e5m2_type()

def fp8_blockwise_gemm_supported() -> bool:
supported = te.is_fp8_block_scaling_available()
emulated = get_device_compute_capability() >= (10, 0)
return supported and not emulated

if IS_HIP_EXTENSION:
def rocm_blockwise_is_supported(
is_x_1d_scaled,
is_w_1d_scaled,
*,
x_columnwise: bool = False,
w_columnwise: bool = False,
):
is_1d2d = is_x_1d_scaled and not is_w_1d_scaled
is_1d1d = is_x_1d_scaled and is_w_1d_scaled
if not (is_1d2d or is_1d1d):
return False, "Only 1D by 1D and 1D by 2D block scaling GEMM is supported"

if x_columnwise and not w_columnwise:
return False, "does not support TT layout"

return True, None


def cublas_gemm_fp8_blockwise_case(
x_dtype,
Expand All @@ -45,12 +72,22 @@ def cublas_gemm_fp8_blockwise_case(
atol: float = 0.0,
rtol: float = 0.0
):
if x_dtype == torch.float8_e5m2 and w_dtype == torch.float8_e5m2:
if IS_HIP_EXTENSION:
atol = 1e-5
rtol = 1.3e-6
if x_dtype == fp8_e5m2_type and w_dtype == fp8_e5m2_type:
pytest.skip("FP8 GEMM doesn't support both a and b types being torch.float8_e5m2")
if not (is_x_1d_scaled or is_w_1d_scaled):
pytest.skip("FP8 GEMM doesn't support 2dimensional qtile by 2dimensional qtile")
if not fp8_blockwise_gemm_supported():
pytest.skip("CUDA version does not support blockwise FP8 gemm.")
if IS_HIP_EXTENSION:
supported, reason = rocm_blockwise_is_supported(
is_x_1d_scaled, is_w_1d_scaled,
x_columnwise=x_columnwise, w_columnwise=w_columnwise,
)
if not supported:
pytest.skip(reason)
# Setup device and random seed
device = "cuda"
seed = 0
Expand Down Expand Up @@ -228,6 +265,13 @@ def cublas_gemm_test_constraint_enforced(
):
if not fp8_blockwise_gemm_supported():
pytest.skip("CUDA version does not support blockwise FP8 gemm.")
if IS_HIP_EXTENSION:
Comment thread
alextmagro marked this conversation as resolved.
supported, reason = rocm_blockwise_is_supported(
is_x_1d_scaled, is_w_1d_scaled,
x_columnwise=x_columnwise, w_columnwise=w_columnwise,
)
if not supported:
expected_err_msg = reason
# Setup device and random seed
device = "cuda"
seed = 0
Expand Down Expand Up @@ -331,8 +375,8 @@ def cublas_gemm_test_constraint_enforced(
(1024, 4096, 1024),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("noise_type", ["normal"], ids=str)
@pytest.mark.parametrize("x_magnitude", [1], ids=str)
Expand Down Expand Up @@ -387,8 +431,8 @@ def test_cublas_gemm_fp8_blockwise_shape_varying(
(320, 256, 336),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("noise_type", ["normal", "uniform"], ids=str)
@pytest.mark.parametrize("x_magnitude", [1e-28, 1, 1e3], ids=str)
Expand Down Expand Up @@ -447,8 +491,8 @@ def test_cublas_gemm_fp8_blockwise_accumulate_magnitude_varying(
(256, 256, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("noise_type", ["normal"], ids=str)
@pytest.mark.parametrize("x_magnitude", [1e-3], ids=str)
Expand Down Expand Up @@ -509,8 +553,8 @@ def test_cublas_gemm_fp8_blockwise_bias(
(4096, 128, 4096),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn, torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type, fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("noise_type", ["normal"], ids=str)
@pytest.mark.parametrize("x_magnitude", [1], ids=str)
Expand Down Expand Up @@ -582,8 +626,8 @@ def test_cublas_gemm_fp8_blockwise_columnwise(
(256, 256, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16], ids=str)
@pytest.mark.parametrize("noise_type", ["normal"], ids=str)
@pytest.mark.parametrize("x_magnitude", [1], ids=str)
Expand Down Expand Up @@ -654,8 +698,8 @@ def test_cublas_gemm_fp8_gelu(
(256, 128, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("accumulate", [True, False], ids=["accumulate", "no_accumulate"])
@pytest.mark.parametrize("use_split_accumulator", [False], ids=["split_acc"])
Expand All @@ -680,6 +724,10 @@ def test_split_accumulator_enforced(
is_x_1d_scaled,
is_w_1d_scaled,
) -> None:
if IS_HIP_EXTENSION:
expected_err_msg = "requires split accumulator"
Comment thread
wangye805 marked this conversation as resolved.
else:
expected_err_msg = "CUBLAS_STATUS_NOT_SUPPORTED"
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
Expand All @@ -691,6 +739,7 @@ def test_split_accumulator_enforced(
use_split_accumulator,
is_x_1d_scaled,
is_w_1d_scaled,
expected_err_msg=expected_err_msg,
)


Expand All @@ -701,8 +750,8 @@ def test_split_accumulator_enforced(
(256, 128, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("accumulate", [True, False], ids=["accumulate", "no_accumulate"])
@pytest.mark.parametrize("use_split_accumulator", [True], ids=["split_acc"])
Expand All @@ -728,6 +777,10 @@ def test_bgrad_not_supported(
is_w_1d_scaled,
) -> None:
# NOTE: BGRAD epilogue is not supported for fp8.
if IS_HIP_EXTENSION:
Comment thread
alextmagro marked this conversation as resolved.
expected_err_msg = "does not support bias with grad"
else:
expected_err_msg = "Epilogue requested outside of the available"
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
Expand All @@ -741,7 +794,7 @@ def test_bgrad_not_supported(
is_w_1d_scaled,
use_grad=True,
use_bias=True,
expected_err_msg="Epilogue requested outside of the available",
expected_err_msg=expected_err_msg,
)


Expand All @@ -752,8 +805,8 @@ def test_bgrad_not_supported(
(256, 128, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("accumulate", [True, False], ids=["accumulate", "no_accumulate"])
@pytest.mark.parametrize("use_bias", [True, False], ids=["bias", "no_bias"])
Expand Down Expand Up @@ -788,6 +841,13 @@ def test_gelu_unsupported_cases_error(
expected_err = "an unsupported value or parameter was passed"
else:
expected_err = "Epilogue requested outside of the available"
if IS_HIP_EXTENSION:
if use_grad and not use_bias:
expected_err = "DGELU epilogue only supports bfloat16 output"
elif not use_grad:
expected_err = "only supports DGELU grad epilogue"
else:
expected_err = "does not support bias with grad"
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
Expand All @@ -812,8 +872,8 @@ def test_gelu_unsupported_cases_error(
(256, 128, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e5m2], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e5m2_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("accumulate", [True, False], ids=["accumulate", "no_accumulate"])
@pytest.mark.parametrize("use_split_accumulator", [True], ids=["split_acc"])
Expand All @@ -839,6 +899,10 @@ def test_illegal_dtype_enforced(
is_w_1d_scaled,
) -> None:
# e5m2 by e5m2 not supported.
if IS_HIP_EXTENSION:
expected_err_msg = "does not support e5m2 by e5m2 inputs"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e5m2 should be supported by hipkittens, have a look at the mxfp8 kernels to see how we template for that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. The test expects e4m3 x e4m3 / e4m3 x e5m2 / e5m2 x e4m3 but not e5m2 x e5m2 and the current implementation also supports the former 3 but not the e5m2 x e5m2. While this is an easy support, I will leave it as a future PR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the kernel supports the config already it I think it would be better to just disable this test, and allow users to use it if they want.

else:
expected_err_msg = "CUBLAS_STATUS_NOT_SUPPORTED"
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
Expand All @@ -850,6 +914,7 @@ def test_illegal_dtype_enforced(
use_split_accumulator,
is_x_1d_scaled,
is_w_1d_scaled,
expected_err_msg=expected_err_msg,
)


Expand All @@ -859,8 +924,8 @@ def test_illegal_dtype_enforced(
(256, 128, 256),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16, torch.float32], ids=str)
@pytest.mark.parametrize("accumulate", [True, False], ids=["accumulate", "no_accumulate"])
@pytest.mark.parametrize("use_split_accumulator", [True], ids=["split_acc"])
Expand All @@ -884,7 +949,10 @@ def test_illegal_2D_by_2D_enforced(
is_w_1d_scaled,
) -> None:
# 2D block quantization by 2D block quantization is not supported.
expected_err_msg = "Only 1D by 1D, 1D by 2D, and 2D by 1D block scaling GEMM is supported"
if IS_HIP_EXTENSION:
expected_err_msg = "Only 1D by 1D and 1D by 2D block scaling GEMM is supported"
else:
expected_err_msg = "Only 1D by 1D, 1D by 2D, and 2D by 1D block scaling GEMM is supported"
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
Expand All @@ -911,8 +979,8 @@ def test_illegal_2D_by_2D_enforced(
(256, 128, 252, False, False),
],
)
@pytest.mark.parametrize("x_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("w_dtype", [torch.float8_e4m3fn], ids=str)
@pytest.mark.parametrize("x_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("w_dtype", [fp8_e4m3_type], ids=str)
@pytest.mark.parametrize("out_dtype", [torch.bfloat16], ids=str)
@pytest.mark.parametrize("accumulate", [False], ids=["no_accumulate"])
@pytest.mark.parametrize("use_split_accumulator", [True], ids=["split_acc"])
Expand All @@ -939,6 +1007,39 @@ def test_unaligned_shapes(
is_x_1d_scaled,
is_w_1d_scaled,
) -> None:
if IS_HIP_EXTENSION:
legal = (K % 16 == 0) and (N % 16 == 0) # M is unconstrained for rocm
if not legal:
cublas_gemm_test_constraint_enforced(
x_dtype,
w_dtype,
out_dtype,
M,
K,
N,
accumulate,
use_split_accumulator,
is_x_1d_scaled,
is_w_1d_scaled,
expected_err_msg="must be multiple of 16",
)
else:
cublas_gemm_fp8_blockwise_case(
x_dtype,
w_dtype,
out_dtype,
M,
K,
N,
"uniform", # noise type
1.0, # x_magnitude
1.0, # w_magnitude
accumulate,
use_split_accumulator,
is_x_1d_scaled,
is_w_1d_scaled,
)
return
legal = legalX1d if is_x_1d_scaled else legalX2d
if not legal:
cublas_gemm_test_constraint_enforced(
Expand Down
Loading
Loading