a
    MSicu                     @   sB  d dl Z d dlmZ d dlZ d dlmZ d dlmZmZ d dl	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mZ d dlZd dlZd dlZd dlZd d	l m!Z! d dl"Z"d dl#Z#G d
d de$Z%e% Z&e'ee'ef dddZ(e'ee'ef dddZ)e'eee'dddZ*ee'ef edddZ+eddeeef e'e jj,dddZ-eddeeeef e'e jj,dddZ.eddeeeef e'e jj,dd d!Z/eeef e jj,d"d#d$Z0e jj,e jj,e'd%d&d'Z1ee jj,e'd(d)d*Z2G d+d, d,Z3eddG d-d. d.e jj,Z4dS )/    N)
_addindent)PackageImporterPackageExporter)TypeDictListAnyUnionOptionalSet   )Graph_PyTreeCodeGen_is_from_torch_custom_builtins
PythonCode)compatibility)Importersys_importer)Pathc                   @   sF   e Zd Zdd Zeeeef dddZee dddZ	d	d
 Z
dS )_EvalCacheLoaderc                 C   s   i | _ d| _d S )Nr   )
eval_cachenext_idself r   Q/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/fx/graph_module.py__init__   s    z_EvalCacheLoader.__init__srcglobalsc                 C   sB   |   }|| j|< | }||d< ||d< | |d< t|| |S )aV  Store the source in a private cache, and add a lazy entry in linecache
        that allows the source to be retrieved by 'filename'.

        Args:
            src (str): The module source to cache
            globals (dict): The module globals

        Returns:
            str: The cache key (and dummy filename) generated for src.
        __file____name__
__loader__)_get_keyr   copy	linecache	lazycache)r   r   r    keyglobals_copyr   r   r   cache   s    
z_EvalCacheLoader.cachereturnc                 C   s   || j v r| j | S d S N)r   )r   module_namer   r   r   
get_source8   s    

z_EvalCacheLoader.get_sourcec                 C   s   d| j  }|  j d7  _ |S )Nz<eval_with_key>.r   )r   )r   r(   r   r   r   r$   =   s    z_EvalCacheLoader._get_keyN)r"   
__module____qualname__r   strr   r   r*   r
   r/   r$   r   r   r   r   r      s   r   r   c                 C   s"   t | |}tt| |d| d S )Nexec)_loaderr*   r3   compile)r   r    r(   r   r   r   _exec_with_sourceE   s    r6   c                 C   s$   |  }t| | |d }|d= |S )Nforward)r%   r6   )r   r    r)   Z
forward_fnr   r   r   _forward_from_srcJ   s
    
r8   )nameobjimporterr,   c                 C   sB   | t v rt |  jS t| rdS ||\}}d| d| d|  S )Nzimport torchzfrom z import z as )r   Z
import_strr   get_name)r9   r:   r;   r.   	attr_namer   r   r   _format_import_statementS   s    
r>   )r    r;   c                 C   s4   t  }|  D ]\}}|t||| qd|S N
)setitemsaddr>   join)r    r;   Zimport_strsr9   r:   r   r   r   _format_import_block\   s    rE   TZis_backward_compatible)bodyimport_blockr,   c                 C   s*   |  dp| d }t|| i }t|| S )N_codecode)getr8   _deserialize_graph_module)rG   rH   fn_srcr7   r   r   r   reduce_graph_modulec   s    rN   )r;   rG   generated_module_namer,   c                 C   s   |  |j}t||S r-   )import_moduler7   rL   )r;   rG   rO   r7   r   r   r   reduce_package_graph_modulel   s    rQ   )r;   rG   rH   r,   c                 C   s>   t  }| j|d< |d}|d us&J t|| |}t||S )N__builtins__rI   )dictpatched_builtinsrK   r8   rL   )r;   rG   rH   nsrM   r7   r   r   r   reduce_deploy_graph_modules   s    

rV   )rG   r,   c                 C   s   G dd dt jj}| |_|d}|du r<ddlm} |}|dd}|}G d	d
 d
