U
    ‰d1  ã                   @   sd   d dl mZ d dlmZ d dlmZmZ dd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ ZdS )é    )ÚRefine)Ú
TensorType)ÚVarÚunifyc                 C   s*   t | ƒ}| ¡  t|jƒ}t| j|ƒ dS )z-
    Calls our symbolic inferencer once.
    N)r   ÚrefineÚunify_eqÚconstraintsÚsubstitute_all_typesÚgraph©ZtracedÚrZmgu© r   úK/tmp/pip-unpacked-wheel-ua33x9lu/torch/fx/experimental/unify_refinements.pyÚ infer_symbolic_types_single_pass   s    
r   c                 C   sX   t | ƒ}| ¡  t|jƒ}t| j|ƒ t | ƒ}| ¡  t|jƒ}t| j|ƒ | ¡  dS )z¥
    Calls our symbolic inferencer twice.
    This is useful when one pass is not enough
    to infer all the information such as the case
    for braodcasting.
    N)r   r   r   r   r	   r
   Zsymbolic_relationsr   r   r   r   Úinfer_symbolic_types   s    

r   c                 C   s:   g }g }| D ]}|  |j¡ |  |j¡ qt|ƒt|ƒfS )za
    Convert equality constraints in the right format
    to be used by unification library.
    )ÚappendÚlhsÚrhsÚtuple)Ú
list_of_eqr   r   Úeqr   r   r   Ú
convert_eq"   s    r   c                 C   s   t | ƒ\}}t||ƒS )z@
    Apply unification to a set of
    equality constraints
    )r   r   )r   r   r   r   r   r   r   /   s    r   c                 C   sÔ   t |tƒr$||  ¡ kr| | S |S n¬t |tƒrpg }|jD ]*}||  ¡ krX| | | ¡ q8| |¡ q8tt|ƒƒS t |tƒrœg }|D ]}| t| |ƒ¡ q‚|S t |tƒrÌg }|D ]}| t| |ƒ¡ q®t|ƒS |S dS )z2
    Apply the most general unifier to a type
    N)	Ú
isinstancer   Úkeysr   Ú__args__r   r   ÚlistÚsubstitute_solution_one_type)ÚmappingÚtÚnew_typeÚtypr   r   r   r   8   s,    




r   c                 C   sr   d}|rTd}|D ]@}|| }|| |  ¡ kr@|| }|| ||< ||| krd}qq| jD ]}t||jƒ|_qZdS )zž
    Apply the most general unifier to all types in a graph
    till reaching a fixed point. If the input and output graph
    are the same, we converge.
    TFN)r   Únodesr   Útype)r
   r   ÚflagÚkZold_mapping_valZnew_keyÚnr   r   r   r	   [   s    
r	   c                 C   s.   t | j|jƒD ]\}}|j|jkr dS qdS )zv
    A check equality to be used in fixed points.
    We do not use graph equality but instead type
    equality.
    FT)Úzipr!   r"   )Zg1Zg2r%   Úmr   r   r   Úcheck_for_type_equalityo   s    r(   N)Z/torch.fx.experimental.graph_gradual_typecheckerr   Ztorch.fx.tensor_typer   Z!torch.fx.experimental.unificationr   r   r   r   r   r   r   r	   r(   r   r   r   r   Ú<module>   s   		#