Skip to content

Commit 9802385

Browse files
committed
Add persistent MXFP8 grid scheduling
1 parent f0b7481 commit 9802385

3 files changed

Lines changed: 197 additions & 77 deletions

File tree

test/test_mxfp8_tma.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
try:
1212
from transformer_nuggets.cute import (
13+
GridScheduler,
1314
MXFP8_TMA_PROFILE_TAGS,
1415
get_mxfp8_tma_gemv,
1516
mxfp8_tma_gemv,
@@ -80,6 +81,49 @@ def test_mxfp8_tma_gemv_matches_reference(k, block_n, num_stages, num_compute_wa
8081
torch.testing.assert_close(actual, expected, atol=1.0, rtol=0.05)
8182

8283

84+
def test_mxfp8_tma_gemv_persistent_grid_matches_reference():
85+
"""Reuse a bounded physical CTA grid across all logical output tiles."""
86+
k = 2048
87+
q_input, input_scale = quantize_mxfp8(torch.randn((1, k), dtype=torch.bfloat16, device="cuda"))
88+
weight, weight_scale = quantize_mxfp8(
89+
torch.randn((128, k), dtype=torch.bfloat16, device="cuda")
90+
)
91+
92+
output = torch.empty((1, 128), dtype=torch.bfloat16, device="cuda")
93+
actual = mxfp8_tma_gemv(
94+
q_input,
95+
weight,
96+
input_scale,
97+
weight_scale,
98+
block_n=4,
99+
output=output,
100+
num_compute_warps=4,
101+
grid_scheduler=GridScheduler.PERSISTENT,
102+
num_persistent_ctas=3,
103+
)
104+
graph = torch.cuda.CUDAGraph()
105+
with torch.cuda.graph(graph):
106+
mxfp8_tma_gemv(
107+
q_input,
108+
weight,
109+
input_scale,
110+
weight_scale,
111+
block_n=4,
112+
output=output,
113+
num_compute_warps=4,
114+
grid_scheduler=GridScheduler.PERSISTENT,
115+
num_persistent_ctas=3,
116+
)
117+
graph.replay()
118+
torch.cuda.synchronize()
119+
120+
assert actual is output
121+
expected = (
122+
dequantize_mxfp8(q_input, input_scale) @ dequantize_mxfp8(weight, weight_scale).T
123+
).bfloat16()
124+
torch.testing.assert_close(actual, expected, atol=1.0, rtol=0.05)
125+
126+
83127
@pytest.mark.parametrize("num_compute_warps", [1, 2, 4])
84128
def test_mxfp8_tma_gemv_cuda_graph_replay(num_compute_warps):
85129
"""Replay into caller-owned output without hidden allocation or copies."""
@@ -119,7 +163,11 @@ def test_mxfp8_tma_gemv_cuda_graph_replay(num_compute_warps):
119163
torch.testing.assert_close(output, expected, atol=1.0, rtol=0.05)
120164

121165

122-
def test_mxfp8_tma_gemv_profiles_labeled_regions():
166+
@pytest.mark.parametrize(
167+
("grid_scheduler", "num_persistent_ctas"),
168+
[(GridScheduler.STATIC, None), (GridScheduler.PERSISTENT, 3)],
169+
)
170+
def test_mxfp8_tma_gemv_profiles_labeled_regions(grid_scheduler, num_persistent_ctas):
123171
"""Record each compile-time-enabled region with static event slots."""
124172
k = 2048
125173
q_input, input_scale = quantize_mxfp8(torch.randn((1, k), dtype=torch.bfloat16, device="cuda"))
@@ -132,6 +180,8 @@ def test_mxfp8_tma_gemv_profiles_labeled_regions():
132180
4,
133181
enable_profiling=True,
134182
num_compute_warps=4,
183+
grid_scheduler=grid_scheduler,
184+
num_persistent_ctas=num_persistent_ctas,
135185
)
136186

137187
with profile_session(
@@ -193,6 +243,10 @@ def test_mxfp8_tma_cli_writes_pftrace(tmp_path):
193243
"4",
194244
"--num-compute-warps",
195245
"4",
246+
"--grid-scheduler",
247+
"persistent",
248+
"--num-persistent-ctas",
249+
"3",
196250
"--output",
197251
str(trace_path),
198252
],

transformer_nuggets/cute/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515

1616
_MXFP8_TMA_EXPORTS = {
17+
"DEFAULT_PERSISTENT_CTAS_PER_SM",
18+
"GridScheduler",
1719
"MXFP8_TMA_PROFILE_TAGS",
1820
"Mxfp8TmaGemv",
1921
"ProfileTag",

0 commit comments

Comments
 (0)