o
    ei                    @   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ZddlZddlZddlmZmZmZ ddlmZmZ ddlmZ ddlmZmZmZmZmZ ddl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	l0m1Z1 dd
l2m3Z3m4Z4 ddl#m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddlEmFZF ddlGmHZH ddlImJZJmKZKmLZLmMZMmNZNmOZO ddlPmQZQ ddlRmSZS ddlTmUZU ddlVmWZW ddlXmYZYmZZZmZ[m\Z\ ddl]m^Z^m_Z_ ddl`maZambZbmcZcmdZdmeZemfZfmgZgmhZhmiZimjZjmkZk ddllmlZl ddlmmnZn ddlompZp ddlqmrZr dd lZmsZsmtZtmuZumvZvmwZw dd!lxmyZymzZz dd"l{m|Z| dd#l}m~Z~mZ dd$lmZ dd%l1mZmZ dd&lmZ dd'lmZmZmZ dd(lmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ dd)l+mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ dd*lmZmZmZmZ dd+lmZ dd,lmZmZ dd-lmZ dd.lmZ dd/lmZ dd0lmZmZmZ dd1lmZ dd2lmZ er8dd3lmZ dd4lmZ dd5lmZ dd6lmZ eeСZe$jҠed7Ze$jҠed8Ze$jҠed9Ze$jҠed:Ze1jZe$jjjZe$jjjZd;ed<eeef d=ed>ef fd?d@ZedAdBG dCdD dDZedAdBG dEdF dFZ	dudGeee$j/edB f  dHee$jjj dB d=ee$jjj fdIdJZejd=efdKdLZeG dMdN dNZdOed=eg ee f fdPdQZG dRdS dSe$jjڃZG dTdU dUZeeef ZeG dVdW dWZeG dXdY dYZeG dZd[ d[ZeG d\d] d]Zd^ed=eeef fd_d`ZG dadb dbeZG dcdd ddeZG dedf dfZdgZdhediedjedkedled=dfdmdnZe Ze doZe!dpZ G dqdr drZG dsdt dte.jZdS )va  
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)Callable	GeneratorSequence)	dataclassfield)CodeType)AnycastOptionalTYPE_CHECKINGUnion)	ParamSpecTypeVar)fxTensor)guards)ShortenTracebackTensorifyScalarRestartAnalysis)CompileContext	CompileIdGlobalContextCheckpointStateSourcetracingTracingContext)FakeScriptObject)is_opaque_type)
FakeTensor)signpost_event)_ConstraintTarget)_make_graph_module)BackwardState)free_symbolsguard_scalaris_symbolicShapeEnvSpecializationuninteresting_files)Target)insert_deferred_runtime_asserts)
OrderedSet)is_traceable_wrapper_subclass   )configexclogging	variables)
CompiledFn
CompilerFn)create_binary_slicecreate_binary_subscrcreate_build_tuplecreate_call_functioncreate_dup_topcreate_instructioncreate_load_constcreate_rot_ncreate_swapInstruction	unique_id)code_context)	PyCodegen)enter_new_scope)get_interface_for_device)BackendCompilerFailed!exceptions_allowed_to_be_fallback	SkipFrameunimplementedunimplemented_with_warning)has_user_objectsindex_to_bytecode_constructor)apply_graph_deduplication)#get_backend_override_for_compile_id+get_inductor_config_override_for_compile_id)GraphRegionTracker)GuardBuilderinstall_guard)is_dynamic_nn_module)AttributeMutationExistingSideEffectsValueMutationExisting)_get_source_debug_name
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compilation_time_metricscount_callscountersdynamo_timedget_chromium_event_logger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)BackwardStateGraphArgGraphArgTrackedFakewrap_fx_proxy)ContextWrappingVariable)ClosureConversionErrorVariableTracker)BaseListVariable)NullVariable)NNModuleVariable)NumpyNdarrayVariableSymNodeVariableUnspecializedPythonVariable)TensorWithTFOverrideVariable)UserDefinedDictVariableDynamoProfilerState)CompilePackage)InstructionTranslatorBase)StorageWeakRefgraph
graph_codegraph_sizes
trace_callcompiler_fnconfig_patchesreturn.c                    sB   ddl m dtdtdtf fdd}t dd	|_ |_|S )
zW
    Wrap a compiler function to apply inductor config patches during compilation.
    r   )r,   gmexample_inputsr   c                    s8      | |W  d    S 1 sw   Y  d S N)patch)r   r   r   r   inductor_config d/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/_dynamo/output_graph.pywrapped   s   $z+_wrap_with_inductor_config.<locals>.wrapped__name__z	<wrapped>)torch._inductorr,   r   getattrr   __wrapped__)r   r   r   r   r   r   _wrap_with_inductor_config   s
   r   T)frozenc                   @      e Zd ZU eed< eed< dS )AliasingInfohas_aliasingmsgNr   
__module____qualname__bool__annotations__strr   r   r   r   r         
 r   c                   @   r   )MutationInfohas_mutationr   Nr   r   r   r   r   r      r   r   tensors_with_sourcesstop_atc           	      C   s   |du rt  }t  }g }| D ]\}}t|tjr$|j}|dur$|| q|rM| }||v r0q%||v r5q%|| |jD ]\}}|durJ|| q=|s'|S )a  Collect all grad_fns reachable from tensors' autograd graphs.

    Performs a DFS traversal and collects all visited grad_fns.
    Optionally stops traversal nodes in stop_at set. This signals the
    autograd.grad boundary.

    Args:
        tensors_with_sources: List of (tensor, source_name) tuples to start search from.
        stop_at: Optional set of grad_fns where traversal should stop (excluded from result).

    Returns:
        Set of all reachable grad_fns.
    N)	set
isinstancetorchr   grad_fnappendpopaddnext_functions)	r   r   visitedstacktensor_r   nodenext_fnr   r   r   collect_reachable_grad_fns   s.   


r   c                   C   s
   t tS r   )torchdynamo_loggingget_step_loggerlogr   r   r   r   _step_logger     
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d	ZdS )GraphCompileReasonzOStores why a given output graph was compiled; i.e. what caused the graph break.reason
user_stackTgraph_breakr   Nc                 C   s   | j r
t|  d S d S r   )r   rn   r   selfr   r   r   __post_init__   s   z GraphCompileReason.__post_init__r   N)r   r   r   __doc__r   r   list	tracebackFrameSummaryr   r   r   r   r   r   r   r     s   
 r   random_callsc                    s   dt t f fdd}|S )Nr   c                      s   dd  D S )Nc                 S   s    g | ]\}}}||i |qS r   r   ).0fnargskwargsr   r   r   
<listcomp>'  s     zE_get_gen_rand_values_fn.<locals>._gen_rand_values.<locals>.<listcomp>r   r   r   r   r   _gen_rand_values&  s   z1_get_gen_rand_values_fn.<locals>._gen_rand_values)r   r   )r   r   r   r   r   _get_gen_rand_values_fn%  s   r   c                       sb   e Zd ZdZdeeejjf ddf fddZ	defddZ
deeejjf ddfd	d
Z  ZS )FakeRootModulez'Trick the constructor of fx.GraphModule
nn_modulesr   Nc                    s,   t    | D ]
\}}t| || q	d S r   )super__init__itemssetattrr   r   kv	__class__r   r   r   /  s   
zFakeRootModule.__init__c                 C   s   dS )NzFakeRootModule(...)r   r   r   r   r   __repr__4  s   zFakeRootModule.__repr__c                 C   s"   |  D ]
\}}t| || qd S r   )r   r   r   r   r   r   add_nn_modules7  s   zFakeRootModule.add_nn_modules)r   r   r   r   dictr   r   nnModuler   r   r   __classcell__r   r   r   r   r   ,  s
    "&r   c                   @   s>   e Zd ZdeddfddZdejjdeej	 de
fdd	ZdS )
WrapperBackendbackendr   Nc                 C   s
   || _ d S r   )r   )r   r   r   r   r   r   =     
zWrapperBackend.__init__r   r   c                 C   s   t || _|| _t| j}| ||| _| jd u s!| j| jju r%| jjS tj	s+| jS z2z$| jjt
| }| jt
| }t||rJ| jW W |   S td|   ty]   td  w |   w )Nzincorrect results of backend zerror in verify_correctness)rb   restorer   copydeepcopyr   	candidateforwardr,   verify_correctnessrd   rt   RuntimeError	Exceptionr   	exception)r   r   r   copy_gmcorrectresultr   r   r   __call__@  s(   




zWrapperBackend.__call__)r   r   r   r1   r   r   r   GraphModuler   r   r0   r   r   r   r   r   r   <  s    r   c                   @   sL   e Zd ZU dZdZeed< dZeed< dZeed< dZ	eed< dd	d
Z
dS )BytecodeTracingTimingsaX  Accumulated wall-clock time (ns) for major components during Dynamo
    bytecode tracing that are not related to variable trackers.  Each field
    is an int accumulator that gets bumped via ``time.time_ns()`` in the
    corresponding hot-path wrapper.  To add a new timer, add a field here
    and wire up the wrapper in the relevant function.r   get_fake_value_nscreate_proxy_ns!wrap_to_fake_tensor_and_record_nsvariable_builder_call_nsr   Nc                 C   s   t  }i }t| D ]-}t| |j}|dkr7|jd}|d || d< t|g |d  t	| |jd q
|rD|j
di | dS dS )zFlush accumulated timings to the bytecode_tracing chromium event
        and to compilation_time_metrics, then reset all counters.r   _nsg    eA_time_sbytecode_tracingN)r  )ri   dataclassesfieldsr   nameremovesuffixre   
