U
    <cQ,                     @   sH  U d dl mZmZmZmZmZmZmZmZm	Z	m
Z
mZmZ d dlZd dlmZmZ e
dZe
dZe
dZeZeZeegeeef f Zeeegef ZG dd deZi Zeee ef ed	< eeedd
ddZeeef eee ef dddZee eeeef dddZee eee ef dddZee eee dddZeedf eee ef dddZ ee eeedf dddZ!eeee ef dddZ"ee eedddZ#d eee ef dd!d"Z$ee ed dd#d$Z%ee&ee ee'ee ee(e e! eee"e# eee$e% ee)d%d&d'Z*eed%d(d)Z+ee)d%d*d+Z,G d,d- d-Z-G d.d/ d/e-Z.eeee e-f d%d0d1Z/ee e-ed2d3d4Z0eeed5d6d7Z1eee ee f Z2eee eee df f Z3eeeef gef Z4eegef Z5eegef Z6eegeegef f Z7ee2eef e7e4eeef  d8d9d:Z8eee e7e5eef  d8d;d:Z8ee3e7e6e  d8d<d:Z8e3e7e6e  d8d=d:Z8eee e5eef eed>d?d@Z9ee2eef e4eeef eed>dAd@Z9e3e6e eed>dBd@Z9eege)f ee)dCdDdEZ:eege)f ee)dCdFdGZ;eee e5ee)f ee)dHdIdJZ<ee2eef e4eee)f ee)dHdKdJZ<e3e6e) ee)dHdLdJZ<eee e5ee)f ee)dHdMdNZ=ee2eef e4eee)f ee)dHdOdNZ=e3e6e) ee)dHdPdNZ=ee-e	ee  dQdRdSZ>dS )T    )
NamedTupleCallableAnyTupleListDictTypecastOptionalTypeVaroverloadUnionN)
namedtupleOrderedDictTSRc                   @   s   e Zd ZU eed< eed< dS )NodeDef
flatten_fnunflatten_fnN)__name__
__module____qualname__FlattenFunc__annotations__UnflattenFunc r   r   7/tmp/pip-unpacked-wheel-gikjz4vx/torch/utils/_pytree.pyr   &   s   
r   SUPPORTED_NODES)typr   r   returnc                 C   s   t ||t| < d S N)r   r   )r   r   r   r   r   r   _register_pytree_node,   s    r"   )dr    c                 C   s   t |  t |  fS r!   listvalueskeysr#   r   r   r   _dict_flatten/   s    r)   )r&   contextr    c                 C   s   dd t || D S )Nc                 S   s   i | ]\}}||qS r   r   .0keyvaluer   r   r   
<dictcomp>3   s      z#_dict_unflatten.<locals>.<dictcomp>)zipr&   r*   r   r   r   _dict_unflatten2   s    r2   c                 C   s   | d fS r!   r   r(   r   r   r   _list_flatten5   s    r3   c                 C   s   t | S r!   r%   r1   r   r   r   _list_unflatten8   s    r5   .c                 C   s   t | d fS r!   r4   r(   r   r   r   _tuple_flatten;   s    r6   c                 C   s   t | S r!   )tupler1   r   r   r   _tuple_unflatten>   s    r8   c                 C   s   t | t| fS r!   )r%   typer(   r   r   r   _namedtuple_flattenA   s    r:   c                 C   s   t t||  S r!   )r	   r   r1   r   r   r   _namedtuple_unflattenD   s    r;   zOrderedDict[Any, Any]c                 C   s   t |  t |  fS r!   r$   r(   r   r   r   _odict_flattenG   s    r<   c                 C   s   t dd t|| D S )Nc                 s   s   | ]\}}||fV  qd S r!   r   r+   r   r   r   	<genexpr>K   s     z#_odict_unflatten.<locals>.<genexpr>)r   r0   r1   r   r   r   _odict_unflattenJ   s    r>   )pytreer    c                 C   sV   t | }|j}t|dks&|d tkr*dS t|dd }t|tsDdS tdd |D S )N   r   F_fieldsc                 s   s   | ]}t |tkV  qd S r!   )r9   str)r,   entryr   r   r   r=   ^   s     z*_is_namedtuple_instance.<locals>.<genexpr>)r9   	__bases__lenr7   getattr
isinstanceall)r?   r   basesfieldsr   r   r   _is_namedtuple_instanceV   s    
rK   c                 C   s   t | rtS t| S r!   )rK   r   r9   r?   r   r   r   _get_node_type`   s    rM   c                 C   s   t | t kS r!   )rM   r   r'   rL   r   r   r   _is_leaff   s    rN   c                   @   sR   e Zd Zeeed  ddddZedddZee	dd	d
Z
ee	dddZdS )TreeSpecN)r   r*   children_specsr    c                 C   s*   || _ || _|| _tdd |D | _d S )Nc                 S   s   g | ]
}|j qS r   )
num_leaves)r,   specr   r   r   
<listcomp>t   s     z%TreeSpec.__init__.<locals>.<listcomp>)r9   r*   rP   sumrQ   )selfr   r*   rP   r   r   r   __init__p   s    zTreeSpec.__init__r    c                 C   s    d| j j d| j d| j dS )Nz	TreeSpec(z, ))r9   r   r*   rP   rU   r   r   r   __repr__v   s    zTreeSpec.__repr__)otherr    c                 C   s:   | j |j ko.| j|jko.| j|jko.| j|jk}tt|S r!   )r9   r*   rP   rQ   r	   bool)rU   r[   resultr   r   r   __eq__y   s    

zTreeSpec.__eq__c                 C   s   |  | S r!   )r^   )rU   r[   r   r   r   __ne__   s    zTreeSpec.__ne__)r   r   r   r   Contextr   rV   rB   rZ   r\   r^   r_   r   r   r   r   rO   o   s   rO   c                       s0   e Zd Zdd fddZedddZ  ZS )LeafSpecNrW   c                    s   t  d d g  d| _d S )Nr@   )superrV   rQ   rY   	__class__r   r   rV      s    zLeafSpec.__init__c                 C   s   dS )N*r   rY   r   r   r   rZ      s    zLeafSpec.__repr__)r   r   r   rV   rB   rZ   __classcell__r   r   rc   r   ra      s   ra   c           
      C   sr   t | r| gt fS t| }t| j}|| \}}g }g }|D ]"}t|\}}	||7 }||	 q>|t|||fS )zkFlattens a pytree into a list of values and a TreeSpec that can be used
    to reconstruct the pytree.
    )rN   ra   rM   r   r   tree_flattenappendrO   )
r?   	node_typer   child_pytreesr*   r]   rP   childflat
child_specr   r   r   rg      s    
rg   )r&   rR   r    c                 C   s   t |tstdt| dt| |jkrNtdt|  d|j d| dt |tr`| d S t|j j}d}d}g }|j	D ]*}||j7 }|
t| || | |}q~|||jS )zqGiven a list of values and a TreeSpec, builds a pytree.
    This is the inverse operation of `tree_flatten`.
    z^tree_unflatten(values, spec): Expected `spec` to be instance of TreeSpec but got item of type .z2tree_unflatten(values, spec): `values` has length z, but the spec refers to a pytree that holds z items (z).r   )rG   rO   
