33====================================================
44This example demonstrates an FP8 GEMM kernel implemented in Helion. The kernel performs
55matrix multiplication on FP8 inputs, accumulating results in FP32 for accuracy, and
6- outputs in FP16 format. It includes a reference PyTorch implementation using
6+ outputs in half-precision format. It includes a reference PyTorch implementation using
77torch._scaled_mm for correctness comparison, and a test function to validate the kernel.
88"""
99
1717
1818import helion
1919from helion ._testing import DEVICE
20+ from helion ._testing import HALF_DTYPE
2021from helion ._testing import run_example
2122import helion .language as hl
2223
@@ -39,13 +40,13 @@ def fp8_gemm(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
3940 x (torch.Tensor): Input tensor of shape [m, k] in FP8 format.
4041 y (torch.Tensor): Input tensor of shape [k, n] in FP8 format.
4142 Returns:
42- torch.Tensor: Output tensor of shape [m, n] in FP16 format.
43+ torch.Tensor: Output tensor of shape [m, n] in half-precision format.
4344 """
4445 m , k = x .size ()
4546 k2 , n = y .size ()
4647 assert k == k2 , f"size mismatch { k } != { k2 } "
47- # Output is in FP16 to match tritonbench behavior
48- out = torch .empty ([m , n ], dtype = torch . float16 , device = x .device )
48+ # Output is in half-precision to match tritonbench behavior
49+ out = torch .empty ([m , n ], dtype = HALF_DTYPE , device = x .device )
4950 for tile_m , tile_n in hl .tile ([m , n ]):
5051 # Accumulate in FP32 for accuracy
5152 acc = hl .zeros ([tile_m , tile_n ], dtype = torch .float32 )
@@ -55,7 +56,7 @@ def fp8_gemm(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
5556 y_tile = y [tile_k , tile_n ]
5657 # Use hl.dot for FP8 GEMM
5758 acc = hl .dot (x_tile , y_tile , acc = acc )
58- out [tile_m , tile_n ] = acc .to (torch . float16 )
59+ out [tile_m , tile_n ] = acc .to (HALF_DTYPE )
5960 return out
6061
6162
@@ -69,14 +70,14 @@ def reference_fp8_gemm_pytorch(
6970 x_fp8 (torch.Tensor): Input tensor in FP8 format.
7071 y_fp8 (torch.Tensor): Input tensor in FP8 format.
7172 Returns:
72- torch.Tensor: Output tensor in FP16 format.
73+ torch.Tensor: Output tensor in half-precision format.
7374 """
7475 # torch._scaled_mm requires column-major for second operand
7576 y_fp8_t = y_fp8 .T .contiguous ().T
7677 scale_a = torch .tensor (1.0 , device = x_fp8 .device )
7778 scale_b = torch .tensor (1.0 , device = x_fp8 .device )
7879 return torch ._scaled_mm (
79- x_fp8 , y_fp8_t , scale_a , scale_b , use_fast_accum = False , out_dtype = torch . float16
80+ x_fp8 , y_fp8_t , scale_a , scale_b , use_fast_accum = False , out_dtype = HALF_DTYPE
8081 )
8182
8283
@@ -97,7 +98,7 @@ def fp8_gemm_tritonbench(
9798 scale_a (torch.Tensor): Scale factor for tensor a (unused in our implementation).
9899 scale_b (torch.Tensor): Scale factor for tensor b (unused in our implementation).
99100 Returns:
100- Callable that returns output tensor in FP16 format.
101+ Callable that returns output tensor in half-precision format.
101102 """
102103 return lambda : fp8_gemm (a , b )
103104
0 commit comments