1313
1414Reports per-kernel latency (ms), speedup, and numerical accuracy (max abs error,
1515cosine similarity for compress; mask match rate for topk).
16+
17+ Also benchmarks backward pass of compress (fused Triton bwd kernel vs. PyTorch autograd).
1618"""
1719
1820from __future__ import annotations
@@ -116,14 +118,13 @@ def accuracy_topk(ref_mask: torch.Tensor, test_mask: torch.Tensor) -> dict:
116118# Benchmark runner
117119# ---------------------------------------------------------------------------
118120
119- def bench_compress (
121+ def bench_compress_fwd (
120122 B : int , H : int , seq_len : int , D : int , block_elements : int ,
121123 dtype : torch .dtype , warmup : int , rep : int ,
122124) -> None :
123125 num_blocks = seq_len // block_elements
124126 x = torch .randn (B , H , seq_len , D , dtype = dtype , device = "cuda" )
125127 vbs = torch .full ((num_blocks ,), block_elements , dtype = torch .int32 , device = "cuda" )
126- # Make a few blocks partially filled to exercise variable block sizes
127128 if num_blocks > 4 :
128129 vbs [1 ] = block_elements - 2
129130 vbs [- 2 ] = block_elements - 5
@@ -138,7 +139,58 @@ def bench_compress(
138139 new_ms = do_bench (lambda : fused_block_mean (x , vbs , block_elements ), warmup = warmup , rep = rep )
139140
140141 speedup = old_ms / new_ms if new_ms > 0 else float ("inf" )
141- print (f" compress | old: { old_ms :8.3f} ms | new: { new_ms :8.3f} ms | speedup: { speedup :5.2f} x "
142+ print (f" compress fwd | old: { old_ms :8.3f} ms | new: { new_ms :8.3f} ms | speedup: { speedup :5.2f} x "
143+ f"| max_abs_err: { acc ['max_abs_err' ]:.2e} | cos_sim: { acc ['cosine_sim' ]:.8f} " )
144+
145+
146+ def bench_compress_bwd (
147+ B : int , H : int , seq_len : int , D : int , block_elements : int ,
148+ dtype : torch .dtype , warmup : int , rep : int ,
149+ ) -> None :
150+ num_blocks = seq_len // block_elements
151+ vbs = torch .full ((num_blocks ,), block_elements , dtype = torch .int32 , device = "cuda" )
152+ if num_blocks > 4 :
153+ vbs [1 ] = block_elements - 2
154+ vbs [- 2 ] = block_elements - 5
155+
156+ # --- Accuracy: compare gradients ---
157+ x_old = torch .randn (B , H , seq_len , D , dtype = dtype , device = "cuda" , requires_grad = True )
158+ grad_out = torch .randn (B , H , num_blocks , D , dtype = dtype , device = "cuda" )
159+
160+ out_old = pytorch_block_mean (x_old , vbs , block_elements )
161+ out_old .backward (grad_out )
162+ grad_ref = x_old .grad .clone ()
163+
164+ x_new = x_old .detach ().clone ().requires_grad_ (True )
165+ out_new = fused_block_mean (x_new , vbs , block_elements )
166+ out_new .backward (grad_out )
167+ grad_fused = x_new .grad .clone ()
168+
169+ acc = accuracy_compress (grad_ref , grad_fused )
170+
171+ # --- Latency: isolate backward-only via retain_graph ---
172+ x_o = x_old .detach ().clone ().requires_grad_ (True )
173+ out_o = pytorch_block_mean (x_o , vbs , block_elements )
174+ loss_o = (out_o * grad_out ).sum ()
175+ for _ in range (warmup ):
176+ torch .autograd .grad (loss_o , x_o , retain_graph = True )
177+ old_ms = do_bench (
178+ lambda : torch .autograd .grad (loss_o , x_o , retain_graph = True ),
179+ warmup = 0 , rep = rep ,
180+ )
181+
182+ x_n = x_old .detach ().clone ().requires_grad_ (True )
183+ out_n = fused_block_mean (x_n , vbs , block_elements )
184+ loss_n = (out_n * grad_out ).sum ()
185+ for _ in range (warmup ):
186+ torch .autograd .grad (loss_n , x_n , retain_graph = True )
187+ new_ms = do_bench (
188+ lambda : torch .autograd .grad (loss_n , x_n , retain_graph = True ),
189+ warmup = 0 , rep = rep ,
190+ )
191+
192+ speedup = old_ms / new_ms if new_ms > 0 else float ("inf" )
193+ print (f" compress bwd | old: { old_ms :8.3f} ms | new: { new_ms :8.3f} ms | speedup: { speedup :5.2f} x "
142194 f"| max_abs_err: { acc ['max_abs_err' ]:.2e} | cos_sim: { acc ['cosine_sim' ]:.8f} " )
143195
144196
@@ -188,7 +240,8 @@ def main() -> None:
188240 print (f"seq_len={ seq_len } , num_blocks={ num_blocks } , topk={ topk } " )
189241 print ("-" * 100 )
190242
191- bench_compress (B , H , seq_len , D , block_elements , dtype , args .warmup , args .rep )
243+ bench_compress_fwd (B , H , seq_len , D , block_elements , dtype , args .warmup , args .rep )
244+ bench_compress_bwd (B , H , seq_len , D , block_elements , dtype , args .warmup , args .rep )
192245 bench_topk (B , H , num_blocks , topk , dtype , args .warmup , args .rep )
193246
194247
0 commit comments