a
    h	                    @   s  d 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mZ ddlmZmZmZmZmZm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 m!  m"Z# ddlm$Z$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/m0Z0 dd	l1m2Z2 dd
l3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZF ddlGmHZHmIZImZJmKZK ddlLmMZMmNZN ddlOmPZPmQZQmRZRmSZSmTZT ddlUmUZU ddlVmWZW ddlXmYZY ddlZm[Z[ ddlIm\Z\m]Z]m^Z^m_Z_m`Z` ddlambZb ddlcmdZd ddl'meZemfZf ddlgmhZh ddlimjZjmkZk dd llmmZmmnZnmoZompZpmqZqmrZrmsZsmtZtmuZumvZvmwZwmxZxmyZymzZz dd!l!m{Z{m|Z|m}Z}m~Z~mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ dd"lmZ dd#lmZmZmZmZ dd$lmZ dd%lmZ dd&lmZmZ dd'lmZ dd(lmZmZmZmZ dd)lmZ erdd*lmZ eeZejed+Zejed,Zejed-Zejed.Ze'jZed/d0G d1d2 d2Zed/d0G d3d4 d4Zed/d0G d5d6 d6ZG d7d8 d8Zejd9d: ZeG d;d< d<Zd=d> ZG d?d@ d@ejjZG dAdB dBZeeef ZeG dCdD dDZeG dEdF dFZG dGdH dHeZdIZdJdK Zeơ ZG dLdM dMZG dNdO dOe$jɃZdS )Pa  
Core graph building functionality for PyTorch's Dynamo system. This module contains
the essential components for constructing and managing FX graphs during compilation:

- OutputGraph: Manages the overall graph construction and compilation process. It owns
  a SubgraphTracer and handles graph compilation, execution, and state management.
  OutputGraph also manages features like graph deduplication, symbolic shape handling,
  and tracking of side effects.

- SubgraphTracer: Handles the actual FX graph construction by tracing Python code.
  It supports advanced features like higher-order operators through nested tracers,
  lifting of free variables, and handling of symbolic shapes.

The module supports key Dynamo features including:
- Higher-order operators through nested SubgraphTracers
- Graph deduplication for optimization
- Symbolic shape handling and propagation
- Side effect tracking and management
- Guard insertion and management
    N)	dataclassfield)AnyCallablecastOptionalTYPE_CHECKINGUnion)fxTensor)guards)ShortenTracebackTensorifyScalarRestartAnalysis)CompileContext	CompileIdGlobalContextCheckpointStateSourcetracingTracingContext)
FakeTensor)signpost_event)_make_graph_module)BackwardState)free_symbolsguard_scalaris_symbolicShapeEnvSpecialization)insert_deferred_runtime_asserts)StorageWeakRef)
OrderedSet)is_traceable_wrapper_subclass   )configexclogging	variables)
CompiledFn
CompilerFn)create_call_functioncreate_instructioncreate_load_constInstruction	unique_id)code_context)	PyCodegen)enter_new_scope)get_interface_for_device)BackendCompilerFailed!exceptions_allowed_to_be_fallback	SkipFrameunimplemented_v2unimplemented_v2_with_warning)apply_graph_deduplication)GraphRegionTracker)GuardBuilderinstall_guard)is_dynamic_nn_module)AttributeMutationExistingSideEffects)
AttrSourceBackwardStateSourceConstantSourceGetItemSourceGlobalStateSourceis_constant_sourceis_from_local_sourceLocalSourceNumpyTensorSourceParamBufferSourceShapeEnvSourceSyntheticLocalSourceTensorPropertyTensorPropertySource)_extract_tensor_dictcheckpoint_paramsCleanupHookclone_inputscount_callscountersdynamo_timedget_instruction_source_311get_locals_to_stealget_static_address_typeget_unique_name_wrtgraph_break_reasonsincrement_op_countistypelazy_format_graph_code
LazyStringnn_module_proxysameset_example_value)VariableTracker)BackwardStateGraphArgGraphArgTrackedFakewrap_fx_proxy)ContextWrappingVariable)BaseListVariable)CellVariableNullVariable)NNModuleVariable)NumpyNdarrayVariableSymNodeVariableTensorVariableUnspecializedPythonVariable)TensorWithTFOverrideVariable)InstructionTranslatorBasegraphZ
graph_codeZgraph_sizesZ
trace_callT)frozenc                   @   s   e Zd ZU eed< eed< dS )VariableTrackerCacheKeyZvt_idsourceN)__name__
__module____qualname__int__annotations__r    rx   rx   H/var/www/auris/lib/python3.9/site-packages/torch/_dynamo/output_graph.pyrq      s   
rq   c                   @   s   e Zd ZU eed< eed< dS )AliasingInfohas_aliasingmsgNrs   rt   ru   boolrw   strrx   rx   rx   ry   rz      s   
rz   c                   @   s   e Zd ZU eed< eed< dS )MutationInfoZhas_mutationr|   Nr}   rx   rx   rx   ry   r      s   
r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )VariableTrackerCachec                 C   s
   i | _ d S N)cacheselfrx   rx   ry   __init__   s    zVariableTrackerCache.__init__c                 C   s&   t t||}|| jvrd S | j| S r   rq   idr   )r   valuerr   keyrx   rx   ry   lookup   s    
zVariableTrackerCache.lookupc                 C   s   t t||}|| j|< d S r   r   )r   r   rr   vtr   rx   rx   ry   add   s    zVariableTrackerCache.addc                 C   s   t  }|j| j |S r   )r   r   update)r   Z	new_cacherx   rx   ry   clone   s    zVariableTrackerCache.clonec                 C   s   | j   d S r   )r   clearr   rx   rx   ry   r      s    zVariableTrackerCache.clearN)rs   rt   ru   r   r   r   r   r   rx   rx   rx   ry   r      s
   r   c                   C   s
   t tS r   )torchdynamo_loggingZget_step_loggerlogrx   rx   rx   ry   _step_logger   s    r   c                   @   s<   e Zd ZU dZeed< eej ed< dZ	e
ed< dd ZdS )	GraphCompileReasonzOStores why a given output graph was compiled; i.e. what caused the graph break.reasonZ
user_stackTgraph_breakc                 C   s   | j rt|  d S r   )r   rW   appendr   rx   rx   ry   __post_init__   s    z GraphCompileReason.__post_init__N)rs   rt   ru   __doc__r   rw   list	tracebackFrameSummaryr   r~   r   rx   rx   rx   ry   r      s
   
r   c                    s    fdd}|S )Nc                      s   dd  D S )Nc                 S   s    g | ]\}}}||i |qS rx   rx   ).0fnargskwargsrx   rx   ry   
<listcomp>       zE_get_gen_rand_values_fn.<locals>._gen_rand_values.<locals>.<listcomp>rx   rx   random_callsrx   ry   _gen_rand_values   s    z1_get_gen_rand_values_fn.<locals>._gen_rand_valuesrx   )r   r   rx   r   ry   _get_gen_rand_values_fn   s    r   c                       sZ   e Zd ZdZeeejjf d fddZ	edddZ
eeejjf ddd	Z  ZS )
FakeRootModulez'Trick the constructor of fx.GraphModule)
nn_modulesc                    s,   t    | D ]\}}t| || qd S r   )superr   itemssetattrr   r   kv	__class__rx   ry   r      s    
zFakeRootModule.__init__returnc                 C   s   dS )NzFakeRootModule(...)rx   r   rx   rx   ry   __repr__   s    zFakeRootModule.__repr__c                 C   s"   |  D ]\}}t| || qd S r   )r   r   r   rx   rx   ry   add_nn_modules   s    zFakeRootModule.add_nn_modules)rs   rt   ru   r   dictr   torchnnModuler   r   r   __classcell__rx   rx   r   ry   r      s   r   c                   @   s4   e Zd ZedddZejjeej	 dddZ
dS )WrapperBackendbackendc                 C   s
   || _ d S r   r   )r   r   rx   rx   ry   r     s    zWrapperBackend.__init__)gmexample_inputsc                 C   s   t || _|| _t| j}| ||| _| jd u sB| j| jju rJ| jjS tj	sV| jS zxzL| jjt
| }| jt
| }t||r| jW W |   S td|  W n ty   td  Y n0 W |   n
|   0 d S )Nzincorrect results of backend zerror in verify_correctness)rM   restorer   copydeepcopyr   	candidateforwardr#   verify_correctnessrO   r]   RuntimeError	Exceptionr   	exception)r   r   r   Zcopy_gmcorrectresultrx   rx   ry   __call__  s(    



zWrapperBackend.__call__N)rs   rt   ru   r(   r   r   r
   GraphModuler   r   r   rx   rx   rx   ry   r      s   r   c                   @   s   e Zd ZU dZeed< eed< eejj	 ed< e
e ed< eeeeef f ed< eed< eejjj ed< eej ed	< d
Zeed< d
Zeed< dZeejj ed< dZeeejj  ed< edd Zedd Zedd ZdS )OutputGraphGuardsStatear  
    A base class containing fields that are considered "persistent" when we
    want to save all the important state for reconstrucing guards in a different
    process. Normally we don't need to add states here, but we may have to when
    the information is needed to serialize the guards, so the fields here are
    supposed to be serializable as a requirement.
    local_scopeglobal_scopetorch_function_mode_stackguard_on_key_orderinput_source_to_sizes_strides