|}||}|di }	| j|fi |	}
||
_t	||
|d}|
 D ]\}}t||st||| q|S )a  
    Deserialize a GraphModule given the dictionary of the original module,
    using the code to reconstruct the graph. We delete the actual graph before
    saving the dictionary so that changes to the in-memory graph format do not
    get serialized.
    c                       s   e Zd Z fddZ  ZS )z1_deserialize_graph_module.<locals>.CodeOnlyModulec                    s   t    || _d S r-   )superr   __dict__)r   rG   	__class__r   r   r      s    
z:_deserialize_graph_module.<locals>.CodeOnlyModule.__init__)r"   r0   r1   r   __classcell__r   r   rY   r   CodeOnlyModule   s   r\   _tracer_clsNr   )Tracer_graphmodule_cls_nameGraphModulec                   @   s"   e Zd ZejjeedddZdS )z._deserialize_graph_module.<locals>.KeepModules)___r,   c                 S   s   dS NTr   )r   ra   rb   r   r   r   is_leaf_module   s    z=_deserialize_graph_module.<locals>.KeepModules.is_leaf_moduleN)	r"   r0   r1   torchnnModuler2   boolrd   r   r   r   r   KeepModules   s   ri   _tracer_extras)
class_name)re   rf   rg   r7   rK   _symbolic_tracer^   tracer]   r`   rB   hasattrsetattr)r7   rG   r\   Z
tracer_clsr^   Zgraphmodule_cls_nameZ
cls_tracerri   comZtracer_extrasgraphgmkvr   r   r   rL      s$    	

rL   )from_module	to_moduletargetc           	      C   s   | d^ }}|D ]P}t| |}t||d }||u r< d S |d u rZtj }t||| || } }qt| |}t|tjrt|tjjs|	|| nt||| d S N.
splitgetattrre   rf   rg   ro   
isinstanceTensor	Parameterregister_buffer)	ru   rv   rw   prefixfielditemftorigr   r   r   
_copy_attr   s    


r   )from_objrv   rw   c                 C   s   | d^ }}|D ]2}t||d }|d u rBtj }t||| |}qt| tjrpt| tjjsp|	||  nt|||  d S rx   rz   )r   rv   rw   r   r   r   r   r   r   r   _assign_attr   s    
r   c                       s:   e Zd Zdd ZeejedddZ fddZ	  Z
S )_WrappedCallc                 C   s   || _ || _d S r-   )clscls_call)r   r   r   r   r   r   r      s    z_WrappedCall.__init__)frame_summaryr,   c           
      C   s   | j }|d usJ | j}|d us$J t|}t| j}t }d| d}d||d | }d| d }d|||d  }	d|||||	gS )Nz%Call using an FX-traced Module, line z3 of the traced Module's generated forward function:    ~z~~~ <--- HEREr@   )	linenolinelenr&   getlinesfilename	traceback
format_excrD   )
r   Z
err_linenor   Zerr_line_lenZall_src_linesZtb_repr
custom_msgZ
before_errmarkerZerr_and_after_errr   r   r   _generate_error_message   s    z$_WrappedCall._generate_error_messagec              
      s   zB| j d ur&| j |g|R i |W S t| j|j|i |W S W nt ty } z\|js\J tjt	|jd }d|j
v rtt|tjd |d n|W Y d }~n
d }~0 0 d S )NZeval_with_key)file)r   rW   r   __call__	Exception__traceback__r   StackSummaryextractwalk_tbr   printr   r   sysstderrwith_traceback)r   r:   argskwargseZtopmost_framesummaryrY   r   r   r     s    



z_WrappedCall.__call__)r"   r0   r1   r   staticmethodr   FrameSummaryr2   r   r   r[   r   r   rY   r   r      s   r   c                       sz  e Zd ZdZdd fddZeddd3eejj	e
eef f eed fd	d
ZdgZeedddZejeddddZeddd4eeejf edddZeddeejj	edddZeddeedddZeddddddZeeddd Zeddedd!d"Zed#d$d%Zed&d'd(Z d)d* Z!d+d, Z"d-d. Z#ed fd/d0Z$d1d2 Z%  Z&S )5r`   a  
    GraphModule is an nn.Module generated from an fx.Graph. Graphmodule has a
    ``graph`` attribute, as well as ``code`` and ``forward`` attributes generated
    from that ``graph``.

    .. warning::

        When ``graph`` is reassigned, ``code`` and ``forward`` will be automatically
        regenerated. However, if you edit the contents of the ``graph`` without reassigning
        the ``graph`` attribute itself, you must call ``recompile()`` to update the generated
        code.
    zType[GraphModule])r   c                    sH   | j D ]$}|jdd }|dkr|}  q,qG dd d| }t |S )Nry   r   GraphModuleImplc                   @   s   e Zd ZdS )z,GraphModule.__new__.<locals>.GraphModuleImplN)r"   r0   r1   r   r   r   r   r   3  s   )__mro__r1   r{   rW   __new__)r   r   r   r   cr   rY   r   r   r   %  s    
