
    -`i                         d dl mZ d dlZd dlmZ d dlmZ d dlmZ ddl	m
Z
 ddlmZ  ee          Z G d	 d
e          ZdS )    )IterableN)SymIntstatically_known_true)init_logger   )is_func)VllmInductorPassc                       e Zd ZdZej        dej        j        ddfd            Z	de
ez  de
ez  defdZd	ee
ez           d
ee
ez           defdZdS )NoOpEliminationPassa_  
    This is an inductor pass that removes redundant reshape/slice operations.
    It is required for RMSNorm-quant fusion to work properly.
    That's because apply_fp8_linear adds a reshape, which is redundant
    in the 2D-case. Additionally, torch internal no-op elimination pass does
    not handle certain slice variants.

    Cases handled:
      1. A chain of reshapes is equivalent to the last reshape called on the
      base tensor (input of the first reshape).
      2. A reshape that produces the shape of the input is redundant
      3. A slice that produces the shape of the input is redundant

    Example graph 1:
    mul_1: "f16[s0, 4096]" = ...
    view_1: "f16[s0, 128, 32]" = torch.reshape(mul_1, [-1, 128, 32])
    view_2: "f16[s0, 4096]" = torch.reshape(view_2, [-1, 4096])
    view_3: "f16[s0, 128, 32]" = torch.reshape(view_3, [-1, 128, 32])

    Can be replaced with:
    mul_1: "f16[s0, 4096]" = ...
    view_3: "f16[s0, 128, 32]" = ...

    Example graph 2:
    getitem_1: "f16[s0, 4096]" = ...
    view_1: "f16[s0, 4096]" = torch.reshape(getitem_1, [-1, 4096])
    at = auto_functionalized(static_scaled_fp8_quant, input = view_1, ...)
    out: "f8e4m3fn[s0, 4096]" = at[1]

    Can be replaced with:
    getitem_1: "f16[s0, 4096]" = ...
    at = auto_functionalized(static_scaled_fp8_quant, input = getitem_1, ...)
    out: "f8e4m3fn[s0, 4096]" = at[1]

    Example graph 3:
    arg0: "s0" = SymInt(s0)
    scaled_mm: "f16[s0, 4096]" = ...
    slice_1: "f16[s0, 4096]" = torch.slice(scaled_mm, -1, 0, arg0)
    at = auto_functionalized(fused_add_rms_norm, input = slice_1, ...)
    out: "f16[s0, 4096]" = torch.slice_scatter(scaled_mm, at[1], 0, 0, arg0)

    Can be replaced with:
    arg0: "s0" = SymInt(s0)
    scaled_mm: "f16[s0, 4096]" = ...
    at = auto_functionalized(fused_add_rms_norm, input = scaled_mm, ...)
    out: "f16[s0, 4096]" = at[1]
    graphreturnNc                    d}|j         D ]&}t          |t          j        j        j        j                  r|j        d         }t          |t          j        j        j        j                  rS|                    d|j        d                    t          |j
                  dk    r|                    |           |dz  }t          |t          j        j        j        j                  s)t          |t          j        j        j        j                  rx|j        d         }|j        d         j        }|j        d         j        }|                     ||          r/|                    |           |                    |           |dz  }t          |t          j        j        j        j                  r~|j        d d         \  }}}	}
}|j        d         j        }|j        d         j        }|                     ||          r/|                    |           |                    |           |dz  }(t&                              d|           d S )Nr   r   val   z$Removed %s no-op reshapes and slices)nodesr	   torchopsatenreshapedefaultargs
update_arglenusers
erase_nodesliceTensormetashapeall_dims_equivalentreplace_all_uses_withslice_scatterloggerdebug)selfr   countnodeinputinput_shapeoutput_shapebaseview	dim_indexstartend
base_shape
view_shapes                 u/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/vllm/compilation/noop_elimination.py__call__zNoOpEliminationPass.__call__C   s   K  	  	DtUY^3;<< 
#	!5%)."8"@AA # OOAuz!}5555;''1,,((///
 tUY^3;<< ein*1A A  	!#j/5#y/5++KFF ..u555$$T***QJEuy~;CDD 48IbqbM1dIuc!Yu-3
!Yu-3
++J
CC ..t444$$T***QJE;UCCCCC    dimi_dimc                 (    t          ||k              S )a  
        This function checks if two dimensions are equivalent.
        :param dim: The dimension arg to reshape/slice
        :param i_dim: The corresponding dimension in the input tensor
        :return: Are the dimensions equivalent?

        There are two cases in which the dimensions are equivalent:
        1. The dimensions are equal (both integers)
        2. The dimensions both correspond to the same SymInt
        r   )r&   r6   r7   s      r3   dims_equivalentz#NoOpEliminationPass.dims_equivalentl   s     %SE\222r5   dimsi_dimsc                      t          |          }t          |          }t          |          t          |          k    rdS t           fdt          ||          D                       S )NFc              3   J   K   | ]\  }}                     ||          V  d S )N)r9   ).0si_sr&   s      r3   	<genexpr>z:NoOpEliminationPass.all_dims_equivalent.<locals>.<genexpr>   s7      PPFAs4''3//PPPPPPr5   )listr   allzip)r&   r:   r;   dims_i_dims_s   `    r3   r!   z'NoOpEliminationPass.all_dims_equivalentz   sd     T

v,,u::W%%5PPPPc$>O>OPPPPPPr5   )__name__
__module____qualname____doc__r
   time_and_logr   fxGraphr4   intr   boolr9   r   r!    r5   r3   r   r      s        . .` "%Dehn %D %D %D %D #"%DP33< 3f 3 3 3 3 3QS6\*Q4<S6\4JQ	Q Q Q Q Q Qr5   r   )collections.abcr   torch.fxr   r   %torch.fx.experimental.symbolic_shapesr   vllm.loggerr   fx_utilsr	   vllm_inductor_passr
   rG   r$   r   rP   r5   r3   <module>rW      s    % $ $ $ $ $        G G G G G G # # # # # #       0 0 0 0 0 0	X		pQ pQ pQ pQ pQ* pQ pQ pQ pQ pQr5   