o
    ‡ZŽh¯  ã                   @   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   úQ/var/www/auris/lib/python3.10/site-packages/torch/fx/experimental/merge_matmul.pyÚ
<listcomp>   ó    z(split_result_tensors.<locals>.<listcomp>)Ú
isinstanceÚtorchZfxZProxyÚlenÚsplit)r   r   Z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   Z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 |¡ 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   )r*   r%   ÚoperatorÚgetitem)r   Úout©r,   Zmerge_mm_splitr   r   r   ¡   s    ÿÿ)r   r*   r   ÚopÚtargetr   Úmatmulr'   Ú
setdefaultÚappendÚitemsr   r#   r   r)   r&   r%   Úcatr   ÚrangeÚzipZreplace_all_uses_withZ
erase_noder   Z	recompileZlint)r$   Z	rhs_usersZ	lhs_usersÚnodeÚlhsÚrhsÚmmsZlhs_valsZmerge_mm_catZmerge_mmZmerge_mm_resÚoldÚnewr   r0   r   Úmerge_matmul[   sP   
þú
ÿ
þ


r@   )r   )r   r-   r   Ztorch.fx._symbolic_tracer   Ztorch.fx.noder   Ztorch.fx.passes.tools_commonr   ZTensorÚlistÚtupler   Úintr   r#   ÚnnÚModuler@   r   r   r   r   Ú<module>   s    ÿÿ
þ%