o
    h                     @  s<  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rqeJe"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#Zrdvd(d)ZsG d*d+ d+e"jtjuZvd,d- Zwd.d/ Zxd0d1 Zyejzdwdxd7d8Z{G d9d: d:Z|G d;d< d<e|Z}G d=d> d>e|Z~G d?d@ d@e|ZdAdB ZdydEdFZedd2ddfdydGdHZdIdJ ZG dKdL dLejcZdMdN ZdOdP Z	Qdzd2ddd2ddRdSdTZe!dUdVdWdX ZG dYdZ dZe"j6jjZG d[d\ d\eZd]d^ Zd_d` Zd2d2ddadd2dVdbd{dpd5Ze<ddd2dddqdrdsZG dtdu duZdS )|    )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;   N/var/www/html/ai/venv/lib/python3.10/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, codecodetypes.CodeTypereturnList[CacheEntry]c                 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?   
cache_listr;   r;   r<   rG   e   s   rG   c                      sV   e Zd ZdZ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.
    modtorch.nn.Modulec                   s"   t    || _|| _|   d S N)super__init__	_orig_mod
dynamo_ctx_initialize)selfrM   rS   	__class__r;   r<   rQ   s   s   
zOptimizedModule.__init__c                 C  sn   t | jjtjrtt| jjr| 	t
| j| _n| 	| jj| _t| jdr5| j| _| j| _d S d S )N_initialize_hook)
isinstancerR   forwardtypes
MethodTyper*   checkinspectgetsourcefilerS   r)   wrap_inline__call__hasattr_forward_call_lazy_checkrU   r;   r;   r<   rT   z   s   zOptimizedModule._initializec                 C  s&   t | j}|dd  |dd  |S )NrZ   ra   )dict__dict__poprU   stater;   r;   r<   __getstate__   s   
zOptimizedModule.__getstate__c                 C  s   || _ |   d S rO   )rg   rT   ri   r;   r;   r<   __setstate__   s   zOptimizedModule.__setstate__c                 C  s   |dkr	| j d S t| j|S )NrR   )_modulesgetattrrR   )rU   namer;   r;   r<   __getattr__   s   
zOptimizedModule.__getattr__c                 O  s<   t | jdrt|dksJ | j| j| | j|i |S )NrX   r   )rb   rR   len_infer_parametersrc   )rU   argskwargsr;   r;   r<   rd      s   z OptimizedModule._call_lazy_checkc                   s&   | j     fddt  D  S )Nc                   s   g | ]}| vr|qS r;   r;   ).0attrorig_mod_attrsr;   r<   
<listcomp>   s    z+OptimizedModule.__dir__.<locals>.<listcomp>)rR   __dir__rP   re   rV   rw   r<   rz      s   
zOptimizedModule.__dir__)rM   rN   )r7   r8   r9   __doc__rQ   rT   rk   rl   rp   rd   rz   __classcell__r;   r;   rV   r<   rL   m   s    
rL   c                 C  st   t | tjrt|  dS t| drt| j dS tt| dddr)t| jj dS ddlm	} |  t
d|  dS )zA
    Make sure f.__code__ is not cached to force a recompile
    __code__rZ   Nr   resetz#could not determine __code__ for %s)rY   r[   CodeTyper    rb   r}   rn   rZ    r   logwarning)fr   r;   r;   r<   remove_from_cache   s   
r   c                   C  s   d S rO   r;   r;   r;   r;   r<   nothing   s   r   c                 C  s.   | }t |dr|j}t|sJ t |ds|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)rb   r   callable)fnunaltered_fnr;   r;   r<   innermost_fn   s   

