a
    MSic?                     @   sz  d dl Z d dlZd dlZd dlZd dlZddlmZmZmZ d dl	m
Z
mZmZmZmZmZmZ ddlmZmZmZmZmZ ddlmZ ddlmZ edd	G d
d dZedd	G dd deZedd	dd Zedd	G dd deZedd	G dd dZ edd	G dd de Z!edd	G dd de Z"eD ]Z#dd Z$e$e# qBdd Z%eD ]Z&e%e& qfdS )    N   )magic_methodsreflectable_magic_methodsGraph)TupleDictOptionalIterableAnyIteratorCallable)TargetNodeArgument
base_typesmap_aggregate)compatibility)check_for_mutable_operationTis_backward_compatiblec                   @   sb  e Zd ZU eed< dZeed< dZeed< dZeed< dZ	eed< dZ
eed< ed	d
d#eeeedf eeef ee ee edddZed	d
eddddZed	d
d$eeeedf eeef ee ee eegdf dddZdd Zed	d
eedddZed	d
dedddZed	d
deddd Zed	d
dedd!d"ZdS )%
TracerBasegraphFrecord_stack_tracescheck_mutable_operationstrace_assertsproxy_buffer_attributesforwardtraced_func_nameTr   N.)kindtargetargskwargsname	type_exprreturnc                 C   s0   |dkr| j rt||| | j||||||S )a'  
        Inserts a graph node given target, args, kwargs, and name.

        This method can be overridden to do extra checking, validation, or
        modification of values used in node creation. For example, one might
        want to disallow in-place operations from being recorded.
        call_function)r   r   r   create_node)selfr   r   r    r!   r"   r#    r(   J/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/fx/proxy.pyr&      s    zTracerBase.create_nodeProxy)noder$   c                 C   s
   t || S N)r*   )r'   r+   r(   r(   r)   proxy-   s    zTracerBase.proxy)r   r   r    r!   r"   r#   proxy_factory_fnc                 C   s   |  |}|  |}	t|ts"J t|	ts0J | ||||	||}
|sT| |
}n||
}| jr|  }|rt	|}tj
|}| }d||j_|S )ao  
        Create a Node from the given arguments, then return the Node
        wrapped in a Proxy object.

        If kind = 'placeholder', then we're creating a Node that
        represents the parameter of a function. If we need to encode
        a default parameter, we use the ``args`` tuple. ``args`` is
        otherwise empty for ``placeholder`` Nodes.
         )
create_arg
isinstancetupledictr&   r-   r   _find_user_frame	traceback
walk_stackStackSummaryextractformatjoinr+   stack_trace)r'   r   r   r    r!   r"   r#   r.   args_Zkwargs_r+   r-   Z
user_frameZwalk_stack_gensummaryZtb_linesr(   r(   r)   create_proxy1   s     


zTracerBase.create_proxyc                    sD   t   ddg} r8 j  rt fdd|D rq8q s@dS  S )zf
        Find the Python stack frame executing the user code during
        symbolic tracing.
        ztorch/fx/proxy.pyztorch/fx/symbolic_trace.pyc                 3   s   | ]} j j| V  qd S r,   )f_codeco_filenameendswith).0fileframer(   r)   	<genexpr>c       z.TracerBase._find_user_frame.<locals>.<genexpr>N)inspectcurrentframef_backall)r'   Zfx_filesr(   rD   r)   r4   V   s    zTracerBase._find_user_frame)ar$   c                    sF  t |tst|dr| S t |trTt|drTt fdd|D }t|| S t |ttfr|t| fdd|D S t |tri }| D ]2\}} 	|}dd }t
||  	|||< q|S t |t rt 	|j 	|j 	|jS t |tr|jS t |ts,|du s,|d	u r0|S td
t| dS )z
        A method that lowers the objects seen as arguments during symbolic evaluation
        into Argument types that can be stored in IR.

        Can be override to support more trace-specific types.
        __fx_create_arg___fieldsc                 3   s   | ]}  |V  qd S r,   r0   rB   elemr'   r(   r)   rF   z   rG   z(TracerBase.create_arg.<locals>.<genexpr>c                 3   s   | ]}  |V  qd S r,   rO   rP   rR   r(   r)   rF   }   rG   c                 S   s   t | trtdd S )NzMKeys for dictionaries used as an argument cannot contain a Node. Got key: {k})r1   r   RuntimeError)argr(   r(   r)   no_node   s    
z&TracerBase.create_arg.<locals>.no_nodeN.zargument of type: )r1   r*   hasattrrM   r2   typelistr3   itemsr0   r   slicestartstopstepr+   r   NotImplementedError)r'   rL   r    rkvrU   r(   rR   r)   r0   k   s,    



$ zTracerBase.create_arg)objr$   c                 C   s   t ddS )aF  Called when a proxy object is being converted to a boolean, such as
        when used in control flow.  Normally we don't know what to do because
        we don't know the value of the proxy, but a custom tracer can attach more
        information to the graph node using create_node and can choose to return a value.
        zFsymbolically traced variables cannot be used as inputs to control flowN
