1111
1212pytestmark = pytest .mark .skipif (
1313 not (
14- torch .cuda . is_available ()
14+ torch .ops . torch_cluster . cuda_version () != - 1
1515 and importlib .util .find_spec ('triton' ) is not None
1616 ),
1717 reason = 'CUDA and Triton are required for Triton benchmark tests.' ,
1818)
1919
2020KNN_SIZES = [
2121 (256 , 128 ),
22+ (512 , 256 ),
2223 (1024 , 512 ),
24+ (2048 , 1024 ),
2325 (4096 , 2048 ),
26+ (8192 , 4096 ),
27+ (8192 , 8192 ),
28+ (8201 , 4103 ),
2429 (255 , 127 ),
2530 (256 , 5 ),
2631 (1024 , 5 ),
2934]
3035KNN_GROUPS = [1 , 2 , 4 , 8 , 16 , 32 ]
3136
37+ FEATURES = [8 , 64 , 200 ]
38+
3239
3340def to_set (edge_index ):
3441 return set ([(i , j ) for i , j in edge_index .t ().tolist ()])
@@ -55,19 +62,29 @@ def _make_batch(
5562 )
5663
5764
58- @pytest .mark .parametrize (
59- 'num_x,num_y,num_groups' ,
60- (
61- (* p [0 ], p [1 ])
62- for p in product (KNN_SIZES , KNN_GROUPS )
65+ def _knn_param_grid ():
66+ return (
67+ (* p [0 ], p [1 ], p [2 ])
68+ for p in product (KNN_SIZES , KNN_GROUPS , FEATURES )
6369 if p [1 ] <= min (p [0 ])
64- ),
70+ )
71+
72+
73+ @pytest .mark .parametrize (
74+ 'num_x,num_y,num_groups,num_features' ,
75+ _knn_param_grid (),
6576)
6677@pytest .mark .benchmark (group = "knn" )
67- def test_triton_knn_benchmark_cuda (benchmark , num_x , num_y , num_groups ):
78+ def test_triton_knn_benchmark_cuda (
79+ benchmark ,
80+ num_x ,
81+ num_y ,
82+ num_groups ,
83+ num_features ,
84+ ):
6885 torch .manual_seed (99 )
69- x = torch .randn (num_x , 16 , device = 'cuda' )
70- y = torch .randn (num_y , 16 , device = 'cuda' )
86+ x = torch .randn (num_x , num_features , device = 'cuda' )
87+ y = torch .randn (num_y , num_features , device = 'cuda' )
7188 groups = min (num_groups , x .size (0 ), y .size (0 ))
7289 batch_x = _make_batch (num_x , groups , x .device )
7390 batch_y = _make_batch (num_y , groups , y .device )
@@ -94,23 +111,60 @@ def cuda_fn():
94111
95112
96113@pytest .mark .parametrize (
97- 'num_x,num_y,num_groups' ,
98- (
99- (* p [0 ], p [1 ])
100- for p in product (KNN_SIZES , KNN_GROUPS )
101- if p [1 ] <= min (p [0 ])
102- ),
114+ 'num_x,num_y,num_groups,num_features' ,
115+ _knn_param_grid (),
103116)
104- @pytest .mark .benchmark (group = "knn" )
117+ @pytest .mark .benchmark (group = "knn_cosine" )
118+ def test_triton_knn_benchmark_cuda_cosine (
119+ benchmark ,
120+ num_x ,
121+ num_y ,
122+ num_groups ,
123+ num_features ,
124+ ):
125+ torch .manual_seed (99 )
126+ x = torch .randn (num_x , num_features , device = 'cuda' )
127+ y = torch .randn (num_y , num_features , device = 'cuda' )
128+ groups = min (num_groups , x .size (0 ), y .size (0 ))
129+ batch_x = _make_batch (num_x , groups , x .device )
130+ batch_y = _make_batch (num_y , groups , y .device )
131+
132+ def cuda_fn ():
133+ knn (
134+ x ,
135+ y ,
136+ k = 16 ,
137+ batch_x = batch_x ,
138+ batch_y = batch_y ,
139+ cosine = True ,
140+ use_triton = False ,
141+ )
142+
143+ for _ in range (5 ):
144+ cuda_fn ()
145+ torch .cuda .synchronize ()
146+
147+ benchmark (cuda_fn )
148+ print (
149+ f"[knn][cuda] num_x={ num_x } num_y={ num_y } groups={ groups } "
150+ )
151+
152+
153+ @pytest .mark .parametrize (
154+ 'num_x,num_y,num_groups,num_features' ,
155+ _knn_param_grid (),
156+ )
157+ @pytest .mark .benchmark (group = "knn_cosine" )
105158def test_triton_knn_benchmark_triton_cosine (
106159 benchmark ,
107160 num_x ,
108161 num_y ,
109162 num_groups ,
163+ num_features ,
110164):
111165 torch .manual_seed (99 )
112- x = torch .randn (num_x , 16 , device = 'cuda' )
113- y = torch .randn (num_y , 16 , device = 'cuda' )
166+ x = torch .randn (num_x , num_features , device = 'cuda' )
167+ y = torch .randn (num_y , num_features , device = 'cuda' )
114168 groups = min (num_groups , x .size (0 ), y .size (0 ))
115169 batch_x = _make_batch (num_x , groups , x .device )
116170 batch_y = _make_batch (num_y , groups , y .device )
@@ -141,7 +195,11 @@ def triton_fn():
141195 if i == 0 :
142196 out_cuda = cuda_fn ()
143197 out_triton = triton_fn ()
144- assert to_set (out_cuda ) == to_set (out_triton )
198+ for a , b in zip (
199+ sorted (list (to_set (out_cuda ))),
200+ sorted (list (to_set (out_triton ))),
201+ ):
202+ assert a == b
145203 else :
146204 triton_fn ()
147205 torch .cuda .synchronize ()
@@ -153,18 +211,20 @@ def triton_fn():
153211
154212
155213@pytest .mark .parametrize (
156- 'num_x,num_y,num_groups' ,
157- (
158- (* p [0 ], p [1 ])
159- for p in product (KNN_SIZES , KNN_GROUPS )
160- if p [1 ] <= min (p [0 ])
161- ),
214+ 'num_x,num_y,num_groups,num_features' ,
215+ _knn_param_grid (),
162216)
163217@pytest .mark .benchmark (group = "knn" )
164- def test_triton_knn_benchmark_triton (benchmark , num_x , num_y , num_groups ):
218+ def test_triton_knn_benchmark_triton (
219+ benchmark ,
220+ num_x ,
221+ num_y ,
222+ num_groups ,
223+ num_features ,
224+ ):
165225 torch .manual_seed (99 )
166- x = torch .randn (num_x , 16 , device = 'cuda' )
167- y = torch .randn (num_y , 16 , device = 'cuda' )
226+ x = torch .randn (num_x , num_features , device = 'cuda' )
227+ y = torch .randn (num_y , num_features , device = 'cuda' )
168228 groups = min (num_groups , x .size (0 ), y .size (0 ))
169229 batch_x = _make_batch (num_x , groups , x .device )
170230 batch_y = _make_batch (num_y , groups , y .device )
@@ -195,7 +255,11 @@ def triton_fn():
195255 if i == 0 :
196256 out_cuda = cuda_fn ()
197257 out_triton = triton_fn ()
198- assert to_set (out_cuda ) == to_set (out_triton )
258+ for a , b in zip (
259+ sorted (list (to_set (out_cuda ))),
260+ sorted (list (to_set (out_triton ))),
261+ ):
262+ assert a == b
199263 else :
200264 triton_fn ()
201265 torch .cuda .synchronize ()
@@ -206,7 +270,7 @@ def triton_fn():
206270 )
207271
208272
209- @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 255 ])
273+ @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 8192 , 255 ])
210274@pytest .mark .parametrize ('num_groups' , [1 , 2 , 4 , 6 , 8 , 16 , 24 , 32 ])
211275@pytest .mark .benchmark (group = "knn_graph" )
212276def test_triton_knn_graph_benchmark_cuda (benchmark , num_x , num_groups ):
@@ -229,7 +293,7 @@ def cuda_fn():
229293 )
230294
231295
232- @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 255 ])
296+ @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 8192 , 255 ])
233297@pytest .mark .parametrize ('num_groups' , [1 , 2 , 4 , 6 , 8 , 16 , 24 , 32 ])
234298@pytest .mark .benchmark (group = "knn_graph" )
235299def test_triton_knn_graph_benchmark_triton (benchmark , num_x , num_groups ):
@@ -261,12 +325,93 @@ def triton_fn():
261325 if i == 0 :
262326 out_cuda = cuda_fn ()
263327 out_triton = triton_fn ()
264- assert to_set (out_cuda ) == to_set (out_triton )
328+ for a , b in zip (
329+ sorted (list (to_set (out_cuda ))),
330+ sorted (list (to_set (out_triton ))),
331+ ):
332+ assert a == b
265333 else :
266334 triton_fn ()
267335 torch .cuda .synchronize ()
268336
269337 benchmark (triton_fn )
270- print (
271- f"[knn_graph][triton] num_x={ num_x } groups={ groups } k={ k } "
272- )
338+ print (f"[knn_graph][triton] num_x={ num_x } groups={ groups } k={ k } " )
339+
340+
341+ @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 8192 , 255 ])
342+ @pytest .mark .parametrize ('num_groups' , [1 , 2 , 4 , 6 , 8 , 16 , 24 , 32 ])
343+ @pytest .mark .benchmark (group = "knn_graph_cosine" )
344+ def test_triton_knn_graph_benchmark_cuda_cosine (benchmark , num_x , num_groups ):
345+ torch .manual_seed (199 )
346+ x = torch .randn (num_x , 8 , device = 'cuda' )
347+ groups = min (num_groups , x .size (0 ))
348+ batch = _make_batch (num_x , groups , x .device )
349+ k = min (16 , max (1 , num_x - 1 ))
350+
351+ def cuda_fn ():
352+ knn_graph (
353+ x ,
354+ k = k ,
355+ batch = batch ,
356+ loop = False ,
357+ use_triton = False ,
358+ cosine = True ,
359+ )
360+
361+ for _ in range (5 ):
362+ cuda_fn ()
363+ torch .cuda .synchronize ()
364+
365+ benchmark (cuda_fn )
366+ print (f"[knn_graph][cuda] num_x={ num_x } groups={ groups } k={ k } " )
367+
368+
369+ @pytest .mark .parametrize ('num_x' , [256 , 1024 , 4096 , 8192 , 255 ])
370+ @pytest .mark .parametrize ('num_groups' , [1 , 2 , 4 , 6 , 8 , 16 , 24 , 32 ])
371+ @pytest .mark .benchmark (group = "knn_graph_cosine" )
372+ def test_triton_knn_graph_benchmark_triton_cosine (
373+ benchmark ,
374+ num_x ,
375+ num_groups ,
376+ ):
377+ torch .manual_seed (199 )
378+ x = torch .randn (num_x , 8 , device = 'cuda' )
379+ groups = min (num_groups , x .size (0 ))
380+ batch = _make_batch (num_x , groups , x .device )
381+ k = min (16 , max (1 , num_x - 1 ))
382+
383+ def cuda_fn ():
384+ return knn_graph (
385+ x ,
386+ k = k ,
387+ batch = batch ,
388+ loop = False ,
389+ use_triton = False ,
390+ cosine = True ,
391+ )
392+
393+ def triton_fn ():
394+ return knn_graph (
395+ x ,
396+ k = k ,
397+ batch = batch ,
398+ loop = False ,
399+ use_triton = True ,
400+ cosine = True ,
401+ )
402+
403+ for i in range (5 ):
404+ if i == 0 :
405+ out_cuda = cuda_fn ()
406+ out_triton = triton_fn ()
407+ for a , b in zip (
408+ sorted (list (to_set (out_cuda ))),
409+ sorted (list (to_set (out_triton ))),
410+ ):
411+ assert a == b
412+ else :
413+ triton_fn ()
414+ torch .cuda .synchronize ()
415+
416+ benchmark (triton_fn )
417+ print (f"[knn_graph][triton] num_x={ num_x } groups={ groups } k={ k } " )
0 commit comments