dual_levelfunctorch_layerscurrent_deviceFexportexport_constraintsN_guards_aotautograd_guardsc                 C   s   t dt|  d S )Nz%shape_env shouldn't be accessed from )AssertionErrortyper   rx   rx   ry   	shape_env@  s    z OutputGraphGuardsState.shape_envc                 C   s   | j S r   )r   r   rx   rx   ry   r   D  s    zOutputGraphGuardsState.guardsc                 C   s   | j S r   )r   r   rx   rx   ry   aotautograd_guardsH  s    z)OutputGraphGuardsState.aotautograd_guards) rs   rt   ru   r   Scoperw   r   r   Z	overridesZTorchFunctionModesetr   r   r   r   rv   
_functorchpyfunctorchZFuncTorchInterpreterr   devicer   r~   r   r   	GuardsSetr   ZGuardEnvExprpropertyr   r   r   rx   rx   rx   ry   r   %  s&   


r   c                   @   s   e Zd ZU dZeedZee ed< eedZ	ee
 ed< eedZeeeeedf f  ed< eedZee ed< eedZeee
eedf f  ed< d	S )
StackLocalsMetadatazf
    Stores metadata for a frame's stack and locals for the purposes of building resume functions
    )default_factorystack_null_idxeslocals_null_keys.stack_ctx_argsstack_ctx_idxes_origlocals_ctx_argsN)rs   rt   ru   r   dc_fieldr   r   rv   rw   r   r   r   tupler   r   r   rx   rx   rx   ry   r   M  s   
&r   c                       s  e Zd ZU dZeed< eeef e	e
 eeed fddZdd Zdd	 Zd
d ZdedddZdd Zdd Ze	ee  dddZdd Zdd Zeg ef dddZdd Zed d! Zed"d# Zd$d% Zed&d' Z e j!d(d' Z ed)d* Z"ed+d, Z#ed-d. Z$d/d0 Z%d1d2 Z&d3d4 Z'e(j)d5d6 Z*ed7d8 Z+ed9d: Z,ed;d< Z-ee.j/j0dd=d>Z1eeeef dd?d@Z2edAdB Z3ddDdEZ4dFdG Z5dHdI Z6edJdK Z7dLdM Z8dNdO Z9dPdQ Z:ddSdTZ;dUdV Z<e=dWdX Z>eee?j@dYdZd[ZAeBe.jCjDe.jEef d\d]d^ZFd_d` ZGdadb ZHddeeIdfdgdhZJdidj ZKdkdl ZLdmdn ZMedodpdqZNe(j)drds ZOdtdu ZPdvdw ZQeee?jR ddxdyZSeeeT ddzd{ZUe?jVeeE eWd|d}d~ZXe?jVeeE eWd|ddZYdd ZZdd Z[ee.jE dddZ\dCdddZ]dCdddZ^dCdddZ_ee` dCdddZadCdddZbedddZcedddZddCdddZeee?jVgdCf dCdddZfe.j?jRdddZg  ZhS )OutputGrapha  
    Wrapper class to hold outputs of InstructionTranslator.  Mainly the
    generated fx.Graph.

    OutputGraph is 1:1 with a frame being processed. Each frame is associated
    with some root InstructionTranslator. When user code calls a function,
    we construct a InliningInstructionTranslator that continues to write into
    the root InstructionTranslator's OutputGraph.
    side_effects)code_optionscompiler_fnr   r   r   c              
      s0  t  j|||
t i tjjjtjj	 tj
jjd t| |dg| _i | _|| _|| _|| _g | _tt| _t | _|	j|	j|	jd| _t | _g | _t| jt j!t j"t j#t j$| jd}dd l%m  m } |j&dd. tj'j(|| jrdnd| jd	}W d    n1 s0    Y  t)|| _*| j*j+,|	 t-. | _/| 0  t12t3| _4i | _5t6| | _7t8 | _9t:; | _<t=|| _>g | _?d| _@g | _A|| _B|| _C|| _Di | _Eg | _Fg | _Gd| _Hi | _ItjJK | _Ld| _Mti | _Nti | _O| P  i | _Qg | _Rd | _Sg | _Ti | _Ud | _Vd | _W| X | _YtZ[ | _\| ] | _^d S )
N)r   r   r   r   r   )	is_export)co_nameco_filenameco_firstlineno)tracked_fakesZallow_scalar_outputsZallow_dynamic_output_shape_ops+prefer_deferred_runtime_asserts_over_guards'allow_complex_guards_as_runtime_asserts	co_fieldsr   FZ(fake_tensor_allow_unsafe_data_ptr_accessT)r   Zallow_non_fake_inputsr   )_r   r   r   r   ZautogradZ
forward_adZ_current_levelr   r   Z#retrieve_all_functorch_interpretersutilsZ_deviceZCURRENT_DEVICESubgraphTracertracersinput_source_to_varr   r   frame_statecleanup_hooksnext_compile_id_counter
compile_idinstalled_globalsr   r   r   r   r8   region_trackerr   r   r#   Zcapture_scalar_outputsZ capture_dynamic_output_shape_opsr   r   torch._functorch.configpatch_subclassesFakeTensorModer   tracing_contextZtraced_coder   r   Zcurrent_compile_iddynamo_compile_idinit_ambient_guardscollectionsdefaultdictr   Ztracked_fakes_id_to_sourceparam_name_to_sourcer=   r   r   variable_tracker_cache	itertoolscountunique_var_idr   r   output_instructions	timestampregister_finalizer_fnsr   root_txpackagesource_to_user_stacks_current_txcleanupsshould_exitunspec_variable_map_CZ_is_torch_function_mode_enabledZtorch_function_mode_enabled!has_user_defined_allowed_in_graphnon_compliant_opscompliant_custom_opssave_global_state dynamo_flat_name_to_original_fqnr   random_values_varpregraph_bytecodebackward_statebackward_state_proxybackward_state_var!install_builtins_dict_in_fglobalsZ%name_of_builtins_dict_key_in_fglobals
contextlib	ExitStackcompiler_trace_stack+maybe_install_saved_tensors_hooks_subgraphs"saved_tensors_hooks_subgraph_names)r   r   r   r  r   r   r   r   r   f_coder   r  r   _config	fake_moder   rx   ry   r   g  s    


&






zOutputGraph.__init__c                 C   s   | j tddd d S )NZbytecode_tracingTlog_pt2_compile_event)r+  enter_contextrR   r   rx   rx   ry   mark_bytecode_tracing_start)  s    z'OutputGraph.mark_bytecode_tracing_startc                 C   s   | j   d S r   )r+  closer   rx   rx   ry   mark_bytecode_tracing_stop1  s    z&OutputGraph.mark_bytecode_tracing_stopc                 C   s&   | j d }t|ts|j}| d|S )N__builtins__Z__builtins_dict__)r   
isinstancer   __dict__install_global)r   
f_builtinsrx   rx   ry   r(  4  s    

z-OutputGraph.install_builtins_dict_in_fglobalshook)r<  c                 C   s6   | t | j }|| jvs J || j|< ||  fS r   )lenr%  get_backward_state_proxy)r   r<  prefixnamerx   rx   ry   add_backward_state_hookG  s    
z#OutputGraph.add_backward_state_hookc                 C   sb   | j d u r\| jr tdddg d t }| jjdt||t d| _ t | j j	j
d< |  | _| j S )Nz&backward_state does not support export z3Compiled autograd doesn't work with `torch.export`.Zgb_typecontextZexplanationhintsZdynamo_backward_staterr   grapharg)r&  r   r5   r   root_tracercreate_graph_inputr   r?   r`   nodemetanew_varr'  )r   example_valuerx   rx   ry   r>  M  s$    

z$OutputGraph.get_backward_state_proxyc                 C   s   | j t tj | j t tj | j t tj | j t tj	 | j t tj
 tjj }|d ur| j t tj tjjjs| j t tj d S r   )r   r   rH   
make_guardr9   Z	SHAPE_ENVrB   ZDETERMINISTIC_ALGORITHMSZ	GRAD_MODEZDEFAULT_DEVICEZTORCH_FUNCTION_STATEr   r  r   Zpeek_interpreter_stackZFUNCTORCH_STACK_MATCH_dynamocompiled_autogradin_compiled_autograd_regionZAUTOGRAD_SAVED_TENSORS_HOOKS)r   cirx   rx   ry   r  b  s(    
zOutputGraph.init_ambient_guardsr   c                 C   s   t jjjrd S t jjjj}t jjjj}| }||s8d S |\}}| 	dt j
| j|j}| 	dt j
| j|j}|dksJ |dksJ ||gS )NZsaved_tensors_hooks_packZsaved_tensors_hooks_unpackZsaved_tensors_hooks_pack_0Zsaved_tensors_hooks_unpack_0)r   rO  rP  rQ  r   Z_aot_autogradr   Ztop_saved_tensors_hooksZ"saved_tensors_hooks_are_inlineableinstall_subgraphr
   r   r   ro   )r   Z	get_hooksZare_inline_hookshooksZpack_gmZ	unpack_gmZpack_subgraph_nameZunpack_subgraph_namerx   rx   ry   r,    s(    

z7OutputGraph.maybe_install_saved_tensors_hooks_subgraphsc                 C   s8   t | j| j| j| j| j| j| j| j| j	| j
| j| jdS )N)r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   rx   rx   ry   dump_guards_state  s    zOutputGraph.dump_guards_statec                    s   | }|   }t| j   fdd  ttjj|  	t
|d  | | j   t|}t| j||}| }t jj| |S )z]
        call fn(*args) before the graph runs and turn the result into a fake input.
        c                      s     jjS r   )Zload_import_fromrt   rs   rx   cgr   rx   ry   <lambda>  s   z3OutputGraph.synthetic_graph_input.<locals>.<lambda>F)rL  r/   r  add_push_nullZforeachmapr&   ZConstantVariablecreatecall_functionr=  storer$  extendget_instructionsrI   r_   buildZrealizer   getguards_contextdynamo_guardsZremove_guards_with_source)r   r   r   rM  varnamerr   r   rx   rV  ry   synthetic_graph_input  s"    