setdefaultr   r   try_add_event_data)r   chromium_log
event_datafns_valkeyr   r   r   report_and_resetp  s   z'BytecodeTracingTimings.report_and_resetr   )r   r   r   r   r   intr   r   r   r   r  r   r   r   r   r   c  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	< ejjjjed
< ejjed< eejj ed< dZeed< dZeed< dZeed< dZ ee ed< e!de"fddZ#e!dejjfddZe!deejj fddZ$d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_deviceglobal_state_guard_guards_aotautograd_guardsFexportskip_guards_checkexport_constraintsN%name_of_builtins_dict_key_in_fglobalsr   c                 C   s   t dt|  )Nz%shape_env shouldn't be accessed from )AssertionErrortyper   r   r   r   	shape_env     z OutputGraphGuardsState.shape_envc                 C      | j S r   )r  r   r   r   r   r        zOutputGraphGuardsState.guardsc                 C   r#  r   )r  r   r   r   r   aotautograd_guards  r$  z)OutputGraphGuardsState.aotautograd_guardsc                 C   sD   t | j| j| j| 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  r  r  r   r%  r  r   r   r   r   dump_guards_state  s"   z(OutputGraphGuardsState.dump_guards_state)r   r  )&r   r   r   r   Scoper   r   r   	overridesTorchFunctionModer   r   r   r   r   r  
_functorchpyfunctorchFuncTorchInterpreterr
   device_C_dynamor   GlobalStateGuardr  	GuardsSetGuardEnvExprr  r   r  r  r  propertyr$   r!  r%  r&  r   r   r   r   r    s0   
 r  c                   @   s   e Zd ZU dZdZeed< eedZ	ee
ef ed< 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
    r   	num_stackdefault_factorylocals_namesstack_null_idxeslocals_null_keys.stack_ctx_argsstack_ctx_idxes_origlocals_ctx_argsN)r   r   r   r   r5  r  r   dc_fieldr   r8  r   r   r9  r:  r;  tupler   r<  r=  r   r   r   r   r4    s   
 &*r4  c                   @   s   e Zd ZU eedZeeedB f ed< eedZ	eee
eef f ed< ejjjZeejjjejjjf ed< eedZeeeeeejjjejjjf f f ed< dS )ExportMetaDatar6  Ngraph_input_idx_to_local_sourceoutput_return_typeout_specmodule_call_spec)r   r   r   r>  r   rA  r  r   r   rB  r?  r   r   r   utils_pytree
_LEAF_SPECrC  r   TreeSpecLeafSpecrD  r   r   r   r   r@    s   
 "r@  r  c                 C   s   | d }t |ts|j}|S )N__builtins__)r   r   __dict__)r  
f_builtinsr   r   r   get_builtins_dict  s   
rM  c                       s   e Zd ZdZ				ddedeeeef  dee dee	 deee
ee f  ddf fd	d
ZedefddZddededdfddZ  ZS )OutputGraphCommona  
    A minimal interface for full graph capture. It is intended to be
    the target of any tracer that feeds into backends.

    Currently dynamo's OutputGraph is the only known implementation
    of this interface, used by (aot) precompile and (strict) export.
    Importantly, that implementation also contains many other fields
    that are using during tracing but not included in this interface
    because they are not used once tracing is complete.

    It should be safe to assume that (caching) precompile also uses
    this interface.

    In the future, we want make_fx, used by (non-strict) export, to
    also implement this interface.

    The serializable part of this interface is OutputGraphGuardsState.
    We do not need to serialize other parts; however it will pay to
    be disciplined about what those other parts are, especially since
    we want other tracers to be able to meaningfully implement them,
    and we should generally try to cut them down when possible.
    Noutput_graph_guards_stateimport_sourcesr!  export_metadatatracked_fakes_id_to_sourcer   c                    sv   t  |j|j|j|j|j|j|j|j	|j
|j|j|j|j|j|j |p&i | _|p,t | _|p2t | _|p7i | _d S r   )r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rP  r$   
_shape_envr@  rQ  rR  )r   rO  rP  r!  rQ  rR  r   r   r   r     s,   
zOutputGraphCommon.__init__c                 C   r#  r   )rS  r   r   r   r   r!  <  r$  zOutputGraphCommon.shape_env r   r   c                 K   s   t r   )NotImplementedErrorr   r   r   r   r   r   bypass_package@  s   z OutputGraphCommon.bypass_packageNNNNrT  )r   r   r   r   r  r
   r   r   r$   r@  r  r   r   r   r3  r!  r   rW  r   r   r   r   r   rN    s,    & rN  c                   @   s  e Zd ZU dZeed< 	ddeeef de	e
 ddded	ee d
ededededeejj de	d deddfddZdededefddZdededdfddZdddZddd Zdefd!d"Z	#dd#ed$edeeejjf fd%d&Z dejjfd'd(Z!dd)d*Z"de	ee  fd+d,Z#d-e$d.ef d/eed.f defd0d1Z%d-e$g ef ddfd2d3Z&dd4d5Z'e(dd7d8Z)e(dd9d:Z*defd;d<Z+e(dejj,fd=d>Z-e-j.d?ejj,ddfd@d>Z-e(deeejf fdAdBZ/e(deej0ej1f fdCdDZ2e(dee3j4e5ejjdEf f fdFdGZ6d/edHedejjfdIdJZ7d/edHedejj0fdKdLZ8d/edHeddfdMdNZ9e:j;	ddOe	e< dPe	d6 dQe	e de=dR fdSdTZ>e(ddUdVZ?e(dej@jAfdWdXZBe(deCfdYdZZDe(dejEjFfd[d\ZGe(deeef fd]d^ZHe(deejEjI fd_d`ZJ	ddae	eeee$d.ef ef f  ddfdbdcZKddedfZLddgdhZMe(ddidjZNdeOfdkdlZPdefdmdnZQdefdodpZRdqede5ejSjTef fdrdsZUdduedefdvdwZVdueddfdxdyZWeXdzedefd{d|ZYd}ed~edejfddZZde5ejSjTej1ef dzededefddZ[ddddeee\ eeef f fddZ]ddddeOdeee e^f fddZ_	ddddde`deOdee^ fddZaddddebddfddZcddddee debdeddf
ddZddddZeddedHeddfddZfdeeee5eOef  f fddZgduedefddZhe:j;defddZidddZjded dddddfddZkddddee deldee\ fddZme(deej0 fddZne(deeo fddZpdejqdee1 derfddZsdejqdee1 derfddZtdeeejjqf fddZuduedejjqdefddZvdeej1 fddZwdddZxdddZydddZzd$ee\ ddfddZ{dued?eddfddÄZ|d$ed?edefddńZ}d$ed?edefddǄZ~dddɄZde$ejqgdf ddfdd̄Zdejj0defddτZdejSjTdeddfddӄZdS )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_effectsFcode_optionsr   root_txr   r  r  frame_stater  r  f_coder  packager   	one_graphr   Nc                 C   s  t j| |||
t i tjjjtjj	 tj
jjtjjjp!tjjj tj g d t| |dg| _i | _g | _|| _|| _|| _g | _tt| _t | _ |	j!|	j"|	j#d| _$t% | _&g | _'t(| j'|pdt)j*|pht)j+t)j,| j$d}dd l-m  m)} |j.dd tj/j0|t1| j| jd}W d    n1 sw   Y  t2|| _3| j3j45|	 | j3j4| _4t67 | _8| 9  t:;t<| _=i | _>t?| | _@i | _Ai | _BtCD | _EtF|| _Gg | _Hd| _Ig | _J|| _K|| _Ld | _M|| _Ni | _Og | _Pg | _Qd| _Ri | _StjT | _Ud| _Vt | _Wti | _Xti | _Y| Z  i | _[g | _\d | _]g | _^i | __d | _`d | _a| b | _ctde | _ftg | _h| i | _ji | _ktl | _mtn | _oi | _pd S )	N)r  r  r  r  r  r  r  r  )	is_export)co_nameco_filenameco_firstlineno)tracked_fakesallow_scalar_outputsallow_dynamic_output_shape_ops+prefer_deferred_runtime_asserts_over_guards	co_fieldsr   F(fake_tensor_allow_unsafe_data_ptr_access)r!  allow_non_fake_inputsr  )qr  r   r   r   autograd
forward_ad_current_levelr*  r+  #retrieve_all_functorch_interpretersrE  _deviceCURRENT_DEVICEr/  convert_frameinitial_global_stater.  r   r0  r  r1  SubgraphTracertracersinput_source_to_varleaf_var_creation_orderr  r  r^  cleanup_hooksnext_compile_id_counter
compile_idinstalled_globalsrc  rd  re  rj  rK   region_trackerrf  r$   r,   capture_scalar_outputs capture_dynamic_output_shape_opsri  torch._functorch.configr   _subclassesFakeTensorModer   r   tracing_contexttraced_coder   r   current_compile_iddynamo_compile_idinit_ambient_guardscollectionsdefaultdictr   rR  param_name_to_sourcerP   r[  variable_tracker_cachesignature_cache	itertoolscountunique_var_idr   r\  output_instructions	timestampregister_finalizer_fnsr   r]  profiler_stater`  source_to_user_stacks_current_txcleanupsshould_exitunspec_variable_map_is_torch_function_mode_enabledtorch_function_mode_enabled!has_user_defined_allowed_in_graphautograd_grad_consumed_grad_fns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_fglobalsr  
contextlib	ExitStackcompiler_trace_stackr   bytecode_tracing_timings+maybe_install_saved_tensors_hooks_subgraphs"saved_tensors_hooks_subgraph_namesrP  r@  rQ  r)   "used_inlined_inbuilt_modules_namesattr_source_cache)r   r\  r   r]  r  r  r^  r  r  r_  r  r`  ra  r!  _config	fake_moder   r   r   r   T  s   











zOutputGraph.__init__basepathc                 C   s   | d}||d f}|| jvrt||d | j|< | j| }|dd  D ]}||f}|| jvr8t||| j|< | j| }q%|S )N.r   r+   )splitr  rS   )r   r  r  partsr  r   partr   r   r   get_chained_attr_source>  s   



z#OutputGraph.get_chained_attr_sourcer\   c                 C   s@   | dd}t|dkrt||S | ||d }t||d S )Nr  r+   r   )rsplitlenr\   r  )r   r  r  r  intermediate_baser   r   r   get_chained_param_buffer_sourceK  s
   
z+OutputGraph.get_chained_param_buffer_sourcec                 C   sd   | j tddd tjr0ddlm} | jd u r| | _| jj	}| j
|j|j|jt  d S d S )Nr  Tlog_pt2_compile_eventr   r   )r  enter_contextrh   r,   dynamo_profilertorch._dynamo.dynamo_profilerr   r  r]  r_  pushrc  rd  re  timetime_ns)r   r   coder   r   r   mark_bytecode_tracing_startT  s$   
z'OutputGraph.mark_bytecode_tracing_startc                 C   s   | j   | j  tjra| jd urcddlm} | j	 }t
 }|d urN||j }||j }||j|j|j||t| jjjdd d d |jdd}| j| d }ttjtrYtj}| j| d S d S d S )Nr   )FunctionTraceTimingr   )	func_namefilenamefirstlineno
