1616from benchmark .attri_util import BenchmarkMetrics , BenchmarkResult , OperationAttribute
1717from 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+
1932PARALLEL_WORKER_ENV = "FLAGGEMS_BENCH_PARALLEL_WORKER"
2033PARALLEL_RESULT_FILE_ENV = "FLAGGEMS_BENCH_RESULT_FILE"
2134torch_device_object = flag_gems .runtime .backend .gen_torch_device_object ()
35+ DEEPGEMM_N_MULTIPLE = 64
36+ DEEPGEMM_K_MULTIPLE = 128
2237
2338
2439def _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):
482502class 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 [
0 commit comments