TraceErrorr'   rb   r(   r(   r)   to_bool   s    zTracerBase.to_boolc                 C   s   t ddS )aA  Called when a proxy object is being iterated over, such as
        when used in control flow.  Normally we don't know what to do because
        we don't know the value of the proxy, but a custom tracer can attach more
        information to the graph node using create_node and can choose to return an iterator.
        aH  Proxy object cannot be iterated. This can be attempted when the Proxy is used in a loop or as a *args or **kwargs function argument. See the torch.fx docs on pytorch.org for a more detailed explanation of what types of control flow can be traced, and check out the Proxy docstring for help troubleshooting Proxy iteration errorsNrc   re   r(   r(   r)   iter   s    zTracerBase.iterc                 C   s   t |d S )zCalled when a proxy object is has the keys() method called.
        This is what happens when ** is called on a proxy. This should return an
        iterator it ** is suppose to work in your custom tracer.
        keys	Attributere   r(   r(   r)   rh      s    zTracerBase.keys)NN)NNN)__name__
__module____qualname__r   __annotations__r   boolr   r   r   r   strr   r   r   r   r   r   r
   r   r&   r-   r   r>   r4   r0   rf   r   rg   rh   r(   r(   r(   r)   r      s>   
    $-r   c                       s"   e Zd Zed fddZ  ZS )GraphAppendingTracer)r   c                    s   t    || _d S r,   )super__init__r   )r'   r   	__class__r(   r)   rs      s    
zGraphAppendingTracer.__init__)rk   rl   rm   r   rs   __classcell__r(   r(   rt   r)   rq      s   rq   Fc                 C   s   | sJ d S r,   r(   )xr(   r(   r)   	assert_fn   s    rx   c                   @   s   e Zd ZdS )rd   N)rk   rl   rm   r(   r(   r(   r)   rd      s   rd   c                   @   s   e Zd ZdZedddeddddZed	d
dZdd	ddZ	d d	ddZ
ed  d	ddZed	ddZedddd Zdd ZedddZdS )r*   a  
    ``Proxy`` objects are ``Node`` wrappers that flow through the
    program during symbolic tracing and record all the operations
    (``torch`` function calls, method calls, operators) that they touch
    into the growing FX Graph.

    If you're doing graph transforms, you can wrap your own ``Proxy``
    method around a raw ``Node`` so that you can use the overloaded
    operators to add additional things to a ``Graph``.

    ``Proxy`` objects cannot be iterated. In other words, the symbolic
    tracer will throw an error if a ``Proxy`` is used in a loop or as
    an ``*args``/``**kwargs`` function argument.

    There are two main ways around this:
    1. Factor out the untraceable logic into a top-level function and
    use ``fx.wrap`` on it.
    2. If the control flow is static (i.e. the loop trip count is
    based on some hyperparameter), the code can be kept in its original
    position and refactored into something like::

        for i in range(self.some_hyperparameter):
            indexed_item = proxied_value[i]

    For a more detailed description into the Proxy internals, check out
    the "Proxy" section in `torch/fx/OVERVIEW.md`
    Tr   NzOptional[TracerBase])r+   tracerc                 C   s"   |d u rt |j}|| _|| _d S r,   )rq   r   ry   r+   )r'   r+   ry   r(   r(   r)   rs      s    
zProxy.__init__r$   c                 C   s   d| j j dS )NzProxy())r+   r"   rR   r(   r(   r)   __repr__   s    zProxy.__repr__rj   c                 C   s
   t | |S r,   ri   )r'   r`   r(   r(   r)   __getattr__   s    zProxy.__getattr__c                 O   s   | j dd| f| |S )Ncall_method__call__)ry   r>   r'   r    r!   r(   r(   r)   r      s    zProxy.__call__c                    sn   t  }|d usJ |j}|d us&J tt|j|jd  }|jdkrb fddt	|j
D S  j S )N   UNPACK_SEQUENCEc                 3   s   | ]} | V  qd S r,   r(   )rB   irR   r(   r)   rF     rG   z!Proxy.__iter__.<locals>.<genexpr>)rH   rI   rJ   rX   disget_instructionsr?   f_lastiopnamerangeargvalry   rg   )r'   rE   calling_frameinstr(   rR   r)   __iter__   s    
zProxy.__iter__c           	      C   s   | j jrt }|d usJ |j}|d us.J tt|j}|j	d }|| }|j
dkr||d  }|jd ustJ ||jd d  }|j
dkr|jdkp|j
dk}|r|j
dkr| j dt| fi  d	S | j | S )
Nr   POP_JUMP_IF_TRUEr   LOAD_GLOBALAssertionErrorLOAD_ASSERTION_ERRORRAISE_VARARGSr%   T)ry   r   rH   rI   rJ   rX   r   r   r?   r   r   rT   r   r>   rx   rf   )	r'   rE   r   Zinstscurr   firstlastZstarts_with_assertr(   r(   r)   __bool__  s&    