cumtime_ns
tottime_nsbytecode_countinline_depthcaller_func_namecaller_filenamecaller_firstlinenois_primitive_call
call_stack)r  r  r  closer,   r  r  r  r  r   r  r  start_time_nschild_time_nsr  r  r  r  r]  r_  co_coder  record_timingr   r   
dump_stats)r   r  stack_entrytrace_end_nsr  r  timingoutput_filer   r   r   mark_bytecode_tracing_stopi  s:   




z&OutputGraph.mark_bytecode_tracing_stopc                 C   s   t | j}| d|S )N__builtins_dict__)rM  r  install_global)r   rL  r   r   r   r    s   
z-OutputGraph.install_builtins_dict_in_fglobalshookprefixc                 C   s6   | t | j }|| jvsJ || j|< ||  fS r   )r  r  get_backward_state_proxy)r   r  r  r  r   r   r   add_backward_state_hook  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 exportrT  z3Compiled autograd doesn't work with `torch.export`.gb_typecontextexplanationhintsdynamo_backward_statesourcegrapharg)r  r  rD   r    root_tracercreate_graph_inputr   rT   rv   r   metanew_varr  )r   example_valuer   r   r   r    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
 | j t tj tjj }|d urW| j t tj tjjjsi| j t tj d S d S r   )r   r   r]   
make_guardrL   	SHAPE_ENVrW   DETERMINISTIC_ALGORITHMS	GRAD_MODEDEFAULT_DEVICEGLOBAL_STATETORCH_FUNCTION_STATEr   r.  r*  peek_interpreter_stackFUNCTORCH_STACK_MATCHr/  compiled_autogradin_compiled_autograd_regionAUTOGRAD_SAVED_TENSORS_HOOKS)r   cir   r   r   r    s,   
zOutputGraph.init_ambient_guardsc                 C   s   t jjjrd S t jjjj}t jjjj}| }||sd S |\}}| 	dt j
| j|j}| 	dt j
| j|j}|dks@J |dksFJ ||gS )Nsaved_tensors_hooks_packsaved_tensors_hooks_unpacksaved_tensors_hooks_pack_0saved_tensors_hooks_unpack_0)r   r/  r  r  r*  _aot_autogradrE  top_saved_tensors_hooks"saved_tensors_hooks_are_inlineableinstall_subgraphr   r   r   r   )r   	get_hooksare_inline_hookshookspack_gm	unpack_gmpack_subgraph_nameunpack_subgraph_namer   r   r   r    s(   

z7OutputGraph.maybe_install_saved_tensors_hooks_subgraphsr   .r   c                    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   )load_import_fromr   r   r   cgr   r   r   <lambda>  s    z3OutputGraph.synthetic_graph_input.<locals>.<lambda>F)r  r>   r]  add_push_nullforeachmapr/   ConstantVariablecreatecall_functionr  storer  extendget_instructionsr^   r|   buildrealizer   getguards_contextdynamo_guardsremove_guards_with_source)r   r   r   r  varnamer  r   r   r  r   synthetic_graph_input  s"   

z!OutputGraph.synthetic_graph_inputc                 C      | j | d S r   )rz  r   )r   r   r   r   r   add_cleanup_hook     zOutputGraph.add_cleanup_hookc                 C   s$   t | jD ]}|  q| j  d S r   )reversedrz  clear)r   r  r   r   r   call_cleanup_hooks  s   zOutputGraph.call_cleanup_hooksrv  c                 C   
   | j d S Nr   rw  r   r   r   r   r    r   zOutputGraph.root_tracerc                 C   r+  Nr-  r   r   r   r   current_tracer  r   zOutputGraph.current_tracerc                 C   s   t | jdkS )Nr+   )r  rw  r   r   r   r   is_root_tracer     zOutputGraph.is_root_tracerc                 C      | j jS r   r0  r   r   r   r   r   r        zOutputGraph.graphvaluec                 C   s   || j _d S r   r4  )r   r6  r   r   r   r     s   c                 C   r3  r   )r0  input_name_to_proxyr   r   r   r   r7     r5  zOutputGraph.input_name_to_proxyc                 C   r3  r   )r0  real_value_cacher   r   r   r   r8  $  r5  zOutputGraph.real_value_cache	LazyProxyc                 C   r3  r   )r0  bound_symbolsr   r   r   r   r:  (  r5  zOutputGraph.bound_symbolsr   c                 O      | j j|i |S r   )r0  create_proxyr   r   r   r   r   r   r<  2     zOutputGraph.create_proxyc                 O   r;  r   )r0  create_noder=  r   r   r   r?  5  r>  zOutputGraph.create_nodec                 O   r;  r   )r0  remove_noder=  r   r   r   r@  8  r>  zOutputGraph.remove_nodesource_targetprior_tracerdescription)rv  NNc                 c   s    t  }z6|r|j| ju sJ |  |r|nt| | j|| jj|d}| j| |V  W |d d d  | j	  d S |d d d  | j	  w )N)parentrA  rb  rC  )
r?   rD  r0  	__enter__rv  rb  rw  r   __exit__r   )r   rA  rB  rC  new_scope_ctxtracerr   r   r   	subtracer;  s,   zOutputGraph.subtracerc                 C   s   | S r   r   r   r   r   r   outputY  s   zOutputGraph.outputc                 C   s   | j jd usJ | j jS r   )r  r  r   r   r   r   r  ]  s   zOutputGraph.fake_modec                 C   s,   | j jd usJ | j jjd usJ | j jjS r   )r  r  r!  r   r   r   r   r!  b  s   
zOutputGraph.shape_envc                 C   
   | j jjS r   )r  r   r!  r   r   r   r   r   h  r   zOutputGraph.guardsc                 C   rK  r   )r  module_contextr   r   r   r   r   r   l  r   zOutputGraph.nn_modulesc                 C   rK  r   )r  r   r%  r   r   r   r   r%  p  r   zOutputGraph.aotautograd_guardsoutc                 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_enabledcudaautocast_enabledcpuautocast_cpu_enabledautocast_gpu_dtypeautocast_cpu_dtypeautocast_cache_enabled)r	   r   r   r?  r   r   r   r  global_contextglobal_stater   set_grad_enabledis_grad_enabled	functoolspartialset_autocast_enabledis_autocast_enabledset_autocast_dtypeget_autocast_dtypeset_autocast_cache_enabledis_autocast_cache_enabled)r   rM  rW  r   r   r   r  t  s,   	zOutputGraph.save_global_statetxc                 C   r%  r   )r  r   )r   rb  r   r   r   push_tx  r'  zOutputGraph.push_txc                 C   s
   | j  S r   )r  r   r   r   r   r   pop_tx  r   zOutputGraph.pop_txc                 C   s   | j s| jS | j d S r.  )r  r]  r   r   r   r   
current_tx  s   zOutputGraph.current_txc                 C   s
   t | jS r   )rf   r   r   r   r   r   rf     r   zOutputGraph.count_callsc                 C   s   t t| jjdkS r,  )r  r   r   nodesr   r   r   r   is_empty_graph     zOutputGraph.is_empty_graphc                 C   s   t dd | jjD dkS )Nc                 S   s   g | ]	}|j d kr|qS )rJ  opr   xr   r   r   r         z+OutputGraph.has_outputs.<locals>.<listcomp>r   )r  r   rf  r   r   r   r   has_outputs  s   zOutputGraph.has_outputskeysc                 C   s@   |sJ | j }|dD ]}t|tr|| }qt||}q|S Nr  )r   r  r   r   r   )r   ro  objr   r   r   r   get_submodule  s   

zOutputGraph.get_submoduletmpr  c                 C   sF   t | jd }	 | dt| j }||vr"| jd  |f7  < |S q)Nco_varnamesTr   )r   r\  r{  r  )r   r  existingvarr   r   r   r    s   zOutputGraph.new_varc                 C   s*   || j d vr| j d  |f7  < dS dS )z/Ensure self.code_options.co_names contains nameco_namesN)r\  )r   r  r   r   r   update_co_names  s   zOutputGraph.update_co_namesnamesc                  G   sr   d tt| }tdd|}tdd|}tdd|}tdd	|}td
d|}|r3|d  s7d| }|S )Nr   z9\._(?:modules|parameters|buffers)\[(['\"])([^'\"\]]+)\1\]z.\2z2getattr\(\s*([^,]+?)\s*,\s*(['\"])([^'\"]+)\2\s*\)z\1.\3z^[GL]\['?(.*?)'?\]$z\1z	\[(\d+)\]z_\g<1>z[^a-zA-Z0-9]r   sub)joinr  r   rerz  isalpha)ry  r  r   r   r   module_key_name  s   zOutputGraph.module_key_nameattr_prefix
attr_valuec                 C   sx   t |tjjr!| j D ]\}}||u r | d|di }|  S qt|| j}|| j|< | d|di }t|j	| |S )Nget_attrr   )
r   r   r   r   r   r   r<  rm   ru   r   )r   r  r  r  modproxy	attr_namer   r   r   %register_static_attr_and_return_proxy  s   
z1OutputGraph.register_static_attr_and_return_proxytargetoptionsc           
         s  t jrtjjfi S tdv sJ d ttr&J ttj	rFj
 s6jdtdtffdd}nWttjjrzttjjsVJ rmttj dtdtffdd}n0dtdtffdd}n#ttjtjfrdtdtffdd}ndtdtffd	d}j D ]\}}|u r||  S qtj|  t jj j < ttjjrd
tdd f fdd}tdr D ]\}}	|| qtdr D ]\}}	|| q| S )Nr  
module_keyr   c                    s   j d usJ j | < jd usJ jjjv r!jjj S tdkr5tts5tt	j
 ntsAtt	j tjd| di fdi }jjj|}d| jjvsfJ t| jjd< |S )Nguardedr  r   r  tensor_dict)r  r]  rJ  r[  rl   r   r[   rM   r  rL   ID_MATCHrX   TENSOR_MATCHry   r<  track_object_existingas_proxyr   r  ra   )r  vt)r  r   r  r  rH  r   r   	wrap_name  s.   
	z6OutputGraph.register_attr_or_module.<locals>.wrap_namec                    s   t t| fi  S r   )r   r   r  r  r  r   r   r  8  s   c                    s   t jfi  S r   )r/   UnspecializedNNModuleVariabler  r  r   r   r  A  r"  c                    s&   t jjd| di fdi S )Nr  r   sym_num)r   r  r]  r<  r  )r  r   r  r   r   r  M  s   c                    s*    j |   j| < t t| dS )N)source_name)rJ  rx  r  r|   r  rU   r  )r   r  r   r   r  X  s   
	leaf_namec                    V   j d usJ | }  d|  }|j |< ttr)| jt|j< d S d S rp  r  r  r   rZ   r  rZ  r~  r  r  
