U
    ©Ê¹j]  ã                   @   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 e jee j ee jdf dœdd	„Zdeeedœdd„Zee dœdd„Ze jjdœdd„ZdS )é    N)ÚNode)Úsymbolic_trace)Úlegalize_graph)ÚDictÚListÚTuple.)ÚresultÚinputsÚreturnc                 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   s   g | ]}|j d  ‘qS ©r   )Úshape)Ú.0Úx© r   úa/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/fx/experimental/merge_matmul.pyÚ
<listcomp>    s     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 ƒr0 dS q0d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   Z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 ]r}|jdks|jtjk	r4q|j\}}|jdkrN|jn|}|jdkrb|jn|}| |g ¡ 	|¡ | |g ¡ 	|¡ q| 
¡ D ]è\}}t|ƒdk rªq”t|ƒs´q”dd„ |D ƒ}‡ fdd„|D ƒ}t|tƒrêˆ 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 |¡ �qRtˆ ƒ q”ˆ  ¡  ˆ 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   s   g | ]}|j d  ‘qS r   )Úargs)r   Úmmr   r   r   r   ‡   s     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\   sH    
  ÿ
þ


r@   )r   )r   Ztorch.fx.noder   Ztorch.fx._symbolic_tracer   Ztorch.fx.passes.tools_commonr   r   r-   Útypingr   r   r   ZTensorr   Úintr   r#   ÚnnÚModuler@   r   r   r   r   Ú<module>   s    þ%