z!OutputGraph.synthetic_graph_input)r   c                 C   s   | j | d S r   )r   r   )r   r   rx   rx   ry   add_cleanup_hook  s    zOutputGraph.add_cleanup_hookc                 C   s$   t | jD ]
}|  q
| j  d S r   )reversedr   r   )r   r<  rx   rx   ry   call_cleanup_hooks  s    zOutputGraph.call_cleanup_hooksc                 C   s
   | j d S Nr   r   r   rx   rx   ry   rH    s    zOutputGraph.root_tracerc                 C   s
   | j d S Nrj  r   rx   rx   ry   current_tracer  s    zOutputGraph.current_tracerc                 C   s   t | jdkS )Nr"   )r=  r   r   rx   rx   ry   is_root_tracer  s    zOutputGraph.is_root_tracerc                 C   s   | j jS r   rm  ro   r   rx   rx   ry   ro     s    zOutputGraph.graphc                 C   s   || j _d S r   ro  )r   r   rx   rx   ry   ro     s    c                 C   s   | j jS r   )rm  input_name_to_proxyr   rx   rx   ry   rp    s    zOutputGraph.input_name_to_proxyc                 C   s   | j jS r   )rm  real_value_cacher   rx   rx   ry   rq    s    zOutputGraph.real_value_cachec                 C   s   | j jS r   )rm  bound_symbolsr   rx   rx   ry   rr    s    zOutputGraph.bound_symbolsc                 O   s   | j j|i |S r   )rm  create_proxyr   r   r   rx   rx   ry   rs    s    zOutputGraph.create_proxyc                 O   s   | j j|i |S r   )rm  create_nodert  rx   rx   ry   ru    s    zOutputGraph.create_nodec                 O   s   | j j|i |S r   )rm  remove_nodert  rx   rx   ry   rv    s    zOutputGraph.remove_nodec                 c   s   t  }zh|r|j| ju sJ |  |r,|nt| | j|| jjd}| j| |V  W |d d d  | j	  n|d d d  | j	  0 d S )N)parentsource_targetr   )
r0   rw  rm  	__enter__r   r   r   r   __exit__pop)r   rx  Zprior_tracerZnew_scope_ctxtracerrx   rx   ry   	subtracer  s(    
zOutputGraph.subtracerc                 C   s   | S r   rx   r   rx   rx   ry   output  s    zOutputGraph.outputc                 C   s   | j jS r   )r	  r0  r   rx   rx   ry   r0    s    zOutputGraph.fake_modec                 C   s
   | j jjS r   )r	  r0  r   r   rx   rx   ry   r     s    zOutputGraph.shape_envc                 C   s
   | j jjS r   )r	  rb  rc  r   rx   rx   ry   r   "  s    zOutputGraph.guardsc                 C   s
   | j jjS r   )r	  Zmodule_contextr   r   rx   rx   ry   r   &  s    zOutputGraph.nn_modulesc                 C   s
   | j jjS r   )r	  rb  r   r   rx   rx   ry   r   *  s    zOutputGraph.aotautograd_guardsNc                 C   s   t ttttdtf tf f |dur(|n| jjj	}t
jt
 f|d< tt
jdt
df|d< tt
jdt
df|d< tt
jdt
df|d< tt
jdt
df|d	< t
jt
 f|d
< dS )zc
        Saves to out if it is provided. Else saves to the tracing context's global_state.
        .Ngrad_enabledZcudaZautocast_enabledcpuZautocast_cpu_enabledZautocast_gpu_dtypeZautocast_cpu_dtypeZautocast_cache_enabled)r   r   r   r   r   r   r~   r	  global_contextglobal_stater   Zset_grad_enabledis_grad_enabled	functoolspartialZset_autocast_enabledZis_autocast_enabledZset_autocast_dtypeZget_autocast_dtypeZset_autocast_cache_enabledZis_autocast_cache_enabled)r   outr  rx   rx   ry   r!  .  s,    	zOutputGraph.save_global_statec                 C   s   | j | d S r   )r  r   )r   txrx   rx   ry   push_txR  s    zOutputGraph.push_txc                 C   s
   | j  S r   )r  r{  r   rx   rx   ry   pop_txU  s    zOutputGraph.pop_txc                 C   s   | j s| jS | j d S rk  )r  r  r   rx   rx   ry   
current_txX  s    zOutputGraph.current_txc                 C   s
   t | jS r   )rP   ro   r   rx   rx   ry   rP   \  s    zOutputGraph.count_callsc                 C   s   t t| jjdkS ri  )r=  r   ro   nodesr   rx   rx   ry   is_empty_graph_  s    zOutputGraph.is_empty_graphc                 C   s@   |sJ | j }|dD ]"}t|tr0|| }qt||}q|S N.)r   splitr8  r   getattr)r   keysobjr   rx   rx   ry   get_submoduleb  s    

zOutputGraph.get_submoduletmpc                 C   sH   t | jd }| dt| j }||vr| jd  |f7  < |S qd S )Nco_varnames_)r   r   r   r  )r   r@  existingvarrx   rx   ry   rL  l  s
    zOutputGraph.new_varc                 C   s&   || j d vr"| j d  |f7  < dS )z/Ensure self.code_options.co_names contains nameco_namesN)r   )r   r@  rx   rx   ry   update_co_namesu  s    zOutputGraph.update_co_namesc                  G   sV   d tt| }tdd|}tdd|}tdd|}|rJ|d  sRd| }|S )	Nr  z^[GL]\['?(.*?)'?\]$z\1z	\[(\d+)\]z_\g<1>z[^a-zA-Z0-9]r   sub)joinrZ  r   rer  isalpha)namesr@  rx   rx   ry   module_key_namez  s    zOutputGraph.module_key_name)attr_prefix
attr_valuer   c                 C   s6   t || j}|| j|< | d|di }t|j| |S )Nget_attrrx   )rV   r   rs  r^   rJ  )r   r  r  	attr_nameproxyrx   rx   ry   %register_static_attr_and_return_proxy  s
    
z1OutputGraph.register_static_attr_and_return_proxytargetc           
         s  t jr"tjjfi S tdv s6J d ttrLJ ttj	rj
 sljfdd}nttjjrttjjsJ rttj fdd}nfdd}n2ttjtjfrfdd}nfdd}j D ] \}}|u r||  S qtj|  t jj j < ttjjrȇ fdd	}td
r D ]\}}	|| qtdrȈ D ]\}}	|| q| S )Nrr   c                    s   j d usJ j | < jjjv r4jjj S tdkr\tts\tt	j
 ntsttt	j tjd| di fdi }jjj|}d|jjjvsJ t|jjjd< |S )NZguardedr  rx   rM  Ztensor_dict)r  r  r~  r   rU   r8  rF   r:   rN  r9   ZID_MATCHrC   ZTENSOR_MATCHrc   rs  Ztrack_object_existingr  rJ  rK  rL   )
module_keyr   )optionsr   rr   r  r|  rx   ry   	wrap_name  s,    
	z6OutputGraph.register_attr_or_module.<locals>.wrap_namec                    s   t t| fi  S r   )rh   r   r  r  r  rx   ry   r    s    c                    s   t jfi  S r   )r&   ZUnspecializedNNModuleVariabler  r  rx   ry   r    s    c                    s$   t jd| di fdi S )Nr  rx   Zsym_num)rj   r[  rs  r  )r  r   r  rx   ry   r    s    c                    s*    j |   j| < t t| dS )N)Zsource_name)r~  r  r   r_   r`  r@   r  )r   r  rx   ry   r    s    
c                    sR   j d usJ t| }  d|  }|j |< ttrN| jt| < d S r  )r  rG   r8  rE   r"  r   r  r@  )	leaf_nameZ
new_sourcenew_name)r@  r   rr   rx   ry   register_leaf_name  s    


z?OutputGraph.register_attr_or_module.<locals>.register_leaf_name_parameters_buffers)r;   r   r_   r`  r  r   r8  rG   r   r   rm  rn  rH  r   r   r:   rN  r9   Z	NN_MODULESymIntZSymFloatr   r   r   r  rV   r   hasattrZnamed_parametersZnamed_buffers)
r   r  r  r  r  r   r   r  r  r  rx   )r@  r  r   rr   r  r|  ry   register_attr_or_module  sF     	