new_sourcenew_namer  r   r  r   r   register_leaf_namek     


z?OutputGraph.register_attr_or_module.<locals>.register_leaf_name_parameters_buffers)rN   r  r|   r  re  r   r   r\   r   r   r0  r1  r  r   r   r   rM   r  rL   	NN_MODULESymIntSymFloatr   r   rZ  r~  rm   r  hasattrnamed_parametersnamed_buffers)
r   r  ry  r  r  r   r   r  r  r   r   )r  r  r   r  r  rH  r   register_attr_or_module  sH    "		





z#OutputGraph.register_attr_or_modulec                 C   s  | j d}t|}|sg i fS g }i }g |j|j | jj }|rt|	 }t
|tr=t
|jts7J ||j7 }q$|| jjvsIt
|jtr]t
|jtr]t
|jjtr]|jjj|v s^q$|jjj}||vrkg ||< || | |s&i }	i }
| jD ]p}t
|jtrt
|jtr|jj|v sq{|jj}|| jd v sJ || D ]I}|j|
v rq|jd usJ |jj}||	vr| | d}||	|< |td|dt|t td|dg |jd usJ |j}t|	| |
|< qq{||
fS )Nr   rt  _ref	LOAD_FASTargval
STORE_FAST)r  r  rk   r   symbolic_localsvaluesr[  store_attr_mutationsro  r   r   r}   r   r   mutation_typerO   r  rV   r  rZ   
local_namer   	graphargs_exampler\  indexr  r  r7   r8   r3   )r   rb  maybe_gmstolen_list_namesalias_instsneeds_aliasqueuerl  stolen_namer   overridden_sourcesarg	list_namelist_idx
alias_name
old_sourcer   r   r   handle_aliases_for_stolen_lists  s   












"z+OutputGraph.handle_aliases_for_stolen_lists
stack_popsc                 C   s  |   g }t }dtddfdd}t|jD ]]\}}t|j| |k}tjj||d t	|tj
s8t|| |r@|| qt	|trL|j| n|| t	|trt|jdu r]dnt|j}	|jt|d |	f |j| qt||_t| |  }
|j D ]b\}}t|| t	|jtr|jj|kr|| ju rq||
v rqtjd	krt !t|r|j"| qnt !t|rJ t|j#|j#|< t	|tr|jdu rdnt|j}	|j$||	f || 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
            - meta: locations of NULLs and ContextWrappingVariables in the stack/locals
                (ignores the top `stack_pops` values on the stack)
        rv  r   Nc                 S   s   t tj| rtdd S )NzCAttempted to reconstruct WithExitFunctionVariable outside the stack)r   __instancecheck__r/   WithExitFunctionVariabler  )rv  r   r   r   ctx_exit_check  s
   z@OutputGraph._get_stack_values_to_restore.<locals>.ctx_exit_check)allow_lazy_constantr   r+   )      )%prune_dead_localsr4  r|   	enumerater   r  r/   LazyVariableTrackerrealize_allr   r  visitr   r~   r9  rz   target_valuesr?  r;  r<  r5  r   cellvarsfreevarsr  r   r  rZ   r  r]  sysversion_infor   r  r:  r8  r=  )r   rb  r  stack_valuesr  r  ir6  r  r  cell_and_freevarsr   r   r   r   r   _get_stack_values_to_restore  s^   






	


z(OutputGraph._get_stack_values_to_restorer   r   c           7   
   C   s  | j dusJ tjs| j |u sJ |   || _d| _td| g }tj	dkrL| j j
D ]}|jdkrC|tdt| j jd d q,|t| q,g }g }|}|durtdd	 |jD sbJ | |||u rk|nd
\}	}
||	 ||
 t|jD ]
}|j||jd q|j}|dusV| j| | | | jr| jrJ d| | j | | j \}}| | |   d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 }d}d}| j |u r|rtdd	 |D rtdd	 |D rtt.|t|kr| j/ r|j0s| j1s|d j2s|d j3st)| j }| 4|| | g | 5|t6t|||7 t8dtdt|d nc| %d}t)| j |||d}| 9|||d i }|j:  D ]\}}|dkrt;|t<t=fsd||< qt)| j ||||d}| 9|||d t>j?jj@r|rt|dkr|d
 }tA|t>j?jBjCr|jDt>j?jEjFu r|j d
 }|j d } tA|t>j?jBjGsJ i }!|jHI D ]}"tA|"t>j?jJjKs&J |"jL}#|"jM|!|#< qtN|j D ]N\}$}||!v rJd|!| f| jOjP|$< q5|jQduritR|jQd d }%ri|%jSrid!|jQf| jOjP|$< q5|T rzd"|U f| jOjP|$< q5tVd#| d$|$ z| U | jO_WW n! tXy }& ztYd%d&|  d'd(d)g|&d* W Y d}&~&nd}&~&ww g }'tZ| j[d
kst|jHd
kr|'*| 5||\ | t|jHd
kr|'|-| d}n|'td+ n| ]  | |'|7   | td,t||d
 j^ dg d
}(d
})tN|D ]\}*}
t|
j_}+|*d
kr |+|
j^7 }+|+d
kr4| td,d
dgt8d n|)|+7 })| t` gta|(|)t8d |(|+7 }(|*t|d krt)| j },i }-| j jb  D ]&\}.}/tA|/jQt=r|/jQjc|.kr|,d|,e|. t|
j_t|- |-|.< qb| |,7 td,t|-dtd-ddg  |
j_f|- q| td+td,t|dgtg|d
 j^d  |r|r| td.|d/g t>j?jjhd0v rqd
d1limj}0 g }1| jk D ]j}2tl|2d2rL|2jm}3tA|3tntofrLtA|2tpr:tA|2jq|0r:|2j   D ]1\}.}/i }4|/j   D ]\}5}|U |4|5jrU < qd3d4gt6|4s ks/J |4| jOjt|.jrU < qtA|2tprGtA|2jq|0sL|1|2 qd5d |1D }6|6rqt>j?jjhd6krjtuvd7|6  |S twd7|6 |S )8a  
        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     COPY_FREE_VARSco_freevarsr  c                 s       | ]}|  V  qd S r   )can_restore)r   blockr   r   r   	<genexpr>~      z/OutputGraph.compile_subgraph.<locals>.<genexpr>r   )is_graph_breakz)export does not support pregraph_bytecodec                 S   s   i | ]	\}}|t |qS r   )rs   )r   r  r  r   r   r   
<dictcomp>  s    z0OutputGraph.compile_subgraph.<locals>.<dictcomp>r+   disablerandom_valuesz.do not trace into Dynamo rng recovery functionr   __gen_rand_values)r  Fc                 S   s   g | ]	}|D ]}|qqS r   r   )r   valsvalr   r   r   r     rm  z0OutputGraph.compile_subgraph.<locals>.<listcomp>c                 s   s:    | ]}t |tttf ot |to| tu  V  qd S r   )r   r   r   r   r   python_typefloat)r   r   r   r   r   r    s    

c                 s   r  r   )	is_tensorrk  r   r   r   r    r  r/     UNPACK_SEQUENCE	graph_out)tempvarsr  r  inputconstantzEncountered unrecognized type z at output z8nested function with non-constructible closure in outputz as_python_constant for out_spec zCannot return a nested function with closure from a compiled function. Dynamo failed to construct the function defined in the compiled region with closure objects.zGDefine the function at module scope instead of inside another function z0Ensure that all closure variables are constants.)r  r  r  r  from_excPOP_TOP
BUILD_LISTLIST_EXTENDDELETE_FASTr  )warnerror)_ExportModuleSpecTrackerDictr  in_specrC  c                 S   s   g | ]}t |jqS r   )rR   r  )r   rv  r   r   r   r     s    
r  zWhile compiling, we found certain side effects happened in the model.forward. Here are the list of potential sources you can double check: )xr]  r,   nested_graph_breaksr  compile_subgraph_reasonr  r   debugr  r  prefix_instsopnamer   r7   r  r\  r   allblock_stackr  r(  exitr   rD  r[  prune_dead_object_newadd_output_instructionsr  r  r  cleanup_graphr   r   r   
decoratorsr  r   r  r  r   r  r>   r  load_function_namer5   create_storer   is_emptydebug_localsr  r9  r:  codegen_cellscompile_and_call_fx_graphr   r  r:   codegen_suffixusesrp   r^   rZ   r   r/  log_graph_in_out_metadatar   r/   NamedTupleVariable	tuple_clsfunctional_exportExportTracerOutputListVariablegraph_outputsr  codegenGraphOutputEntryvariabler  r  rQ  rB  r  r   is_inputis_python_constantas_python_constantr  rC  r{   rD   rf   r   graph_output_varsrun_compiler_collectiver5  r8  r6   r2   r  r  append_outputcreate_loadupdater9   side_effect_replay_policytorch.export._tracer  _get_modified_varsr  r  rO   rQ   r   r6  r  ro  rD  warningsr  r   )7r   rb  r   r  r  install_stack_valuesall_stack_locals_metascur_txr  r  r  r  r  nn_modules_proxiesrootr  random_calls_instructionsrand_fnrand_fn_namer  stack_values_flatstored_graph_output_vargraph_output_varcell_cgpass1r  r  r  pass2r  flat_returnsrC  vt_to_graph_out_idxr6  r  idxr  erJ  	start_idxend_idxr  n_valsroot_cgunmodified_locals_namesr   r   r  potential_side_effectsrv  mut_typespecsk_specside_effect_refsr   r   r   compile_subgraphE  sV  

















 	












zOutputGraph.compile_subgraphr  c                 C   s   | j jrRd}|}|d urGtt| }|D ]}|| ju r&||| q|js+J ||j|  q|t	t
| |j}|d7 }|d us|td|d d S |tddd d S )Nr   r+   r  r  )r  r   r?  sortedr  r]  r  create_load_closurepost_prune_cell_and_freevarsr4   r  rD  r7   )r   rb  r  tx_cntr)  r  cellr   r   r   r    s    

zOutputGraph.codegen_cellsr  log_side_effectsc           	         s   | j   | jr1| jrJ | j D ]\}} | | jd us"J   | j  | qt	j
r:| j   |jD ])\}  fdd |D ]} | qM tt|d  tdg q=| |   j||j d | j  | d S )Nc                      s    S r   r   r   r  	debug_varr   r   r  A  s    z,OutputGraph.codegen_suffix.<locals>.<lambda>Fr  )value_from_source)r[  codegen_save_tempvarsr  r  r   r  r  r   
store_attrr,   replay_side_effectscodegen_hooksr  r  extend_outputr5   r  r7   r  restore_stackcodegen_update_mutated)	r   rb  r  r  rI  r  r  r   r  r   rJ  r   r  )  s&   


zOutputGraph.codegen_suffixc                 C   s   | j sJ t| jj}|D ]	}|jdd qt }t	|D ]@\}}|j
tjju r`t|j| fkr`|js`|jd }|j
tjju r`t|j| fkr`|js`|jd }| j| | j| q d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   rf  r  r   r   rY  r  pairwiser  r.  _set_grad_enabledr?  r   _erased
erase_node)r   rf  r   rN  node1node2r   r   r   r  M  s(   


zOutputGraph.cleanup_graphrT  c                    sd   | j sdS tjjjrtjjdtd tj	j
ddd  fddd | j   d| _ dS )zE
        Do not save this output graph to the CompilePackage
        NzDetected a package bypass: %sartifactc                   S   
   dddS )Nprecompile_cache_bypassjsonr  encodingr   r   r   r   r   r  x     z,OutputGraph.bypass_package.<locals>.<lambda>c                      s   di S )N_reasonr   r   r   r   r   r   r  |  s   metadata_fn
payload_fn)r`  r   r/  r,   strict_precompiler-   PackageErrorr   warning_loggingtrace_structuredbypass_current_entryrV  r   rc  r   rW  k  s   


