Skip to content

Commit 917238b

Browse files
authored
Split benchmark for special operators (#2661)
1 parent cd0bfeb commit 917238b

45 files changed

Lines changed: 1837 additions & 1537 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

benchmark/test_assert_async.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import pytest
2+
import torch
3+
4+
import flag_gems
5+
6+
from . import performance_utils as utils
7+
8+
9+
def _input_fn(shape, dtype, device):
10+
if dtype == torch.bool:
11+
tensor = torch.ones(shape, dtype=dtype, device=device)
12+
else:
13+
tensor = torch.ones(shape, dtype=dtype, device=device)
14+
15+
msg = "Benchmark assert_async"
16+
17+
yield (
18+
tensor,
19+
msg,
20+
)
21+
22+
23+
class AssertAsyncBenchmark(utils.GenericBenchmark):
24+
def __init__(self, *args, **kwargs):
25+
super().__init__(*args, **kwargs)
26+
27+
def set_shapes(self, shape_file_path=None):
28+
self.shapes = [
29+
(),
30+
(1,),
31+
(1, 1),
32+
(1, 1, 1),
33+
]
34+
35+
def set_more_shapes(self):
36+
return None
37+
38+
39+
@pytest.mark.assert_async
40+
def test_assert_async():
41+
bench = AssertAsyncBenchmark(
42+
op_name="assert_async",
43+
input_fn=_input_fn,
44+
torch_op=torch._assert_async,
45+
dtypes=[
46+
torch.bool,
47+
torch.int32,
48+
torch.float32,
49+
torch.float16,
50+
torch.bfloat16,
51+
],
52+
)
53+
54+
bench.set_gems(flag_gems._assert_async)
55+
bench.run()

benchmark/test_conj_physical.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import pytest
2+
import torch
3+
4+
import flag_gems
5+
6+
from . import attri_util as attr_utils
7+
from . import performance_utils as utils
8+
9+
10+
def _input_fn(shape, dtype, device):
11+
if dtype.is_complex:
12+
float_dtype = torch.float32 if dtype == torch.complex64 else torch.float64
13+
real = torch.randn(shape, dtype=float_dtype, device=device)
14+
imag = torch.randn(shape, dtype=float_dtype, device=device)
15+
input_tensor = torch.complex(real, imag).to(dtype)
16+
elif dtype.is_floating_point:
17+
input_tensor = torch.randn(shape, dtype=dtype, device=device)
18+
else:
19+
input_tensor = torch.randn(shape, device=device).to(dtype)
20+
yield (input_tensor,)
21+
22+
23+
class Conj_physicalBenchmark(utils.GenericBenchmarkExcluse3D):
24+
def __init__(self, *args, **kwargs):
25+
super().__init__(*args, **kwargs)
26+
27+
def set_shapes(self, shape_file_path=None):
28+
conj_physical_shapes = [
29+
(256,),
30+
(2048, 2048),
31+
(128, 512, 256),
32+
(32, 64),
33+
(512, 1024),
34+
(2, 3, 4),
35+
]
36+
self.shapes = conj_physical_shapes
37+
38+
def set_more_shapes(self):
39+
return None
40+
41+
42+
@pytest.mark.conj_physical
43+
def test_conj_physical():
44+
dtypes = attr_utils.FLOAT_DTYPES + attr_utils.INT_DTYPES + attr_utils.COMPLEX_DTYPES
45+
46+
bench = Conj_physicalBenchmark(
47+
input_fn=_input_fn,
48+
op_name="conj_physical",
49+
torch_op=torch.conj_physical,
50+
dtypes=dtypes,
51+
)
52+
53+
bench.set_gems(flag_gems.conj_physical)
54+
bench.run()

benchmark/test_contiguous.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import pytest
2+
import torch
3+
4+
from . import attri_util as attr_utils
5+
from . import performance_utils as utils
6+
7+
8+
def _input_fn(shape, dtype, device):
9+
if dtype in attr_utils.FLOAT_DTYPES:
10+
inp = torch.randn(shape, dtype=dtype, device=device)
11+
else:
12+
inp = torch.randint(
13+
low=-10000, high=10000, size=shape, dtype=dtype, device="cpu"
14+
).to(device)
15+
inp = inp[::2]
16+
17+
yield inp,
18+
19+
20+
@pytest.mark.contiguous
21+
def test_contiguous():
22+
bench = utils.GenericBenchmark(
23+
op_name="contiguous",
24+
input_fn=_input_fn,
25+
torch_op=torch.Tensor.contiguous,
26+
dtypes=attr_utils.FLOAT_DTYPES + attr_utils.INT_DTYPES,
27+
)
28+
29+
bench.run()

benchmark/test_diag.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import random
2+
3+
import pytest
4+
import torch
5+
6+
from . import attri_util as attr_utils
7+
from . import performance_utils as utils
8+
9+
10+
def _input_fn(shape, dtype, device):
11+
input = utils.generate_tensor_input(shape, dtype, device)
12+
diagonal = random.randint(-4, 4)
13+
yield input, {
14+
"diagonal": diagonal,
15+
},
16+
17+
18+
@pytest.mark.diag
19+
def test_diag():
20+
bench = utils.GenericBenchmarkExcluse3D(
21+
op_name="diag",
22+
input_fn=_input_fn,
23+
torch_op=torch.diag,
24+
dtypes=attr_utils.FLOAT_DTYPES + attr_utils.INT_DTYPES + attr_utils.BOOL_DTYPES,
25+
)
26+
27+
bench.run()

benchmark/test_diag_embed.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import pytest
2+
import torch
3+
4+
from . import attri_util as attr_utils
5+
from . import performance_utils as utils
6+
7+
8+
class EmbeddingBenchmark(utils.GenericBenchmark2DOnly):
9+
def set_more_shapes(self):
10+
return None
11+
12+
13+
def _input_fn(shape, dtype, device):
14+
inp = utils.generate_tensor_input(shape, dtype, device)
15+
yield {"input": inp},
16+
17+
if utils.Config.bench_level == utils.BenchLevel.COMPREHENSIVE:
18+
yield {"input": inp, "offset": 1, "dim1": 0, "dim2": -1},
19+
20+
21+
@pytest.mark.diag_embed
22+
def test_diag_embed():
23+
bench = EmbeddingBenchmark(
24+
op_name="diag_embed",
25+
input_fn=_input_fn,
26+
torch_op=torch.diag_embed,
27+
dtypes=attr_utils.FLOAT_DTYPES + attr_utils.INT_DTYPES + attr_utils.BOOL_DTYPES,
28+
)
29+
30+
bench.run()

benchmark/test_diagonal.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pytest
2+
import torch
3+
4+
from . import attri_util as attr_utils
5+
from . import performance_utils as utils
6+
7+
8+
def _input_fn(shape, dtype, device):
9+
inp = utils.generate_tensor_input(shape, dtype, device)
10+
yield inp,
11+
12+
if utils.Config.bench_level == utils.BenchLevel.COMPREHENSIVE:
13+
yield inp, {"offset": 1, "dim1": 0, "dim2": -1},
14+
15+
16+
@pytest.mark.diagonal_backward
17+
def test_diagonal_backward():
18+
bench = utils.GenericBenchmarkExcluse1D(
19+
op_name="diagonal_backward",
20+
input_fn=_input_fn,
21+
torch_op=torch.diagonal,
22+
dtypes=attr_utils.FLOAT_DTYPES,
23+
is_backward=True,
24+
)
25+
26+
bench.run()

benchmark/test_embedding.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import pytest
2+
import torch
3+
4+
from . import performance_utils as utils
5+
6+
7+
class EmbeddingBenchmark(utils.GenericBenchmark2DOnly):
8+
def set_more_shapes(self):
9+
# TODO: add more shapes
10+
return None
11+
12+
13+
def embedding_input_fn(shape, dtype, device):
14+
num_embeddings, embedding_dim = shape
15+
indices = torch.randint(0, num_embeddings, (num_embeddings,), device=device)
16+
weight = torch.randn((num_embeddings, embedding_dim), device=device, dtype=dtype)
17+
yield {"input": indices, "weight": weight},
18+
19+
if utils.Config.bench_level == utils.BenchLevel.COMPREHENSIVE:
20+
indices_2d = torch.randint(
21+
0,
22+
num_embeddings,
23+
(num_embeddings, num_embeddings),
24+
device=device,
25+
)
26+
27+
yield {"input": indices_2d, "weight": weight},
28+
29+
30+
def embedding_backward_input_fn(shape, dtype, device):
31+
for forward_args in embedding_input_fn(shape, dtype, device):
32+
input = forward_args[0]["input"]
33+
weight = forward_args[0]["weight"]
34+
35+
weight.requires_grad_(True)
36+
# import pudb; pudb.set_trace()
37+
# output = torch.nn.functional.embedding(input, weight)
38+
# grad_output = torch.randn_like(output)
39+
yield input, weight
40+
41+
42+
@pytest.mark.embedding
43+
def test_embedding():
44+
# Note(Zhengzekang): triton do not support bfloat16 atomic add which is used in embedding grad.
45+
bench = EmbeddingBenchmark(
46+
input_fn=embedding_input_fn,
47+
op_name="embedding",
48+
torch_op=torch.nn.functional.embedding,
49+
dtypes=[
50+
torch.float32,
51+
torch.float16,
52+
],
53+
)
54+
bench.run()
55+
56+
57+
@pytest.mark.embedding_backward
58+
def test_embedding_backward():
59+
# Note(Zhengzekang): triton do not support bfloat16 atomic add which is used in embedding grad.
60+
bench = EmbeddingBenchmark(
61+
input_fn=embedding_backward_input_fn,
62+
op_name="embedding_backward",
63+
torch_op=torch.nn.functional.embedding,
64+
dtypes=[
65+
torch.float32,
66+
torch.float16,
67+
],
68+
is_backward=True,
69+
)
70+
bench.run()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
import torch
3+
4+
import flag_gems
5+
6+
from . import attri_util as attr_utils
7+
from . import performance_utils as utils
8+
9+
10+
class EmbeddingDenseBackwardBenchmark(utils.GenericBenchmark):
11+
def set_shapes(self, shape_file_path=None):
12+
self.shapes = [
13+
(32, 2048, 128, 8192),
14+
(16, 2048, 256, 16384),
15+
(8, 4096, 256, 32768),
16+
]
17+
18+
19+
def _input_fn(shape, dtype, device):
20+
B, M, D, num_weights = shape
21+
22+
grad_output = torch.randn((B, M, D), device=device, dtype=dtype)
23+
indices = torch.randint(0, num_weights, (B, M), device=device, dtype=torch.long)
24+
25+
def inject_padding_idx(cur_indices: torch.Tensor, padding_idx: int) -> torch.Tensor:
26+
if padding_idx < 0:
27+
return cur_indices
28+
mask = torch.rand((B, M), device=device) < 0.25
29+
return torch.where(mask, torch.full_like(cur_indices, padding_idx), cur_indices)
30+
31+
test_cases = [(-1, False), (0, True), (5, False)]
32+
for padding_idx, scale_grad_by_freq in test_cases:
33+
cur_indices = inject_padding_idx(indices, padding_idx)
34+
yield grad_output, cur_indices, num_weights, padding_idx, scale_grad_by_freq
35+
36+
37+
@pytest.mark.skipif(
38+
(not torch.cuda.is_available()) or (flag_gems.device != "cuda"),
39+
reason="CUDA backend is not available for this benchmark.",
40+
)
41+
@pytest.mark.embedding_dense_backward
42+
def test_embedding_dense_backward():
43+
bench = EmbeddingDenseBackwardBenchmark(
44+
input_fn=_input_fn,
45+
op_name="embedding_dense_backward",
46+
torch_op=torch.ops.aten.embedding_dense_backward,
47+
dtypes=attr_utils.FLOAT_DTYPES,
48+
)
49+
bench.run()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
import torch
3+
4+
from . import attri_util as attr_utils
5+
from . import performance_utils as utils
6+
7+
8+
def _input_fn(shape, cur_dtype, device):
9+
dep_token = utils.generate_tensor_input(shape, cur_dtype, device)
10+
yield 5, 1, 10, dep_token
11+
12+
13+
@pytest.mark.functional_sym_constrain_range_for_size
14+
def test_functional_sym_constrain_range_for_size():
15+
bench = utils.GenericBenchmark(
16+
op_name="functional_sym_constrain_range_for_size",
17+
torch_op=torch.ops.aten._functional_sym_constrain_range_for_size,
18+
dtypes=attr_utils.FLOAT_DTYPES,
19+
input_fn=_input_fn,
20+
)
21+
bench.run()

0 commit comments

Comments
 (0)