zGraphModule.__new__TrF   )rootrq   rk   c                    s^  t    || j_t|tjjrht|dr2|j	| _	|j
D ],}|jdv r8t|jtsVJ t|| |j q8nt|trg }|j
D ]R}|jdv r|t|jtsJ |j|vrtdt| d |j d ||j q||jdd d |D ]}t|| | | qntd	t| d
 || _d| _| jjr@d| jjjvr@| jj| _i | _| jjrZ| jj| _dS )a  
        Construct a GraphModule.

        Args:

            root (Union[torch.nn.Module, Dict[str, Any]):
                ``root`` can either be an nn.Module instance or a Dict mapping strings to any attribute type.
                In the case that ``root`` is a Module, any references to Module-based objects (via qualified
                name) in the Graph's Nodes' ``target`` field will be copied over from the respective place
                within ``root``'s Module hierarchy into the GraphModule's module hierarchy.
                In the case that ``root`` is a dict, the qualified name found in a Node's ``target`` will be
                looked up directly in the dict's keys. The object mapped to by the Dict will be copied
                over into the appropriate place within the GraphModule's module hierarchy.

            graph (Graph): ``graph`` contains the nodes this GraphModule should use for code generation

            class_name (str): ``name`` denotes the name of this GraphModule for debugging purposes. If it's unset, all
                error messages will report as originating from ``GraphModule``. It may be helpful to set this
                to ``root``'s original name or a name that makes sense within the context of your transform.
        training)get_attrcall_modulezNode z referenced target z. but that target was not provided in ``root``!c                 S   s
   |  dS rx   )count)r   r   r   r   <lambda>h      z&GraphModule.__init__.<locals>.<lambda>)r(   zUnsupported type z passed for root!Nz<locals>)rW   r   rZ   r"   r}   re   rf   rg   rn   r   nodesoprw   r2   r   rS   RuntimeErrorappendsortr   rq   r]   r1   rj   )r   r   rq   rk   nodeZtargets_to_copyZtarget_to_copyrY   r   r   r   7  s<    









zGraphModule.__init__rq   r+   c                 C   s   | j S )zF
        Return the ``Graph`` underlying this ``GraphModule``
        )_graphr   r   r   r   rq     s    zGraphModule.graphN)gr,   c                 C   s4   t |tsJ dt| || _| |_|   dS )z
        Set the underlying ``Graph`` for this ``GraphModule``. This will internally
        recompile the ``GraphModule`` so that the generated ``forward()`` function
        corresponds to ``g``
        z#Expected a Graph instance, but got N)r}   r   typer   Zowning_module	recompile)r   r   r   r   r   rq     s    FFxModule)folderr.   c              
   C   s  t |}t |jdd t|  |d  d}d| d}ttjjtt ddd	}g }| 	 D ]\}}|||}|d
u r|| d }	t||	 |
| | dddd}
d|	 d|
 }||d  d| d| d7 }qb| j D ]@\}}|d
u rq||d  d| dt|j d|j d7 }q| j D ]D\}}|d
u rTq>||d  d| dt|j d|j d7 }q>||d  d| d7 }|t| jd d7 }|d }	|	| |d }|d t|dkrtd |  d
S )!aa  Dumps out module to ``folder`` with ``module_name`` so that it can be
        imported with ``from <folder> import <module_name>``

        Args:

            folder (Union[str, os.PathLike]): The folder to write the code out to

            module_name (str): Top-level name to use for the ``Module`` while
                writing out the code
        T)exist_okzstate_dict.ptz    z+