zOutputGraph.bypass_packagec                 C   sN   i }| j jD ]}|jdd }t|tjjr$| }dd |D ||j	< q|S )Nr  c                 S   s"   g | ]}t |tr|nt|qS r   )r   r  reprr   sr   r   r   r     s   " z:OutputGraph.get_graph_sizes_structured.<locals>.<listcomp>)
r   rf  r  r  r   r   r  r   sizer  )r   retr   r  rp  r   r   r   get_graph_sizes_structured  s   z&OutputGraph.get_graph_sizes_structuredc           	      C   s   d}|d| d7 }| j jD ]U}|jdd }t|tjjrc| }||j	 dt
| d7 }g }d}|D ]}t|trB|| q5t|tjrRd}||jj q5 n|rc||j	 d	t
| d7 }q|S )
NzTRACED GRAPH TENSOR SIZES
z===== z =====
r  z: 
FTz (concrete): )r   rf  r  r  r   r   r  r   rp  r  r?  r  r   r  r   hint)	r   r  graph_sizes_strr   r  rp  concrete_size
has_symintszr   r   r   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| dS | j jt| w )zj
        Momentarily restores the global state to what it was prior to tracing the current output
        )rM  N)r  rV  copy_graphstater  restore_graphstater   )r   prior_global_statecurrent_global_stater   r   r   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sAJ dd	|t| | tj  1 td
dd d g|  }tj| j|d | _W d    n1 svw   Y  W d    n1 sw   Y  |j  tjd S d S )Nzcompiler_collective %sr[  c                   S   r\  )Ncompiler_collectivestringr_  r   r   r   r   r   r    ra  z5OutputGraph.run_compiler_collective.<locals>.<lambda>c                      s
    j  S r   )local_staterenderr   dsr   r   r       
 rd  r+   z&Expect only one device type but got {}+r  Tr  )group)r]  distributed_state
all_states
compile_pgr   infor  r   rj  rk  _device_typesr  formatr{  r@   r   r-  rankacceleratordevice_countrh   rp  distall_gather_objectspeculation_logr)  r-    CompileCollectiveRestartAnalysis)r   rb  r  device_typesr  r   r  r   r    s:   

 
z#OutputGraph.run_compiler_collectivervr|   c                 C   s   | j sdS ddlm} |D ]:}t||r|jsq| jjd}t|t	j
jjs+J |jdu r1qt|dfg}|| j @ rGd|j_tjddqdS )aj  
        Validate that if torch.autograd.grad is used in the graph and outputs
        require grad, we trigger AutogradGradRestartAnalysis only if the output is connected
        to the autograd.grad computation.

        rv here refers to list of variables that are being returned from dynamo graph.

        See Note [Tracing autograd.grad in dynamo]
        Nr+   )TensorVariabler  Tz3autograd.grad consumed grad_fns of returned tensors)restart_reason)r  variables.tensorr  r   requires_gradr  r   r  r  r   r  fake_tensorr   r   r   r  graph_break_on_autograd_gradr-   AutogradGradRestartAnalysis)r   r  rb  r  rv  r  reachable_grad_fnsr   r   r   )_validate_outputs_safe_for_autograd_nodes  s$   

z5OutputGraph._validate_outputs_safe_for_autograd_nodesr+  c                     s  t jj  ddlm} jsJ   tj	dkr-t
|dkr-g W  d   S tddd}t|ts:J t|tsAJ || ddjtd	d
 |D fi } }|| j|| tjstd7 t|D ]}t||}	t|	tjrt|	j|j d qw!  tt|j	j|j d W d   n1 sw   Y  "  tj	}
t#d d  |
7  < $  j%&  t'|j	ddl(m)} | j*rj*D ]}t+|t|| qj,D ]}| qt-. ddurj/dt j0jj1j2ddddd j3dur|_4j5_5j67 j8d< j9j8d< |j8d< t:;dt<|dddd t j=j>dfddfddd ?  j@jA}|dusaJ |_Bj sddlCmD  m} |jEdd t jFjG|jd}W d   n	1 sw   Y  |j@_AH  IJ W d   n	1 sw   Y  dd lKmL} t|sttd!d|rjMd"krt|rՈnjN}|O| t|s|jPj3durj3Q| |d#d$t#d d%  d7  < |jdusJ |jjR }rsg i d&d' jSD }|D ]3}|T|jU}tVW|jXY }tZ }t[\||jX|gd}t];d(| ^t_`|fd)d||f q t j0jd#d$d*tad+tad,taffd-d.}b|| nb| jcdusJ tdjc te rɈ f fd/d g }tgh D ]}|  i } j| |^| q|D ]} k l| q mt
tgd  n  tojSD ]\}}|jUjpjq|< qΈ r|  s W  d   S 1 sw   Y  dS )0z
        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  r   N__compiled_fnT)	with_uuidrJ  c                 s   r  r   )r  rk  r   r   r   r  "	  r  z8OutputGraph.compile_and_call_fx_graph.<locals>.<genexpr>r(   )r  statscalls_captured)dce_hop_extra_outputszfGraph contains named parameters: either inline_inbuilt_nn_modules=False or there are static addresses.Fprint_outputinclude_strideinclude_device)inline_builtin_nn_modulesr   r  r  
backend_id%s)r  r  coloreddynamo_output_graphc                      s   d   iS )Nsizes)rr  r   r   r   r   r  y	  s    z7OutputGraph.compile_and_call_fx_graph.<locals>.<lambda>c                      s    j ddddS )NFTr  )print_readabler   )r   r   r   r  z	  s    )rf  rk  )r!  )_LazyGraphModule__self___lazy_forwardz"do not trace Dynamo-compiled graphr  unique_graphsc                 S      g | ]}|j qS r   r  r   ar   r   r   r   	      z9OutputGraph.compile_and_call_fx_graph.<locals>.<listcomp>z:Compiling backend specialized graph with specialization=%sc                 S   s   |||  S r   r   )r7  r   check_fnr   r   r   r  	  s    r   r   r   c               
      s   D ]a\}}|| rc|v r| | i |  S j |j|j. |jd< t| }tj ||< W d    n1 sDw   Y  W d    n1 sSw   Y  | | i |  S q | i |S )Nspecialization)	r!  patch_source_specializationr  r  r  r   r   r  call_user_compiler)r   r   r  r  r   )compiled_fnr   r   specialization_cachespecialization_guardsr   r   specialized_dispatch	  s,   


zCOutputGraph.compile_and_call_fx_graph.<locals>.specialized_dispatchc                      s     tjjjdS )Nstore_user_object_weakrefs)r  r   r/  graph_bytecode_inputsr   r   )r  r   r   r  
  s    )tr   r  r   clear_framer  r  r  r  rf   r   r  r<   r   r   r   r  r?  r0  
create_argr?  
dedup_passr   _maybe_preserve_original_metar,   do_not_emit_runtime_assertsrh   dirr   r   r   r(   r!  r  remove_unused_get_attr_nodesremove_unused_graphargsrg   &remove_tensorify_specialized_graphargsr8  r)  r   dce_extra_outputsr  r  r   r  r{  
parametersrW  r/  inline_inbuilt_nn_modulesr  r`  _backend_idr  r  r   r  r  graph_code_logr  rq   rj  rk  r*  r  r  _old_fake_moder  r*  r   r  r  r~  r  r   torch.fx._lazy_graph_moduler  r   r  force_recompiler   add_backend_idspecializationsr  r  r  inspect	getsourcer  stripRootGuardManagerr   LAMBDA_GUARDr   r   rZ  r[  r   install_global_unsafer]  r>   rF   r  rG   r  r  r  r  r   r  pop_topr  rQ  rA  make_call_generated_coder  ) r   rb  r  r+  r  r  output_nodesub_gmsattrsubgraphncallsr  subgraph_nameregister_finalizerold_fake_moder  backend_fake_moder  lazy_gmr  sourcesr  source_indexcheck_fn_sourceunused_root_guard_managerr  r  tmp_varsconstructorvar_namer7  r  r   )r  r  r   r   r  r  r   r   	  sN  
	












	

