o
    ÚÜÓh]  ã                   @   s¸   d dl Z d dlmZ d dlmZ d dlmZ d dlZd dlZd dl	m
Z
mZ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)ÚNode)Úsymbolic_trace)Úlegalize_graph)ÚDictÚListÚTupleÚ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   úX/var/www/html/ai/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_independentJ   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 |¡ q©tˆ ƒ 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   )r1   r,   ÚoperatorÚgetitem)r   Úout©r3   Úmerge_mm_splitr   r   r   ›   s    ÿÿ)r   r1   r$   ÚopÚtargetr   Úmatmulr.   Ú
setdefaultÚappendÚitemsr   r*   r   r0   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   r7   r   Úmerge_matmul\   sD   

ÿ
þ


rR   )r   )r   Útorch.fx.noder   Útorch.fx._symbolic_tracer   Útorch.fx.passes.tools_commonr   r&   r4   Útypingr   r   r   ÚTensorr   Úintr"   r*   ÚnnÚModulerR   r   r   r   r   Ú<module>   s"    ÿÿ
þ%