import torch
from torch.nn import *
class zF(torch.nn.Module):
    def __init__(self):
        super().__init__()
)r.   moduler,   c                 S   s>   t jt jt jt jt jt jt jg}t||v r6|	  S d S d S r-   )
rf   LinearConv1dConv2dConv3dBatchNorm1dBatchNorm2dBatchNorm3dr   __repr__)r.   r   Z
safe_reprsr   r   r   _gen_model_repr  s     
z.GraphModule.to_folder.<locals>._gen_model_reprNz.pt r@   ztorch.load(r'z') # r   zself.z = zself.register_buffer('z', torch.empty(z, dtype=z))
z" = torch.nn.Parameter(torch.empty(z"self.load_state_dict(torch.load(r'z/state_dict.pt'))
   z	module.pyz__init__.pyzfrom .module import *r   z^Was not able to save the following children modules as reprs -saved as pickled files instead: )r   mkdirre   save
state_dictr2   rf   rg   r
   named_childrenr   r   replace_buffersrB   listshapedtype_parametersr   rJ   
write_textr   warningswarn)r   r   r.   tab	model_strr   Zblobified_modulesr   
module_strZmodule_filemodule_reprbuffer_namebuffer
param_nameparamZ	init_filer   r   r   	to_folder  sH    

 
.
0

zGraphModule.to_folder)rw   mr,   c                 C   sp   | d^ }}| }|D ]F}t||d}|du rFtj }t||| t|tjjsZ dS |}q||| dS )a%  
        Adds the given submodule to ``self``.

        This installs empty Modules where none exist yet if they are
        subpaths of ``target``.

        Args:
            target: The fully-qualified string name of the new submodule
                (See example in ``nn.Module.get_submodule`` for how to
                specify a fully-qualified string.)
            m: The submodule itself; the actual object we want to
                install in the current Module

        Return:
            bool: Whether or not the submodule could be inserted. For
                this method to return True, each object in the chain
                denoted by ``target`` must either a) not exist yet,
                or b) reference an ``nn.Module`` (not a parameter or
                other attribute)
        ry   NFT)r{   r|   re   rf   rg   ro   r}   
add_module)r   rw   r   r   r   modr   submodr   r   r   add_submodule  s    
zGraphModule.add_submodule)rw   r,   c                 C   s   | d}|dd |d  }}| }|D ]2}t||s< dS t||}t|tjjs( dS q(t||sjdS tt||tjjsdS t|| dS )ab  
        Deletes the given submodule from ``self``.

        The module will not be deleted if ``target`` is not a valid
        target.

        Args:
            target: The fully-qualified string name of the new submodule
                (See example in ``nn.Module.get_submodule`` for how to
                specify a fully-qualified string.)

        Returns:
            bool: Whether or not the target string referenced a
                submodule we want to delete. A return value of ``False``
                means that the ``target`` was not a valid reference to
                a submodule.
        ry   Nr   FT)r{   rn   r|   r}   re   rf   rg   delattr)r   rw   atomspathZtarget_submodr   r   r   r   r   delete_submodule   s    




zGraphModule.delete_submodulec           
   	      s   g  | j jD ]}|jdks$|jdkr|jd}tttddd}t||D ]} | qN|jdkrz@| 	|j}|
 D ]&\}}|dkr~ d|j|g q~W q ty   Y q0 q fdd	| 
 D }|D ]}	| |	 qd
S )a  
        Deletes all unused submodules from ``self``.

        A Module is considered "used" if any one of the following is
        true:
        1. It has children that are used
        2. Its forward is called directly via a ``call_module`` node
        3. It has a non-Module attribute that is used from a
        ``get_attr`` node

        This method can be called to clean up an ``nn.Module`` without
        manually calling ``delete_submodule`` on each unused submodule.
        r   r   ry   )xyr,   c                 S   s   d |r| |gn| gS rx   )rD   )r   r   r   r   r   join_fnH  s    z9GraphModule.delete_all_unused_submodules.<locals>.join_fnr   c                    s   g | ]\}}| vr|qS r   r   ).0r9   ra   usedr   r   