$



  &z%OutputGraph.compile_and_call_fx_graphc                 C   s   | j jddS )Nplaceholderri  )r   
find_nodesr   r   r   r   placeholders"
  r2  zOutputGraph.placeholdersc                 C   s   dd | j D S )Nc                 S   s   g | ]}|j d  qS )r  r  )r   r   r   r   r   r   (
  s    z)OutputGraph.graphargs.<locals>.<listcomp>)r  r   r   r   r   r  &
  s   zOutputGraph.graphargsr   r   c                 C   sD   t ddddddd | ||W  d    S 1 sw   Y  d S )NOutputGraph.call_user_compilerbackend_compileTcompile_aot_autograd'aot_autograd_cumulative_compile_time_us)
phase_namer  log_waitcounterwaitcounter_name_overridedynamo_compile_column_us)rh   _call_user_compiler)r   r   r   r   r   r   r  *
  s   
$r  c                 C   s2  | j d usJ d}g }|jjD ]}|jdv r|d7 }|jdkr$|| qt| |D ]}t|ds;|jd }|j|_	q+| j
|_| j|_t| jtjpM| j }t| jtj}	|	r\t||	}t|drd|jnd}
z*t tjd	|
  tjrxt|}|||}t tjd
|
  t|sJ dW nq ttfy     ty } z;| jrt | j |t!" #|j$d t%|| j&j'dd|
 dt(| d| j&)  d|
 dt(| ddgd W Y d }~n&d }~w t*y     t+y } zt | j |t!" #|j$d d }~ww t,ddi | j-|t.|jjt.|d |S )Nr   r  call_methodcall_moduler+   r  _dynamo_sourcer  r   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.r  dynamor  )op_count
node_countinput_count)/r   r   rf  rj  r   ro   r  r  r  r  r  _param_name_to_sourcer  _source_to_user_stacksrI   r  r,   debug_backend_overriderJ   debug_inductor_config_overrider   r   r   r.   INFOr   r   callabler   r   rB   r  rA   r  currentframewith_traceback__traceback__rE   r]  r_  r   format_frame_summaryrC   r   r   rj  r  )r   r   r   totr  r   plr  r   inductor_config_overrider  r  r8  r   r   r   r  7
  s   









zOutputGraph._call_user_compilerc                 C   s   t jjjr	t| S i S r   )r   r/  r,   use_graph_deduplicationrH   r   r   r   r   r  
  s   
zOutputGraph.dedup_passsub_gmc                 C   s0   t || jdd}||_d|_| j||d d |S )NT)requires_suffixFr  )rm   r   r   torchdynamo_force_dynamicr  )r   r  r  	next_namer   r   r   r  
  s
   zOutputGraph.install_subgraphc                 C   s   dd | j D }|S )Nc                 S   r  r   )example)r   r  r   r   r   r   
  r  z.OutputGraph.example_inputs.<locals>.<listcomp>)r  )r   r   r   r   r   r   
  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  ri  T)reverser   )rD  r   r  r  r   usersr@  r   r   r   r   r   r  
  s
   
z(OutputGraph.remove_unused_get_attr_nodesc                    s  j sJ dtjjdtfdd}dtjjdtfdd dtjdtf fd	d
}ddlm} tt	j
jD ]:}tt	|jdkro|jdksj|jdkrP|jtju sj|jdkrb|jtju rb||jd sj||sj||ro| q5dtjdttj fdd}dtjdd ffdd}t dttj dttjtjf dd fddg }jD ]}||d u}|r|js|| q|jst|j d t!s|| q|j d }	t|	t!rqt|j d j"tj#r|j d j"}
|j d j$}tj%j&'|
st(|
) }|D ]}t*|j+|}t,-tjtjffdd| qqt.t/|j d j"r q|	j0d ur)|	j0n|	j"}| q|D ]}||}|d urO|vrJ|| q41| q4d S )Nb_noder   c                 S   sf   | du rdS t | tjsdS | jd}|d u rdS |du r dS t |tjr1|j  }d ur1|S dS )NTFr  )	r   r   Noder  r  r   SymBoolr   maybe_as_bool)r  brr   r   r   is_static_true
  s   
z;OutputGraph.remove_unused_graphargs.<locals>.is_static_truer  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   SymTypesTr  F)
torch.fx.experimental.sym_noder!  r   r  r  r   r   r  r  r  )r  r!  r   r   r   is_symnode_arg
  s   z;OutputGraph.remove_unused_graphargs.<locals>.is_symnode_argr   c                    sp   ddl m} | jdkrdS t| jd|sdS t fdd| jD s&dS t fdd| j	 D s6dS d	S )
Nr   r   r  Fr  c                 3       | ]} |V  qd S r   r   r  r#  r   r   r  
  r  zWOutputGraph.remove_unused_graphargs.<locals>.is_symnode_compute_node.<locals>.<genexpr>c                 3   r$  r   r   r  r%  r   r   r  
  r  T)
r"  r!  rj  r   r  r  r  r   r   r  )r   r!  r%  r   r   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rt|jjtjr|jjS d S Nr  )	r  r  r   r   r  r   exprsympySymbol)r   r  r  r   r   r   placeholder_binds_symbol
  s   

zEOutputGraph.remove_unused_graphargs.<locals>.placeholder_binds_symbolc                    s:   t d| jd jj | jd=  |   j| d  d S )NzREMOVE UNUSED GRAPHARG %sr  )r   r  r  r  r  r@  r8  r   )r   r   r   r   remove_unused  s   
z:OutputGraph.remove_unused_graphargs.<locals>.remove_unusedused_symbolsfakec                 S   s   | t |O } d S r   )r!   )r.  r/  r   r   r   update_used_symbols     z@OutputGraph.remove_unused_graphargs.<locals>.update_used_symbolsr  c                    s
    | S r   r   )t)r0  r.  r   r   r  1  r  z5OutputGraph.remove_unused_graphargs.<locals>.<lambda>)2r  r   r   Argumentr   r  %torch.fx.experimental.symbolic_shapesr'  r(  r   r   rf  r  r  rj  r  operatorgetitemr   _checkr   r@  r
   r*  r+  r   r   r  r   r  r   r   r  rv   r  ScriptObjectexample_strong_ref_libraryfake_class_registrytracing_with_realr   __obj_flatten__r   wrapped_objpytreetree_map_onlyr   r   r  remove)r   r  r&  r'  r   r,  r-  recheck_placeholdersbinds_symbolr  real_script_objfake_script_obj	flat_dictr  fake_attr_valr/  symbolr   )r#  r   r0  r.  r   r  
  s   



	










z#OutputGraph.remove_unused_graphargsc                 C   s   ddl m} | jjD ]G}|jd}t|trQ|jd urQt	|jj
jdrQtdd |jD rQ||jj
jjrQt|jD ]}|t|j | | q<| | q
d S )Nr   )TensorifyStater  r  c                 s   s    | ]}|j d kV  qdS )itemNr  )r   ur   r   r   r  ]  s    zEOutputGraph.remove_tensorify_specialized_graphargs.<locals>.<genexpr>)torch._dynamo.symbolic_convertrI  r   rf  r  r  r   r   	item_memor  r   _exprr  r  should_specializer  r   replace_all_uses_withr"   r@  )r   rI  r   r  rL  r   r   r   r  F  s(   


z2OutputGraph.remove_tensorify_specialized_graphargsc                 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  r   r   r   r  h  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   rc   r  r  )r   r  r6  r   r   r   r  p  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   _c)idr}  r~  r  r   r  r6  r  r   r   r   install_global_by_id|  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<   r  rT  r   r   r   r    s   zOutputGraph.install_globalc                 C   s   d | _ | j  | j  d | _| jjD ]}d|jv r|jd= q| j  | j	  | j
  | j  | j  | j  | j  | j  | j  | j  | j  | j  d S r(  )r]  r   r)  r  r  r   rf  r  r8  r7  r[  r  r  r  r  r  rx  ry  r  r  r  r   r   r   cleanup  s(   













zOutputGraph.cleanupr  c                 C   r%  r   )r  r   )r   r  r   r   r   add_graph_finalizer  r1  zOutputGraph.add_graph_finalizerr   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  r  r  )rj  r  r  r   r  r  r   r   r   example_value_from_input_node  s   
z)OutputGraph.example_value_from_input_nodeinlined_moduler  c                    s   t j t jj j  dtdd f fdd}t|dr>t	|j
r>|j
jtu r>|
 D ]\}}|| q5t|dr[t	|jr]|jjtu r_| D ]\}}|| qRd S d S d S d S )Nr  r   c                    r  rp  r  r  r  r   r   r    r  zHOutputGraph.add_fqn_info_for_inlined_modules.<locals>.register_leaf_namer  r  )rZ  r~  r  rm   r  r  r   r   r  r  r  __func__!og_module_named_parameters_fn_ptrr  og_module_named_buffers_fn_ptr)r   rY  r  r  r  r   r   r  r    add_fqn_info_for_inlined_modules  s4   




z,OutputGraph.add_fqn_info_for_inlined_modulesFr   )r  )r   rv  r   )r   rZ  )rb  r   r   N)r   r   )rs  )r   rY  )r   r   r   r   rP   r   r   r   r   r
   r1   r   r   r   r'  r   r   r   r(  r)  r   r   rS   r  r  r  r  r  r|   r?  r   Proxyr  r  r  r  r   r$  r&  r*  r3  r  r0  r1  Graphr   setterr7  r  r   r8  r*  r+  r   r:  r<  r?  r@  r  contextmanagerr'   r   rI  rJ  r  r  r  r$   r!  r  r1  r   r   r2  r%  r  rc  rd  re  r  rf   rg  rn  r   r   rr  r  rx  staticmethodr~  r  r  r;   r  r4  r  r   rC  r>   r  r  r  rW  rr  ry  r~  r  r  r   r  r  rw   r  r   r0   r  r  r  r  r   r  r  r  r  r  rU  r  rV  rW  rX  r]  r   r   r   r   rZ  G  s  
 

	


 k

	
"





&	

