U
    9%e                     @  sj  U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZ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 d dlmZ d dlmZmZ d dlmZmZmZmZmZmZmZmZmZmZ d dl m!Z! d dl"Z"d dl#Z"d dl$m%  m&Z' d dl(Z"d dl"m)Z) d d	l*m+Z+ d d
l,m-Z- d dl.m/Z/m0Z0 d dl1m2Z2m3Z3 d dl4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z: ddl;m<Z< erd dl=m>Z>m?Z?m@Z@mAZAmBZBmCZC n<eDe"jEjFjGD ],ZHeHIdrqeJe"jEjFjGeHeK eH< qddlLmMZMmNZNmOZOmPZPm%Z% ddlQmRZRmSZSmTZTmUZU ddlVmWZW ddlmXZX ddl%mYZY eZe[Z\d dl]m^Z^ d dl_m`Z` e%a ZbejcZdd dleZed dlfmgZg G dd deZhehjiZje
k Zldamdend < eoe7eeeepd!hZqed"d#Zrd$d%d&d'd(ZsG d)d* d*e"jtjuZvd+d, Zwd-d. Zxd/d0 Zyejzdnd2d3d4d5d6Z{G d7d8 d8Z|G d9d: d:e|Z}G d;d< d<e|Z~G d=d> d>e|Zd?d@ ZdAdBdCdDZedd1ddfdAdBdEdFZdGdH ZG dIdJ dJejcZdKdL ZdMdN Zdod1ddd1ddPdQdRZe!dSdTdUdV ZG dWdX dXe"j6jjZG dYdZ dZeZd[d\ Zd]d^ Zd1d1dd_dd1dTd`dad3d3dbdcddd3d3dedf	dgdhZe<ddd1dddidjdkZG dldm dmZdS )p    )annotationsN)
namedtuple)Enum)dirnamejoin)
AnyCallableDictList
NamedTupleOptionalSetTupleTYPE_CHECKINGUnion)patch)_guards)fake_tensor)
Constraint)make_fxmaybe_disable_fake_tensor_mode)_PyTreeCodeGen_PyTreeInfo)DistributedDataParallel   )GraphModule   )
CompilerFnlookup_backend)Hooks)
reset_codeset_eval_frameset_guard_error_hookset_guard_fail_hook	skip_codeunsupported__)configconvert_frameexternal_utils	skipfilesutils)CondOpArgsMismatchErrorResetRequired	UserErrorUserErrorType)install_generation_tagging_init)DynamoCallback)compile_times)enable_python_dispatcher)_disable_current_modes)ConstraintViolationErrorc                   @  s   e Zd ZdZdS )Unsetr   N)__name__
__module____qualname__token r;   r;   W/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/_dynamo/eval_frame.pyr6   S   s   r6   zOptional[CompilerFn]most_recent_backendz+onnx/_internal/fx/dynamo_graph_extractor.py
CacheEntryzcheck_fn, codeztypes.CodeTypezList[CacheEntry])codereturnc                 C  s    t jjj| }tttj|S )zN
    Given a code object, retrieve the cache entries stored in this code.
    )	torch_C_dynamo
eval_frame_debug_get_cache_entry_listlistmapr>   _make)r?   Z
cache_listr;   r;   r<   rE   e   s    rE   c                      sZ   e Zd ZdZdd fddZdd Zdd	 Zd
d Zdd Zdd Z	 fddZ
  ZS )OptimizedModulezx
    Wraps the original nn.Module object and later patches its
    forward method to optimized self.forward method.
    ztorch.nn.Module)modc                   s"   t    || _|| _|   d S N)super__init__	_orig_mod
dynamo_ctx_initialize)selfrJ   rO   	__class__r;   r<   rM   s   s    
zOptimizedModule.__init__c                 C  sj   t | jjtjr:tt| jjr:| 	t
| j| _n| 	| jj| _t| jdrf| j| _| j| _d S )N_initialize_hook)
isinstancerN   forwardtypes
MethodTyper*   checkinspectgetsourcefilerO   r)   wrap_inline__call__hasattr_forward_call_lazy_checkrQ   r;   r;   r<   rP   z   s    zOptimizedModule._initializec                 C  s&   t | j}|dd  |dd  |S )NrV   r]   )dict__dict__poprQ   stater;   r;   r<   __getstate__   s    
zOptimizedModule.__getstate__c                 C  s   || _ |   d S rK   )rc   rP   re   r;   r;   r<   __setstate__   s    zOptimizedModule.__setstate__c                 C  s   |dkr| j d S t| j|S )NrN   )Z_modulesgetattrrN   )rQ   namer;   r;   r<   __getattr__   s    
zOptimizedModule.__getattr__c                 O  s8   t | jdr,t|dkst| j| j| | j||S )NrT   r   )r^   rN   lenAssertionErrorZ_infer_parametersr_   )rQ   argskwargsr;   r;   r<   r`      s    z OptimizedModule._call_lazy_checkc                   s&   | j     fddt  D  S )Nc                   s   g | ]}| kr|qS r;   r;   ).0attrZorig_mod_attrsr;   r<   
<listcomp>   s     z+OptimizedModule.__dir__.<locals>.<listcomp>)rN   __dir__rL   ra   rR   rr   r<   rt      s    
zOptimizedModule.__dir__)r7   r8   r9   __doc__rM   rP   rg   rh   rk   r`   rt   __classcell__r;   r;   rR   r<   rI   m   s   
rI   c                 C  sn   t | tjrt|  nTt| dr,t| j n>tt| dddrLt| jj nddlm	} |  t
d|  dS )zA
    Make sure f.__code__ is not cached to force a recompile
    __code__rV   Nr   resetz#could not determine __code__ for %s)rU   rW   CodeTyper    r^   rw   ri   rV    ry   logwarning)fry   r;   r;   r<   remove_from_cache   s    

