-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrms_norm.py
75 lines (59 loc) · 2.68 KB
/
rms_norm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import torch
from tvm import tl
import tvm.tl.language as T
def rms_norm_splitk(M, N, blk_m, blk_k):
dtype = "float"
@T.prim_func
def main(A: T.Buffer((M, N), dtype), B: T.Buffer((M, N), dtype)):
with T.Kernel(T.ceildiv(M, blk_m), threads=128) as bx:
A_shared = T.alloc_shared((blk_m, blk_k), dtype)
A_local = T.alloc_fragment((blk_m, blk_k), dtype)
A_powsum = T.alloc_fragment((blk_m,), dtype)
num_k_step = T.ceildiv(N, blk_k)
T.clear(A_local)
for k in range(num_k_step):
T.copy(A[bx * blk_m, k * blk_k], A_shared)
for i, j in T.Parallel(blk_m, blk_k):
A_local[i, j] += A_shared[i, j] * A_shared[i, j]
T.reduce_sum(A_local, A_powsum, dim=1)
for i in T.Parallel(blk_m):
A_powsum[i] = T.rsqrt(A_powsum[i] / N) + 1e-12
for k in range(num_k_step):
# reverse, better cache hit rate
T.copy(A[bx * blk_m, (num_k_step - 1 - k) * blk_k], A_shared)
for i, j in T.Parallel(blk_m, blk_k):
A_shared[i, j] *= A_powsum[i]
T.copy(A_shared, B[bx * blk_m, (num_k_step - 1 - k) * blk_k])
return main
def rms_norm(M, N, blk_m):
dtype = "float"
@T.prim_func
def main(A: T.Buffer((M, N), dtype), B: T.Buffer((M, N), dtype)):
with T.Kernel(T.ceildiv(M, blk_m), threads=128) as bx:
A_shared = T.alloc_shared((blk_m, N), dtype)
A_local = T.alloc_fragment((blk_m, N), dtype)
A_powsum = T.alloc_fragment((blk_m,), dtype)
T.copy(A[bx * blk_m : (bx + 1) * blk_m, :], A_shared)
for i, j in T.Parallel(blk_m, N):
A_local[i, j] = A_shared[i, j] * A_shared[i, j]
T.reduce_sum(A_local, A_powsum, dim=1)
for i in T.Parallel(blk_m):
A_powsum[i] = T.rsqrt(A_powsum[i] / N) + 1e-12
for i, j in T.Parallel(blk_m, N):
A_shared[i, j] *= A_powsum[i]
T.copy(A_shared, B[bx * blk_m : (bx + 1) * blk_m, :])
return main
def ref_program(x):
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + 1e-12)
if __name__ == "__main__":
M, N, blk_m, blk_k = 8192, 8192, 1, 512
# program = rms_norm_splitk(M, N, blk_m, blk_k)
program = rms_norm(M, N, blk_m)
mod, params = tl.lower(program)
mod = tl.Profiler(mod, params, [1], tl.TensorSupplyType.Normal)
print(mod.get_kernel_source())
mod.assert_allclose(ref_program)
latency = mod.do_bench(ref_program, warmup=500)
print("{:.2f} ms".format(latency))
latency = mod.do_bench(mod.func)
print("{:.2f} ms".format(latency))