&

	

 
[
n
   N

$"	
#
$
  $

\	

 
"

rZ  c                   @   s   e Zd ZU eed< eed< ee ed< ee ed< eeedf  ed< e	e
ef ed< 	dd	d
dee ddfddZdddZdS )DynamoTracerOutputerror_on_graph_breakis_tracing_resume_prologueoutput_graphoutput_graph_for_cleanup.closure	f_globalsNrH  r   r  r   c                 C   sB   |j | _ |j| _|j| _|j| _|j| _|rd | _d S |j| _d S r   )re  rf  ri  rj  rJ  rh  rg  )r   rH  r  r   r   r   r     s   
zDynamoTracerOutput.__init__c                 C   sN   | j }|r!|jD ]}|j  q|jjr#|jjjr%d |jjj_d S d S d S d S r   )rh  rw  r   _clear_nodesr  r  r!  rf  )r   rg  rH  r   r   r   _cleanup_output_graph  s   
z(DynamoTracerOutput._cleanup_output_graphr   r   )r   r   r   r   r   r
   rZ  r?  r   r   r   r   rl  r   r   r   r   rd    s    
 
rd  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.htmlrg  kindr  r   r   c              
      s  |dkrd S dt jjdd f fdd}dt jjdtdd f fdd}t|t jjrAt jj|jv r6|| d S ||d	| d
 d S t|t jjrt	|
 }t|dkrst||d }t jj|jv rh|| 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 }
~
ww t||	}t jj|jv r|| d S ||d| d|	 d d S d S )Nr  r  r   c                    s   | j dv rd S  j|  d S )N>   atenprimprims)	namespacer  r   rK  rg  r   r   encountered_compliant_op  s   
z8check_pt2_compliant_op.<locals>.encountered_compliant_opr   c                    s2    j |  tjrtdd|d t g d d S d S )Nz Encountered non-PT2-compliant oprT   r  )r  r   r,   only_allow_pt2_compliant_opsrD   err_epilogue)r  r   rr  r   r   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 packetrT  r  z+Encountered the torch.ops.OpOverloadPacket z! which resolves to the overload (z) that is not PT2 compliant.)r   _ops
OpOverloadr   r   Tagpt2_compliant_tagtagsOpOverloadPacketr?  	overloadsr  r   r/  rE  get_fake_values_from_nodesre  r.  _jit_resolve_packet_qualified_op_namer   rD   )rg  rm  r  r   r   rs  rw  r~  rj  overloadr8  r   rr  r   check_pt2_compliant_op  sr   



	r  PRc                
   @   sD   e Zd Zdddeeef dejdejddf
dd	Zde	fd
dZ
dS )r9  rH  rv  r   r   r   r   Nc                 O   s   || _ || _|| _|| _d S r   )rH  r   r   r   )r   rH  r   r   r   r   r   r   r   b  s   
zLazyProxy.__init__c                 C   s   | j | ji | jS r   )r   r   r   r   r   r   r   r   o  rh  zLazyProxy.__call__)r   r   r   r   r  r  r   r   r   r   r   r   r   r   r   r9  a  s    

r9  c                       sH  e Zd ZdZ				d<ddded  dedee d	ee d
df fddZde	d
dfddZ
dddejd
dfddZ			d=dededededee dee deeejgejf  d
ejfddZ			d=dededededee dee deeejgejf  d
ejf fddZ				d>dededededee dee d
ejf fd d!Zdejd
dfd"d#Z		d?deded$ed%ed&ee d
ejfd'd(Zd)ejd
eeejf fd*d+Zd,ed
efd-d.Zd$ed/eeejjf d
dfd0d1Zd$eejejf d2ee d
dfd3d4Zd5ejd
e e!j" fd6d7Z#d
e$fd8d9Z%d
e&fd:d;Z'  Z(S )@rv  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.
    NFrg  rZ  rD  rb  rA  rC  r   c                    s   t    t|| _tj | _|| _	i | _
i | _|| _|| _|| _i | _i | _i | _d | _d| _d| _d| _d| _|d urD|jd nd| _d | _d | _d | _d | _| jd u r\g | _n| jj| j||fg | _t | _g | _ t! ryt"dt | _#d S )NFr+   r   zSInference mode is supposed to be disabled during compilation. Please open an issue.)$r   r   weakrefr  rg  r   r   r`  r   rb  r7  r8  rD  rA  rC  lifted_freevarsr:  dynamic_scalar_nodes	prev_inst,unsafe_allow_externally_visible_side_effects+traced_with_externally_visible_side_effectsallow_side_effects_in_hopis_reconstructing_generatordebug_level	_cur_code_orig_gm_meta_orig_gm_lineno_map_orig_gm_firstlinenosource_fn_stack_target_to_strr)   _used_names_input_versions_at_beginningis_inference_mode_enabledr   tracked_tensor_or_symint_vt)r   rg  rD  rb  rA  rC  r   r   r   r   {  sD   

zSubgraphTracer.__init__r  c                 C   r%  r   )r  r   )r   r  r   r   r   record_tensor_or_symint_vt  r'  z)SubgraphTracer.record_tensor_or_symint_vtrb  r   r   c                 C   s   | j rE| jrG| jrI|jj}d }|d ur| j|| j d }|d urK| j | }tjjD ]}||v r7|| |j	|< q*d|v rM|d |j	d< d S d S d S d S d S d S )Nstack_trace)
r  r  r  current_instructionstarts_liner  r   r  _COPY_META_FIELDSr  )r   rb  r   linenonode_idxr  r   r   r   r   r    s.   

z,SubgraphTracer._maybe_preserve_original_metarm  r  r   r   r  	type_exprproxy_factory_fnc           	   
   C   sX   t  }z| |||||||W | jj jt  | 7  _S | jj jt  | 7  _w r   )r  r  _create_proxyrg  r  r   )	r   rm  r  r   r   r  r  r  _t0r   r   r   r<    s   



zSubgraphTracer.create_proxyc              	      s  | j d ur't||f\}}	g }
|D ]}| |}|
| qt|
|	\}}t ||||||| jj	}t
jdkru|dv ru|j  | juru jd uru jjd uru|j|j jjddtf fdd}tdt|  | _d}|j| jurt|jd	d
d  }t|tjjrd}dd |jjD | _ |j!| _"|j#j$j%| _&n	d | _ d | _"d | _&|j'}|r|( j)j*d< |dv rj)j+f}|rt,j)j*d - d d }|j./dr|j./dsj)j+|f}| j0|g j)j*d< n4|dkr)| j d urt1dd| j2 dg d | j0j)j+t3fddj)j*d 4 D fg j)j*d< | 5|j) |sdj)j*vrH|j'}|rH|( j)j*d< dj)j*vr|dv rc| j0j)j+fg j)j*d< n)|dkr| j d urvt1dddg d | j0j)j+j)j*d  d fg j)j*d< dj)j*vrg }|r|6 s||7  t8|d d }|sd!d |D }|9  t:j;<|= }d>|j)_?tj@jAjBstj@jAjCr| jjDE| jj	j) S )"Nr  r  )r  r   c                     s(   t   } djj d d|  S )NzTRACE FX call z from rs  )rj   rstripr   r  )line)cur_instheaderr  tx_coder   r   get_trace_call_log_strX  s   z<SubgraphTracer._create_proxy.<locals>.get_trace_call_log_strr  Forig_graphmodulec                   S   s   d S r   r   r   r   r   r   r  c  s    z.SubgraphTracer._create_proxy.<locals>.<lambda>Tc                 S   r  r   r  )r   ndr   r   r   r   g  s    z0SubgraphTracer._create_proxy.<locals>.<listcomp>nn_module_stack>   r  r  r/  r+   )ztorch.nn.modulesz	torch.ao.ztorch.nn.modules.containerr  r  z4Invoking an nn.Module inside a higher order operatorzHigher order op name: zThis is not supported.r  c                 3   s.    | ]\}\}}| d d  kr|V  qdS )@r   N)r  )r   r   r   tyrK  r   r   r    s    
z/SubgraphTracer._create_proxy.<locals>.<genexpr>z2Invoking an nn.Module inside a HigherOrderOperatorrT  r  rD  c                 S   s   g | ]
}|j t vr|qS r   )r  r&   )r   framer   r   r   r     s
    )FrD  r?  tree_flatten#maybe_lift_tracked_freevar_to_inputr   tree_unflattenr   r<  rg  re  r  r  r  r  	positionsr  r_  get_line_of_code_headerr   trace_call_logr  rr   r  r=   get_contextr  r   r   r   r   r   rf  r  _lineno_mapr  r   __code__re  r  r  r   r   r  r  r   r  r   
startswithr  rD   rA  r{  r   r  is_co_filename_from_nn_modulesframe_summaryr   r  r   StackSummary	from_listr  r{  r  r/  r,   r  track_nodes_for_deduplicationr  
track_node)r   rm  r  r   r   r  r  r  	flat_args	tree_specnew_flat_argsr  maybe_new_argrb  r  is_retracingorig_graphmodule_mayber  r   current_nn_moduleframe_summariesfiltered_frame_summariesmsgsr   )r  r  r  r  r  r   r    s   
+









zSubgraphTracer._create_proxyc           
         s   t | j|||| | jd ur-tj|i |}|D ]}t|tjjs"q|j	| j	ks,J dqt
 ||||||}	| jj|	jd< | j|	j |	S )Nz2create_node using arg not from this SubgraphTracerrT  )r  rg  rD  r?  arg_tree_leavesr   r   r   r  r   r   r?  r  r  r  r   r  )