r   c                   C  s   d S rK   r;   r;   r;   r;   r<   nothing   s    r   c                 C  s&   | }t |dr"|j}t|stq|S )z
    In case of nesting of _TorchDynamoContext calls, find the innermost
    function. TorchDynamo caches on fn.__code__ object, so its necessary to find
    the innermost function to pass on the optimize, run, disable etc.
    _torchdynamo_orig_callable)r^   r   callablerm   )fnZunaltered_fnr;   r;   r<   innermost_fn   s
    
r   FzOptional[bool]boolenableexportc              	   c  sX   | d krd V  nD| r4t jdd d V  W 5 Q R X n t jddd d V  W 5 Q R X d S )NF)assume_static_by_defaultT)automatic_dynamic_shapesr   )r'   r   r   r;   r;   r<   enable_dynamic   s     r   c                      sN   e Zd Zeeedfdddddd fddZdd	 Zd
d Zdd Z  Z	S )_TorchDynamoContextFNr   dynamiccompiler_configr1   callbackc          	        s`   t    t|s&|dks&|d ks&t|| _t| _|| _|| _|| _	|| _
|| _|| _|  d S NF)rL   rM   r   rm   r   unsetprioron_enterextra_ctx_ctor	first_ctxr   r   r   )	rQ   r   r   backend_ctx_ctorpatch_fnr   r   r   r   rR   r;   r<   rM      s    
z_TorchDynamoContext.__init__c                 C  sT   t jrtd|   t| j| _|  | _| j	  t
| j| j| _| j	  d S )Nztorch._dynamo.optimize(...) is used with a context manager. Please refer to https://pytorch.org/tutorials/intermediate/torch_compile_tutorial.html to use torch._dynamo.optimize(...) as an annotation/decorator. )r'   Zraise_on_ctx_manager_usageRuntimeErrorr   r!   r   r   r   backend_ctx	__enter__r   r   r   dynamic_ctxra   r;   r;   r<   r      s    

z_TorchDynamoContext.__enter__c                 C  sB   | j tk	stt| j  t| _ | j||| | j||| d S rK   )r   r   rm   r!   r   __exit__r   )rQ   exc_typeexc_valexc_tbr;   r;   r<   r     s
    
z_TorchDynamoContext.__exit__c                   sN  fdd}t ttjjrP}t|}|j|_t|drFt	||_
|S ts\t	zt}W n tk
r   d }Y nX |d kst|rtdddkr|tkrtjjj t fdd}ttrd	|_n|_|_t|drt	||_
d
krJtds@ttdd	t j!< |S )Nc                     s    j S rK   )r   r;   ra   r;   r<   get_compiler_config  s    z9_TorchDynamoContext.__call__.<locals>.get_compiler_configr   r7   r{   )Z
_call_implZ_wrapped_call_implc                    s   t ts0tjj r0tjr&tdn
| |S   t	}  }|
  tjj}|
  z| |W S t	| |d d d  |d d d  X d S )NzvDetected that you are using FX to symbolically trace a dynamo-optimized function. This is not supported at the moment.)rU   DisableContextrA   fx_symbolic_traceZis_fx_tracingr'   Zerror_on_nested_fx_tracer   r!   r   r   r   r   r   )rn   ro   r   r   r   r   r   r   r   rQ   r;   r<   _fn3  s(    

z)_TorchDynamoContext.__call__.<locals>._fnTr   rw   a  

                        torch._dynamo.optimize is called on a non function object.
                        If this is a callable class, please wrap the relevant code into a function and optimize the
                        wrapper function.

                        >> class CallableClass:
                        >>     def __init__(self):
                        >>         super().__init__()
                        >>         self.relu = torch.nn.ReLU()
                        >>
                        >>     def __call__(self, x):
                        >>         return self.relu(torch.sin(x))
                        >>
                        >>     def print_hello(self):
                        >>         print("Hello world")
                        >>
                        >> mod = CallableClass()

                        If you want to optimize the __call__ function and other code, wrap that up in a function

                        >> def wrapper_fn(x):
                        >>     y = mod(x)
                        >>     return y.sum()

                        and then optimize the wrapper_fn

                        >> opt_wrapper_fn = torch._dynamo.optimize(wrapper_fn)
                        )"r   rU   rA   nnModulerI   rV   r   r^   rm   r   r   rZ   r[   	TypeErrorr*   rY   ri   DONT_WRAP_FILESr)   r\   r   r   r   	functoolswrapsr   Z_torchdynamo_disableZ_torchdynamo_inliner   textwrapdedentalways_optimize_code_objectsrw   )rQ   r   r   rJ   new_modfilenamer   r;   r   r<   r]     sV    




!
z_TorchDynamoContext.__call__)
r7   r8   r9   r   null_contextrM   r   r   r]   rv   r;   r;   rR   r<   r      s   r   c                      s4   e Zd Zedd Zddddd fddZ  ZS )	OptimizeContextc                 C  s   | |kp| d k S rK   r;   )oldnewr;   r;   r<   _different_backend  s    z"OptimizeContext._different_backendFNr   c             
     s6    fdd}t | t j|||tj||||d d S )Nc                     s2   t t r$tjrt n
td  at  d S )Nz`changing options to `torch.compile()` may require calling `torch._dynamo.reset()` to take effect)	r   r   r=   r'   Zraise_on_backend_changer-   warningswarnr0   r;   compiler_fnr;   r<   r     s    z*OptimizeContext.__init__.<locals>.on_enter)r   r   r   r   r   r   r   r   )r   rL   rM   TorchPatcherr   )rQ   r   r   r   r   r   r   r   rR   r   r<   rM     s    
zOptimizeContext.__init__)F)r7   r8   r9   staticmethodr   rM   rv   r;   r;   rR   r<   r     s   
 r   c                      s   e Zd Z fddZ  ZS )RunOnlyContextc                   s   dd }t  jd|d d S )Nc                   S  s   t jjj jd7  _d S )Nr   )rA   rC   mutation_guardZGenerationTrackerZ
