Skip to content

Commit 61764a4

Browse files
committed
Add compile-time MXFP8 region profiling
1 parent ffd2e75 commit 61764a4

4 files changed

Lines changed: 283 additions & 96 deletions

File tree

test/test_mxfp8_tma.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88
pytest.skip("MXFP8 TMA GEMV requires SM100 or SM103", allow_module_level=True)
99

1010
try:
11-
from transformer_nuggets.cute import mxfp8_tma_gemv
11+
from transformer_nuggets.cute import (
12+
MXFP8_TMA_PROFILE_TAGS,
13+
get_mxfp8_tma_gemv,
14+
mxfp8_tma_gemv,
15+
)
16+
from transformer_nuggets.cute.profiler import profile_session
17+
from transformer_nuggets.cute.profiler.host import decode_events
1218
except ImportError:
1319
pytest.skip("CuTe DSL not available", allow_module_level=True)
1420

@@ -95,13 +101,47 @@ def test_mxfp8_tma_gemv_cuda_graph_replay():
95101
torch.testing.assert_close(output, expected, atol=1.0, rtol=0.05)
96102

97103

98-
def test_mxfp8_tma_gemv_combines_cancelling_scales():
104+
def test_mxfp8_tma_gemv_profiles_labeled_regions():
105+
"""Record each compile-time-enabled region with static event slots."""
106+
k = 2048
107+
q_input, input_scale = quantize_mxfp8(torch.randn((1, k), dtype=torch.bfloat16, device="cuda"))
108+
weight, weight_scale = quantize_mxfp8(
109+
torch.randn((128, k), dtype=torch.bfloat16, device="cuda")
110+
)
111+
op = get_mxfp8_tma_gemv(128, k, 4, enable_profiling=True)
112+
113+
with profile_session(
114+
max_events_per_unit=op.max_profile_events_per_cta,
115+
num_units=(op.num_profile_units, "CTA"),
116+
tag_names=list(MXFP8_TMA_PROFILE_TAGS),
117+
device=q_input.device,
118+
) as (prof, tags):
119+
actual = op.interface(
120+
q_input,
121+
weight,
122+
input_scale,
123+
weight_scale,
124+
profile_buffer=prof.tensor,
125+
)
126+
127+
expected = (
128+
dequantize_mxfp8(q_input, input_scale) @ dequantize_mxfp8(weight, weight_scale).T
129+
).bfloat16()
130+
torch.testing.assert_close(actual, expected, atol=1.0, rtol=0.05)
131+
events = decode_events(prof, tags)
132+
assert len(events) == op.num_profile_units * (3 * op.num_k_tiles + 1)
133+
assert {event.tag_name for event in events} == set(MXFP8_TMA_PROFILE_TAGS)
134+
assert {event.unit_id for event in events} == set(range(op.num_profile_units))
135+
136+
137+
@pytest.mark.parametrize(("input_byte", "weight_byte"), [(254, 0), (0, 254)])
138+
def test_mxfp8_tma_gemv_combines_cancelling_scales(input_byte, weight_byte):
99139
"""Avoid an infinite intermediate when E8M0 scale exponents cancel."""
100140
k = 2048
101141
q_input = torch.ones((1, k), dtype=torch.float8_e4m3fn, device="cuda")
102142
weight = torch.ones((128, k), dtype=torch.float8_e4m3fn, device="cuda")
103-
input_scale = torch.full((1, k // 32), 254, dtype=torch.uint8, device="cuda")
104-
weight_scale = torch.zeros((128, k // 32), dtype=torch.uint8, device="cuda")
143+
input_scale = torch.full((1, k // 32), input_byte, dtype=torch.uint8, device="cuda")
144+
weight_scale = torch.full((128, k // 32), weight_byte, dtype=torch.uint8, device="cuda")
105145

106146
actual = mxfp8_tma_gemv(
107147
q_input,

transformer_nuggets/cute/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515

1616
_MXFP8_TMA_EXPORTS = {
17+
"MXFP8_TMA_PROFILE_TAGS",
1718
"Mxfp8TmaGemv",
1819
"get_mxfp8_tma_gemv",
1920
"mxfp8_tma_gemv",

0 commit comments

Comments
 (0)