z#OutputGraph.register_attr_or_modulec                 C   s  | j d}t|}|s g i fS g }i }g |j|j | jj }|r|	 }t
|trzt
|jtsnJ ||j7 }qH|| jjvst
|jtrHt
|jtrHt
|jjtrH|jjj|v sqH|jjj}||vrg ||< || | qHi }	i }
| jD ]}t
|jtrt
|jtr|jj|v s q|jj}|| jd v s<J || D ]}|j|
v rXqD|jj}||	vr| | d}||	|< |td|dt|tdtd|dg |j}t|	| |
|< qDq||
fS )Nr   r  Z_ref	LOAD_FASTargvalBINARY_SUBSCR
STORE_FAST)r   ra  rT   stacksymbolic_localsvaluesr   Zstore_attr_mutationsr  r{  r8  re   r   r   Zmutation_typer<   rr   rA   baserE   
local_namer   	graphargsZ_exampler   indexrL  r^  r*   r+   )r   r  Zmaybe_gmZstolen_list_namesalias_instsZneeds_aliasqueuexZstolen_namevisitedoverridden_sourcesargZ	list_nameZlist_idxZ
alias_nameZ
old_sourcerx   rx   ry   handle_aliases_for_stolen_lists!  s    





	








z+OutputGraph.handle_aliases_for_stolen_listsc                 C   s  |   g }t }t|jD ]\}}tj| t|j| |krN|| qt	|t
rf|j| n
|| t	|tr|jdu rdnt|j}|jt|d |f |j| qg }i }	|j D ]\}
}t	|jtr|jj|
krqt	|tr|j|
krqtjdkr0tt
|rB|j|
 qntt
|rBJ t	|trx|jdu r^dnt|j}|j|
|f ||	vrg |	|< |	| |
 q|	 D ],}||	|  ||gt|	|   q|||fS )a
  
        Gets the stack + locals values belonging to tx that need to be restored.

        Also prunes dead tx locals and realizes all VTs in the tx's stack.

        NullVariables in stack/locals will NOT be restored, unless they are the top `stack_pops`
        elements of the stack - it is expected that the next instruction to run will pop the top
        `stack_pops` elements of the stack, so we should codegen NULLs.

        Returns:
            - stack_values: stack and locals values that need to be restored
            - restore_vars: names of locals corresponding to the locals part of `stack_values`
            - meta: locations of NULLs and ContextWrappingVariables in the stack/locals
                (ignores the top `stack_pops` values on the stack)
        Nrx   r"   )      )Zprune_dead_localsr   	enumerater  r&   ZLazyVariableTrackerZrealize_allr=  r   r8  rg   r   rd   target_valuesr   r   r   r  r   rr   rE   r  rf   sysversion_infor   __instancecheck__r   r   r  r^  )r   r  
stack_popsstack_valuesrK  ir   r  restore_varsZval_to_namesr   r   rx   rx   ry   _get_stack_values_to_restorew  sN    



	
z(OutputGraph._get_stack_values_to_restoreFr   rn   )r  r   c           "         s  | j dusJ | j |u sJ |   || _|| _d| _td| g }tjdkr|j	D ]\}|j
dkrz|td|jd qV|j
dkr|tdt|jd d	 qV|t| qV| | | jr| jrJ d
| | j | | j \}}| | t| j jD ]}	|	j| j |jd q|   g }
g }g }|}|dusDJ tdd |jD s^J | ||\}}}|
| || || || j u rq|j}q6dd | j D }t|}ddl m!} t| j"dkr\g }| #d| _$|t%| j"dd}| &d|}t'| j ||d}|(|)|d |(t*dd ||+| j$ | | d}d}|
d }| j |u r"|r"tdd |D r"tdd |D r"tt,|t|kr"| j-. r"|j/s"| j0s"|d j1s"|d j2s"| | 3|t4t||tdt|d	g  n&| #d}dd t|
D }t'| j |||d}| 5||| i }|j6 D ],\}}|dkrlt7|t8t9fsld||< qlt'| j ||||d } | 5|||  g }!t:| j;dkst| j<dkr.|!(| 3|| = | t| j<dkr|!| +| d}n|!td! n| >  | |!| ?   t'| j |d |  fd"dt|d D  |r|r|  @|g |S )#a  
        Compiles the current subgraph, with inputs w.r.t. self.root_tx, and codegens:
            - Call the compiled subgraph
            - Apply side effects
            - Codegen stack and locals
            - Store the locals

        Python does not allow NULL to be an arg to a function, so we do not codegen NULLs on the stack,
        unless the value is one of the top `stack_pops` values on the stack (these values are expected to be
        popped immediately after this generated code. The prologue of the resume function is expected to restore
        any dropped NULLs.

        Returns stack indices and locals keys where we dropped NULLs, and where we found inactive context manager objects.
        NTzCOMPILING GRAPH due to %sr     Z	MAKE_CELLr  ZCOPY_FREE_VARSco_freevars)r  z)export does not support pregraph_bytecode)Zis_graph_breakc                 s   s   | ]}|  V  qd S r   )Zcan_restore)r   blockrx   rx   ry   	<genexpr>  r   z/OutputGraph.compile_subgraph.<locals>.<genexpr>c                 S   s   i | ]\}}|t |qS rx   )r\   )r   r@  modrx   rx   ry   
<dictcomp>-  s   z0OutputGraph.compile_subgraph.<locals>.<dictcomp>r"   disabler   Zrandom_valuesz.do not trace into Dynamo rng recovery functionr   Z__gen_rand_values)r  Frl  c                 s   s8   | ]0}t |tttf o.t |to,| tu  V  qd S r   )r8  rl   ri   rm   rj   Zpython_typefloat)r   r   rx   rx   ry   r  P  s   
c                 s   s   | ]}t |tV  qd S r   )r8  rk   r   r  rx   rx   ry   r  \  r   UNPACK_SEQUENCEZ	graph_outc                 S   s   g | ]}|D ]}|qqS rx   rx   )r   valsvalrx   rx   ry   r   n  s   z0OutputGraph.compile_subgraph.<locals>.<listcomp>)tempvarsr  POP_TOPc                    s   g | ]}  |qS rx   )create_store)r   r  Zlocal_restore_cgrx   ry   r     s   )Ar  r6  partial_convertcompile_subgraph_reasonr  r   debugr  r  prefix_instsopnamer   r*   r  r=  r   r   add_output_instructionsr$  r   r  rg  Zblock_stackexitr   cleanup_graphallr  rw  r   r   r   
decoratorsr  r   rL  r#  r   r:  r/   r^  Zload_function_namer)   r  r   r   Zis_emptydebug_localsr%  r   r   compile_and_call_fx_graphr   codegen_suffixZusesrY   rI   rE   rP   ro   Zgraph_outputsZgraph_output_varsrun_compiler_collectiver_  Zcreate_delete)"r   r  r   r  r  r  instr  r  r  Zall_stack_valuesZall_restore_varsZall_stack_locals_metasZcur_txr  r  rK  Znn_modules_proxiesrootr  Zrandom_calls_instructionsZrand_fnZrand_fn_namecodegenZgraph_output_varZstored_graph_output_varZroot_stack_valuesZstack_values_flatZpass1r  r  r  Zpass2r~  rx   r  ry   compile_subgraph  s.   















 


zOutputGraph.compile_subgraphc                    s   | j   | jrT| jrJ | j D ],\}} |   | j  | q&| j 	  |j
D ]R\}  fdd |D ]} | q tt|d  tdg qf j||j d | j   d S )Nc                      s    S r   rx   rx   rW  Z	debug_varrx   ry   rX    r   z,OutputGraph.codegen_suffix.<locals>.<lambda>Fr  )Zvalue_from_source)r   Zcodegen_save_tempvarsr%  r   r   Zappend_outputZcreate_loadr'  Z
store_attrZcodegen_hooksr  rY  Zextend_outputr)   r=  r*   Zrestore_stackZcodegen_update_mutated)r   r  r  rW  r@  r  r   r  rx   r  ry   r    s     

zOutputGraph.codegen_suffixc                 C   s   | j s
J t| jj}|D ]}|jdd qt }t||dd D ]\}}|j	tj
ju rHt|j| fkrH|jsH|jd }|j	tj
ju rHt|j| fkrH|jsH|jd }| j| | j| qHdS )z
        Remove "creation_timestamp" from node meta

        Remove this pattern from the graph:
            torch._C._set_grad_enabled(False)
            torch._C._set_grad_enabled(True)
        creation_timestampNr"   r   )r  r   ro   r  rK  r{  r   r  zipr  r  Z_set_grad_enabledr   r   Z_erased
erase_node)r   r  rJ  r  node1node2rx   rx   ry   r    s,    