generationr;   r;   r;   r<   r     s    z)RunOnlyContext.__init__.<locals>.on_enterF)r   r   rL   rM   )rQ   r   rR   r;   r<   rM     s    zRunOnlyContext.__init__r7   r8   r9   rM   rv   r;   r;   rR   r<   r     s   r   c                      s   e Zd Z fddZ  ZS )r   c                   s   t  jd d d S )Nr   r   ra   rR   r;   r<   rM     s    zDisableContext.__init__r   r;   r;   rR   r<   r     s   r   c                 C  sB   t jdk rdS t| D ]}|jdkr|jd   S qtdd S )N)      r   RESUMEr   z$RESUME instruction not found in code)sysversion_infodisget_instructionsopnameoffsetr   )r?   instr;   r;   r<   first_real_inst_idx  s    

r   r   hooksc                   s"   t   fdd} |_|S )Nc                   s   |d k	st | jt| jks0t| jjs0tjrJt	
d| jj| jj d S | jjdkrf| jjdkrfd S tjrt }|rtV ddlm} ||j jd}t dst d |j}|| ||W  5 Q R  S Q R X t: t (  | ||W  5 Q R  W  5 Q R  S Q R X W 5 Q R X d S )	Nzskipping %s %sz<string>__new__r   )DDPOptimizer)bucket_bytes_capZbackend_compile_fn_clone_with_backendzJDDPOptimizer only supports callback fns that know how to clone themselves.)rm   f_lastir   f_coder*   rY   co_filenamer'   disabler|   debugco_nameZoptimize_ddpr   Z_get_active_ddp_modulecompile_lockZ"torch._dynamo.backends.distributedr   r   r   r^   r   
compile_fnr4   )framecache_entryZframe_stateZ
ddp_moduler   Zddp_optimizerZhijacked_callbackr   r   r;   r<   catch_errors  s@      z*catch_errors_wrapper.<locals>.catch_errors)r   r   r   )r   r   r   r;   r   r<   catch_errors_wrapper  s    #r   c                 C  s   t t| ||d|||dS )NT)r   r   r   r   r   )r   r   )r   r   r   r   r   r   r;   r;   r<   _optimize_catch_errors  s    r   c                 C  sD   ddl m} t| dr| j}nt| tr.| }nd }t| } || |S )Nr   )wrap_backend_debugcompiler_name)Zrepro.after_dynamor   r^   r   rU   strr   )r   r   Zcompiler_strr;   r;   r<   get_compiler_fn  s    

