Skip to content

Commit bf48aef

Browse files
authored
Merge branch 'master' into w
Signed-off-by: YY4994 <15141404368@163.com>
2 parents f48d910 + 5708f53 commit bf48aef

28 files changed

Lines changed: 1649 additions & 316 deletions

benchmark/test_binary_pointwise_perf.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ def get_tflops(self, op, *args, **kwargs):
7272
for name, op, dtype in [
7373
# Arithmetic operations
7474
("add", torch.add, FLOAT_DTYPES + COMPLEX_DTYPES),
75-
("atan2", torch.atan2, FLOAT_DTYPES),
76-
("copysign", torch.copysign, FLOAT_DTYPES),
77-
("div", torch.div, FLOAT_DTYPES),
75+
("div", torch.div, FLOAT_DTYPES + COMPLEX_DTYPES),
7876
("mul", torch.mul, FLOAT_DTYPES + COMPLEX_DTYPES),
7977
("sub", torch.sub, FLOAT_DTYPES + COMPLEX_DTYPES),
8078
("pow", torch.pow, FLOAT_DTYPES),

benchmark/test_blas_perf_parallel.py

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,24 @@
1616
from benchmark.attri_util import BenchmarkMetrics, BenchmarkResult, OperationAttribute
1717
from benchmark.conftest import Config, emit_record_logger
1818

19+
try:
20+
from vllm.utils.deep_gemm import (
21+
fp8_gemm_nt,
22+
is_deep_gemm_supported,
23+
transform_sf_into_required_layout,
24+
)
25+
26+
DEEPGEMM_AVAILABLE = is_deep_gemm_supported()
27+
except Exception:
28+
fp8_gemm_nt = None
29+
transform_sf_into_required_layout = None
30+
DEEPGEMM_AVAILABLE = False
31+
1932
PARALLEL_WORKER_ENV = "FLAGGEMS_BENCH_PARALLEL_WORKER"
2033
PARALLEL_RESULT_FILE_ENV = "FLAGGEMS_BENCH_RESULT_FILE"
2134
torch_device_object = flag_gems.runtime.backend.gen_torch_device_object()
35+
DEEPGEMM_N_MULTIPLE = 64
36+
DEEPGEMM_K_MULTIPLE = 128
2237

2338

2439
def _parallel_device_is_available():
@@ -197,6 +212,7 @@ def estimate_shape_cost(shape):
197212
"bmm",
198213
"baddbmm",
199214
"w8a8_block_fp8_matmul",
215+
"w8a8_block_fp8_matmul_deepgemm",
200216
}:
201217
normalized_shape = shape
202218
if len(shape) == 3:
@@ -209,7 +225,11 @@ def estimate_shape_cost(shape):
209225
if normalized_shape is None:
210226
return 1
211227

212-
if self.op_name in {"mm", "bmm", "w8a8_block_fp8_matmul"}:
228+
if self.op_name in {
229+
"mm",
230+
"bmm",
231+
"w8a8_block_fp8_matmul",
232+
}:
213233
return m * n * k * 2
214234
return m * n * (2 * k + 1)
215235

@@ -482,7 +502,7 @@ class ParallelAddrBenchmark(ParallelBenchmarkMixin, blas_perf.AddrBenchmark):
482502
class ParallelW8A8BlockFP8MatmulBenchmark(
483503
ParallelBenchmarkMixin, blas_perf.W8A8BlockFP8MatmulBenchmark
484504
):
485-
SHAPE_CONFIG_KEYS = ("mm", "BlasBenchmark")
505+
SHAPE_CONFIG_KEYS = ("w8a8_block_fp8_matmul", "BlasBenchmark")
486506

487507
def set_more_shapes(self):
488508
if os.environ.get(PARALLEL_WORKER_ENV):
@@ -537,6 +557,118 @@ def set_shapes(self, shape_file_path=None):
537557
self.shape_desc = "M, N, K"
538558

539559