zOutputGraph.cleanup_graphc                 C   sN   i }| j jD ]<}|jdd }t|tjjr| }dd |D ||j	< q|S )NrM  c                 S   s"   g | ]}t |tr|nt|qS rx   )r8  rv   reprr   srx   rx   ry   r     r   z:OutputGraph.get_graph_sizes_structured.<locals>.<listcomp>)
ro   r  rK  ra  r8  r   r  r   sizer@  )r   retrJ  rM  r  rx   rx   ry   get_graph_sizes_structured  s    z&OutputGraph.get_graph_sizes_structuredr@  c           	      C   s   d}|d| d7 }| j jD ]}|jdd }t|tjjr| }||j	 dt
| d7 }g }d}|D ]>}t|tr|| qjt|tjrd}||jj qj qqj|r||j	 d	t
| d7 }q|S )
NzTRACED GRAPH TENSOR SIZES
z===== z =====
rM  z: 
FTz (concrete): )ro   r  rK  ra  r8  r   r  r   r  r@  r   rv   r   r  rJ  hint)	r   r@  Zgraph_sizes_strrJ  rM  r  Zconcrete_sizeZ
has_symintszrx   rx   ry   get_graph_sizes  s*    
zOutputGraph.get_graph_sizesc              
   c   s`   | j j }i }| j|d z*| j j| dV  W | j jt| n| j jt| 0 dS )zj
        Momentarily restores the global state to what it was prior to tracing the current output
        )r  N)r	  r  Zcopy_graphstater!  Zrestore_graphstater   )r   Zprior_global_stateZcurrent_global_staterx   rx   ry   restore_global_state  s    z OutputGraph.restore_global_statec              	      s.  | j }|d usJ |j  d ur* jd u r* j}td j tjj	ddd  fddd |j
}t|dksJ dd	|t| | tj  b td
dd6 d g|  }tj| j|d | _W d    n1 s0    Y  W d    n1 s0    Y  |j  tjd S )Nzcompiler_collective %sZartifactc                   S   s
   dddS )Ncompiler_collectivestring)r@  encodingrx   rx   rx   rx   ry   rX  !  s    z5OutputGraph.run_compiler_collective.<locals>.<lambda>c                      s
    j  S r   )local_staterenderrx   Zdsrx   ry   rX  %  r   )Zmetadata_fn
payload_fnr"   z&Expect only one device type but got {}+r  Tr1  )group)r  Zdistributed_state
all_states
compile_pgr   infor  r   _loggingtrace_structuredZ_device_typesr=  formatr  r1   r{  r   ZrankZacceleratorZdevice_countrR   r  distZall_gather_objectZspeculation_logr   r$   Z CompileCollectiveRestartAnalysis)r   r  r  Zdevice_typesr  rx   r  ry   r    s2    

D
z#OutputGraph.run_compiler_collectivec                    s  t jj  ddlm} js&J   tddd}t	|t
sHJ t	|tsVJ ddjtdd |D fi } }|| j|| tjsʈ  tt|jj|jd	   tj}td
 d  |7  <   j !  t"|jj#r6j#D ]}	t$|	t%||	 qj&D ]}
|
 q<|_'j(_(j)* j+d< j,j+d< t-.dt/|dddd t j0j1dfddfddd 2  j3j4}js"ddl5m6  m} |j7dd  t j8j9|jd}W d   n1 s0    Y  |j3_4:   ;<  W d   n1 sR0    Y  ddl=m>} t	 |st	t% dd|rƈ j?dkrt	 |r n j@}|A| t	 |s|jB jCdurjCD|  | dd td
 d  d7  < |jjE }rg i d d! jFD }|D ]\}|G|jH}tIJ|jKL }tMN|jK|g}tO.d"| PtQR|fd#d||f q*t jSjdd fd$d%}T|| nT|  jUdusJ tVjU}|W| |X W  d   S 1 s0    Y  dS )&z
        Generate code from self.graph and return the Instruction()s to
        call that generated code.

        Code is generated w.r.t. self.root_tx.
        tx is only used for preserving GraphModule metadata
        r"   r  Z__compiled_fnT)Z	with_uuidr~  c                 s   s   | ]}|  V  qd S r   )Zas_proxyr  rx   rx   ry   r  P  r   z8OutputGraph.compile_and_call_fx_graph.<locals>.<genexpr>)r   statsZcalls_capturedr"  r
  %s)include_strideinclude_deviceZcoloredZdynamo_output_graphc                      s   d   iS )Nsizes)r  rx   r   rx   ry   rX    r   z7OutputGraph.compile_and_call_fx_graph.<locals>.<lambda>c                      s    j ddddS )NFT)Zprint_outputr  r  )Zprint_readablerx   )r   rx   ry   rX    s   )r  r   NFr   )r   )_LazyGraphModule__self__Z_lazy_forwardz"do not trace Dynamo-compiled graphr  Zunique_graphsc                 S   s   g | ]
}|j qS rx   rF  r   arx   rx   ry   r     r   z9OutputGraph.compile_and_call_fx_graph.<locals>.<listcomp>z:Compiling backend specialized graph with specialization=%sc                 S   s   |||  S r   rx   )idxr   check_fnrx   rx   ry   rX    s   c               
      s   D ]\}}|| r|v r2| | i |  S j |j|j\ |jd< t| }tj  ||< W d    n1 s0    Y  W d    n1 s0    Y  | | i |  S q | i |S )Nspecialization)	r   Zpatch_source_specializationrr   r&  rK  r   r   r	  call_user_compiler)r   r   r&  r'  r   compiled_fnr   r   Zspecialization_cacheZspecialization_guardsrx   ry   specialized_dispatch  s$    


BzCOutputGraph.compile_and_call_fx_graph.<locals>.specialized_dispatch)Yr   r   r   Zclear_framer  r  r  r  r-   r8  r   r   ru  rm  Z
create_argr   
dedup_passr   _maybe_preserve_original_metar#   Zdo_not_emit_runtime_assertsremove_unused_get_attr_nodesr   r
   r   ro   r   r   remove_unused_graphargsrP   rQ   &remove_tensorify_specialized_graphargsrq  r   r   r-  r   r  r  Z_backend_idr  r"  r   rK  r
  graph_code_logr  rZ   r  r  rh  r	  r0  r  r   r  r  r  r  r(  r   torch.fx._lazy_graph_moduler!  rs   r"  Zforce_recompiler   r  Zadd_backend_idspecializationsr  r  rr   inspect	getsourcer&  stripr   ZLAMBDA_GUARDr   r   r  r  rO  install_global_unsafer  r/   Zmake_call_generated_coder_  )r   r  rvr  r  r@  Zoutput_nodeZsub_gmsZncallsZsubgraph_nameregister_finalizerZold_fake_moder/  Zbackend_fake_moder!  Zlazy_gmr3  sourcesr'  Zsource_indexZcheck_fn_sourcer&  r+  rW  rx   r)  ry   r  9  s    








&
0



z%OutputGraph.compile_and_call_fx_graphc                 C   s   | j jddS )Nplaceholderop)ro   
find_nodesr   rx   rx   ry   placeholders   s    zOutputGraph.placeholdersc                 C   s   dd | j D S )Nc                 S   s   g | ]}|j d  qS )rG  rK  )r   rJ  rx   rx   ry   r     r   z)OutputGraph.graphargs.<locals>.<listcomp>)r?  r   rx   rx   ry   r    s    zOutputGraph.graphargs)r   r   r   c                 C   sD   t ddddddd | ||W  d    S 1 s60    Y  d S )NOutputGraph.call_user_compilerZbackend_compileTZcompile_aot_autogradZ'aot_autograd_cumulative_compile_time_us)Z
phase_namer2  Zlog_waitcounterZwaitcounter_name_overrideZdynamo_compile_column_us)rR   _call_user_compiler)r   r   r   rx   rx   ry   r(    s    rA  c                 C   s>  | j d usJ d}g }|jjD ]*}|jdv r4|d7 }|jdkr|| qt| |D ] }t|dsV|jd }|j|_	qV| j
|_| j|_t| j dr| j jnd}z\t tjd	|  | j }	tjrt|	}	|	||}
t tjd
|  t|
sJ dW n ttfy    Y n ty } zx| jrJt| j |t |jd t|| j j!dd| dt"| d| j #  d| dt"| ddgd W Y d }~nrd }~0  t$y } z|W Y d }~nJd }~0  t%y } z(t| j |t |jd W Y d }~n
d }~0 0 t&ddi | j'|t(|jjt(|d |
S )Nr   r\  call_methodcall_moduler"   r;  _dynamo_sourcerG  rs   z<unknown compiler_fn>zcalling compiler function zdone compiler function z#compiler_fn did not return callablezBackend compiler exceptionz	Backend: z
Exception:z
Traceback:
zBackend compiler `z` failed with z. Adding a graph break.z-Report an issue to the backend compiler repo.rC  ZdynamorA  )Zop_countZ
node_countZinput_count))r   ro   r  r=  r   rX   r  rK  rr   rF  r  Z_param_name_to_sourcer  Z_source_to_user_stacksrs   r   r%   INFOr#   r   r   callabler   r   r3   r  r2   r4  currentframewith_traceback__traceback__r6   r  r.  r   Zformat_frame_summaryr4   r   r   r   r=  )r   r   r   Ztotr?  rJ  plr  r@  r   r*  erx   rx   ry   rB    s    









zOutputGraph._call_user_compilerc                 C   s   t jjjrt| S i S d S r   )r   rO  r#   use_graph_deduplicationr7   r   rx   rx   ry   r,  `  s    
zOutputGraph.dedup_passc                 C   s0   t || jdd}||_d|_| j||d d |S )NT)Zrequires_suffixFrF  )rV   r   rs   Ztorchdynamo_force_dynamicr  )r   r@  Zsub_gmZ	next_namerx   rx   ry   rS  f  s
    zOutputGraph.install_subgraphc                 C   s   dd | j D }|S )Nc                 S   s   g | ]
}|j qS rx   )example)r   r  rx   rx   ry   r   p  r   z.OutputGraph.example_inputs.<locals>.<listcomp>)r  )r   r   rx   rx   ry   r   o  s    zOutputGraph.example_inputsc                 C   s<   t | jjddddD ] }tt|jdkr| | qd S )Nr  r<  T)reverser   )sortedro   r>  r=  r   usersrv  r   rJ  rx   rx   ry   r.  s  s    z(OutputGraph.remove_unused_get_attr_nodesc                    sd  j s
J tjjddd}tjjddd  fdd}d	d
lm} ttjj	D ]t}t
t|jd	krV|jdks|jdkr|jtju s|jdkr|jtju r||jd	 s||s||rV| qVdd }fdd}t ttjtjf dddg }jD ]}||d u}|r6|js || n|jsZt|jd tsZ|| n|jd }	t|	trtq
t|jd jtjr|jd j}
|jd j}tj j!"|
s
t#|
$ }|% D ]2}t&|j'|}t()tjtjffdd| qƐq
|	j*d ur|	j*n|	j}| q
|D ]6}||}|d ur(|vrR|| n
+| q(d S )N)b_nodec                 S   sf   | du rdS t | tjsdS | jd}|d u r4dS |du r@dS t |tjrb|j  }d urb|S dS )NTFrM  )	r8  r
   NoderK  ra  r   ZSymBoolrJ  Zmaybe_as_bool)rT  brrx   rx   ry   is_static_true  s    
