Skip to content

Commit abb5e6e

Browse files
authored
Split benchmark for concat and stack (#2671)
1 parent 427bcf8 commit abb5e6e

8 files changed

Lines changed: 341 additions & 200 deletions

File tree

benchmark/test_cat.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from typing import Generator
2+
3+
import pytest
4+
import torch
5+
6+
from benchmark.attri_util import FLOAT_DTYPES, INT_DTYPES, BenchLevel
7+
from benchmark.performance_utils import Benchmark, Config, generate_tensor_input
8+
9+
10+
def _input_fn(shape, dtype, device):
11+
inp1 = generate_tensor_input(shape, dtype, device)
12+
inp2 = generate_tensor_input(shape, dtype, device)
13+
inp3 = generate_tensor_input(shape, dtype, device)
14+
yield [inp1, inp2, inp3], {"dim": 0},
15+
16+
if Config.bench_level == BenchLevel.COMPREHENSIVE:
17+
yield [inp1, inp2, inp3], {"dim": -1},
18+
19+
20+
class CatBenchmark(Benchmark):
21+
def __init__(self, *args, **kwargs):
22+
self.input_fn = kwargs.pop("input_fn", _input_fn)
23+
super().__init__(*args, **kwargs)
24+
25+
def get_input_iter(self, dtype) -> Generator:
26+
for shape in self.shapes:
27+
yield from self.input_fn(shape, dtype, self.device)
28+
29+
def set_more_shapes(self):
30+
more_shapes_2d = [[1024, 2**i] for i in range(1, 11, 4)]
31+
more_shapes_3d = [[64, 64, 2**i] for i in range(0, 8, 4)]
32+
33+
return more_shapes_2d + more_shapes_3d
34+
35+
36+
@pytest.mark.skip("Benchmark test fails: issue #2673")
37+
@pytest.mark.cat
38+
def test_cat():
39+
bench = CatBenchmark(
40+
op_name="cat",
41+
input_fn=_input_fn,
42+
torch_op=torch.cat,
43+
dtypes=FLOAT_DTYPES + INT_DTYPES,
44+
)
45+
bench.run()

benchmark/test_hstack.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from typing import Generator
2+
3+
import pytest
4+
import torch
5+
6+
from benchmark.attri_util import FLOAT_DTYPES
7+
from benchmark.performance_utils import Benchmark, generate_tensor_input
8+
9+
10+
def _input_fn(shape, dtype, device):
11+
inp1 = generate_tensor_input(shape, dtype, device)
12+
inp2 = generate_tensor_input(shape, dtype, device)
13+
inp3 = generate_tensor_input(shape, dtype, device)
14+
15+
yield [inp1, inp2, inp3],
16+
17+
18+
class HStackBenchmark(Benchmark):
19+
def __init__(self, *args, **kwargs):
20+
self.input_fn = kwargs.pop("input_fn", _input_fn)
21+
super().__init__(*args, **kwargs)
22+
23+
def get_input_iter(self, dtype) -> Generator:
24+
for shape in self.shapes:
25+
yield from self.input_fn(shape, dtype, self.device)
26+
27+
def set_more_shapes(self):
28+
more_shapes_2d = [[1024, 2**i] for i in range(1, 11, 4)]
29+
more_shapes_3d = [[64, 64, 2**i] for i in range(0, 8, 4)]
30+
31+
return more_shapes_2d + more_shapes_3d
32+
33+
34+
@pytest.mark.skip("Benchmark test fails: issue #2673")
35+
@pytest.mark.vstack
36+
def test_vstack():
37+
bench = HStackBenchmark(
38+
op_name="hstack", input_fn=_input_fn, torch_op=torch.hstack, dtypes=FLOAT_DTYPES
39+
)
40+
bench.run()

benchmark/test_repeat.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import pytest
2+
import torch
3+
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import GenericBenchmark, generate_tensor_input
6+
7+
8+
class RepeatBenchmark(GenericBenchmark):
9+
"""
10+
RepeatBenchmark designed to evaluate tensor repeat operations along specified dimensions.
11+
This includes operations like tile, repeat, and repeat_interval.
12+
Due to potential memory limitations, benchmark sizes need to be carefully controlled.
13+
14+
Notably, when the input size is set to (1024, 1024, 1024) and the repeat dimensions
15+
are set to [1, 1, 2], the system encountered an "illegal memory access" error.
16+
To avoid such issues, we constrain the benchmark input sizes for these operations
17+
to prevent excessive memory usage.
18+
"""
19+
20+
def set_more_shapes(self):
21+
return [(16, 256, 256), (512, 512, 512), (64, 64, 64, 64)]
22+
23+
24+
def _input_fn(shape, cur_dtype, device):
25+
inp1 = generate_tensor_input(shape, cur_dtype, device)
26+
inp2 = [1] * len(shape)
27+
inp2[0] = 2
28+
29+
yield inp1, inp2,
30+
31+
32+
@pytest.mark.repeat
33+
def test_repeat():
34+
bench = RepeatBenchmark(
35+
op_name="repeat",
36+
input_fn=_input_fn,
37+
torch_op=torch.Tensor.repeat,
38+
dtypes=FLOAT_DTYPES,
39+
)
40+
bench.run()
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import pytest
2+
import torch
3+
4+
from benchmark.attri_util import FLOAT_DTYPES
5+
from benchmark.performance_utils import GenericBenchmark, generate_tensor_input
6+
7+
8+
class RepeatInterleaveBenchmark(GenericBenchmark):
9+
"""
10+
Due to potential memory limitations, benchmark sizes need to be carefully controlled.
11+
12+
Notably, when the input size is set to (1024, 1024, 1024) and the repeat dimensions
13+
are set to [1, 1, 2], the system encountered an "illegal memory access" error.
14+
To avoid such issues, we constrain the benchmark input sizes for these operations
15+
to prevent excessive memory usage.
16+
"""
17+
18+
def set_more_shapes(self):
19+
return [
20+
(16, 256, 256),
21+
(512, 512, 512),
22+
(64, 64, 64, 64),
23+
]
24+
25+
26+
# repeat_interleave.self_int(Tensor self, SymInt repeats, int? dim=None, *, SymInt? output_size=None) -> Tensor
27+
def repeat_interleave_self_int_input_fn(shape, dtype, device):
28+
inp = generate_tensor_input(shape, dtype, device)
29+
repeats = 3
30+
yield inp, repeats,
31+
32+
33+
@pytest.mark.repeat_interleave
34+
def test_repeat_interleave_self_int():
35+
bench = RepeatInterleaveBenchmark(
36+
input_fn=repeat_interleave_self_int_input_fn,
37+
op_name="repeat_interleave.self_int",
38+
torch_op=torch.repeat_interleave,
39+
dtypes=FLOAT_DTYPES,
40+
)
41+
bench.run()
42+
43+
44+
# repeat_interleave.self_Tensor(Tensor self, Tensor repeats, int? dim=None, *, SymInt? output_size=None) -> Tensor
45+
def repeat_interleave_self_tensor_input_fn(shape, dtype, device):
46+
inp = generate_tensor_input(shape, dtype, device)
47+
repeats = torch.randint(
48+
low=0,
49+
high=0x1F, # control the repeats number here
50+
size=[
51+
shape[0],
52+
],
53+
device=device,
54+
)
55+
dim = 0
56+
yield inp, repeats, dim
57+
58+
59+
@pytest.mark.skip(reason="This test case runs out of memory: issue #2674")
60+
@pytest.mark.repeat_interleave
61+
def test_repeat_interleave_self_tensor():
62+
bench = RepeatInterleaveBenchmark(
63+
op_name="repeat_interleave.self_tensor",
64+
input_fn=repeat_interleave_self_tensor_input_fn,
65+
torch_op=torch.repeat_interleave,
66+
dtypes=[torch.int32],
67+
)
68+
bench.run()
69+
70+
71+
# repeat_interleave.Tensor(Tensor repeats, *, SymInt? output_size=None) -> Tensor
72+
def repeat_interleave_tensor_input_fn(shape, dtype, device):
73+
repeats = torch.randint(
74+
low=0,
75+
high=0x1F, # control the repeats number here
76+
size=[
77+
shape[0],
78+
],
79+
device=device,
80+
)
81+
yield repeats,
82+
83+
84+
@pytest.mark.skip(reason="This test case runs out of memory: issue #2674")
85+
@pytest.mark.repeat_interleave
86+
def test_repeat_interleave_tensor():
87+
bench = RepeatInterleaveBenchmark(
88+
op_name="repeat_interleave.tensor",
89+
input_fn=repeat_interleave_tensor_input_fn,
90+
torch_op=torch.repeat_interleave,
91+
dtypes=[torch.int32],
92+
)
93+
94+
bench.run()

benchmark/test_stack.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from typing import Generator
2+
3+
import pytest
4+
import torch
5+
6+
from benchmark.attri_util import FLOAT_DTYPES, BenchLevel
7+
from benchmark.performance_utils import Benchmark, Config, generate_tensor_input
8+
9+
10+
class StackBenchmark(Benchmark):
11+
def __init__(self, *args, input_fn, **kwargs):
12+
super().__init__(*args, **kwargs)
13+
self.input_fn = input_fn
14+
15+
def get_input_iter(self, cur_dtype) -> Generator:
16+
for shape in self.shapes:
17+
yield from self.input_fn(shape, cur_dtype, self.device)
18+
19+
def set_more_shapes(self):
20+
more_shapes_2d = [(1024, 2**i) for i in range(1, 11, 4)]
21+
more_shapes_3d = [(64, 64, 2**i) for i in range(0, 8, 4)]
22+
return more_shapes_2d + more_shapes_3d
23+
24+
25+
def _input_fn(shape, dtype, device):
26+
inp1 = generate_tensor_input(shape, dtype, device)
27+
inp2 = generate_tensor_input(shape, dtype, device)
28+
inp3 = generate_tensor_input(shape, dtype, device)
29+
yield [inp1, inp2, inp3], {"dim": 0},
30+
31+
if Config.bench_level == BenchLevel.COMPREHENSIVE:
32+
yield [inp1, inp2, inp3], {"dim": -1},
33+
34+
35+
@pytest.mark.skip(reason="CUDA error - illegal memory access: issue #2675")
36+
@pytest.mark.stack
37+
def test_stack():
38+
bench = StackBenchmark(
39+
op_name="stack", input_fn=_input_fn, torch_op=torch.stack, dtypes=FLOAT_DTYPES
40+
)
41+
bench.run()

0 commit comments

Comments
 (0)