1+ import functools
2+
13import ninetoothed
24from ninetoothed import Tensor , block_size
35
6+ from ops .ninetoothed .kernels ._common import DTYPES , build
47from ops .ninetoothed .kernels .mm import application
58
6- BLOCK_SIZE_M = block_size ()
7- BLOCK_SIZE_N = block_size ()
8- BLOCK_SIZE_K = block_size ()
9-
109
1110def arrangement (
1211 input ,
1312 other ,
1413 output ,
15- BLOCK_SIZE_M = BLOCK_SIZE_M ,
16- BLOCK_SIZE_N = BLOCK_SIZE_N ,
17- BLOCK_SIZE_K = BLOCK_SIZE_K ,
14+ block_size_m ,
15+ block_size_n ,
16+ block_size_k ,
1817):
19- output_arranged = output .tile ((1 , BLOCK_SIZE_M , BLOCK_SIZE_N ))
18+ output_arranged = output .tile ((1 , block_size_m , block_size_n ))
2019 output_arranged .dtype = output_arranged .dtype .squeeze (0 )
2120
22- input_arranged = input .tile ((1 , BLOCK_SIZE_M , BLOCK_SIZE_K ))
21+ input_arranged = input .tile ((1 , block_size_m , block_size_k ))
2322 input_arranged = input_arranged .tile ((1 , 1 , - 1 ))
2423 input_arranged = input_arranged .expand ((- 1 , - 1 , output_arranged .shape [- 1 ]))
2524 input_arranged .dtype = input_arranged .dtype .squeeze ((0 , 1 ))
2625 input_arranged .dtype .dtype = input_arranged .dtype .dtype .squeeze (0 )
2726
28- other_arranged = other .tile ((1 , BLOCK_SIZE_K , BLOCK_SIZE_N ))
27+ other_arranged = other .tile ((1 , block_size_k , block_size_n ))
2928 other_arranged = other_arranged .tile ((1 , - 1 , 1 ))
3029 other_arranged = other_arranged .expand ((- 1 , output_arranged .shape [- 2 ], - 1 ))
3130 other_arranged .dtype = other_arranged .dtype .squeeze ((0 , 2 ))
@@ -34,6 +33,87 @@ def arrangement(
3433 return input_arranged , other_arranged , output_arranged
3534
3635
37- tensors = (Tensor (3 ), Tensor (3 ), Tensor (3 ))
36+ def premake (k , n , dtype , block_size_m , block_size_n , block_size_k ):
37+ arrangement_ = functools .partial (
38+ arrangement ,
39+ block_size_m = block_size_m ,
40+ block_size_n = block_size_n ,
41+ block_size_k = block_size_k ,
42+ )
43+ shape_options = ({"upper_bound" : 4 }, None , None )
44+ tensors = (
45+ Tensor (shape = (None , None , k ), shape_options = shape_options , dtype = dtype ),
46+ Tensor (shape = (None , k , n ), shape_options = shape_options , dtype = dtype ),
47+ Tensor (shape = (None , None , n ), shape_options = shape_options , dtype = dtype ),
48+ )
49+
50+ return arrangement_ , application , tensors
51+
52+
53+ _SHAPES = (
54+ (4096 , 4096 ),
55+ (4096 , 1024 ),
56+ (4096 , 14336 ),
57+ (14336 , 4096 ),
58+ (4096 , 128256 ),
59+ )
60+
61+ configs = tuple (
62+ (
63+ (),
64+ {
65+ "k" : k ,
66+ "n" : n ,
67+ "dtype" : dtype ,
68+ "block_size_m" : bm ,
69+ "block_size_n" : bn ,
70+ "block_size_k" : bk ,
71+ },
72+ {"num_warps" : nw , "num_stages" : ns },
73+ )
74+ for k , n in _SHAPES
75+ for dtype in DTYPES
76+ for bm in (16 , 64 )
77+ for bn in (64 , 128 )
78+ for bk in (32 , 64 )
79+ for nw in (4 , 8 )
80+ for ns in (3 , 4 )
81+ )
82+
83+ _build_kernel = build (
84+ premake ,
85+ configs ,
86+ meta_parameters = ("block_size_m" , "block_size_n" , "block_size_k" ),
87+ kernel_name = "bmm" ,
88+ )
89+
90+
91+ _BUILD_KN = frozenset (_SHAPES )
92+
93+
94+ _BLOCK_SIZE_M = block_size ()
95+ _BLOCK_SIZE_N = block_size ()
96+ _BLOCK_SIZE_K = block_size ()
97+
98+
99+ def _fallback_arrangement (
100+ input ,
101+ other ,
102+ output ,
103+ BLOCK_SIZE_M = _BLOCK_SIZE_M ,
104+ BLOCK_SIZE_N = _BLOCK_SIZE_N ,
105+ BLOCK_SIZE_K = _BLOCK_SIZE_K ,
106+ ):
107+ return arrangement (input , other , output , BLOCK_SIZE_M , BLOCK_SIZE_N , BLOCK_SIZE_K )
108+
109+
110+ _fallback_kernel = ninetoothed .make (
111+ _fallback_arrangement , application , (Tensor (3 ), Tensor (3 ), Tensor (3 ))
112+ )
113+
114+
115+ def kernel (lhs , rhs , output , k , n , dtype ):
116+ if (k , n ) in _BUILD_KN :
117+ return _build_kernel (lhs , rhs , output , k , n , dtype )
38118
39- kernel = ninetoothed . make ( arrangement , application , tensors )
119+ return _fallback_kernel ( lhs , rhs , output )
0 commit comments