z;OutputGraph.remove_unused_graphargs.<locals>.is_static_true)r$  c                 S   sB   ddl m} t| tttfr dS t| tjr>t| j	d|S dS )Nr   SymTypesTrM  F)
torch.fx.experimental.sym_noderZ  r8  rv   r  r~   r
   rU  rK  ra  )r$  rZ  rx   rx   ry   is_symnode_arg  s    z;OutputGraph.remove_unused_graphargs.<locals>.is_symnode_argc                    sp   ddl m} | jdkrdS t| jd|s0dS t fdd| jD sLdS t fdd| j	 D sldS d	S )
Nr   rY  r\  FrM  c                 3   s   | ]} |V  qd S r   rx   r#  r\  rx   ry   r    r   zWOutputGraph.remove_unused_graphargs.<locals>.is_symnode_compute_node.<locals>.<genexpr>c                 3   s   | ]} |V  qd S r   rx   r#  r]  rx   ry   r    r   T)
r[  rZ  r=  r8  rK  ra  r  r   r   r  )rJ  rZ  r]  rx   ry   is_symnode_compute_node  s    
zDOutputGraph.remove_unused_graphargs.<locals>.is_symnode_compute_noder   )is_accessor_noder  r\  c                 S   s8   | j d }|j}t|tjr4t|jjtjr4|jjS d S NrG  )	rK  rO  r8  r   r  rJ  exprsympySymbol)rJ  r  rO  rx   rx   ry   placeholder_binds_symbol  s    

zEOutputGraph.remove_unused_graphargs.<locals>.placeholder_binds_symbolc                    s<   t d| jd j  | jd=  |   j| d  d S )NzREMOVE UNUSED GRAPHARG %srG  )r   r  rK  rr   r@  rv  rq  r{  rJ  r   rx   ry   remove_unused  s    
z:OutputGraph.remove_unused_graphargs.<locals>.remove_unused)fakec                 S   s   | t |O } d S r   )r   )used_symbolsrg  rx   rx   ry   update_used_symbols  s    z@OutputGraph.remove_unused_graphargs.<locals>.update_used_symbolsrG  c                    s
    | S r   rx   )t)ri  rh  rx   ry   rX    r   z5OutputGraph.remove_unused_graphargs.<locals>.<lambda>),r  r
   rJ  ZArgument%torch.fx.experimental.symbolic_shapesr_  rg  r   ro   r  r=  rR  r=  r  operatorgetitemr   _checkr   rv  r   r	   r  r   r?  r   r8  rK  r`   rO  ZScriptObjectZexample_strong_refZ_libraryZfake_class_registryZtracing_with_realr   Z__obj_flatten__r  r  Zwrapped_objpytreeZtree_map_onlyfake_tensorremove)r   rX  r^  r_  rJ  rd  rf  Zrecheck_placeholdersZbinds_symbolr  Zreal_script_objZfake_script_objZ	flat_dictattrZfake_attr_valrg  symbolrx   )r\  r   ri  rh  ry   r/  x  s    


		







z#OutputGraph.remove_unused_graphargsc                 C   s   ddl m} | jjD ]}|jd}t|tr|jd urt	|jj
jdrtdd |jD r||jj
jjrt|jD ]}|t|j | | qx| | qd S )Nr   )TensorifyStaterM  r@  c                 s   s   | ]}|j d kV  qdS )itemNr  )r   urx   rx   ry   r  %  r   zEOutputGraph.remove_tensorify_specialized_graphargs.<locals>.<genexpr>)torch._dynamo.symbolic_convertrt  ro   r  rK  ra  r8  r   Z	item_memor  rJ  Z_exprr  rR  Zshould_specializer@  r   Zreplace_all_uses_withr   rv  )r   rt  rJ  rM  rv  rx   rx   ry   r0    s&    

z2OutputGraph.remove_tensorify_specialized_graphargs)r?  r   c                 C   s   | j | d| _dS )zt
        We call this on the creation of a new compiled subgraph that is inserted
        before user code.
        TN)r  r^  r  )r   r?  rx   rx   ry   r  0  s    z#OutputGraph.add_output_instructionsc                 C   s6   || j vsJ | j | | jt| j|| dS )a`  
        WARNING: prefer the safer `install_global_by_id/install_global`.
        torch.compile instances should be independent of each other;
        one footgun is to have one instance depend on the existence of
        a global installed by another instance. This can happen if we mangle
        a global the same way across both instances.
        N)r  r   r  r   rN   r[  r   )r   r@  r   rx   rx   ry   r7  8  s    z!OutputGraph.install_global_unsafec                 C   s8   | dt | d| j }|| jv r(|S | || |S )z
        Installs a global if it hasn't been installed already.
        This is determined by (prefix, id(value)) pair.

        Returns the name of the newly installed global.
        r  Z_c)r   r  r  r7  r   r?  r   r@  rx   rx   ry   install_global_by_idD  s
    	