r   FenableOptional[bool]exportboolc                 c  s    | d u r
d V  d S | r(t jdd d V  W d    d S 1 s!w   Y  d S t jddd d V  W d    d S 1 s>w   Y  d S )NF)assume_static_by_defaultT)automatic_dynamic_shapesr   )r'   r   )r   r   r;   r;   r<   enable_dynamic   s   
""r   c                      sJ   e Zd Zeeedfddddd fddZdd	 Zd
d Zdd Z  Z	S )_TorchDynamoContextFNr   dynamiccompiler_configcallbackr1   c          	        s`   t    t|s|du s|d u sJ || _t| _|| _|| _|| _|| _	|| _
|| _|  d S NF)rP   rQ   r   r   unsetprioron_enterextra_ctx_ctor	first_ctxr   r   r   )	rU   r   r   backend_ctx_ctorpatch_fnr   r   r   r   rV   r;   r<   rQ      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'   raise_on_ctx_manager_usageRuntimeErrorr   r!   r   r   r   backend_ctx	__enter__r   r   r   dynamic_ctxre   r;   r;   r<   r      s   

z_TorchDynamoContext.__enter__c                 C  sB   | j tusJ t| j  t| _ | j||| | j||| d S rO   )r   r   r!   r   __exit__r   )rU   exc_typeexc_valexc_tbr;   r;   r<   r     s
   
z_TorchDynamoContext.__exit__c                   sF  fdd}t ttjjr(}t|}|j|_t|dr#J ||_	|S t
s.J zt}W n ty@   d }Y nw |d u sJt|r[tdddvr[|tvr[tjjj t fdd}ttr|d	|_n|_|_t|drJ ||_	d
vrtdsttdd	tj < |S )Nc                     s    j S rO   )r   r;   re   r;   r<   get_compiler_config  s   z9_TorchDynamoContext.__call__.<locals>.get_compiler_configr   r7   r   )
_call_impl_wrapped_call_implc                    s   t tstjj rtjrtd| i |S   t	}  }|
  tjj}|
  z| i |W t	| |d d d  |d d d  S t	| |d d d  |d d d  w )NzvDetected that you are using FX to symbolically trace a dynamo-optimized function. This is not supported at the moment.)rY   DisableContextrC   fx_symbolic_traceis_fx_tracingr'   error_on_nested_fx_tracer   r!   r   r   r   r   r   )rs   rt   r   r   r   r   r   r   r   rU   r;   r<   _fn3  s.   
z)_TorchDynamoContext.__call__.<locals>._fnTr   r}   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   rY   rC   nnModulerL   rZ   r   rb   r   r   r^   r_   	TypeErrorr*   r]   rn   DONT_WRAP_FILESr)   r`   r   r   r   	functoolswrapsr   _torchdynamo_disable_torchdynamo_inliner   textwrapdedentalways_optimize_code_objectsr}   )rU   r   r   rM   new_modfilenamer   r;   r   r<   ra     sN   




!z_TorchDynamoContext.__call__)r   r1   )
r7   r8   r9   r   null_contextrQ   r   r   ra   r|   r;   r;   rV   r<   r      s    r   c                      s6   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 u  S rO   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                     s0   t t rtjrt 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'   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   rP   rQ   TorchPatcherr   )rU   r   r   r   r   r   r   r   rV   r   r<   rQ     s   

