o
    i                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ dej	de
ej	 deej	df fd	d
ZddededefddZde
e fddZdejjfddZdS )    N)symbolic_trace)Node)legalize_graphresultinputsreturn.c                 C   s8   t | tjjrdgt| }ndd |D }t| |S )a  
    A free function for use in the merge_matmul graph transformation below that
    splits the output from a merged matmul into the individual results for each
    input tensor.

    Arguments:
        result: The merged matmul result tensor.
        inputs: The list of inputs that were merged into one for the matmul.

    Returns:
        List of matmul results for each input tensor.
    r   c                 S      g | ]}|j d  qS r   )shape).0x r   _/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/torch/fx/experimental/merge_matmul.py
<listcomp>       z(split_result_tensors.<locals>.<listcomp>)
isinstancetorchfxProxylensplit)r   r   splitsr   r   r   split_result_tensors   s   r      absearch_depthc                 C   sP   | |krdS t | jdkrdS |dkrdS | jD ]}t|||d r% dS qdS )a^  
    Determine if one node depends on another in a torch.fx.Graph.

    Arguments:
        a: The node that may have a dependency on b.
        b: The node that a may have a dependency on.
        search_depth: In the case of an indirect dependency, this function
                        searches upto this many nodes away in search of a
                        data dependency. If none is found, the function
                        makes the conservative assumption that there is a
                        dependency.

    Returns:
        True if a may depend on b, False if it definitely does not.
    Tr   F   )r   all_input_nodesmay_depend_on)r   r   r   inpr   r   r   r   $   s   
r   nodesc                 C   s4   t | dD ]\}}t||st||r dS qdS )z
    Check if all of the given nodes are pairwise-data independent.

    Arguments:
        nodes: The nodes to check for data dependencies.

    Returns:
        True if any pair in nodes has a data dependency.
       FT)	itertoolscombinationsr   )r!   ijr   r   r   are_nodes_independentI   s
   r'   in_modc                    s  t |  i }i } jjD ]9}|jdks|jtjurq|j\}}|jdkr'|jn|}|jdkr1|jn|}||g 	| ||g 	| q|
 D ]s\}}t|dk rUqJt|sZqJdd |D } fdd|D }t|tru j|n|} jtj|fi } jtj||fi }	 jt|	|fi  fddtt|D }
t||
D ]\}}||  j| qt  qJ    j   S )a  
    A graph transformation that merges matrix multiplication operations that share the same right-hand
    side operand into one large matrix multiplication.
               ____      _________        _________
      ----    |    |    |         |     M|  A * C  |
    M| A  |  T| B  | * K|    C    | =    |---------|
      ---- ,  |    |    |         |     T|  B * C  |
       K       ----      ---------        ---------
                K            R                R
    call_functionget_attrr"   c                 S   r   r	   )args)r   mmr   r   r   r      r   z merge_matmul.<locals>.<listcomp>c                    s&   g | ]}t |tr j|n|qS r   )r   strgraphr*   )r   l)gmr   r   r      s   & c                    s"   g | ]} j tj|fi qS r   )r.   r)   operatorgetitem)r   outr0   merge_mm_splitr   r   r      s    )r   r.   r!   optargetr   matmulr+   
setdefaultappenditemsr   r'   r   r-   r*   r)   catr   rangezipreplace_all_uses_with
erase_noder   	recompilelint)r(   	rhs_users	lhs_usersnodelhsrhsmmslhs_valsmerge_mm_catmerge_mmmerge_mm_resoldnewr   r4   r   merge_matmul[   sP   





rO   )r   )r#   r1   r   torch.fx._symbolic_tracer   torch.fx.noder   torch.fx.passes.tools_commonr   Tensorlisttupler   intr   r'   nnModulerO   r   r   r   r   <module>   s    
%