z OutputGraph.install_global_by_idc                 C   s   t |}| || |S )z~
        Installs a global, generating a unique name for it.

        Returns the name of the newly installed global.
        )r-   r7  rx  rx   rx   ry   r:  S  s    zOutputGraph.install_globalc                 C   s   d | _ | j  d | _| jjD ]}d|jv r|jd= q| j  | j  | j	  | j
  | j  | j  | j  | j  | j  | j  d S r`  )r  r   r   r  ro   r  rK  rq  rp  r   r  r  r"  r	  r   r  r%  rS  rx   rx   ry   cleanup^  s     











zOutputGraph.cleanup)r9  r   c                 C   s   | j | d S r   )r  r   )r   r9  rx   rx   ry   add_graph_finalizers  s    zOutputGraph.add_graph_finalizerre  c                 C   s0   |j dkr|jd jS |j dks$J | j|j S )z#Extract the non-fake example tensorr;  rG  r  )r=  rK  rO  r   r  rS  rx   rx   ry   example_value_from_input_nodex  s    
z)OutputGraph.example_value_from_input_node)r<  )N)r  )Fr   )irs   rt   ru   r   r=   rw   r   r   r   r   r(   r~   r   r   r4  r6  r(  r_   rA  r>  r  r   r,  rU  re  r   rf  rh  r   rH  rm  rn  ro   setterrp  rq  rr  rs  ru  rv  r)  contextmanagerr}  r~  r0  r   r   r   r   r   r   r   r!  r  r  r  rP   r  r  rL  r  staticmethodr  r
   Proxyr  r	   r   r   r   r  r  r  r   r  r  r  r  r
  r  r  r  rU  r?  ra   r  r   r'   r(  rB  r,  rS  r   r.  r/  r0  r,   r  r7  ry  r:  rz  r{  r|  r   rx   rx   r   ry   r   Z  s   


 C






	





$


	
 VY   d	
  H

K	 "r   a  With the current config, we will graph break (and fall back to eager-mode PyTorch) on all ops that have do not have the 'pt2_compliant_tag'. Please see the following doc for how to mark this op as PT2 compliant https://pytorch.org/tutorials/advanced/custom_ops_landing_page.htmlc              
      s  |dkrd S  fdd} fdd}t |tjjrbtjj|jv rL|| d S ||d| d d S t |tjjr|t|	 }t
|dkrt||d	 }tjj|jv r|| d S ||d
| d d S tjj j||fd\}}z tjj|jg|R i |}	W n: ty> }
 z tddt|
g d W Y d }
~
n
d }
~
0 0 t||	}tjj|jv rd|| n||d| d|	 d d S )Nr\  c                    s   | j dv rd S  j|  d S )N>   ZprimsZprimaten)	namespacer   r   r  output_graphrx   ry   encountered_compliant_op  s    
z8check_pt2_compliant_op.<locals>.encountered_compliant_opc                    s.    j |  tjr*tdd|d t g d d S )Nz Encountered non-PT2-compliant oprB   rC  )r  r   r#   Zonly_allow_pt2_compliant_opsr5   err_epilogue)r  r|   r  rx   ry   encountered_non_compliant_op  s    
z<check_pt2_compliant_op.<locals>.encountered_non_compliant_opz%Encountered the torch.ops.OpOverload z that is not PT2 compliant.r"   r   z:Encountered the non-overloaded torch.ops.OpOverloadPacket z that is not PT2 compliant. Fz*Error when attempting to resolve op packetrB  rC  z+Encountered the torch.ops.OpOverloadPacket z! which resolves to the overload (z) that is not PT2 compliant.)r8  r   Z_opsZ
OpOverloadTagZpt2_compliant_tagtagsZOpOverloadPacketr   	overloadsr=  r  rO  r   Zget_fake_values_from_nodesr  r  Z_jit_resolve_packetZ_qualified_op_namer   r5   r   )r  kindr  r   r   r  r  r  r=  overloadrM  rx   r  ry   check_pt2_compliant_op  sl    




r  c                   @   s   e Zd Zdd Zdd ZdS )	LazyProxyc                 O   s   || _ || _|| _|| _d S r   )r|  r   r   r   )r   r|  r   r   r   rx   rx   ry   r     s    zLazyProxy.__init__c                 C   s   | j | ji | jS r   )r   r   r   r   rx   rx   ry   r     s    zLazyProxy.__call__N)rs   rt   ru   r   r   rx   rx   rx   ry   r    s   r  c                       s   e Zd ZdZd! fdd	Zdd Zd" fdd		Zd# fd
d	Zdd Zd$ddZ	dd Z
dd Zeeejjf dddZeejejf ee dddZejeej dddZdd Zdd  Z  ZS )%r   a  
    Holds an FX graph that is being traced. OutputGraph owns a SubgraphTracer
    and the separation of responsibilities is that SubgraphTracer is
    responsible for building the graph while OutputGraph is responsible for
    compiling and executing the graph.
    NFc                    s   t    t|| _tj | _|| _	i | _
i | _|| _|| _i | _i | _d | _d| _d| _d| _d| _|d ur||jd nd| _d | _d | _d | _d | _| jd u rg | _n| jj| j||fg | _t | _g | _t rt dd S )NFr"   r   zSInference mode is supposed to be disabled during compilation. Please open an issue.)!r   r   weakrefr  r  r   r
   ZGraphro   r   rp  rq  rw  rx  lifted_freevarsrr  	prev_instZunder_activation_checkpointZ#allow_side_effects_under_checkpointZ,unsafe_allow_externally_visible_side_effectsZis_reconstructing_generatordebug_level	_cur_code_orig_gm_meta_orig_gm_lineno_map_orig_gm_firstlinenosource_fn_stackZ_target_to_strr    _used_names_input_versions_at_beginningZis_inference_mode_enabledr   )r   r  rw  r   rx  r   rx   ry   r     s>    

zSubgraphTracer.__init__c                 C   s   | j r| jr| jr|jj}d }|d ur:| j|| j d }|d ur| j | }tjjD ]}||v rT|| |j	|< qTd|v r|d |j	d< d S )Nstack_trace)
r  r  r  current_instructionstarts_linera  r
   r  Z_COPY_META_FIELDSrK  )r   r  rJ  linenoZnode_idxrK  r   rx   rx   ry   r-  <	  s&    

z,SubgraphTracer._maybe_preserve_original_metac              	      sj  | j d urNt||f\}}	g }
|D ]}| |}|
| q$t|
|	\}}t ||||||| jj	}t
jdkr|dv r|j  | jur jd ur jjd ur|j|j jjd fdd}tdt|  | _d}|j| jur`t|jdd	d
  }t|tjjrNd}dd |jjD | _|j | _!|j"j#j$| _%nd | _d | _!d | _%|j&}|r||' j(j)d< |dv r| j*j(j+fg j(j)d< nh|dkr| j d urt,dd| j- dg d | j*j(j+t.fddj(j)d / D fg j(j)d< | 0|j( |sdj(j)vrJ|j&}|rJ|' j(j)d< dj(j)vr|dv r| j*j(j+fg j(j)d< nR|dkr| j d urt,dddg d | j*j(j+j(j)d  d fg j(j)d< dj(j)vr8g }|r|1 s||2  t3|dd }q|4  t5j67|8 }d9|j(_:tj;j<j=sPtj;j<j>rf| jj?@| jj	j( S )Nr  rC  )r  c                     s(   t   } djj d d|  S )NzTRACE FX call z from r  )rS   rstriprJ  r@  )line)cur_instheaderr8  tx_coderx   ry   get_trace_call_log_str	  s    z;SubgraphTracer.create_proxy.<locals>.get_trace_call_log_strr  FZorig_graphmodulec                   S   s   d S r   rx   rx   rx   rx   ry   rX  	  r   z-SubgraphTracer.create_proxy.<locals>.<lambda>Tc                 S   s   g | ]
}|j qS rx   r@  )r   Zndrx   rx   ry   r   	  s   z/SubgraphTracer.create_proxy.<locals>.<listcomp>nn_module_stack>   rD  r\  r  rE  z4Invoking an nn.Module inside a higher order operatorzHigher order op name: zThis is not supported.rC  c                 3   s,   | ]$\}\}}| d d  kr|V  qdS )@r   N)r  )r   r   r  tyr  rx   ry   r  	  s   
z.SubgraphTracer.create_proxy.<locals>.<genexpr>z2Invoking an nn.Module inside a HigherOrderOperatorrB  r"   r  rw  )Arw  ro  Ztree_flatten#maybe_lift_tracked_freevar_to_inputr   Ztree_unflattenr   rs  r  r  r  r  r  r  Z	positionsr  r.  Zget_line_of_code_headertrace_call_logr  r[   r  r.   Zget_contextra  r8  r   r
   r   ro   r  r  Z_lineno_mapr  r   __code__r   r  r  r   rJ  rK  r  r@  r5   rx  r   r   r-  Zis_co_filename_from_nn_modulesframe_summaryr  rP  r   StackSummary	from_listr  r  r  rO  r#   rN  Ztrack_nodes_for_deduplicationr  Z
track_node)r   r  r  r   r   r@  	type_exprZproxy_factory_fn	flat_argsZ	tree_specZnew_flat_argsr  Zmaybe_new_argr  r  Zis_retracingZorig_graphmodule_mayber  Zframe_summariesZmsgsr   )r  r  r8  r  r  ry   rs  P	  s    +











zSubgraphTracer.create_proxyc           
         s   t | j|||| | jd urZtj|i |}|D ](}t|tjjsDq0|j	| j	ks0J dq0t
 ||||||}	| jj|	jd< | j|	j |	S )Nz2create_node using arg not from this SubgraphTracerr  )r  r  rw  ro  Zarg_tree_leavesr8  r   r
   rU  ro   r   ru  r  rK  r  r   r@  )
r   r=  r  r   r   r@  r  r  r  rJ  r   rx   ry   ru  
  s    
zSubgraphTracer.create_nodec                 C   sz   t |jdkrZg }|j D ]&}|j| jkr|tt|jj q|D ]}|j| qH| j| | j	
|jd  d S ri  )r=  rR  r  ro   r^  rg  r   r  r  rp  r{  r@  )r   rJ  Zuser_graph_nodesuserZother_graph_noderx   rx   ry   rv  
  s    zSubgraphTracer.remove_nodec                 C   sN  t |tjr| j|j td||d ur2| nd|| j	| |d u rh| j
d ushJ d| d| d| jr| j
d u rt|dds| jj|g t  t|| j}| jrtt| j}| j| j}|r| j|}q| j|}n| jd }|< | jd|d	i |d
}	t|	j| | jrP|rP| j \}
}|	| j|< || j|
< n
|	| j|< | j| | j}tj  }|s|st |tjr| !|| nZt |t"t#frt$|D ]@\}}t |tjsАqd }|rt%||dd}| !|| qt |tj&r&t |jj't(j)r&|	| j*|jj'< |	W  d    S 1 s@0    Y  d S )Nz7create_graph_input %s %s %s at debug_level %s before=%sz(none)z0you are required to provide a source for inputs z example_val z on the root tracerT)Zonly_allow_inputr;  rx   r  F)r  r  Zindex_is_slice)+r8  r   r   r  r   _versionr   r  r@  r  rw  r   rD   r  r  
setdefaultr   extract_stackrV   r  rp  r   rg  rJ  ro   Zinserting_beforeZinserting_afterrs  r^   popitemr   compilerZis_compiling_lift_basic_symbolsr   r   r  rA   r  ra  rb  rc  rr  )r   r@  r  rM  beforerr   Z	prev_namerJ  ctxr  r   r   Zis_strict_exportZis_non_strict_exportr  rM  Ze_sourcerx   rx   ry   rI  1
  sp    



z!SubgraphTracer.create_graph_inputc                 C   s   | j d usJ d|jjd }t|tjrF|jj| jv rF| j|jj S || jv rZ| j| S |j	| j krr| j 
| |jjd }| |jjt||}|| j|< |S )NzIlift_tracked_freevar_to_input should not be called on root SubgraphTracerrM  )rw  rJ  rK  r8  r   r  ra  rr  r  r|  lift_tracked_freevar_to_inputrI  r@  r   )r   r  rM  Z	new_proxyrx   rx   ry   r  
  s&    	



z,SubgraphTracer.lift_tracked_freevar_to_inputc                    sX   t |tjjs@t |tr:t fdd|j|j|jfD  S |S n|j krN|S  	|S )z
        If arg is a free variable, then lift it to be an input.
        Returns the new lifted arg (if arg was a freevar), else the
        original arg.
        c                 3   s   | ]}  |V  qd S r   )r  )r   Zsub_argr   rx   ry   r  
  s   zESubgraphTracer.maybe_lift_tracked_freevar_to_input.<locals>.<genexpr>)