560+
def _deepgemm_block_scaled_mm(A, B, As_dg, Bs_dg, output):
561+
fp8_gemm_nt((A, As_dg), (B, Bs_dg), output)
562+
return output
563+
564+
565+
class ParallelW8A8BlockFP8DeepGemmBenchmark(ParallelW8A8BlockFP8MatmulBenchmark):
566+
def __init__(self, *args, output_dtype=torch.bfloat16, **kwargs):
567+
super().__init__(*args, **kwargs)
568+
self.output_dtype = output_dtype
569+
570+
def set_shapes(self, shape_file_path=None):
571+
super().set_shapes(shape_file_path)
572+
self.shapes = [
573+
(m, n, k)
574+
for m, n, k in self.shapes
575+
if n % DEEPGEMM_N_MULTIPLE == 0 and k % DEEPGEMM_K_MULTIPLE == 0
576+
]
577+
578+
def get_input_iter(self, cur_dtype):
579+
fp8_dtype = blas_perf.get_w8a8_block_fp8_dtype()
580+
if fp8_dtype is None:
581+
raise RuntimeError(
582+
"DeepGEMM benchmark requires CUDA device with FP8 support"
583+
)
584+
585+
block_n, block_k = self.block_size
586+
recipe = (1, 128, 128)
587+
588+
for m, n, k in self.shapes:
589+
num_k_groups = (k + block_k - 1) // block_k
590+
num_n_groups = (n + block_n - 1) // block_n
591+
592+
A = blas_perf.rand_fp8_tensor((m, k), self.device, fp8_dtype).contiguous()
593+
B = blas_perf.rand_fp8_tensor((n, k), self.device, fp8_dtype).contiguous()
594+
As = (
595+
0.01
596+
* torch.rand((m, num_k_groups), dtype=torch.float32, device=self.device)
597+
+ 0.005
598+
).contiguous()
599+
Bs = (
600+
0.01
601+
* torch.rand(
602+
(num_n_groups, num_k_groups),
603+
dtype=torch.float32,
604+
device=self.device,
605+
)
606+
+ 0.005
607+
).contiguous()
608+
609+
As_dg = transform_sf_into_required_layout(
610+
sf=As.unsqueeze(0),
611+
mn=m,
612+
k=k,
613+
recipe=recipe,
614+
num_groups=1,
615+
is_sfa=True,
616+
).squeeze(0)
617+
Bs_dg = transform_sf_into_required_layout(
618+
sf=Bs.unsqueeze(0),
619+
mn=n,
620+
k=k,
621+
recipe=recipe,
622+
num_groups=1,
623+
is_sfa=False,
624+
).squeeze(0)
625+
output = torch.empty((m, n), dtype=self.output_dtype, device=self.device)
626+
627+
yield (
628+
A,
629+
B,
630+
As_dg,
631+
Bs_dg,
632+
output,
633+
), (
634+
A,
635+
B,
636+
As,
637+
Bs,
638+
self.block_size[:],
639+
self.output_dtype,
640+
)
641+
642+
def _build_metric_from_input(self, input_item):
643+
dg_input, gems_input = input_item
644+
metric = BenchmarkMetrics()
645+
646+
dg_args, dg_kwargs = self.unpack_to_args_kwargs(dg_input)
647+
gems_args, gems_kwargs = self.unpack_to_args_kwargs(gems_input)
648+
metric.shape_detail = self.record_shapes(*gems_args, **gems_kwargs)
649+
650+
if "latency_base" in self.to_bench_metrics:
651+
metric.latency_base = self.get_latency(self.torch_op, *dg_args, **dg_kwargs)
652+
if "latency" in self.to_bench_metrics:
653+
metric.latency = self.get_latency(self.gems_op, *gems_args, **gems_kwargs)
654+
if "speedup" in self.to_bench_metrics:
655+
metric.speedup = metric.latency_base / metric.latency
656+
if "tflops" in self.to_bench_metrics:
657+
metric.tflops = (
658+
self.get_tflops(self.torch_op, *dg_args, **dg_kwargs)
659+
/ metric.latency
660+
/ 1e12
661+
* 1e3
662+
)
663+
return metric
664+
665+
def get_tflops(self, op, *args, **kwargs):
666+
A, B = args[0], args[1]
667+
m, k = A.shape
668+
n = B.shape[0]
669+
return 2 * m * n * k
670+
671+
540672
@pytest.mark.parametrize(
541673
"op_name, torch_op, input_fn, bench_cls",
542674
[
@@ -604,6 +736,25 @@ def test_perf_w8a8_block_fp8_matmul():
604736
bench.run()
605737

606738

739+
@pytest.mark.w8a8_block_fp8_matmul_deepgemm
740+
def test_perf_w8a8_block_fp8_matmul_deepgemm():
741+
if not DEEPGEMM_AVAILABLE:
742+
pytest.skip("DeepGEMM is not available on this platform")
743+
if blas_perf.get_w8a8_block_fp8_dtype() is None:
744+
pytest.skip(
745+
"w8a8_block_fp8_matmul benchmark requires CUDA device with FP8 support"
746+
)
747+
748+
bench = ParallelW8A8BlockFP8DeepGemmBenchmark(
749+
op_name="w8a8_block_fp8_matmul_deepgemm",
750+
torch_op=_deepgemm_block_scaled_mm,
751+
dtypes=["fp8"],
752+
output_dtype=torch.bfloat16,
753+
)
754+
bench.set_gems(flag_gems.w8a8_block_fp8_matmul)
755+
bench.run()
756+
757+
607758
@pytest.mark.parametrize(
608759
"op_name, torch_op, input_fn",
609760
[

benchmark/test_select_and_slice_perf.py

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ def index_select_gbps(bench_fn_args, latency):
7878
return io_amount * 1e-9 / (latency * 1e-3)
7979

8080

81-
@pytest.mark.index_select
8281
@pytest.mark.parametrize(
8382
"op_name, torch_op, input_fn, gbps_fn, dtypes",
8483
[
@@ -128,7 +127,6 @@ def test_perf_masked_scatter_inplace():
128127
bench.run()
129128

130129

131-
@pytest.mark.masked_select
132130
@pytest.mark.parametrize(
133131
"op_name, torch_op, input_fn, gbps_fn, dtypes",
134132
[
@@ -142,7 +140,7 @@ def test_perf_masked_scatter_inplace():
142140
),
143141
],
144142
)
145-
def test_perf_masked_select(op_name, torch_op, input_fn, gbps_fn, dtypes):
143+
def test_masked_select(op_name, torch_op, input_fn, gbps_fn, dtypes):
146144
bench = TensorSelectBenchmark(
147145
input_fn=input_fn,
148146
op_name=op_name,
@@ -193,8 +191,8 @@ def inner(shape, dtype, device):
193191
return inner
194192

195193

196-
@pytest.mark.scatter
197-
def test_perf_scatter():
194+
@pytest.mark.scatter_src
195+
def test_scatter_src():
198196
bench = TensorSelectBenchmark(
199197
op_name="scatter.src",
200198
torch_op=torch.scatter,
@@ -205,8 +203,8 @@ def test_perf_scatter():
205203
bench.run()
206204

207205

208-
@pytest.mark.scatter
209-
def test_perf_scatter_add():
206+
@pytest.mark.scatter_reduce
207+
def test_scatter_reduce_add():
210208
bench = TensorSelectBenchmark(
211209
op_name="scatter.reduce",
212210
torch_op=torch.scatter,
@@ -217,29 +215,8 @@ def test_perf_scatter_add():
217215
bench.run()
218216

219217

220-
@pytest.mark.scatter_add_
221-
def test_perf_scatter_add_():
222-
def scatter_input_fn(shape, dtype, device):
223-
input_gen = gather_input_fn(shape, dtype, device)
224-
inp, dim, index = next(input_gen)
225-
src_shape = list(size + 16 for size in index.shape)
226-
src = torch.randn(src_shape, dtype=dtype, device=device)
227-
228-
yield inp, dim, index, src
229-
230-
bench = TensorSelectBenchmark(
231-
op_name="scatter_add_",
232-
torch_op=torch.Tensor.scatter_add_,
233-
input_fn=scatter_input_fn,
234-
get_gbps=gather_scatter_gbps,
235-
dtypes=FLOAT_DTYPES,
236-
)
237-
bench.run()
238-
239-
240-
@pytest.mark.scatter_multiply
241-
@pytest.mark.scatter
242-
def test_perf_scatter_multiply():
218+
@pytest.mark.scatter_reduce
219+
def test_scatter_reduce_multiply():
243220
bench = TensorSelectBenchmark(
244221
op_name="scatter.reduce",
245222
torch_op=torch.scatter,
@@ -250,8 +227,8 @@ def test_perf_scatter_multiply():
250227
bench.run()
251228

252229

253-
@pytest.mark.scatter_
254-
def test_perf_scatter_inplace():
230+
@pytest.mark.scatter_src_
231+
def test_scatter_src_inplace():
255232
bench = TensorSelectBenchmark(
256233
op_name="scatter_.src",
257234
torch_op=torch.Tensor.scatter_,
@@ -263,8 +240,8 @@ def test_perf_scatter_inplace():
263240
bench.run()
264241

265242

266-
@pytest.mark.scatter_
267-
def test_perf_scatter_add_inplace():
243+
@pytest.mark.scatter_reduce_
244+
def test_scatter_reduce_add_inplace():
268245
bench = TensorSelectBenchmark(
269246
op_name="scatter_.reduce",
270247
torch_op=torch.Tensor.scatter_,
@@ -276,8 +253,8 @@ def test_perf_scatter_add_inplace():
276253
bench.run()
277254

278255

279-
@pytest.mark.scatter_
280-
def test_perf_scatter_multiply_inplace():
256+
@pytest.mark.scatter_reduce_
257+
def test_scatter_reduce_multiply_inplace():
281258
bench = TensorSelectBenchmark(
282259
op_name="scatter_.reduce",
283260
torch_op=torch.Tensor.scatter_,
@@ -289,6 +266,26 @@ def test_perf_scatter_multiply_inplace():
289266
bench.run()
290267

291268

269+
@pytest.mark.scatter_add_
270+
def test_scatter_add_inplace():
271+
def scatter_input_fn(shape, dtype, device):
272+
input_gen = gather_input_fn(shape, dtype, device)
273+
inp, dim, index = next(input_gen)
274+
src_shape = list(size + 16 for size in index.shape)
275+
src = torch.randn(src_shape, dtype=dtype, device=device)
276+
277+
yield inp, dim, index, src
278+
279+
bench = TensorSelectBenchmark(
280+
op_name="scatter_add_",
281+
torch_op=torch.Tensor.scatter_add_,
282+
input_fn=scatter_input_fn,
283+
get_gbps=gather_scatter_gbps,
284+
dtypes=FLOAT_DTYPES,
285+
)
286+
bench.run()
287+
288+
292289
def gather_input_fn(shape, dtype, device):
293290
inp = torch.randn(shape, dtype=dtype, device=device)
294291

benchmark/test_special_perf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,8 +1511,7 @@ def _functional_sym_constrain_range_for_size_input_fn(shape, cur_dtype, device):
15111511

15121512

15131513
@pytest.mark.functional_sym_constrain_range_for_size
1514-
@pytest.mark.performance
1515-
def test_perf_functional_sym_constrain_range_for_size():
1514+
def test_functional_sym_constrain_range_for_size():
15161515
bench = GenericBenchmark(
15171516
op_name="functional_sym_constrain_range_for_size",
15181517
torch_op=torch.ops.aten._functional_sym_constrain_range_for_size,

benchmark/test_unary_pointwise_perf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,7 @@ def set_gems(self, gems_op):
418418
flag_gems.vendor_name in UNSUPPORTED_VENDORS, reason="Vendor not supported"
419419
)
420420
@pytest.mark.apply_repetition_penalties
421-
@pytest.mark.performance
422-
def test_perf_repetition_penalty():
421+
def test_apply_repetition_penalties():
423422
vllm_ops = pytest.importorskip("vllm._custom_ops")
424423

425424
bench = RepetitionPenaltyBenchmark(

benchmark/test_vllm_perf.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ def get_input_iter(self, dtype):
236236
reason="requires vLLM and NVIDIA Hopper architecture",
237237
)
238238
@pytest.mark.cutlass_scaled_mm
239-
@pytest.mark.performance
240239
def test_cutlass_scaled_mm_benchmark():
241240
bench = CutlassScaledMMBenchmark()
242241
bench.run()
@@ -1403,11 +1402,7 @@ def make_input_flashmla(param: Flashmla_Sparse_Test_Param):
14031402

14041403

14051404
@pytest.mark.flashmla_sparse
1406-
@pytest.mark.performance
14071405
@pytest.mark.skipif(not HAS_VLLM_FLASHMLA_SPARSE, reason="vllm not installed")
14081406
def test_perf_flashmla_sparse_gems_vs_vllm():
1409-
"""
1410-
Benchmark FlagGems flash_mla_sparse_fwd vs vLLM flash_mla_sparse_fwd.
1411-
"""
14121407
bench = FlashmlaSparseBenchmark()
14131408
bench.run()

0 commit comments

Comments
 (0)