zOptimizeContext.__init__)F)r7   r8   r9   staticmethodr   rQ   r|   r;   r;   rV   r<   r     s    
r   c                         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   )rC   rE   mutation_guardGenerationTracker
generationr;   r;   r;   r<   r     s   z)RunOnlyContext.__init__.<locals>.on_enterF)r   r   rP   rQ   )rU   r   rV   r;   r<   rQ     s   zRunOnlyContext.__init__r7   r8   r9   rQ   r|   r;   r;   rV   r<   r         r   c                      r   )r   c                   s   t  jd d d S )N)r   r   re   rV   r;   r<   rQ     s   zDisableContext.__init__r   r;   r;   rV   r<   r     r   r   c                 C  s>   t jdk rdS t| D ]}|jdkr|jd   S qtd)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   hooksr   c                   s"   t   fdd} |_|S )Nc              	     sP  |d usJ | j t| jkst| jjstjr%t	d| jj
| jj d S | jjdkr3| jj
dkr3d S tjrrt }|rrt, ddlm} ||j jd}t dsVJ d |j}|| ||W  d    S 1 smw   Y  t* t   | ||W  d    W  d    S 1 sw   Y  W d    d S 1 sw   Y  d S )	Nzskipping %s %sz<string>__new__r   )DDPOptimizer)bucket_bytes_capbackend_compile_fn_clone_with_backendzJDDPOptimizer only supports callback fns that know how to clone themselves.)f_lastir   f_coder*   r]   co_filenamer'   disabler   debugco_nameoptimize_ddpr   _get_active_ddp_modulecompile_lock"torch._dynamo.backends.distributedr   r   r   rb   r   
compile_fnr4   )framecache_entryframe_state
ddp_moduler   ddp_optimizerhijacked_callbackr   r   r;   r<   catch_errors  s@    Rz*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)repro.after_dynamor   rb   r   rY   strr   )r   r   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J |S rO   )r   )rU   r   r;   r;   r<   ra     s   z_NullDecorator.__call__N)r7   r8   r9   ra   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y   Y dS w )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 |stjdddkrt S t	| } t
| dt}|r0t| ||dS ttj| |d|||t| d	rE|  dS 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.optimizeTORCHDYNAMO_DISABLEr   1r   )r   r   )r   r   N)r   r   )r  r   rC   rD   _log_api_usage_onceosenvirongetr   r   rn   r   optimize_assertr   r(   rb   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 ||i |S |S )Nc               	     sL  ddl m} |  g g  dg g d fdd}fdd	}tt d
d  t|d|d}|| i | W d    n1 sFw   Y  t}i } D ]}|jd }	||t|	< qSd}
t|	 D ]\}}d
t|j}|d  d|j d| d}|
|7 }
qi|d }tdd}|  ddlm} ||| |S )Nr   r~   r   gmtorch.fx.GraphModulec                   s,   ddl m} ||  \}  | jS )Nr   )_explain_graph_detail)backends.debuggingr  rZ   )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 rO   )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  r  )r   r   r   r7   r  rq   
user_stackr(  	enumeratevaluesr   	tracebackformat_listreasonr2   r  r)  )rs   rt   r   r  r$  opt_fgraph_countdeduped_reasonsr0  innermost_frameformatted_listidxbreak_reasonformatted_stackmsggraph_break_countcompile_timer)  r   )r  r  r  r  r#  r<   innerk  sV   	


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rA  c                      sB   e Zd Z	dd fddZdd Z fddZ fddZ  ZS )FlattenInputOutputSignatureNmr  	flat_args
Tuple[Any] matched_input_elements_positions	List[int]!matched_output_elements_positionsexample_fake_inputsList[torch.Tensor]	fake_mode$Optional[fake_tensor.FakeTensorMode]c           
        s   t  |  fddt|D }g _tdt|D ]7}t  d| di }	||v r5|| |	jjd< n|d urLt	|| t
jrL||| |	jjd< j|	 qfdd|D _|_d S )	Nc                   s   i | ]	\}}| | qS r;   r;   )ru   ixval)rI  r;   r<   
<dictcomp>  s    z8FlattenInputOutputSignature.__init__.<locals>.<dictcomp>r   argr;   rN  c                 3  s    | ]} j | V  qd S rO   )new_argsru   ire   r;   r<   	<genexpr>  s    z7FlattenInputOutputSignature.__init__.<locals>.<genexpr>)rP   rQ   r,  rQ  rangerq   placeholdernodemetarY   rC   Tensorfrom_tensorappendold_args_genrH  )
rU   rC  rD  rF  rH  rI  rK  matched_input_elements_to_fakerS  rP  rV   )rI  rU   r<   rQ     s   	

z$FlattenInputOutputSignature.__init__c                 C  sN   t | j}d| jjv r| jjd |jjd< d| jjv r%| jjd |jjd< |S )NrN  tensor_dict)nextr\  current_noderX  rW  )rU   targetrs   rt   rP  r;   r;   r<   rV    s   
z'FlattenInputOutputSignature.placeholderc                   s<   |d }g || j   fdd| jD }t ||fi S )Nr   c                   s   g | ]} | qS r;   r;   rR  lookupr;   r<   ry     s    z6FlattenInputOutputSignature.output.<locals>.<listcomp>)rQ  rH  rP   output)rU   ra  rs   rt   dynamo_result_flatnew_result_flatrV   rb  r<   rd    s   z"FlattenInputOutputSignature.outputc                   s6   || _ t |}d| j jv r| j jd |jjd< |S )NrN  )r`  rP   run_noderX  rW  )rU   nrrV   r;   r<   rg    s
   z$FlattenInputOutputSignature.run_noderO   )rC  r  rD  rE  rF  rG  rH  rG  rI  rJ  rK  rL  )r7   r8   r9   rQ   rV  rd  rg  r|   r;   r;   rV   r<   rB    s    rB  c                   @  s   e Zd ZU ded< ded< dS )ExportResultr  graph_moduleSet[_guards.Guard]r!  N)r7   r8   r9   __annotations__r;   r;   r;   r<   rj    s   
 rj  c           
      C  s   g }| j jD ]j}|jdkrpt|dsJ |j}| j|}|d u r"qt|dks*J d }|D ]}t|dkr7q.|} |d u rF|  d}n%d	t