<listcomp>`  s   z<GraphModule.delete_all_unused_submodules.<locals>.<listcomp>N)rq   r   r   rw   r{   r2   	itertools
accumulater   get_submodulenamed_modulesrD   AttributeErrorr   )
r   r   fullpathr   r   r   Zsubmod_namera   	to_deleter9   r   r   r   delete_all_unused_submodules+  s$    
z(GraphModule.delete_all_unused_submodulesc                 C   s   t | dstd| jS )zn
        Return the Python code generated from the ``Graph`` underlying this
        ``GraphModule``.
        rI   z;Code has not been generated! Please report a bug to PyTorch)rn   r   rI   r   r   r   r   rJ   f  s    
zGraphModule.codec                 C   s   t | jjtr*| jjjj| _| jjjj| _| jj	dd}|j
| _t| }t| j|j|_dt|v rj|jnd}dt|vrt|||_dd }||_|S )z
        Recompile this GraphModule from its ``graph`` attribute. This should be
        called after editing the contained ``graph``, otherwise the generated
        code of this ``GraphModule`` will be out of date.
        r   )root_moduler   N_wrapped_callc                 _   s   | j | g|R i |S r-   )r   )r   r   r   r   r   r   call_wrapped  s    z+GraphModule.recompile.<locals>.call_wrapped)r}   r   Z_codegenr   Zpytree_infoZin_specZ_in_specout_specZ	_out_specpython_coder   rI   r   r8   r    r7   varsr   r   r   )r   r  r   r   r  r   r   r   r   p  s    zGraphModule.recompile)r;   c                 C   s<   | j  }| jj|d< |d= |  }t|j|}t||ffS )Nr_   r   )rX   r%   rZ   r"   r   rE   r    rV   )r   r;   dict_without_graphr  rH   r   r   r   __reduce_deploy__  s    
zGraphModule.__reduce_deploy__)exporterc                 C   sb   | j  }| jj|d< |d= d|  }|  }t|j|j}|| j	 }|
|| t||ffS )Nr_   r   zfx-generated._)rX   r%   rZ   r"   get_unique_idr   rE   r    r;   rJ   save_source_stringrQ   )r   r  r  rO   r  rH   module_coder   r   r   __reduce_package__  s    

zGraphModule.__reduce_package__c                 C   s0   | j  }|  }t|jt}|d= t||ffS )a|  
        Serialization of GraphModule. We serialize only the generated code, not
        the underlying ``Graph``. This is because ``Graph`` does not have on-disk
        backward-compatibility guarantees, whereas Python source code does.
        On the deserialization side, we symbolically trace through the generated
        code to regenerate the underlying ``Graph``
        r   )rX   r%   r   rE   r    r   rN   )r   r  r  rH   r   r   r   
__reduce__  s
    
zGraphModule.__reduce__c                 C   s(   t j }t| j|_t||jd S )Nr   )re   rf   rg   r%   deepcopyrX   r`   )r   memoZfake_modr   r   r   __deepcopy__  s    
zGraphModule.__deepcopy__c                 C   s   t | | jS r-   )r`   rq   r   r   r   r   __copy__  s    zGraphModule.__copy__c                    s   t   }d|| jgS r?   )rW   __str__rD   rI   )r   Zorig_strrY   r   r   r    s    
zGraphModule.__str__c                 C   s   |   }d|_|S rc   )r  _is_replica)r   Znew_gmr   r   r   _replicate_for_data_parallel  s    z(GraphModule._replicate_for_data_parallel)r`   )r   )'r"   r0   r1   __doc__r   r   r	   re   rf   rg   r   r2   r   r   r   __jit_unused_properties__propertyrq   setterosPathLiker   rh   r   r   r   rJ   r   r   r   r  r   r  r  r  r  r  r  r[   r   r   rY   r   r`     sB    I@(*:	#	r`   )5re   torch.nnrf   torch.overridesZtorch.nn.modules.moduler   Ztorch.packager   r   r&   typingr   r   r   r   r	   r
   r   rq   r   r   r   r   r   _compatibilityr   r   r   r%   r   r   r   pathlibr   r  r   objectr   r4   r2   r6   r8   r>   rE   rg   rN   rQ   rV   rL   r   r   r   r`   r   r   r   r   <module>   sL   $+		 75