@@ -344,6 +344,24 @@ def __init__(
344344 # Each |m| group occupies a contiguous (in, out) block on the diagonal.
345345 self ._block_diag_slices = self ._build_block_diag_slices ()
346346
347+ # Inference fast path (opt-in via ``DP_TRITON_INFER``): the per-|m|-block
348+ # batched bmm + cat of _block_diagonal_matmul is replaced by a fused
349+ # Triton BN=64 block-diagonal GEMM that consumes the strided operands
350+ # without a contiguity copy. Bound only when Triton is available and every
351+ # block width aligns to BN=64; otherwise the eager path is kept.
352+ self ._block_diag_gemm = None
353+ if use_triton_infer ():
354+ from .triton .so2_block_gemm import (
355+ SO2_BLOCK_GEMM_TRITON_AVAILABLE ,
356+ block_diag_gemm ,
357+ slices_supported ,
358+ )
359+
360+ if SO2_BLOCK_GEMM_TRITON_AVAILABLE and slices_supported (
361+ self ._block_diag_slices
362+ ):
363+ self ._block_diag_gemm = block_diag_gemm
364+
347365 def forward (self , x : torch .Tensor ) -> torch .Tensor :
348366 """
349367 Parameters
@@ -522,6 +540,8 @@ def _block_diagonal_matmul(
522540 Flattened output with shape ``(F, E, D_m*Cout)``.
523541 """
524542 weight = weight .permute (1 , 0 , 2 ) # (F, D_m*Cin, D_m*Cout)
543+ if self ._block_diag_gemm is not None and not self .training :
544+ return self ._block_diag_gemm (x_flat , weight , self ._block_diag_slices )
525545 blocks = [
526546 torch .bmm (
527547 x_flat [:, :, in0 :in1 ],
0 commit comments