r   rm  r  r   r   r  r  r  r  r   r   r   r   r?    s   	
zSubgraphTracer.create_nodec                 C   sv   t |jdkr+g }|jD ]}|j| jkr|tt|jj q|D ]}|j| q"| j| | j	|j
d  d S r,  )r  r  r   r  r(  r   rf  rX  r7  r   r  )r   r   user_graph_nodesuserother_graph_noder   r   r   r@    s   
zSubgraphTracer.remove_noder  beforer  c                 C   sB  t |tjr| j|j td||d ur|jnd|| j	| |d u r3| j
d us3J d| d| d| jrT| j
d u rT|d usAJ t|ddsT| jj|g t  t|| j}| jrztt| j}| j| j}|rs| j|}n| j|}n| jd }| | jd|d	i |d
}	t|	j| | jr|r| j \}
}|	| j|< || j|
< n|	| j|< | j| | j}tj  }|s|st |tjr| !|| n(t |t"t#frt$|D ]\}}t |tjsqd }|rt%||dd}| !|| qt |tj&rt |jj't(j)r|	| j*|jj'< |	W  d    S 1 sw   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)only_allow_inputr  r   r  F)r  r  index_is_slice)+r   r   r   r  r   _versionr   r  r  r  rD  rb  rY   rg  r  r  r   extract_stackrm   r  r7  r{  r(  r   r   inserting_beforeinserting_afterr<  ru   popitemr   compileris_compiling_lift_basic_symbolsr   r?  r  rV   r  r)  r*  r+  r:  )r   r  r  r  r  r  	prev_namer   ctxr  r   r   is_strict_exportis_non_strict_exportr  r8  e_sourcer   r   r   r    sx   


 

&z!SubgraphTracer.create_graph_inputr  c                 C   s   | j d us	J d|jjd }t|tjr#|jj| jv r#| j|jj S || jv r-| j| S |j	| j kr9| j 
| |jjd }t|trIt|jnt|}| |jj||}|| j|< |S )NzIlift_tracked_freevar_to_input should not be called on root SubgraphTracerr  )rD  r   r  r   r   r  r)  r:  r  rH  lift_tracked_freevar_to_inputr   r   real_objr  r  )r   r  r  r  	new_proxyr   r   r   r    s(   
	


z,SubgraphTracer.lift_tracked_freevar_to_inputr  c                    sV   t |tjjst |trt fdd|j|j|jfD  S |S |j kr&|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   sub_argr   r   r   r    s
    
zESubgraphTracer.maybe_lift_tracked_freevar_to_input.<locals>.<genexpr>)
r   r   r   r_  slicestartstopsteprH  r  )r   r  r   r   r   r    s   



z2SubgraphTracer.maybe_lift_tracked_freevar_to_inpute_proxyc                    s   j tts
J dtdtffdd}dtdtdtdtjf fdd	}t|tjr1t	|
 D ],\}}||r_td
| |j t||dtjjjj |fi t|d}|| q3| }||rtd| j t||dtjjj fi t|d}|| |jtju rt	| D ],\}}||rtd| |j t||dtjjjj |fi t|d}|| qnK|jtju rڈ|   |   n4|jtjtjhv r|    |!   n|jtj"tj#hv r|$   |%   t&|r-|' \}	}
|	D ]}t(||}|t( | qd S d S t|tj)rH||rJ|j*j+} j,|< d S d S d S )Nro  r   c                    s2   ddl m} || ot| jjtjo| jj jvS )Nr   )r#   )r4  r#   r   r   r)  r*  r+  r:  )ro  r#   r   r   r   	need_bind  s   z8SubgraphTracer.track_produced_symints.<locals>.need_bindr  r   r   c                    sx   t  tr  n  t  tjjsJ j j j|i |}t	|j|  |W  d    S 1 s5w   Y  d S r   )
r   r9  r   r   r_  r   r  r   r<  ru   )r  r   r   r  )r  rH  r   r   _proxy_with_example_value  s   $zHSubgraphTracer.track_produced_symints.<locals>._proxy_with_example_valuez=track_produced_symints %s for %s.size()[%s] at debug_level %sr  r  zCtrack_produced_symints %s for %s.storage_offset() at debug_level %sz?track_produced_symints %s for %s.stride()[%s] at debug_level %s)-rH  r   rv  r   r   r   r_  r   r   r  rp  r   r  r  r9  opsrn  sym_sizer  r   track_produced_symintsstorage_offsetsym_storage_offsetlayoutstridedstride
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  r   r)  r:  )r   r  r  r  r  r  ro  
lazy_proxyr  attrsr  r  inner_tr)  r   )r  r   rH  r   r    s   	







z%SubgraphTracer.track_produced_symintssrcc           
   	      s  	d
dt ttjf dtt dtdd f fdd}t|tjrt	|
 D ]\}}|||d ur5t|tj|nd dd	 q$|jtju rrt	| D ]\}}|||d urXt|tj|nd dd	 qG|| |d urlt|tjnd dd	 nJ|jtju r | |  | | n3|jtjtjhv r | |  | | n|jtjtjhv r | |  | | t |r|! \}}|D ]}t"||}	 |	|d urt#||nd  qd S d S t|tjr||| d S d S )NFro  r  r  r   c                    sn  t | sd S t| tjsJ  | }t|dkrd S  jd ure j| | |D ]9} jj| }|j	j
d }t|tjs?J  jt|t||||d}td||d urX|jnd j | j|< q)d S t|dksuJ d| d|  |d usJ d	|  d
|  dtt|} jt|t| | ||d}td| |d ur|jnd j t|| dd dd|j	j
d< d S )Nr   r  )r  r  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)pass_arg_as_tensorr  r  r  )r#   r   r   r  lookup_unbound_symbolsr  rD  r  r:  r   r  r  r   r   r   r  r  r  r  r{  iterrw   )ro  r  r  self_to_be_bounds0parent_proxyexample_valphr   r   r   _lift_symbols_in_symintU  sx   


zCSubgraphTracer._lift_basic_symbols.<locals>._lift_symbols_in_symintT)r  r^  )$r   r  r   r  r
   r   r   r   r   r  rp  r`   r_   SIZEr  r  r  STRIDEr  STORAGE_OFFSETr  r  r  r  r  r  r  r  r  r  r  r  r*   r  r   rS   )
r   r  r  r  r  ro  r   r  r  r  r   r   r   r  N  sv   
D			
z"SubgraphTracer._lift_basic_symbolsro  c                 C   s   |j jj}t|dkrg S g }|D ]3}|| jvr|| q| j| }t|tr0| }|| j|< t|tj	j
r<|j| u sDJ d| dqt|dd dS )Nr   zThe proxy of symbol z" doesn't belong to current tracer.c                 S   r#  r   )r  )ro  r   r   r   r    s    z7SubgraphTracer.lookup_unbound_symbols.<locals>.<lambda>)r  )r   r)  r!   r  r:  r   r   r9  r   r   r_  rH  rD  )r   ro  r!   to_be_boundr  r  r   r   r   r    s    






z%SubgraphTracer.lookup_unbound_symbolsc                    s   | j }g  g }| jjD ]}|jdkr)|jd }t|tjr(||j	  | q dd t
t||D }|rK fdd|D }d| }td|S tdd	S )
Nr  r  c                 S   s    g | ]\}\}}||kr|qS r   r   )r   r  v1v2r   r   r   r     s
    
z5SubgraphTracer.has_input_mutation.<locals>.<listcomp>c                    s   g | ]} | qS r   r   )r   r  input_nodesr   r   r     s    zInput mutation detected at TFrT  )r  r   rf  rj  r  r   r   r   r   r  r  zipr   )r   input_versions_at_beginninginput_versions_at_endr   r  mutated_inputsmutated_nodesr   r   r  r   has_input_mutation  s*   





z!SubgraphTracer.has_input_mutationc                    s  ddl m} ddlm} t  | jjD ]7}|jdkrJ||gd }t|t	j
rI||D ]}| v rDd |  d| }td|    S | |< q+q t | jjdd	d }t|jd D ]:}|r||gd }t|trqJ t|t	j
r||D ]}|v rd
|  d| }td|    S ||< q{q_   @ }	t|	dkrƇ fdd|	D }
ddd |
D }
d|
 }td|S tddS )Nr   )get_tensor_storages)_collect_fake_inputsr  z*Input-to-input aliasing detected at nodes  and TrJ  ri  z,Output-to-output aliasing detected at nodes c                    s   g | ]
} | | fqS r   r   rn  input_storagesoutput_storagesr   r   r   &  s    z/SubgraphTracer.has_aliasing.<locals>.<listcomp>z, c                 S   s   g | ]\}}| d | qS )r  r   )r   r  or   r   r   r   )  s    z+Input-to-output aliasing detected at nodes FrT  )(torch._dynamo.variables.higher_order_opsr  torch._higher_order_ops.utilsr  r   r   rf  rj  r   r   r   r   r  r?  tree_leavesr   r   ro  r  r{  )r   r  r  r   r  storager   	out_nodesout_nodeintersected_storagesaliasedr   r  r   r     sH   





zSubgraphTracer.has_aliasing)NFNN)NNNrX  )FN))r   r   r   r   r
   r   r'   r   r   r|   r  r   r  r  r   r   r_  r<  r  r?  r@  r   r  r   r9  r  r  r   r  r  r   r  r   r*  r+  r  r   r  r   r   r   r   r   r   r   rv  s  s    
_
	
	 U
}
- 
|
 rv  r   (  r   r  r  r   r  rZ  r  r  r.   r5  r|  r  r  r   r%  r  collections.abcr   r   r   r   r   r>  typesr   typingr   r	   r
   r   r   typing_extensionsr   r   r*  torch._guardsr   torch._loggingtorch.distributeddistributedr  torch.nntorch.utils._pytreerE  rF  r?  r   r   torch._C._dynamor   torch._dynamo.excr   r   r   r   r   r   r   r   "torch._library.fake_class_registryr   torch._library.opaque_objectr   torch._subclasses.fake_tensorr   torch._utils_internalr   torch.export.dynamic_shapesr   r  r   %torch.fx.experimental._backward_stater    r4  r!   r"   r#   r$   r%   r&   torch.fx.noder'   torch.fx.passes.runtime_assertr(   torch.utils._ordered_setr)   torch.utils._python_dispatchr*   rT  r,   r-   r   r/   backends.registryr0   r1   bytecode_transformationr2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r  r>   current_scope_idr?   device_interfacer@   rA   rB   rC   rD   rE   r  rF   rG   graph_deduplicationrH   graph_id_filterrI   rJ   graph_region_trackerrK   rL   rM   mutation_guardrN   r[  rO   rP   rQ   r  rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   variables.builderrv   rw   rx   ry   variables.ctx_managerrz   variables.functionsr{   r|   variables.listsr}   variables.miscr~   variables.nn_moduler   r  r   r   r   variables.torch_functionr   variables.user_definedr   r  r   torch._dynamo.packager   rM  r    torch.multiprocessing.reductionsr   	getLoggerr   r   rj  getArtifactLoggergraph_tabular_logr  graph_sizes_logr  r  r   r   r  r\  r  r[  r   r   r   r   r   r   r?  r   rn  r   r  r   cacher   r   r   r   r   objectr'  r   r  r4  r@  rM  rN  rZ  rd  rv  r  r  r|  r  r  r9  Tracerrv  r   r   r   r   <module>   s@     4D\






,$?I                   -%	
M