r   c                   @  s   e Zd Zdd ZdS )_NullDecoratorc                 C  s   t |st|S rK   )r   rm   )rQ   r   r;   r;   r<   r]     s    z_NullDecorator.__call__N)r7   r8   r9   r]   r;   r;   r;   r<   r     s   r   c                   C  s(   t jdkrtdt jdkr$tdd S )Nwin32z+Windows not yet supported for torch.compile)r      z0Python 3.12+ not yet supported for torch.compile)r   platformr   r   r;   r;   r;   r<   check_if_dynamo_supported  s    

r   c                   C  s(   zt   W dS  tk
r"   Y dS X d S )NTF)r   	Exceptionr;   r;   r;   r<   is_dynamo_supported  s
    r   inductor)nopythonguard_export_fnguard_fail_fnr   r   c                C  s   t   t||d}tjd |s4tjdddkr:t S t	| } t
| dt}|r`t| ||dS ttj| |d|||t| d	r|  nd
dS )a  
    The main entrypoint of TorchDynamo.  Do graph capture and call
    backend() to optimize extracted graphs.

    Args:
        backend: One of the two things:
            - Either, a function/callable taking a torch.fx.GraphModule and
            example_inputs and returning a python callable that runs the
            graph faster.
            One can also provide additional context for the backend, like
            torch.jit.fuser("fuser2"), by setting the backend_ctx_ctor attribute.
            See AOTAutogradMemoryEfficientFusionWithContext for the usage.
            - Or, a string backend name in `torch._dynamo.list_backends()`
        nopython: If True, graph breaks will be errors and there will
            be a single whole-program graph.
        disable: If True, turn this decorator into a no-op
        dynamic: If True, upfront compile as dynamic a kernel as possible.  If False,
            disable all dynamic shapes support (always specialize).  If None, automatically
            detect when sizes vary and generate dynamic kernels upon recompile.

    Example Usage::

        @torch._dynamo.optimize()
        def toy_example(a, b):
            ...
    r   r   ztorch._dynamo.optimizeZTORCHDYNAMO_DISABLEr{   1r   )r   r   r   r   N)r   r   )r   r   rA   rB   _log_api_usage_onceosenvirongetr   r   ri   r   optimize_assertr   r(   r^   r   )backendr   r   r   r   r   r   r   r;   r;   r<   optimize$  s,    #
r   z&torch._dynamo.symbolic_convert.explainTc                   s0    fdd}|s|r(t d |||S |S d S )Nc               	     s8  ddl m} |  g g  dg g dd fdd}fdd	}tt d
d " t|d|d}|| | W 5 Q R X t}i } D ]}|jd }	||t|	< qd}
t|	 D ]>\}}d
t|j}|d  d|j d| d}|
|7 }
q|d }tdd}|  ddlm} ||| |S )Nr   rx   r   torch.fx.GraphModulegmc                   s,   ddl m} ||  \}  | jS )Nr   )_explain_graph_detail)backends.debuggingr   rV   )r   example_inputsr   )break_reasonsgraphsop_countops_per_graphr;   r<   "dynamo_graph_accumulating_compilerw  s        zBexplain.<locals>.inner.<locals>.dynamo_graph_accumulating_compilerc                   s     |  d S rK   )extendguards
out_guardsr;   r<   guard_export_print  s    z2explain.<locals>.inner.<locals>.guard_export_print.most_recent_backendF)r   r   r{   z
. Reason: z
   User Stack: 
r   )repr)ExplainOutput)r{   ry   r   r7   r   rl   Z
user_stackr  	enumeratevaluesr   	tracebackformat_listreasonr2   r   r  )rn   ro   ry   r  r	  opt_fZgraph_countZdeduped_reasonsr  Zinnermost_frameZformatted_listidxZbreak_reasonZformatted_stackmsgZgraph_break_countZcompile_timer  r~   )r   r   r  r  r  r<   innerk  sT    


zexplain.<locals>.innerzexplain(f, *args, **kwargs) is deprecated, use explain(f)(*args, **kwargs) instead.  If you don't migrate, we may break your explain call in the future if your user defined kwargs conflict with future kwargs added to explain(f).r   r   )r~   
extra_argsextra_kwargsr  r;   r  r<   explaini  s    J
r  c                      sN   e Zd Zdddddddd fdd	Zd
d Z fddZ fddZ  ZS )FlattenInputOutputSignatureNr   z
Tuple[Any]z	List[int]zList[torch.Tensor]z$Optional[fake_tensor.FakeTensorMode])m	flat_args matched_input_elements_positions!matched_output_elements_positionsexample_fake_inputs	fake_modec           
        s   t  |  fddt|D }g _tdt|D ]n}t  d| di }	||krj|| |	jjd< n.|d k	rt	|| t
jr||| |	jjd< j|	 q6fdd|D _|_d S )	Nc                   s   i | ]\}}| | qS r;   r;   )rp   Zixval)r"  r;   r<   
<dictcomp>  s    z8FlattenInputOutputSignature.__init__.<locals>.<dictcomp>r   argr;   r$  c                 3  s   | ]} j | V  qd S rK   )new_argsrp   ira   r;   r<   	<genexpr>  s     z7FlattenInputOutputSignature.__init__.<locals>.<genexpr>)rL   rM   r  r'  rangerl   placeholdernodemetarU   rA   Tensorfrom_tensorappendold_args_genr!  )
rQ   r  r  r   r!  r"  r#  Zmatched_input_elements_to_faker)  r&  rR   )r"  rQ   r<   rM     s    	
z$FlattenInputOutputSignature.__init__c                 C  sN   t | j}d| jjkr*| jjd |jjd< d| jjkrJ| jjd |jjd< |S )Nr$  Ztensor_dict)nextr2  current_noder.  r-  )rQ   targetrn   ro   r&  r;   r;   r<   r,    s    
z'FlattenInputOutputSignature.placeholderc                   s8   |d }|| j   fdd| jD }t ||fi S )Nr   c                   s   g | ]} | qS r;   r;   r(  lookupr;   r<   rs     s     z6FlattenInputOutputSignature.output.<locals>.<listcomp>)r'  r!  rL   output)rQ   r5  rn   ro   Zdynamo_result_flatZnew_result_flatrR   r6  r<   r8    s    
z"FlattenInputOutputSignature.outputc                   s6   || _ t |}d| j jkr2| j jd |jjd< |S )Nr$  )r4  rL   run_noder.  r-  )rQ   nrrR   r;   r<   r9    s
    z$FlattenInputOutputSignature.run_node)N)r7   r8   r9   rM   r,  r8  r9  rv   r;   r;   rR   r<   r    s
    r  c                   @  s   e Zd ZU ded< ded< dS )ExportResultr   Zgraph_moduleSet[_guards.Guard]r  N)r7   r8   r9   __annotations__r;   r;   r;   r<   r<    s   
r<  c           
      C  s  g }| j jD ]}|jdkrt|ds(t|j}| j|}|d krDqt|dksTtd }|D ]}t|dkrnq\|} qxq\|d kr|	  d}nJd
t|}d}	t|dkrdt|d  d}	|	  d	| |	 }|| q|rttjd
d
| d S )Nr,  _dynamo_sourcer   z, a closed over free variabler{   r   z(elided z more accesses)z, accessed at:
a  Cannot export model which references tensors that are neither buffers/parameters/constants nor are direct inputs.  For each tensor, if you'd like this tensor to be an explicit input, add it as a dummy argument to the top-level model definition you are exporting; if you would like its value to be embedded as an exported constant, wrap its access in a function marked with @assume_constant_result.

z

)graphZnodesopr^   rm   r?  _source_to_user_stacksr   rl   rj   r   r  r  r1  r.   r/   ZINVALID_INPUT)
r@  Zinput_errorsr-  sourceZuser_stacksstacksr  tbextrar;   r;   r<   check_signature_rewritable  s<    
rH  c	                 C  s   t ||\}	}
dd }|d|id|id}t |\}}|d k	sFt|t||dd|id}t|||||| }dd	d
d}tt|| |	|
|||j	_
|  |S )Nc           
   
   S  sB  d dd |  D }dd |  D }g }t }t|D ]\}}||t|< q<| D ]\}}	t|	D ]\}}t|tjrt	|dkrt||kr|
|t|  nJt| |kr|
|t|   n"t| d| dt| d| qjt||kr(t| d| dt| d| |
|t|  qjqZ|S )	Nz or c                 S  s0   g | ](\}}|d  d dd |D  d qS ) (z, c                 S  s   g | ]}t t|qS r;   )r   type)rp   r&  r;   r;   r<   rs   6  s     zJrewrite_signature.<locals>.produce_matching.<locals>.<listcomp>.<listcomp>))r   )rp   descrn   r;   r;   r<   rs   5  s   z?rewrite_signature.<locals>.produce_matching.<locals>.<listcomp>c                 S  s   g | ]}|D ]}|qqS r;   r;   )rp   rn   r&  r;   r;   r<   rs   :  s       r   z #rI  z) is not among )r   itemsr  rb   r  idrU   rA   r/  Znumelr1  itemrm   rJ  )
sources
candidatesZsource_typesZsource_argsZmatched_elements_positionsZdict_of_source_argsr)  r&  Zcandidate_descZcandidate_argsr;   r;   r<   produce_matching3  s8    z+rewrite_signature.<locals>.produce_matchingoriginal argszgraph-captured input)rP  rQ  )zgraph-captured outputsrS  ztraced resultz	List[str])r@   c                   s
  dddd}||   j d t| }t|t j krv jd k	sLtd| fddtdt|t| D 7 }nLt|t j k r j t|t jpg   D ]}||kstd	| q|t| 7 } jD ],} j	pi }||ks||kstd
| q|S )Nzinspect.Signature)sigc           
   	   S  s   t | j }dd |D }dd |D }tdd |D d }tdd |D d }tdd |D }dd	 |D }i }| jrd
| ji}|D ]}	|	j||	j< qt	|||||||S )Nc                 S  s    g | ]}|j tjjkr|jqS r;   )kindrZ   	ParameterPOSITIONAL_OR_KEYWORDrj   rp   pr;   r;   r<   rs   v  s   z_rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<listcomp>c                 S  s    g | ]}|j tjjkr|jqS r;   )rU  rZ   rV  KEYWORD_ONLYrj   rX  r;   r;   r<   rs   {  s     c                 s  s"   | ]}|j tjjkr|jV  qd S rK   )rU  rZ   rV  VAR_POSITIONALrj   rX  r;   r;   r<   r*    s      z^rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<genexpr>c                 s  s"   | ]}|j tjjkr|jV  qd S rK   )rU  rZ   rV  VAR_KEYWORDrj   rX  r;   r;   r<   r*    s      c                 s  s0   | ](}|j tjjkr|jtjjk	r|jV  qd S rK   )rU  rZ   rV  rW  defaultemptyrX  r;   r;   r<   r*    s   c                 S  s2   i | ]*}|j tjjkr|jtjjk	r|j|jqS r;   )rU  rZ   rV  rZ  r]  r^  rj   rX  r;   r;   r<   r%    s
    z_rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<dictcomp>r@   )
rF   
parametersr  r3  tuplereturn_annotation
annotationrj   rZ   FullArgSpec)
rT  paramsrn   
kwonlyargsvarargsvarkwdefaultskwonlydefaultsr   Z	parameterr;   r;   r<   signature_to_fullargspecr  sF    
      zKrewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspeczMore arguments than expectedc                   s   g | ]} j  d | qS )_)rf  r(  Zfullargspecr;   r<   rs     s   z=rewrite_signature.<locals>.argument_names.<locals>.<listcomp>r   zMissing argument zMissing keyword only argument )
rn   rl   rf  rm   r+  rh  rF   keysre  ri  )f_sigrn   ro   rj  Z
input_strsZunprovided_argZ
kwonly_argri  r;   rl  r<   argument_namesq  s0    ,
 


z)rewrite_signature.<locals>.argument_names)pytreeZtree_unflattentree_flattenrm   rF   r  Z	transformr   r   r@  Z_codegenZ	recompile)rn  r@  r#  r  in_specr"  graph_captured_inputZgraph_captured_outputZdynamo_traced_result	orig_argsZorig_kwargsrR  r   Zflat_results_tracedZout_spec_tracedr!  Z	new_graphro  r;   r;   r<   rewrite_signature&  s@    $
R
ru  symbolic)
aten_graphpre_dispatchdecomposition_tabletracing_modeconstraintsr   same_signaturezCallable[..., Any]z9Optional[Dict[torch._ops.OpOverload, Callable[..., Any]]]r   zOptional[List[Constraint]]zCallable[..., ExportResult])	r~   rw  rx  ry  rz  r{  r   r|  r@   c                  sF   | |  fdd}
|s*|	r>t d |
||	S |
S dS )a  
    Export an input function f to a format that can be executed outside of PyTorch using the FX graph.

    Args:
        f (callable): A PyTorch function to be exported.

        aten_graph (bool): If True, exports a graph with ATen operators.
        If False, exports a graph with Python operators. Default is False.

        pre_dispatch (bool): If True, exports a graph with ATen operators,
        but before any logic in the PyTorch dispatcher has run.
        This can be useful if you want to apply further transformations on a graph before running it
        through autograd, autocast, or any other functionalities that are integrated into the dispatcher.
        This flag is only valid if aten_graph=True is set.
        Default is False.

        decomposition_table (dict): A dictionary that maps operators to their decomposition functions.
        Required if aten_graph or tracing_mode is specified. Default is None.

        tracing_mode (str): If "symbolic", turn on dynamic shapes support. Default is "symbolic".

        same_signature (bool): If True, rewrite the returned graph's signature to be the same as f.

    Returns:
        A function that given args and kwargs, returns a tuple of (graph, guards)
        Graph: An FX graph representing the execution of the input PyTorch function with the provided arguments and options.
        Guards: The guards we accumulated during tracing f above

    Raises:
        AssertionError: If decomposition_table is specified without setting aten_graph=True,
        or if graph breaks during tracing in export.

        AssertionError: If Dynamo input and output is not consistent with traced input/output.

    Note - this headerdoc was authored by ChatGPT, with slight modifications by the author.
    c                    s  }}t   tjd 
d k	r.s.tdr>s>tdt|}t|tjjrZ|j	n|}t
|}d d d d d ddfdd}g  dd	 fd
d}t| |f\}}	t| d }
dkrd}tt dd z tjd|ddddZ t|t|d dd	d|}z|| |}W n( tk
rP } z|}
W 5 d }~X Y nX W 5 Q R X W 5 Q R X t| tdd  }d k	rZ|j }d k	rZtt
|sZ|  |  ||}| }|rd| d| }|
r|
jd | f|
_n|rt|}
nt d| |j!" D ]:}t|t#j$rtd%t&'|j(|  d| d}
q|
rd|
d k	svtdt)dstd k	stdd k	strt* fdd D }r^fd d!}t+ z t, h X zt-|
d"ddd#| W n4 t.k
r> } zt/t0j1t2|W 5 d }~X Y nX W 5 Q R X W 5 Q R X W 5 Q R X r|t3|||	||		rd$d 	D ng j4d%< t5S )&Nztorch._dynamo.exportzaSpecifying a decomposition_table table or tracing mode is illegal without setting aten_graph=Truez7pre_dispatch=True can only be used when aten_graph=Truer=  r  c                   s    d kst d|  d S )Nz3whole graph export entails exactly one guard export)rm   r  r  r;   r<   r	    s
    z1export.<locals>.inner.<locals>.guard_export_printr   r   c                   s6   d kst d| t | fdd}|S )Nz\Tried to emit a second graph during export. Tracing through 'f' must produce a single graph.c            	   
     s   | d k	st tjdd}tjdd}t| d k	rHt| n }|p t ^ t|t|}t }| D ]\}}|j|dd||< qxt	
|j| }tj||W 5 Q R X W 5 Q R X S )NF)Zremove_duplicateT)Zstatic_shapes)rm   rb   named_parametersnamed_buffersr   detect_fake_moder3   rM  r0  rp  Ztree_maprA   funcZfunctional_call)	Zgraph_inputsr}  r~  Zambient_fake_modeZparams_and_buffersZfake_params_buffersrj   valueZfake_graph_inputs)r#  r@  rs  graph_captured_resultr;   r<   result_capturing_wrapper3  s8        zhexport.<locals>.inner.<locals>.dynamo_normalization_capturing_compiler.<locals>.result_capturing_wrapper)rm   r   r  )r   Zinner_example_inputsr  )r   r#  r@  rs  r  r;   r<   'dynamo_normalization_capturing_compiler!  s    %zFexport.<locals>.inner.<locals>.dynamo_normalization_capturing_compilerrv  Tr
  F)Zspecialize_intr   r   Z capture_dynamic_output_shape_opsZcapture_scalar_outputsr   )r   r   export_constraints	shape_envzuSome dynamic dimensions need to be specialized because the constraints inferred for them are too complex to specify.
r  r   z#Summary of dimension constraints:%sr{   zk
It appears that you're trying to set a constraint on a value which we evaluated to have a static value of z1. Scroll up to see where this constraint was set.zZFailed to produce a graph during tracing. Tracing through 'f' must produce a single graph.rB  z'Failed to produce guards during tracingc                   s   g | ]}  |qS r;   )r0  )rp   t)r#  r;   r<   rs     s     z)export.<locals>.inner.<locals>.<listcomp>c               
     s6   t jj   t j j|  W  5 Q R  S Q R X d S rK   )rA   r   r  Zpreserve_node_metaZInterpreterrun)rn   )r@  r;   r<   graph_with_interpreter  s    z5export.<locals>.inner.<locals>.graph_with_interpreterreal)ry  rz  Z_allow_non_fake_inputsrx  Z_allow_fake_constantc                 S  s   g | ]
}|j qS r;   )Zserializable_spec)rp   
constraintr;   r;   r<   rs     s     Zinput_shape_constraints)6r   rA   rB   r   rm   r   rU   r   r   rV   rZ   	signaturerp  rq  r   r   r7   r'   r   r   r5   ri   dim_constraintsr*   rY   r[   ZsolveZ remove_redundant_dynamic_resultsZprettify_resultsforced_specializationsrn   r|   infoZvar_to_rangerm  sympyIntegerr   r  r  Zvar_to_stackr^   rH  r   r3   r   r,   r.   r/   ZDYNAMIC_CONTROL_FLOWr   ru  r.  r<  )rn   ro   r~   r   Zcall_to_inspectZoriginal_signaturer	  r  r  rr  Zconstraint_violation_errorr  Zresult_traceder  r  r  r  kr"  r  Z_assume_static_by_defaultZ_frw  r{  ry  rx  r|  rz  )r   r#  r@  rs  r  r  r<   r    s    
;
*

 @zexport.<locals>.innerzexport(f, *args, **kwargs) is deprecated, use export(f)(*args, **kwargs) instead.  If you don't migrate, we may break your export call in the future if your user defined kwargs conflict with future kwargs added to export(f).Nr  )r~   rw  rx  ry  rz  r{  r   r|  r  r  r  r;   r  r<   r     s    3 X
r   )r   r   r  r   c                C  s2   t | } t| dt}ttj| ||d||||dS )zF
    The same as `torch._dynamo.optimize(backend, nopython=True)`
    r   )r   r  )r   r   )r   ri   r   r   r(   Zconvert_frame_assert)r   r   r   r  r   r   r;   r;   r<   r     s      r   c                   @  s.   e Zd Zeeddd Zedd ZdS )r   Nc                  C  s  ddl m}  | tjjtj_| tjjtj_| tjjtj_| tjjj	jtjjj	_tj
jd ddlm}m}m}m}m}m}m}m}m}	m}
m}m}m} |||||||||	|
|||h}|||	|h}|D ]t}|jdd }d| }d	| }t||r ||kr t||| t|| t||rt||| t|| qd
d tjj ! D }tjj"tjj#tjj$h}|D ]j}||kr| |j%|_%t|dr| |j&|_&t|j%dd}|rt|j%dd }|r||_%d|j%_'qrtj(j)j*+  tj(j)j*,  tj(j)j-.  d S )Nr   )r   Fr   )adadeltaadagradadamadamaxadamwasgdlbfgsnadamradamrmsproprpropsgdsparse_adam.r  Z_multi_tensor_Z_fused_c                 S  s(   g | ] }t |rt|tjjr|qS r;   )rZ   isclass
issubclassrA   optimZ	Optimizer)rp   optr;   r;   r<   rs   L  s   
 z&TorchPatcher.patch.<locals>.<listcomp>_init_grouphooked__wrapped__T)/Z
decoratorsr   rA   ZjittraceZtrace_moduleZ_get_trace_graphr   r   ZTracerdistributionsDistributionZset_default_validate_argsr  r  r  r  r  r  r  r  r  r  r  r  r  r  r7   splitr^   setattrri   rc   r  Z
SparseAdamZRAdamZLBFGSstepr  r  rC   	variableslistsZ"_register_dynamo_list_to_tree_specZ#_register_dynamo_tuple_to_tree_specZdictsZ"_register_dynamo_dict_to_tree_spec)r   r  r  r  r  r  r  r  r  r  r  r  r  r  Zoptimizer_modulesZ!disabled_multi_tensor_opt_modulesZopt_modopt_nameZmulti_tensor_fn_nameZfused_fn_nameZoptimizer_classesZexcluded_optimizer_classesr  r  Zunwrapped_stepr;   r;   r<   r     s    
<


  

zTorchPatcher.patchc                   s    fdd}|S )Nc                    s   t jdtdd  | |S )Nignoreztorch.distributed)categorymodule)r   filterwarningsUserWarning)rn   ro   r   r;   r<   inner_fnq  s      zBTorchPatcher.suppress_torch_distributed_warnings.<locals>.inner_fnr;   )r   r  r;   r  r<   #suppress_torch_distributed_warningso  s    z0TorchPatcher.suppress_torch_distributed_warnings)r7   r8   r9   r   r   	lru_cacher   r  r;   r;   r;   r<   r     s
   kr   )NF)r   )
__future__r   
contextlibr   r   rZ   loggingr   r   r   	threadingr  rW   r   collectionsr   enumr   os.pathr   r   typingr   r   r	   r
   r   r   r   r   r   r   Zunittest.mockr   rA   Ztorch.fxZtorch.utils._pytreer+   Z_pytreerp  Ztorch.utils.checkpointr   Ztorch._subclassesr   Ztorch.exportr   Z"torch.fx.experimental.proxy_tensorr   r   Ztorch.fx.graphr   r   Ztorch.nn.parallel.distributedr   r   r   Zbackends.registryr   r   r   r   Ztorch._C._dynamo.eval_framer    r!   r"   r#   r$   r%   dirrB   rC   rD   rj   
startswithri   globalsr{   r'   r(   r)   r*   excr,   r-   r.   r/   r   r0   r1   r2   	getLoggerr7   r|   Ztorch._dispatch.pythonr3   Ztorch.utils._python_dispatchr4   ZExactWeakKeyDictionaryr   nullcontextr   r  Z%torch.fx.experimental.symbolic_shapesr5   r6   r:   r   RLockr   r=   r>  r[   __file__r   r>   rE   r   r   rI   r   r   r   contextmanagerr   r   r   r   r   r   r   r   r   r   r   r   r   r  interpreterZTransformerr  r<  rH  ru  r   r   r   r;   r;   r;   r<   <module>   s    0"	

> ,)		,	 E
V5* ,"  