@@ -44,6 +44,7 @@ def _gdn_decode_bytes(
4444 head_size : int ,
4545 input_dtype : torch .dtype ,
4646 output_dtype : torch .dtype ,
47+ use_cache_indices : bool ,
4748) -> int :
4849 num_o_heads = max (num_q_heads , num_v_heads )
4950 elem_size = _dtype_size (input_dtype )
@@ -57,6 +58,7 @@ def _gdn_decode_bytes(
5758 dt_bias_bytes = num_v_heads * 4
5859 a_bytes = batch_size * num_v_heads * elem_size
5960 b_bytes = batch_size * num_v_heads * elem_size
61+ cache_indices_bytes = batch_size * 4 if use_cache_indices else 0
6062
6163 return (
6264 q_bytes
@@ -68,6 +70,7 @@ def _gdn_decode_bytes(
6870 + dt_bias_bytes
6971 + a_bytes
7072 + b_bytes
73+ + cache_indices_bytes
7174 )
7275
7376
@@ -77,6 +80,7 @@ def _make_inputs(
7780 num_v_heads : int ,
7881 head_size : int ,
7982 dtype : torch .dtype ,
83+ use_cache_indices : bool ,
8084) -> tuple [torch .Tensor , ...]:
8185 device = torch .device ("musa" )
8286 q = torch .randn ((batch_size , 1 , num_q_heads , head_size ), dtype = dtype , device = device )
@@ -91,7 +95,12 @@ def _make_inputs(
9195 dt_bias = torch .randn ((num_v_heads ,), dtype = torch .float32 , device = device ) * 0.1
9296 a = torch .randn ((batch_size , 1 , num_v_heads ), dtype = dtype , device = device ) * 0.1
9397 b = torch .randn ((batch_size , 1 , num_v_heads ), dtype = dtype , device = device )
94- return q , k , v , state , A_log , a , dt_bias , b
98+ state_indices = (
99+ torch .arange (batch_size , dtype = torch .int32 , device = device )
100+ if use_cache_indices
101+ else None
102+ )
103+ return q , k , v , state , A_log , a , dt_bias , b , state_indices
95104
96105
97106def _bench_one_shape (
@@ -101,13 +110,15 @@ def _bench_one_shape(
101110 head_size : int ,
102111 dtype : torch .dtype ,
103112 num_tests : int ,
113+ use_cache_indices : bool ,
104114) -> float :
105- q , k , v , state , A_log , a , dt_bias , b = _make_inputs (
115+ q , k , v , state , A_log , a , dt_bias , b , state_indices = _make_inputs (
106116 batch_size = batch_size ,
107117 num_q_heads = num_q_heads ,
108118 num_v_heads = num_v_heads ,
109119 head_size = head_size ,
110120 dtype = dtype ,
121+ use_cache_indices = use_cache_indices ,
111122 )
112123
113124 def _runner ():
@@ -121,6 +132,7 @@ def _runner():
121132 dt_bias = dt_bias ,
122133 b = b ,
123134 state_layout = "VK" ,
135+ state_indices = state_indices ,
124136 scale = None ,
125137 use_qk_l2norm = True ,
126138 )
@@ -155,61 +167,76 @@ def main():
155167 default = list (DEFAULT_HEAD_CONFIGS ),
156168 help = "Head configs in 'Hq,Hv' form. Default covers 8,16 / 16,32 / 16,64." ,
157169 )
170+ parser .add_argument (
171+ "--cache-indices" ,
172+ choices = ["none" , "identity" , "both" ],
173+ default = "none" ,
174+ help = "Benchmark without cache_indices, with identity cache_indices, or both." ,
175+ )
158176 args = parser .parse_args ()
159177
160178 if not (hasattr (torch , "musa" ) and torch .musa .is_available ()):
161179 raise RuntimeError ("MUSA device is not available." )
162180
163181 dtype = torch .float16 if args .dtype == "fp16" else torch .bfloat16
164182 head_configs = [_parse_head_config (spec ) for spec in args .head_configs ]
183+ cache_index_modes = (
184+ ("none" , "identity" ) if args .cache_indices == "both" else (args .cache_indices ,)
185+ )
165186
166187 print (f"\n MUSA: { torch .musa .get_device_name (0 )} " )
167188 print (f"Kernel: { KERNEL_NAME } " )
168189 print (
169190 f"Config: D={ args .head_size } , dtype={ args .dtype } , "
170- f"head_configs={ head_configs } , batches={ tuple (args .batch_sizes )} "
191+ f"head_configs={ head_configs } , batches={ tuple (args .batch_sizes )} , "
192+ f"cache_indices={ args .cache_indices } "
171193 )
172194 print ()
173195
174196 header = (
175- f"{ 'Hq' :>4s} { 'Hv' :>4s} { 'B' :>4s} "
197+ f"{ 'Hq' :>4s} { 'Hv' :>4s} { 'B' :>4s} { 'cache' :>8s } "
176198 f"{ 'Latency(us)' :>12s} { 'TFLOPS' :>8s} { 'GB/s' :>8s} "
177199 )
178200 print (header )
179201 print ("-" * len (header ))
180202
181203 for num_q_heads , num_v_heads in head_configs :
182204 for batch_size in args .batch_sizes :
183- seconds = _bench_one_shape (
184- batch_size = batch_size ,
185- num_q_heads = num_q_heads ,
186- num_v_heads = num_v_heads ,
187- head_size = args .head_size ,
188- dtype = dtype ,
189- num_tests = args .num_tests ,
190- )
191- flops = _gdn_decode_flops (
192- batch_size = batch_size ,
193- num_q_heads = num_q_heads ,
194- num_v_heads = num_v_heads ,
195- head_size = args .head_size ,
196- )
197- io_bytes = _gdn_decode_bytes (
198- batch_size = batch_size ,
199- num_q_heads = num_q_heads ,
200- num_v_heads = num_v_heads ,
201- head_size = args .head_size ,
202- input_dtype = dtype ,
203- output_dtype = dtype ,
204- )
205- latency_us = seconds * 1e6
206- tflops = flops / seconds / 1e12
207- bandwidth = io_bytes / seconds / 1e9
208- print (
209- f"{ num_q_heads :>4d} { num_v_heads :>4d} { batch_size :>4d} "
210- f"{ latency_us :>12.3f} { tflops :>8.3f} { bandwidth :>8.3f} "
211- )
212- torch .musa .empty_cache ()
205+ for cache_mode in cache_index_modes :
206+ use_cache_indices = cache_mode == "identity"
207+ seconds = _bench_one_shape (
208+ batch_size = batch_size ,
209+ num_q_heads = num_q_heads ,
210+ num_v_heads = num_v_heads ,
211+ head_size = args .head_size ,
212+ dtype = dtype ,
213+ num_tests = args .num_tests ,
214+ use_cache_indices = use_cache_indices ,
215+ )
216+ flops = _gdn_decode_flops (
217+ batch_size = batch_size ,
218+ num_q_heads = num_q_heads ,
219+ num_v_heads = num_v_heads ,
220+ head_size = args .head_size ,
221+ )
222+ io_bytes = _gdn_decode_bytes (
223+ batch_size = batch_size ,
224+ num_q_heads = num_q_heads ,
225+ num_v_heads = num_v_heads ,
226+ head_size = args .head_size ,
227+ input_dtype = dtype ,
228+ output_dtype = dtype ,
229+ use_cache_indices = use_cache_indices ,
230+ )
231+ latency_us = seconds * 1e6
232+ tflops = flops / seconds / 1e12
233+ bandwidth = io_bytes / seconds / 1e9
234+ print (
235+ f"{ num_q_heads :>4d} { num_v_heads :>4d} { batch_size :>4d} "
236+ f"{ cache_mode :>8s} { latency_us :>12.3f} "
237+ f"{ tflops :>8.3f} { bandwidth :>8.3f} "
238+ )
239+ torch .musa .empty_cache ()
213240
214241
215242if __name__ == "__main__" :
0 commit comments