1616import triton
1717
1818
19- def _metax_max_num_warps ():
20- """Return the maximum number of warps safe on the current device.
21-
22- MetaX C550 has warp_size=64 and max 512 threads per block, so
23- max safe num_warps is 8 (64*8=512). For standard warp_size=32
24- devices this returns 16, preserving existing behavior.
25- """
26- props = torch .cuda .get_device_properties (torch .cuda .current_device ())
27- return 512 // props .warp_size
28-
29-
3019def simple_elementwise_blocksize_heur (args ):
3120 return 512
3221
@@ -39,6 +28,110 @@ def argmax_heur_block_n(args):
3928 return min (4096 , triton .next_power_of_2 (args ["N" ]))
4029
4130
31+ def argmax_heur_tile_k (args ):
32+ MAX_TILE_K = 512
33+ NUM_SMS = torch .cuda .get_device_properties (
34+ torch .cuda .current_device ()
35+ ).multi_processor_count
36+
37+ K = args ["K" ]
38+ M = args ["M" ]
39+
40+ if K <= 128 :
41+ return 1 << (K .bit_length () - 1 ) if K > 0 else 1
42+
43+ tile_k = 64
44+ upper_bound = min (K , MAX_TILE_K )
45+
46+ while tile_k <= upper_bound :
47+ num_blocks = M * triton .cdiv (K , tile_k )
48+ num_waves = num_blocks / NUM_SMS
49+ if num_waves > 1 and (tile_k * 2 <= upper_bound ):
50+ tile_k *= 2
51+ else :
52+ break
53+
54+ return tile_k
55+
56+
57+ def argmax_heur_tile_n_non_inner (args ):
58+ n = args ["N" ]
59+ tile_k = args ["TILE_K" ]
60+
61+ if n <= 128 :
62+ return n
63+
64+ target_tile = min (8192 , n )
65+ tile_n = triton .next_power_of_2 (target_tile )
66+ tile_n = max (64 , min (tile_n , 4096 ))
67+
68+ if tile_n * tile_k > 32768 :
69+ tile_n = max (64 , 32768 // tile_k )
70+
71+ return tile_n
72+
73+
74+ def argmax_heur_tile_n_inner (args ):
75+ if args ["N" ] <= (32 * 1024 ):
76+ return triton .next_power_of_2 (args ["N" ])
77+ else :
78+ return 4096
79+
80+
81+ def argmax_heur_one_tile_per_cta (args ):
82+ return args ["TILE_N" ] >= args ["N" ]
83+
84+
85+ def argmax_heur_num_warps_non_inner (args ):
86+ tile_n = args ["TILE_N" ]
87+ if tile_n <= 64 :
88+ return 4
89+ else :
90+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
91+
92+
93+ def argmax_heur_num_warps_inner (args ):
94+ tile_size = args ["TILE_N" ]
95+ if tile_size < 2048 :
96+ return 4
97+ else :
98+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
99+
100+
101+ def mean_heur_tile_k (args ):
102+ MAX_TILE_K = 512
103+ NUM_SMS = torch .cuda .get_device_properties (
104+ torch .cuda .current_device ()
105+ ).multi_processor_count
106+ tile_k = 1
107+ upper_bound = min (args ["K" ], MAX_TILE_K )
108+ while tile_k <= upper_bound :
109+ num_blocks = args ["M" ] * triton .cdiv (args ["K" ], tile_k )
110+ num_waves = num_blocks / NUM_SMS
111+ if (num_waves > 1 ) and (tile_k * 2 <= upper_bound ):
112+ tile_k *= 2
113+ else :
114+ break
115+ return tile_k
116+
117+
118+ def mean_heur_tile_n_non_inner (args ):
119+ tile_k = args .get ("TILE_K" , 1 )
120+ n = args ["N" ]
121+ if n <= 128 :
122+ return n
123+ target_tile = min (8192 , n )
124+ tile_n = triton .next_power_of_2 (target_tile )
125+ tile_n = max (64 , min (tile_n , 4096 ))
126+ if tile_n * tile_k > 32768 :
127+ tile_n = max (64 , 32768 // tile_k )
128+ return tile_n
129+
130+
131+ def mean_heur_one_tile_per_cta (args ):
132+ return args ["TILE_N" ] >= args ["N" ]
133+
134+
42135def bmm_heur_divisible_m (args ):
43136 return args ["M" ] % args ["TILE_M" ] == 0
44137
@@ -69,10 +162,8 @@ def dropout_heur_block(args):
69162def dropout_heur_num_warps (args ):
70163 if args ["N" ] <= 512 :
71164 return 4
72- elif args ["N" ] <= 1024 :
73- return 8
74165 else :
75- return _metax_max_num_warps ()
166+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
76167
77168
78169def exponential_heur_block (args ):
@@ -85,10 +176,8 @@ def exponential_heur_block(args):
85176def exponential_heur_num_warps (args ):
86177 if args ["N" ] <= 512 :
87178 return 4
88- elif args ["N" ] <= 1024 :
89- return 8
90179 else :
91- return _metax_max_num_warps ()
180+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
92181
93182
94183def gather_heur_block_m (args ):
@@ -149,10 +238,8 @@ def rand_heur_block(args):
149238def rand_heur_num_warps (args ):
150239 if args ["N" ] <= 512 :
151240 return 4
152- elif args ["N" ] <= 1024 :
153- return 8
154241 else :
155- return _metax_max_num_warps ()
242+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
156243
157244
158245def randn_heur_block (args ):
@@ -165,10 +252,8 @@ def randn_heur_block(args):
165252def randn_heur_num_warps (args ):
166253 if args ["N" ] <= 512 :
167254 return 4
168- elif args ["N" ] <= 1024 :
169- return 8
170255 else :
171- return _metax_max_num_warps ()
256+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
172257
173258
174259def softmax_heur_tile_k (args ):
@@ -201,14 +286,10 @@ def softmax_heur_num_warps_non_inner(args):
201286 tile_size = args ["TILE_N" ] * args ["TILE_K" ]
202287 if tile_size < 512 :
203288 return 1
204- elif tile_size < 256 :
205- return 2
206289 elif tile_size < 2048 :
207290 return 4
208- elif tile_size < 4096 :
209- return 8
210291 else :
211- return _metax_max_num_warps ()
292+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
212293
213294
214295def softmax_heur_tile_n_inner (args ):
@@ -222,10 +303,8 @@ def softmax_heur_num_warps_inner(args):
222303 tile_size = args ["TILE_N" ]
223304 if tile_size < 2048 :
224305 return 4
225- elif tile_size < 4096 :
226- return 8
227306 else :
228- return _metax_max_num_warps ()
307+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
229308
230309
231310def softmax_heur_tile_n_bwd_non_inner (args ):
@@ -246,10 +325,8 @@ def uniform_heur_block(args):
246325def uniform_heur_num_warps (args ):
247326 if args ["N" ] <= 512 :
248327 return 4
249- elif args ["N" ] <= 1024 :
250- return 8
251328 else :
252- return _metax_max_num_warps ()
329+ return 8 # MetaX C550: max 512 threads = 8 warps × 64
253330
254331
255332def var_mean_heur_block_n (args ):
@@ -269,14 +346,17 @@ def upsample_nearest2d_USE_INT32_IDX(args):
269346
270347
271348def batch_norm_heur_block_m (args ):
272- return min (2048 , triton .next_power_of_2 (args ["batch_dim" ]))
349+ return min (512 , triton .next_power_of_2 (args ["batch_dim" ]))
273350
274351
275352def batch_norm_heur_block_n (args ):
276- # A maximum of 16384 elements are loaded at once.
353+ # Cap total tile elements to 4096 to stay within MetaX C550 4KB/thread
354+ # private memory limit. The kernel holds 3 float32 accumulators (mean, var,
355+ # cnt) of shape (BLOCK_M, BLOCK_N) plus temporaries; 4096 elements keeps
356+ # register spill well under 4KB.
277357 BLOCK_M = batch_norm_heur_block_m (args )
278358 BLOCK_N = triton .next_power_of_2 (args ["spatial_dim" ])
279- return min (BLOCK_N , max (1 , 2 ** 14 // BLOCK_M ))
359+ return min (BLOCK_N , max (1 , 2 ** 12 // BLOCK_M ))
280360
281361
282362def vdot_heur_block_size (args ):
@@ -313,9 +393,16 @@ def zeros_heur_num_warps(args):
313393 "BLOCK_M" : lambda args : 4 ,
314394 "BLOCK_N" : lambda args : 1024 ,
315395 },
316- "argmax" : {
317- "BLOCK_M" : argmax_heur_block_m ,
318- "BLOCK_N" : argmax_heur_block_n ,
396+ "argmax_non_inner" : {
397+ "TILE_K" : argmax_heur_tile_k ,
398+ "TILE_N" : argmax_heur_tile_n_non_inner ,
399+ "ONE_TILE_PER_CTA" : argmax_heur_one_tile_per_cta ,
400+ "num_warps" : argmax_heur_num_warps_non_inner ,
401+ },
402+ "argmax_inner" : {
403+ "TILE_N" : argmax_heur_tile_n_inner ,
404+ "ONE_TILE_PER_CTA" : argmax_heur_one_tile_per_cta ,
405+ "num_warps" : argmax_heur_num_warps_inner ,
319406 },
320407 "argmin" : {
321408 "BLOCK_M" : argmin_heur_block_m ,
@@ -375,6 +462,12 @@ def zeros_heur_num_warps(args):
375462 "ONE_TILE_PER_CTA" : softmax_heur_one_tile_per_cta ,
376463 "num_warps" : softmax_heur_num_warps_inner ,
377464 },
465+ "mean_non_inner" : {
466+ "TILE_K" : mean_heur_tile_k ,
467+ "TILE_N" : mean_heur_tile_n_non_inner ,
468+ "ONE_TILE_PER_CTA" : mean_heur_one_tile_per_cta ,
469+ "num_warps" : softmax_heur_num_warps_non_inner ,
470+ },
378471 "softmax_backward_non_inner" : {
379472 "TILE_N" : softmax_heur_tile_n_bwd_non_inner ,
380473 "ONE_TILE_PER_CTA" : softmax_heur_one_tile_per_cta ,
0 commit comments