zProxy.__bool__c                 C   s   | j | S r,   )ry   rh   rR   r(   r(   r)   rh     s    z
Proxy.keysc                 C   s   t dd S )Nz'len' is not supported in symbolic tracing by default. If you want this call to be recorded, please call torch.fx.wrap('len') at module scope)rS   rR   r(   r(   r)   __len__"  s    zProxy.__len__c                    s   |r|nd}|r|ni }i  fdd}t jj|| t jj|| tdkrrtdt  d| tt	 }t
|t jjr|jf| }|d|j||S t j|r|d|j||S |jd||||j|jd	S d S )
Nr(   c                    s   t |  rd | j< d S r,   )r1   ry   )rL   clsZtracersr(   r)   find_tracer.  s    
z-Proxy.__torch_function__.<locals>.find_tracerr   z!Found multiple different tracers z" while trying to trace operations r~   r%   r"   )torchfxr+   r   lenrS   rX   rh   nextrg   r1   _CScriptMethodownerr>   r"   	overridesis_tensor_method_or_propertyrk   r   _target_to_str)r   orig_methodtypesr    r!   r   ry   r(   r   r)   __torch_function__'  s&    zProxy.__torch_function__)N)NN)rk   rl   rm   __doc__r   r   rs   rp   r|   r}   r   r	   r   ro   r   rh   r   classmethodr   r(   r(   r(   r)   r*      s   
r*   c                   @   s:   e Zd ZeddeedddZedd Zdd	 Z	d
S )rj   Tr   )rootattrc                 C   s   || _ || _|j| _d | _d S r,   )r   r   ry   _node)r'   r   r   r(   r(   r)   rs   E  s    zAttribute.__init__c                 C   s.   | j d u r(| jdt| j| jfi j| _ | j S Nr%   )r   ry   r>   getattrr   r   r+   rR   r(   r(   r)   r+   L  s    
zAttribute.nodec                 O   s   | j d| j| jf| |S )Nr~   )ry   r>   r   r   r   r(   r(   r)   r   T  s    zAttribute.__call__N)
rk   rl   rm   r   r*   rp   rs   propertyr+   r   r(   r(   r(   r)   rj   C  s
   
rj   c                       sn   e Zd ZdZeed fddZedddZe	dd	 Z
d
d Zdd Ze	dd Zdd Zdd Z  ZS )ParameterProxyz
    A special proxy which lets "shape", "size", "dim", and a few other
    attribute accesses pass through to the underlying  module parameter object,
    so that conditional tests on these attributes will not throw exception during tracing
    )ry   r+   c                    s0   t  || t|tjjs J || _|| _d S r,   )rr   rs   r1   r   nn	Parameterparamr"   )r'   ry   r+   r"   r   rt   r(   r)   rs   _  s    zParameterProxy.__init__rz   c                 C   s   d| j  dS )NzParameterProxy(r{   r   rR   r(   r(   r)   r|   e  s    zParameterProxy.__repr__c                 C   s   | j jS r,   )r   shaperR   r(   r(   r)   r   h  s    zParameterProxy.shapec                 C   s
   | j  S r,   )r   sizerR   r(   r(   r)   r   l  s    zParameterProxy.sizec                 C   s
   | j  S r,   )r   dimrR   r(   r(   r)   r   o  s    zParameterProxy.dimc                 C   s   | j jS r,   )r   ndimrR   r(   r(   r)   r   r  s    zParameterProxy.ndimc                 C   s
   | j  S r,   )r   numelrR   r(   r(   r)   r   v  s    zParameterProxy.numelc                 C   s
   | j  S r,   )r   nelementrR   r(   r(   r)   r   y  s    zParameterProxy.nelement)rk   rl   rm   r   r   r   rs   rp   r|   r   r   r   r   r   r   r   rv   r(   r(   rt   r)   r   X  s   

r   c                    s4    fdd} |_ d d d}tt|| d S )Nc                     s$   | d j }tt }|d|| |S )Nr   r%   )ry   r   operatorr>   )r    r!   ry   r   methodr(   r)   impl  s    

z_scope.<locals>.impl___)rk   stripsetattrr*   )r   r   Zas_magicr(   r   r)   _scope~  s    r   c                    s:   d  d d} fdd}||_||_tt|| d S )N__rr   r   c                    s    t t }| jd||| fi S r   )r   r   ry   r>   )r'   rhsr   orig_method_namer(   r)   r     s    
z!_define_reflectable.<locals>.impl)r   rk   rm   r   r*   )r   method_namer   r(   r   r)   _define_reflectable  s
    r   )'r   r   rH   r   r5   r   r   r   r   typingr   r   r   r	   r
   r   r   r+   r   r   r   r   r   _compatibilityr   operator_schemasr   r   rq   rx   
ValueErrorrd   r*   rj   r   r   r   r   r   r(   r(   r(   r)   <module>   s<   $ /
x$
