1717@triton .jit
1818def mean_kernel_1 (
1919 inp ,
20- out ,
20+ mid ,
2121 M ,
2222 BLOCK_SIZE : tl .constexpr ,
2323):
2424 pid = tl .program_id (0 )
2525 num_jobs = tl .num_programs (axis = 0 )
26- block_start = pid * BLOCK_SIZE
27- step = num_jobs * BLOCK_SIZE
28- _tmp = tl .zeros ([BLOCK_SIZE ], dtype = tl .float32 )
29- block_start = block_start .to (tl .int64 )
30- for off in range (block_start , M , step ):
26+ _sum = tl .zeros ([BLOCK_SIZE ], dtype = tl .float32 )
27+ for off in range (pid * BLOCK_SIZE , M , num_jobs * BLOCK_SIZE ):
3128 offset = off + tl .arange (0 , BLOCK_SIZE )
3229 mask = offset < M
3330 inp_val = tl .load (inp + offset , mask = mask , other = 0.0 )
34- _tmp = inp_val + _tmp
31+ _sum += inp_val .to (tl .float32 )
32+ tl .store (mid + pid , tl .sum (_sum , axis = 0 ))
3533
36- mean_val = tl .sum (_tmp , axis = 0 ) / M
37- tl .atomic_add (out , mean_val )
34+
35+ @libentry ()
36+ @triton .jit
37+ def mean_kernel_2 (mid , out , M , MID_SIZE , BLOCK_MID : tl .constexpr ):
38+ offset = tl .arange (0 , BLOCK_MID )
39+ mask = offset < MID_SIZE
40+ mid_val = tl .load (mid + offset , mask = mask , other = 0.0 )
41+ mean_val = tl .sum (mid_val ) / M
42+ tl .store (out , mean_val )
3843
3944
4045def mean (inp , * , dtype = None ):
@@ -43,12 +48,18 @@ def mean(inp, *, dtype=None):
4348 if dtype is None :
4449 dtype = inp .dtype
4550 block_size = triton .next_power_of_2 (math .ceil (math .sqrt (M )))
46- out = torch .zeros ([], dtype = dtype , device = inp .device )
51+ block_size = min (block_size , 1024 )
52+ mid_size = triton .cdiv (M , block_size )
53+ mid_size = min (mid_size , 4096 )
54+ block_mid = triton .next_power_of_2 (mid_size )
55+
56+ mid = torch .empty ((mid_size ,), dtype = torch .float32 , device = inp .device )
57+ out = torch .empty ([], dtype = torch .float32 , device = inp .device )
4758
4859 with torch_device_fn .device (inp .device ):
49- mean_kernel_1 [(triton . cdiv ( M , block_size ), 1 , 1 )](inp , out , M , block_size )
50- # mean_kernel_2[(1, 1, 1)](mid, out, M, mid_size, block_mid)
51- return out
60+ mean_kernel_1 [(mid_size , 1 , 1 )](inp , mid , M , block_size )
61+ mean_kernel_2 [(1 , 1 , 1 )](mid , out , M , mid_size , block_mid )
62+ return out . to ( dtype )
5263
5364
5465@libentry ()
@@ -58,24 +69,28 @@ def mean(inp, *, dtype=None):
5869)
5970@triton .jit
6071def mean_dim_kernel (X , Mean , M , N , BLOCK_M : tl .constexpr , BLOCK_N : tl .constexpr ):
61- # Map the program id to the row of X it should compute.
62- pid = tle .program_id (0 ) * BLOCK_M + tl .arange (0 , BLOCK_M )[:, None ]
63- X = X + pid * N
64- Mean = Mean + pid
65- row_mask = pid < M
66-
67- # Compute mean
68- _mean = tl .zeros ([BLOCK_M , BLOCK_N ], dtype = tl .float32 )
69- for off in range (0 , N , BLOCK_N ):
70- cols = off + tl .arange (0 , BLOCK_N )[None , :]
71- col_mask = cols < N
72- mask = row_mask and col_mask
73-
74- a = tl .load (X + cols , mask , other = 0.0 ).to (tl .float32 )
75- _mean += a
76- mean = tl .sum (_mean , axis = 1 ) / N
77- mean = mean [:, None ]
78- tl .store (Mean , mean , row_mask )
72+ workers = tle .num_programs (0 )
73+ pid = tle .program_id (0 )
74+ total_workloads = tl .cdiv (M , BLOCK_M )
75+ workloads = tl .cdiv (total_workloads , workers )
76+
77+ for w in range (workloads ):
78+ work_id = pid + w * workers
79+ rows = work_id * BLOCK_M + tl .arange (0 , BLOCK_M )[:, None ]
80+ X_ptr = X + rows * N
81+ Mean_ptr = Mean + rows
82+ row_mask = rows < M
83+
84+ _mean = tl .zeros ([BLOCK_M , BLOCK_N ], dtype = tl .float32 )
85+ for off in range (0 , N , BLOCK_N ):
86+ cols = off + tl .arange (0 , BLOCK_N )[None , :]
87+ col_mask = cols < N
88+ mask = row_mask and col_mask
89+ a = tl .load (X_ptr + cols , mask , other = 0.0 ).to (tl .float32 )
90+ _mean += a
91+ mean = tl .sum (_mean , axis = 1 ) / N
92+ mean = mean [:, None ]
93+ tl .store (Mean_ptr , mean , row_mask )
7994
8095
8196def mean_dim (x , dim , keepdim = False , * , dtype = None ):
@@ -98,10 +113,14 @@ def mean_dim(x, dim, keepdim=False, *, dtype=None):
98113 shape [i ] = 1
99114 M = x .numel () // N
100115 out = torch .empty (shape , dtype = dtype , device = x .device )
101- grid = lambda META : (triton .cdiv (M , META ["BLOCK_M" ]),)
116+
117+ def grid (meta ):
118+ axis0 = triton .cdiv (M , meta ["BLOCK_M" ])
119+ axis0 = axis0 if axis0 < 4096 else 4096
120+ return (axis0 ,)
102121
103122 with torch_device_fn .device (x .device ):
104123 mean_dim_kernel [grid ](x , out , M , N )
105124 if not keepdim :
106125 out = out .squeeze (dim )
107- return out
126+ return out
0 commit comments