|}d}	t|dkr`dt|d  d}	|  d	| |	 }|| q|r~ttjd
d	| d S )NrV  _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

)graphnodesoprb   rn  _source_to_user_stacksr  rq   ro   r   r.  r/  r[  r.   r/   INVALID_INPUT)
ro  input_errorsrW  sourceuser_stacksstacksr9  tbextrar;   r;   r<   check_signature_rewritable  s@   

r{  c	                 C  s   t ||\}	}
dd }|d|id|id}t |\}}|d us#J |t||dd|id}t|||||| }dd
d}tt|| |	|
|||j_	|
  |S )Nc           
   
   S  s>  d dd |  D }dd |  D }g }t }t|D ]
\}}||t|< q| D ]o\}}	t|	D ]f\}}t|tjr{t	|dkr{t||v rV|
|t|  q5t| |v rj|
|t|   q5t| d| dt| d| t||vrt| d| dt| d| |
|t|  q5q-|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)ru   rP  r;   r;   r<   ry   6  s    zJrewrite_signature.<locals>.produce_matching.<locals>.<listcomp>.<listcomp>))r   )ru   descrs   r;   r;   r<   ry   5  s    z?rewrite_signature.<locals>.produce_matching.<locals>.<listcomp>c                 S  s   g | ]	}|D ]}|qqS r;   r;   )ru   rs   rP  r;   r;   r<   ry   :  s    r   z #r|  z) is not among )r   itemsr-  rf   r,  idrY   rC   rY  numelr[  itemAssertionErrorr}  )
sources
candidatessource_typessource_argsmatched_elements_positionsdict_of_source_argsrS  rP  candidate_desccandidate_argsr;   r;   r<   produce_matching3  s:   z+rewrite_signature.<locals>.produce_matchingoriginal argszgraph-captured input)r  r  )zgraph-captured outputsr  ztraced resultrA   	List[str]c                   s  ddd}||   j d t| }t|t j kr9 jd us$J d| fddtdt|t| D 7 }n&t|t j k r_ j t|t jpLg   D ]}||v s^J d	| qQ|t| 7 } jD ]} jppi }||v s||v sJ d
| qj|S )Nsiginspect.Signaturec           
   	   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rCd
| ji}|D ]}	|	j||	j< qEt	|||||||S )Nc                 S      g | ]}|j tjjkr|jqS r;   )kindr^   	ParameterPOSITIONAL_OR_KEYWORDro   ru   pr;   r;   r<   ry   v  s
    z_rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<listcomp>c                 S  r  r;   )r  r^   r  KEYWORD_ONLYro   r  r;   r;   r<   ry   {  s    c                 s  $    | ]}|j tjjkr|jV  qd S rO   )r  r^   r  VAR_POSITIONALro   r  r;   r;   r<   rT       " z^rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<genexpr>c                 s  r  rO   )r  r^   r  VAR_KEYWORDro   r  r;   r;   r<   rT    r  c                 s  s2    | ]}|j tjjkr|jtjjur|jV  qd S rO   )r  r^   r  r  defaultemptyr  r;   r;   r<   rT    s    c                 S  s2   i | ]}|j tjjkr|jtjjur|j|jqS r;   )r  r^   r  r  r  r  ro   r  r;   r;   r<   rO    s    z_rewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspec.<locals>.<dictcomp>rA   )
rH   
parametersr-  r_  tuplereturn_annotation
annotationro   r^   FullArgSpec)
r  paramsrs   
kwonlyargsvarargsvarkwdefaultskwonlydefaultsr   	parameterr;   r;   r<   signature_to_fullargspecr  s:   
zKrewrite_signature.<locals>.argument_names.<locals>.signature_to_fullargspeczMore arguments than expectedc                   s   g | ]
} j  d | qS )_)r  rR  fullargspecr;   r<   ry     s    z=rewrite_signature.<locals>.argument_names.<locals>.<listcomp>r   zMissing argument zMissing keyword only argument )r  r  )	rs   rq   r  rU  r  rH   keysr  r  )f_sigrs   rt   r  
input_strsunprovided_arg
kwonly_argr  r;   r  r<   argument_namesq  s*   
,


z)rewrite_signature.<locals>.argument_names)rA   r  )pytreetree_unflattentree_flattenrH   rB  	transformr   r   ro  _codegen	recompile)r  ro  rK  rD  in_specrI  graph_captured_inputgraph_captured_outputdynamo_traced_result	orig_argsorig_kwargsr  rF  flat_results_tracedout_spec_tracedrH  	new_graphr  r;   r;   r<   rewrite_signature&  sD   $

R
r  symbolic)
aten_graphpre_dispatchdecomposition_tabletracing_modeconstraintsr   same_signaturer   Callable[..., Any]r  r  r  9Optional[Dict[torch._ops.OpOverload, Callable[..., Any]]]r  r   r  Optional[List[Constraint]]r   r  Callable[..., ExportResult]c                  sF   | |  fdd}
|s|	r!t d |
|i |	S |
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 ursJ drsJ dt|}t|tjjr-|jn|}t	
|}d d d d d d&fdd}g  d' fd
d}t| |f\}}	t| d }
dkrgd}tt dd N tjd|dddd4 t|t|d dd	d|}z	|| i |}W n ty } z|}
W Y d }~nd }~ww W d    n1 sw   Y  W d    n1 sw   Y  t| tdd  }d ur?|j }d ur?tt	|s?|  |  ||}| }|rd| 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 usMJ dt(dsUJ d us^J dd useJ rlt) fdd D }r݇fd d!}t* S t+ ? , zt,|
d"ddd#| W n t-y } zt.t/j0t1|d }~ww W d    n	1 sw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  rt2|||	||		rd$d 	D ng j3d%< t4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!  rl  c                   s    d u sJ d|  d S )Nz3whole graph export entails exactly one guard exportr;   r   r"  r;   r<   r$    s   
z1export.<locals>.inner.<locals>.guard_export_printr  r  c                   s6   d u sJ 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 usJ t jdd}t jdd}t| d ur$t| n }|R t 6 i t |t |}t  }| D ]\}}|j|dd||< q>t	|j| }t
j||W d    n1 sew   Y  W d    S W d    S 1 s}w   Y  S )NF)remove_duplicateT)static_shapes)rf   named_parametersnamed_buffersr   detect_fake_moder3   r  rZ  r  tree_maprC   funcfunctional_call)	graph_inputsr  r  ambient_fake_modeparams_and_buffersfake_params_buffersro   valuefake_graph_inputs)rK  ro  r  graph_captured_resultr;   r<   result_capturing_wrapper3  s>   
(zhexport.<locals>.inner.<locals>.dynamo_normalization_capturing_compiler.<locals>.result_capturing_wrapper)r   r  )r  inner_example_inputsr  )r  rK  ro  r  r  r;   r<   'dynamo_normalization_capturing_compiler!  s   
%zFexport.<locals>.inner.<locals>.dynamo_normalization_capturing_compilerr  Tr%  F)specialize_intr   r    capture_dynamic_output_shape_ops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.rr  z'Failed to produce guards during tracingc                   s   g | ]}  |qS r;   )rZ  )ru   t)rK  r;   r<   ry     s    z)export.<locals>.inner.<locals>.<listcomp>c                    sB   t jj  t j j|  W  d    S 1 sw   Y  d S rO   )rC   r   r.  preserve_node_metaInterpreterrun)rs   )ro  r;   r<   graph_with_interpreter  s   $z5export.<locals>.inner.<locals>.graph_with_interpreterreal)r  r  _allow_non_fake_inputsr  _allow_fake_constantc                 S  s   g | ]}|j qS r;   )serializable_spec)ru   
constraintr;   r;   r<   ry     s    input_shape_constraints)r!  rl  r*  )5r  rC   rD   r  r   rY   r   r   rZ   r^   	signaturer  r  r   r   r7   r'   r  r   r5   rn   dim_constraintsr*   r]   r_   solve remove_redundant_dynamic_resultsprettify_resultsforced_specializationsrs   r   infovar_to_ranger  sympyIntegerr   r.  r/  var_to_stackrb   r{  r   r3   r   r,   r.   r/   DYNAMIC_CONTROL_FLOWr   r  rX  rj  )rs   rt   r   r   call_to_inspectoriginal_signaturer$  r  rD  r  constraint_violation_errorr1  result_traceder  r  r9  r  krI  r  _assume_static_by_default_fr  r  r  r  r  r  )r  rK  ro  r  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).r>  )r   r  r  r  r  r  r   r  r?  r@  r=  r;   r  r<   r     s   3 X)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   rn   r   r   r(   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 ]8}|jdd }d| }d	| }t||r||v rt||| t|| t||rt||| t|| qfd
d tjj ! D }tjj"tjj#tjj$h}|D ]0}||v r| |j%|_%t|dr| |j&|_&t|j%dd}|rt|j%dd }|r||_%d|j%_'qt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&  _multi_tensor__fused_c                 S  s(   g | ]}t |rt|tjjr|qS r;   )r^   isclass
issubclassrC   optim	Optimizer)ru   optr;   r;   r<   ry   L  s    z&TorchPatcher.patch.<locals>.<listcomp>_init_grouphooked__wrapped__T)/
decoratorsr   rC   jittracetrace_module_get_trace_graphr   r   TracerdistributionsDistributionset_default_validate_argsr  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r7   splitrb   setattrrn   rg   r-  
SparseAdamRAdamLBFGSstepr  r  rE   	variableslists"_register_dynamo_list_to_tree_spec#_register_dynamo_tuple_to_tree_specdicts"_register_dynamo_dict_to_tree_spec)r   r  r	  r
  r  r  r  r  r  r  r  r  r  r  optimizer_modules!disabled_multi_tensor_opt_modulesopt_modopt_namemulti_tensor_fn_namefused_fn_nameoptimizer_classesexcluded_optimizer_classesr  r  unwrapped_stepr;   r;   r<   r     s   
<





zTorchPatcher.patchc                   s    fdd}|S )Nc                    s   t jdtdd  | i |S )Nignoreztorch.distributed)categorymodule)r   filterwarningsUserWarning)rs   rt   r   r;   r<   inner_fnq  s   zBTorchPatcher.suppress_torch_distributed_warnings.<locals>.inner_fnr;   )r   rD  r;   rC  r<   #suppress_torch_distributed_warningso  s   z0TorchPatcher.suppress_torch_distributed_warnings)r7   r8   r9   r   r   	lru_cacher   rE  r;   r;   r;   r<   r     s    kr   )r?   r@   rA   rB   r   )r   r   r   r   )r   r   )r  )r   r  r  r   r  r   r  r  r  r   r  r  r   r   r  r   rA   r  )
__future__r   
contextlibr   r   r^   loggingr  r   r   	threadingr.  r[   r   collectionsr   enumr   os.pathr   r   typingr   r   r	   r
   r   r   r   r   r   r   unittest.mockr   rC   torch.fxtorch.utils._pytreer+   _pytreer  torch.utils.checkpointr   torch._subclassesr   torch.exportr   "torch.fx.experimental.proxy_tensorr   r   torch.fx.graphr   r   torch.nn.parallel.distributedr   r   r   backends.registryr   r   r   r   torch._C._dynamo.eval_framer    r!   r"   r#   r$   r%   dirrD   rE   rF   ro   
startswithrn   globalsr   r'   r(   r)   r*   excr,   r-   r.   r/   r   r0   r1   r2   	getLoggerr7   r   torch._dispatch.pythonr3   torch.utils._python_dispatchr4   ExactWeakKeyDictionaryr   nullcontextr   r  %torch.fx.experimental.symbolic_shapesr5   r6   r:   r   RLockr   r=   rm  r_   __file__r   r>   rG   r   r   rL   r   r   r   contextmanagerr   r   r   r   r   r   r   r   r   r   r  r  r  rA  interpreterTransformerrB  rj  r{  r  r   r  r   r;   r;   r;   r<   <module>   s    0"	



> ,)	
	,	E
V5* ,  