ValueErrorr9   rE   rQ   ra   r   r   rP   rh   tree_unflattenr*   )r&   rR   r   startendrj   rm   r   r   r   rp      s&    



rp   )fnr?   r    c                    s$   t |\}}t fdd|D |S )Nc                    s   g | ]} |qS r   r   )r,   irs   r   r   rS      s     ztree_map.<locals>.<listcomp>)rg   rp   )rs   r?   	flat_argsrR   r   ru   r   tree_map   s    rw   )tyr    c                 C   s   d S r!   r   rx   r   r   r   map_only   s    rz   c                 C   s   d S r!   r   ry   r   r   r   rz      s    c                 C   s   d S r!   r   ry   r   r   r   rz      s    c                    s,   t tgtf t tgtf d fdd}|S )a  
    Suppose you are writing a tree_map over tensors, leaving everything
    else unchanged.  Ordinarily you would have to write:

        def go(t):
            if isinstance(t, Tensor):
                return ...
            else:
                return t

    With this function, you only need to write:

        @map_only(Tensor)
        def go(t):
            return ...

    You can also directly use 'tree_map_only'
    )fr    c                    s$   t  ttd fdd}|S )N)xr    c                    s   t | r | S | S d S r!   rG   )r|   )r{   rx   r   r   inner   s    
z%map_only.<locals>.deco.<locals>.inner)	functoolswrapsr   r   )r{   r~   ry   )r{   r   deco   s    zmap_only.<locals>.deco)r   r   r   )rx   r   r   ry   r   rz      s    ()rx   rs   r?   r    c                 C   s   d S r!   r   rx   rs   r?   r   r   r   tree_map_only   s    r   c                 C   s   d S r!   r   r   r   r   r   r      s    c                 C   s   t t| ||S r!   )rw   rz   r   r   r   r   r      s    )predr?   r    c                 C   s   t |\}}tt| |S r!   )rg   rH   mapr   r?   rv   _r   r   r   tree_all  s    r   c                 C   s   t |\}}tt| |S r!   )rg   anyr   r   r   r   r   tree_any  s    r   )rx   r   r?   r    c                 C   s   d S r!   r   rx   r   r?   r   r   r   tree_all_only
  s    r   c                 C   s   d S r!   r   r   r   r   r   r     s    c                    s$   t |\}}t fdd|D S )Nc                 3   s    | ]}t |r |V  qd S r!   r}   r,   r|   r   rx   r   r   r=     s     
 z tree_all_only.<locals>.<genexpr>)rg   rH   rx   r   r?   rv   r   r   r   r   r     s    c                 C   s   d S r!   r   r   r   r   r   tree_any_only  s    r   c                 C   s   d S r!   r   r   r   r   r   r     s    c                    s$   t |\}}t fdd|D S )Nc                 3   s    | ]}t |r |V  qd S r!   r}   r   r   r   r   r=      s     
 z tree_any_only.<locals>.<genexpr>)rg   r   r   r   r   r   r     s    )r?   rR   r    c           
      C   s   t |tstt| r"| g|j S t |tr0d S t| }||jkrFd S t| j	}|| \}}t
|t
|jksx||jkr|d S g }t||jD ]*\}}t||}	|	d k	r||	7 }q d S q|S r!   )rG   rO   AssertionErrorrN   rQ   ra   rM   r9   r   r   rE   rP   r*   r0   _broadcast_to_and_flatten)
r?   rR   ri   r   rj   ctxr]   rk   rm   rl   r   r   r   r   *  s&    




r   )?typingr   r   r   r   r   r   r   r	   r
   r   r   r   r   collectionsr   r   r   r   r   r`   ZPyTreer   r   r   r   r   r"   r)   r2   r3   r5   r6   r8   r:   r;   r<   r>   dictr%   r7   r\   rK   rM   rN   rO   ra   rg   rp   rw   ZType2ZTypeAnyZFn2ZFnZFnAnyZ	MapOnlyFnrz   r   r   r   r   r   r   r   r   r   r   <module>   s    8$ $
	(""("("(