r8  r   r
   r  slicestartstopstepr|  r  )r   r  rx   r   ry   r  
  s    


z2SubgraphTracer.maybe_lift_tracked_freevar_to_input)e_proxyc                    s$  |j ttsJ td fdd}fdd}t|tjrt| D ]X\}}||rLt	d|||j
 t||dtjjjj||fi t|d} || qL|jtju rt| D ]X\}}||rt	d	|||j
 t||dtjjjj||fi t|d} || qn|jtju rL | |  | | nj|jtjtjhv r | |  | | n4|jtjtjhv r | |  |  | t!|r |" \}}	|D ]"}
t#||
} |t#||
 qn*t|tj$r ||r |j%j&}|j'|< d S )
Nr   c                    sD   ddl m} || oBt| jjtjoB| jj| jjoB| jj j	vS )Nr   )r   )
rk  r   r8  rJ  ra  rb  rc  r   Zis_unbacked_symintrr  )r  r   r   rx   ry   	need_bind
  s    z8SubgraphTracer.track_unbacked_symbols.<locals>.need_bindc                    s     j |i |}t|j|  |S r   )rs  r^   rJ  )rM  r   r   r  )r|  rx   ry   _proxy_with_example_value  s    zHSubgraphTracer.track_unbacked_symbols.<locals>._proxy_with_example_valuez>_track_unbacked_symbols %s for %s.size()[%s] at debug_level %sr\  r  z@_track_unbacked_symbols %s for %s.stride()[%s] at debug_level %s)(r|  r8  r   r~   r   r   r  r  r   r  r  r  opsr  Zsym_sizerv   r   track_unbacked_symbolslayoutstridedstrideZ
sym_stride
sparse_coo_indices_values
sparse_csr
sparse_bsrcrow_indicescol_indices
sparse_csc
sparse_bscccol_indicesrow_indicesr!   __tensor_flatten__r  r  rJ  ra  rr  )r   rM  r  r  r  r  r  Z
lazy_proxyattrsr  rr  inner_tra  rx   )r   r|  ry   r  
  s    







z%SubgraphTracer.track_unbacked_symbols)rM  srcc           
         s  dt ttjf tt td d fdd}t|tjrt	|
 D ],\}}|||d urdt|tj|nd dd qB|jtju rt	| D ],\}}|||d urt|tj|nd dd q|| |d urt|tjnd dd n|jtju r | |  | | nj|jtjtjhv rD | |  | | n4|jtjtjhv rx | |  | | t |r|! \}}|D ]0}t"||}	 |	|d urt#||nd  qnt|tjr||| d S )NF)r  rr   r  r   c                    st  t | sd S t| tjsJ  | }t|dkr6d S  jd urʈ j| | |D ]t} jj| }|j	j
d }t|tjs~J  jt|t||||d}td||d ur| nd j | j|< qRnt|dksJ d| d|  |d us
J d	|  d
|  dtt|} jt|t| | ||d}td| |d urL| nd j t|| dd dd|j	j
d< d S )Nr   rM  )r  rr   z4_lift_symbols_in_symint %s from %s at debug_level %szsubgraph inputsr"   zyFor root tracer, we only expect to bind basic symbols (compound symbols should be cached before) but got unbound symbols z in zSource of 'z' is None when lifting it to input of top-level. If it's an unbacked symbol, this could be because it's not tracked with lazy_bind_unbacked_symbols. Otherwise, should provide a source when create_graph_input for `z` at root tracer.F)Zpass_arg_as_tensorrp  Z	is_tensorrG  )r   r8  r   r  lookup_unbound_symbolsr=  rw  r  rr  rJ  rK  rI  r   r   r   r  r@  r  r  r   iterra   )r  rr   r  Zself_to_be_bounds0Zparent_proxyZexample_valphr   rx   ry   _lift_symbols_in_symintP  sv    

zCSubgraphTracer._lift_basic_symbols.<locals>._lift_symbols_in_symintT)r  )F)$r	   rv   r   r  r   r   r~   r8  r   r  r  rK   rJ   ZSIZEr  r  r  ZSTRIDEZstorage_offsetZSTORAGE_OFFSETr  r  r  r  r  r  r  r  r  r  r  r  r!   r  r  r>   )
r   rM  r  r  r  r  r  r  rr  r  rx   r   ry   r  I  sj    
 D			


z"SubgraphTracer._lift_basic_symbols)r  r   c                 C   s   |j jj}t|dkrg S g }|D ]f}|| jvr<|| q"| j| }t|tr`| }|| j|< t|tj	j
rx|j| u s"J d| dq"t|dd dS )Nr   zThe proxy of symbol z" doesn't belong to current tracer.c                 S   s   | j S r   r  )r  rx   rx   ry   rX    r   z7SubgraphTracer.lookup_unbound_symbols.<locals>.<lambda>)r   )rJ  ra  r   r=  rr  r   r8  r  r   r
   r  r|  rQ  )r   r  r   Zto_be_boundr  r  rx   rx   ry   r    s     






z%SubgraphTracer.lookup_unbound_symbolsc                    s   | j }g  g }| jjD ]@}|jdkrR|jd }t|tjrV||j	  | q qXqdd t
t||D }t|r fdd|D }d| }td|S tdd	S )
Nr;  rM  c                 S   s    g | ]\}\}}||kr|qS rx   rx   )r   r  Zv1Zv2rx   rx   ry   r     s   
z5SubgraphTracer.has_input_mutation.<locals>.<listcomp>c                    s   g | ]} | qS rx   rx   )r   r  Zinput_nodesrx   ry   r     r   zInput mutation detected at TFrB  )r  ro   r  r=  rK  r8  r   r   r   r  r  r  r=  r   )r   Zinput_versions_at_beginningZinput_versions_at_endrJ  rM  Zmutated_inputsZmutated_nodesr|   rx   r  ry   has_input_mutation  s(    



z!SubgraphTracer.has_input_mutationc           
         s  ddl m} t  | jjD ]l}|jdkr||gd }t|tjrt	|
 }| v rxd |  d| }td|  S | |< q qqt | jjddd }t|jd D ]p}|r||gd }t|trJ t|tjrt	|
 }|v rd	|  d| }td|  S ||< q   @ }t|dkr| fd
d|D }	ddd |	D }	d|	 }td|S tddS )Nr   )_collect_fake_inputsr;  z*Input-to-input aliasing detected at nodes  and Tr~  r<  z,Output-to-output aliasing detected at nodes c                    s   g | ]} | | fqS rx   rx   r  Zinput_storagesZoutput_storagesrx   ry   r      s   z/SubgraphTracer.has_aliasing.<locals>.<listcomp>z, c                 S   s   g | ]\}}| d | qS )r  rx   )r   r  orx   rx   ry   r   #  r   z+Input-to-output aliasing detected at nodes FrB  )Ztorch._higher_order_ops.utilsr  r   ro   r  r=  r8  r   r   r   Z_typed_storagerz   r>  ro  Ztree_leavesr   r   r  r=  r  )
r   r  rJ  rM  Zstorager|   Z	out_nodesZout_nodeZintersected_storagesaliasedrx   r  ry   r{     sB    





zSubgraphTracer.has_aliasing)NFN)NNN)NNNN)FN)rs   rt   ru   r   r   r-  rs  ru  rv  rI  r  r  r	   r  r   r
   r  r  r  r   r   r   r  r   rb  rc  r  r  r{   r   rx   rx   r   ry   r     s.   T    9  
n( d r   )r   r  r)  r   r  r4  r  r%   rl  r  r  r   r  Zdataclassesr   r   r   typingr   r   r   r   r   r	   rb  Ztorch._guardsr   Ztorch._loggingZtorch.distributedZdistributedr  Ztorch.nnZtorch.utils._pytreer   Z_pytreero  r
   r   Ztorch._C._dynamor   Ztorch._dynamo.excr   r   r   r   r   r   r   r   Ztorch._subclasses.fake_tensorr   Ztorch._utils_internalr   r2  r   Z%torch.fx.experimental._backward_stater   rk  r   r   r   r   r   Ztorch.fx.passes.runtime_assertr   Z torch.multiprocessing.reductionsr   Ztorch.utils._ordered_setr    Ztorch.utils._python_dispatchr!   rB  r#   r$   r   r&   Zbackends.registryr'   r(   Zbytecode_transformationr)   r*   r+   r,   r-   r.   r  r/   Zcurrent_scope_idr0   Zdevice_interfacer1   r2   r3   r4   r5   r6   Zgraph_deduplicationr7   Zgraph_region_trackerr8   r9   r:   Zmutation_guardr;   r   r<   r=   rr   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   Zvariables.baser_   Zvariables.builderr`   ra   rb   rc   Zvariables.ctx_managerrd   Zvariables.listsre   Zvariables.miscrf   rg   Zvariables.nn_modulerh   Zvariables.tensorri   rj   rk   rl   Zvariables.torch_functionrm   rw  rn   	getLoggerrs   r   r  ZgetArtifactLoggerZgraph_tabular_logr1  Zgraph_sizes_logr  ZRootGuardManagerrq   rz   r   r   r   r   r   r   r   r   r   r   r   r   objectr   r   r   r   r  r  r  r  r  ZTracerr   rx   rx   rx   ry   <module>   s     @T

"'              5	I