o
    Zh                     @   sz  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dl mZ d dlmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlm Z m!Z! d dl"m#Z#m$Z$ d dl%m&Z& erd dl'Z'd dl(m)Z) d dl*Z*d dl+m,  m-Z. d dl/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z> d dl?m@Z@ d dlAmBZB d dlmCZC d dlDmEZEmFZF d dlGmHZH d dlImJZJ d dlKmLZL d dlMmNZN ddlOmPZPmQZQmRZRmSZSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\ g dZ]ee*j^j_geeL f Z`ejaG dd dZbejaG dd dZcdd  Zdd!eee d"e.jfd#eee d$e.jfd%egf
d&d'Zhe*jijjjke*jijjjle*jijjjme*jijjjne*jijjjoe*jijjjpe*jijjjqe*jijjjre*jijjjse*jijjjte*jijjjue*jijjjvgZwe*jijjjxe*jijjjye*jijjjze*jijjj{e*jijjj|e*jijjj}e*jijjj~e*jijjje*jijjjg	ZedPd)d*Zed+d, Zd-ee*jjef d%eee*jjef d.f fd/d0ZdQd2d3Zd4ee*jjef d5ee*jjef d6ee fd7d8Zd9e*j^j_d:eSd%ee*j^j_eSf fd;d<Zd9e*j^j_fd=d>Zd9e*j^j_d?eec fd@dAZd4ee*jjef d5ee*jjef d6ee dBegfdCdDZG dEdF dFZdGdH Z	dRd9e*j^j_dIdJd%dKfdLdMZdNdO ZdS )S    N)
namedtuple)Iterator)contextmanager)AnyCallablefinalOptionalTYPE_CHECKINGUnion)autograd_not_implemented)FakeScriptObject)_deregister_op_impl_is_op_registered_to_fake_ruleregister_op_impl)FakeTensorMode)#first_call_function_nn_module_stack)_PyTreeCodeGen_PyTreeInfo)immutable_dictimmutable_list)insert_deferred_runtime_asserts)ValueRanges)_collect_all_valid_cia_ops_collect_and_set_constant_attrs_collect_param_buffer_metadata_detect_fake_mode_from_gm_fakify_params_buffers_get_decomp_for_cia_is_preservable_cia_op_name_hoo_subgraph_placeholders7_override_graph_signature_for_temp_registered_constants/_overwrite_signature_for_non_persistent_buffers)_populate_param_buffer_metadata_to_new_gm_register_constants_as_buffers_rename_without_collisions_special_op_to_preserve_ciaplaceholder_naming_pass)Verifierdetect_fake_modeunset_fake_temporarily)is_equivalentreorder_kwargsCustomDecompTable)compatibility)
PassResult)PassManager   )ArgumentSpecConstantArgumentCustomObjArgumentExportGraphSignature	InputKind	InputSpec
OutputKind
OutputSpecSymBoolArgumentSymFloatArgumentSymIntArgumentTensorArgumentTokenArgument)ExportedProgramModuleCallEntryModuleCallSignaturedefault_decompositionsc                   @   sV   e Zd ZU ee ed< ee ed< ejed< ejed< dZe	ee
  ed< dd ZdS )	rC   inputsoutputsin_specout_specNforward_arg_namesc                 C   sD   | j D ]}|j|jkr|j|_q| jD ]}|j|jkr|j|_qd S N)rE   namerF   )selfZoriginal_nodenew_nodeio rP   L/var/www/auris/lib/python3.10/site-packages/torch/export/exported_program.pyreplace_all_uses_withf   s   

z)ModuleCallSignature.replace_all_uses_with)__name__
__module____qualname__listr4   __annotations__pytreeTreeSpecrI   r   strrR   rP   rP   rP   rQ   rC   ^   s   
 

rC   c                   @   s&   e Zd ZU eed< dZee ed< dS )rB   fqnN	signature)rS   rT   rU   rZ   rW   r\   r   rC   rP   rP   rP   rQ   rB   o   s   
 rB   c                    s   t   fdd}|S )Nc                     s8   t    | i |W  d    S 1 sw   Y  d S rJ   r*   )argskwargsfnrP   rQ   wrapperv   s   $z/_disable_prexisiting_fake_mode.<locals>.wrapper)	functoolswraps)r`   ra   rP   r_   rQ   _disable_prexisiting_fake_modeu   s   rd   
spec1_typespec1_context
spec2_typespec2_contextreturnc                 C   sx   | du s|du r| |u o||kS t | ttfr"t |ttfr"||kS t | ttfr4t |ttfr4||kS | |u o;||kS )zeTreat containers and their immutable variants as the same type. Otherwise
    compare as normal.
    N)
issubclassdictr   rV   r   )re   rf   rg   rh   rP   rP   rQ   _fx_collection_equivalence_fn~   s   	rl   Tc                 c   sb   i }t  }|  D ]h\}}|j ||< || tD ]}||jvr.||t|dd qt|}t	j
jj|jv rB|jt	j
jj= |rN|t	j
jj| dd }t|sat|tj||d tD ]}	|	|jvrq||	| qcq
z!d V  W |D ]}
|
j  |
j||
  |
j  t|
 qzd S |D ]}
|
j  |
j||
  |
j  t|
 qw )NT)Zdeferred_errorc                 _   sD   |d }|d= |  ||i |W  d    S 1 sw   Y  d S )Noriginal_callablerP   )Zfake_tensor_modeopr]   r^   orig_cia_callablerP   rP   rQ   $_force_dispatch_to_orig_cia_callable   s
   $zQ_override_composite_implicit_decomp.<locals>._force_dispatch_to_orig_cia_callable)rm   )setitemsZ
py_kernelscopyadd(_AUTOGRAD_ALIAS_BACKEND_KEYS_TO_OVERRIDEZpy_implr   r   torch_CDispatchKeyZCompositeImplicitAutogradr   r   rb   partial_BACKEND_KEYS_TO_OVERRIDEclearupdateZ_dispatch_cacher   )cia_ops_to_callablesafeZsaved_tablesZpatched_opsZop_overloadZdecomp_callableZoverride_dispatch_keyro   rp   keyrn   rP   rP   rQ   #_override_composite_implicit_decomp   sZ   









r   c                   c   sR    t tjjjjttjjjjtidd d V  W d    d S 1 s"w   Y  d S )NF)r~   )r   rv   opsatentoZdtype_layoutr%   ZdtyperP   rP   rP   rQ   !_override_decomp_aten_to_variants  s   "r   decomp_table.c                 C   s   t t }i }t|  D ],}||v r"| | ||< || | |= qt|r9| }|dr3J d| | ||< q|D ]}t||< q<|| fS )Nr   zThis should be a custom op)	rq   r   rV   keysremover   rK   
startswithr%   )r   Zall_preservable_cia_opsr}   rn   Zop_namekrP   rP   rQ   ,_split_decomp_table_to_cia_and_python_decomp'  s   


r   r/   c                   C   s   t  S )z
    This is the default decomposition table which contains decomposition of
    all ATEN operators to core aten opset. Use this API together with
    :func:`run_decompositions()`
    r.   rP   rP   rP   rQ   rD   S  s   rD   cia_to_decomppython_decomp_tablejoint_loss_indexc          J         s	  ddl m} ddlm} ddlm}m}m}	m}
m	}m
} ddlm} dd }|| |s|  }i t|jdd	t|jdd	}dd
lm} || i t|jdd	t|jdd	}t| j}|d u rnt| dd}|j}|jjjj}|jttfvrttd |g}t t!||j"||j_|#  t$| j%| j&| t'|| j(| j%j)}t*||}t+|}ddl,m-}m.} g }|jj/D ]8}|j0dkrt1|j2d t3rd }|j2d j4d u r| j&|j2d j5 }n|j2d j4j6}|7| q|7|j2d  q| t8  t9| || j:x t;||j"}||g |d |d < R i |N\}} }!}"||| |!||"|dd|d	}#fdd|#j&= D |#_&|#j>}$|#j?}%t@|%|}%tA||$|% tB| j%|%}%||$|%|"}&tC|$|%|| |!||& W d    n	1 ssw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  |
|$ ||$ ||$|% tD|$|%\}$}%|= D ]\}'}(|'|vr|(| j(|'< q|= D ]&\}'}(|'| j(vrt1|(tEjFjGrJ |'| j(v r	|'|vr	| j(H|' q|$|%| j(fS dd | jjj/D })dd |)D }*dd | j D }+|+D ]	}'tI| j|' q.tJ|*}|d u rEtKL n|}|rMtKjLn|},|	 c |P t9|; |, ' || j|*||d urkdnd|d urs|nd d\}$ |$jM  W d    n	1 sw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  W d    n	1 sw   Y  dd dd |$jj/D t|$jj/d jNd }-tOtO|)ksJ tP|)D ]\}.}/|.j5 |/_5|/_Qqdd D }0|$jj/D ]}|j0dkrqtR|0|j5|j5|_5qtS|$ ddlTmU}1mV}2 ddlWmX}3 tEjYjZj[s_d }4t\|$}5|5d ur_|2|$t]j^|1|4d! t_|$|5d"t`|$j dd# W d    n	1 sZw   Y  |$#  ta|3|$D ]\}6}'t1|-|6 tEjbjcr||'|-|6 _5qifd$dta| j%jdD }7fd%dta| j%jdD }8g }9d&d ta jeD }:t jfg };|;d'd |-d tO|; D ksJ  jf= D ]C\}<}=|:|= }6| j%jd|6 }>|>jhtijjtijkfv sJ |>jhtijkkrtljmntljn}?|>jhtijkkr|>jQn|>joj5}@|97tp|?tq|<d(|@d) qta| j%jrD ]'\}6}A|97tp|6|krtljsn|Ajh|Ajo|-tO|;|6  |7t|AjQ|AjQ q|d ur jud usBJ  jujv}BtO jetO| j%jdksTJ  fd*dta| j%jdD }Cta|-tO|9d  D ]>\}6}|B|j5 }D|C|D }A|Ajhtijwkrtljx}E|AjQ}@n|Ajhtijjkrtljy}E|D}@ntzd+|Ajh |97tp|Etq|j5d(|@ qktOtO|)ksJ t{|8|9d,}%tP|)D ]5\}F}Gt1|Fj2d tEj|s|Fj2d |Gj2d< |GjQ|%j}v s|GjQ|%j~v r|Fj2= D ]
\}H}I|I|Gj2|H< qq|$|%| j(fS )-Nr   )_materialize_and_lift_constants)aot_export_module)2_disable_custom_triton_op_functional_decomposition_export_to_aten_ir_ignore_backend_decomps_verify_nn_module_stack_verify_placeholder_names_verify_stack_trace)ShapeEnvc                 S   s   |d up	| j jd uS rJ   )graph_signaturebackward_signature)epr   rP   rP   rQ   _is_joint_ir_decompp  s   
zO_decompose_and_get_gm_with_new_signature_constants.<locals>._is_joint_ir_decompF)Zremove_duplicate)!unwrap_tensor_subclass_parametersT)	shape_envexport)&_enable_graph_inputs_of_type_nn_module_fakify_script_objectsplaceholdervalr3   )r   Z_check_autograd_stateZ_prettify_placeholder_namesdecompose_custom_triton_opsc                    s(   i | ]\}}|t |tr | n|qS rP   )
isinstancer   ).0r[   obj)map_fake_to_realrP   rQ   
<dictcomp>  s    
zF_decompose_and_get_gm_with_new_signature_constants.<locals>.<dictcomp>c                 S      g | ]	}|j d kr|qS r   rn   r   noderP   rP   rQ   
<listcomp>A  s    zF_decompose_and_get_gm_with_new_signature_constants.<locals>.<listcomp>c                 S   s   g | ]}|j d  qS )r   )metar   rP   rP   rQ   r   D      c                 S   s   g | ]\}}|qS rP   rP   )r   rK   _rP   rP   rQ   r   F  s    )ZdecompositionsZtrace_jointZoutput_loss_indexc                 S   sx   t | tr| S t | trt|jdS t | trt|jdS t | tr(t|jdS t | tr3t|jdS tdt|  )NrK   zType of old_arg not supported: )	r   r5   r?   rK   r>   r=   r<   RuntimeErrortype)Zold_argnew_phrP   rP   rQ   
update_argb  s   




zF_decompose_and_get_gm_with_new_signature_constants.<locals>.update_argc                 S   r   r   r   r   rP   rP   rQ   r   o      c                 S   s   i | ]}|j |j qS rP   r   )r   phrP   rP   rQ   r   x  r   )_node_metadata_hook_set_node_metadata_hook)_graph_output_nameszUFile "torch/fx/passes/runtime_assert.py", line 24, in insert_deferred_runtime_asserts)stack_tracezexported program: )r   c                    s,   i | ]\}}t |jts|jj | jqS rP   )r   argr5   rK   r   rN   spec)new_placeholdersrP   rQ   r     s    
c                    s0   g | ]\}}t |j|j | |j|jqS rP   )r9   kindr   target
persistentr   )r   r   rP   rQ   r     s    c                 S   s   i | ]\}}||qS rP   rP   )r   rN   rK   rP   rP   rQ   r     r   c                 S   s   g | ]}|j qS rP   r   r   rP   rP   rQ   r     s    r   )r   r   r   c                    s(   i | ]\}}t |jtr j| |qS rP   )r   r   r?   user_inputsr   )r   rP   rQ   r     s    

zUnknown input kind: input_specsoutput_specs)Z(torch._export.passes.lift_constants_passr   Ztorch._functorch.aot_autogradr   torch.export._tracer   r   r   r   r   r   Z%torch.fx.experimental.symbolic_shapesr   modulerk   named_parametersnamed_buffersZ7torch._functorch._aot_autograd.subclass_parametrizationr   r   graph_moduler   Z	_out_specgraph_codegenZpytree_info	orig_argsr   rV   tuplerX   rY   r   r   Z_in_spec	recompiler   r   	constantsr#   
state_dictnon_persistent_buffersr   r   Ztorch._export.non_strict_utilsr   r   nodesrn   r   r   r6   Zfake_valrK   Zreal_objappendr   r   example_inputstree_unflattenvaluesrr   gmsigr    r"   r!   r&   !_remove_unneccessary_copy_op_passrv   nn	Parameterpopdelattrr)   
contextlibnullcontextZeliminate_dead_coder]   lenzipr   r$   r   Z(torch._export.passes._node_metadata_hookr   r   Z4torch._functorch._aot_autograd.input_output_analysisr   Z_dynamoconfigZdo_not_emit_runtime_asserts_get_shape_envrb   ry   r   r   	enumeratefxNoder   r   user_inputs_to_mutater   r   r8   
USER_INPUTBUFFERr:   BUFFER_MUTATIONUSER_INPUT_MUTATIONr   r;   r?   r   ZLOSS_OUTPUTgetr   Zgradients_to_user_inputs	PARAMETERZGRADIENT_TO_PARAMETERZGRADIENT_TO_USER_INPUTAssertionErrorr7   TensorZinputs_to_parametersZinputs_to_buffers)Jr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   modZwrapped_params_buffersr   Zunwrapped_params_buffers	fake_moderH   Zorig_arg_namesZtemp_registered_constantsZfake_params_buffersZparams_buffers_to_node_metar   r   Zretracing_argsr   Zreal_script_objZretracing_args_unwrappedZpatched_modZnew_fake_argsZnew_fake_kwargsZnew_fake_constant_attrsZaten_export_artifactr   new_graph_signaturer   rK   pZold_placeholdersZ	fake_argsZbuffers_to_removeZ#custom_triton_ops_decomposition_ctxZnew_outputsZold_phr   Zname_mapr   r   r   r   r   rN   Zold_new_placeholder_mapr   r   Zuser_inputs_indexZmutation_namesZoutput_nameZ
input_nameZ
input_specZoutput_kindr   r   Z	gradientsspecssourcer   old_noderM   r   vrP   )r   r   r   r   rQ   2_decompose_and_get_gm_with_new_signature_constants\  sB   




	   R





	   





$	




r   r   r   c                 C   s   |  | Q | jjD ]=}|jdkrIt|j\}}|D ]+}t|t	j
jrH|j|jv rH|jdkrH|jt	jjjjkrH||jd  | j| qq|   W d   | |fS 1 s[w   Y  | |fS )zQ
    Removes redundant copy_ node that was introduced due to mutated buffer.
    outputcall_functionr3   N)_set_replace_hookget_replace_hookr   r   rn   rX   tree_flattenr]   r   rv   r   r   rK   buffers_to_mutater   r   r   rs   defaultrR   
erase_noder   )r   r   r   r]   r   outrP   rP   rQ   r     s$   



r   c              	   C   s  |  | q |  D ]c}t|tjjsqi }i }t|jj	D ]N}|j
dkri|jtjkri|j\}}||  d| }	|	|v r`|||	  |D ]}
|
jd urX|
j|||	  qH|j| q |||	< |	||< q |j||< q qW d    d S 1 s{w   Y  d S )Nr   .)r   r   modulesr   rv   r   GraphModulerV   r   r   rn   r   operatorgetitemr]   rR   r\   r  rK   )r   r   module_call_graphr   Znode_idZgetitemsr   r   idxZnew_identryrP   rP   rQ    _common_getitem_elimination_pass'  s2   


"r  old_module_call_graphc           	      C   s   t |}i }| jjD ]}|jdg  }r|j||d j< q|D ]}|j}|d u r+q!g |j|j	D ]}||j|j|_q3q!|S )NZ	from_noder   )
rs   deepcopyr   r   r   r   rK   r\   rE   rF   )	r   r  new_module_call_graphZ
provenancer   historyr  r\   xrP   rP   rQ   _get_updated_module_call_graphD  s   
r  r   c             
   C   sb   t | ||||d\}}}t|| j}|j| jj t|| j}	t||j	|||	|| j
| jd}
|
S )Nr   r   r   r   )rootr   r   r   range_constraintsr
  r   r   )r   r  r
  r   r|   r   _get_updated_range_constraintsr  rA   r   r   r   )r   r   r   r   r   r   r   r   r  Znew_range_constraintsZexported_programrP   rP   rQ   _decompose_exported_program\  s>   
r  c                   @   s  e Zd ZdZ		dcdddeejjee	e
f f dejjdedee	eejejjf f dd	d
ee deeee
df ee	e
f f  deee	eejeejjf f  deeee   fddZeedddd Zejedddd Zeedddd Zejedddd Zeedddd Zejedddd Zeedddd Z e jedddd Z eddde!ejj fd d!Z"eddde!ee	ejjf  fd"d#Z#eddde!ej fd$d%Z$eddde!ee	ejf  fd&d'Z%eeddd(d) Z&e&jeddd*d) Z&eeddd+d, Z'e'jeddd-d, Z'eeddd.d/ Z(e(jeddd0d/ Z(eeddd1d2 Z)e)jeddd3d2 Z)eeddde
fd4d5Z*e*jeddd6d5 Z*eeddde	fd7d8Z+e+jeddd9d8 Z+eeddd:d; Z,e,jeddd<d; Z,eeddd=d> Z-e-jeddd?d> Z-eeddd@dA Z.e.jedddBdA Z.dCdD Z/dEe
dFe
de
fdGdHZ0dEe
dFe
de
fdIdJZ1dKdL Z2de	fdMdNZ3dejjfdOdPZ4dQdR Z5e6		dddSeeej7j8e9f  dTe:dd fdUdVZ;dWe<dd fdXdYZ=dZd[ Z>eddd\d] Z?e@d^d_ ZAdddd`	 dedadbZBdS )frA   a  
    Package of a program from :func:`export`. It contains
    an :class:`torch.fx.Graph` that represents Tensor computation, a state_dict containing
    tensor values of all lifted parameters and buffers, and various metadata.

    You can call an ExportedProgram like the original callable traced by
    :func:`export` with the same calling convention.

    To perform transformations on the graph, use ``.module`` property to access
    an :class:`torch.fx.GraphModule`. You can then use
    `FX transformation <https://pytorch.org/docs/stable/fx.html#writing-transformations>`_
    to rewrite the graph. Afterwards, you can simply use :func:`export`
    again to construct a correct ExportedProgram.
    N)	verifiersr  r   r   r   r  dict[sympy.Symbol, Any]r
  r   .r   r  c	          
      C   s   t jj |_t||| _t|t jjr| jj	
|j	 t| j|| || _|| _|| _|d us2J || _|| _|p;i | _|	pAtg}	tdd |	D sMJ |	| _|   d S )Nc                 s   s    | ]}t |tV  qd S rJ   )rj   r'   )r   r   rP   rP   rQ   	<genexpr>  s    z+ExportedProgram.__init__.<locals>.<genexpr>)rv   r   r   ZCodeGenr   _create_graph_module_for_export_graph_moduler   r  r   r|   r  _graph_signature_state_dict_range_constraints_module_call_graph_example_inputs
_constantsr'   all
_verifiersvalidate)
rL   r  r   r   r   r  r
  r   r   r  rP   rP   rQ   __init__  s$   

zExportedProgram.__init__F)Zis_backward_compatiblec                 C      | j S rJ   )r  rL   rP   rP   rQ   r        zExportedProgram.graph_modulec                 C      t d)Nz7Unable to set ExportedProgram's graph_module attribute.r   rL   valuerP   rP   rQ   r        c                 C   s   | j jS rJ   )r   r   r)  rP   rP   rQ   r     r/  zExportedProgram.graphc                 C   r+  )Nz0Unable to set ExportedProgram's graph attribute.r,  r-  rP   rP   rQ   r     r/  c                 C   r(  rJ   )r  r)  rP   rP   rQ   r     r*  zExportedProgram.graph_signaturec                 C   r+  )Nz:Unable to set ExportedProgram's graph_signature attribute.r,  r-  rP   rP   rQ   r     r/  c                 C   r(  rJ   )r  r)  rP   rP   rQ   r     r*  zExportedProgram.state_dictc                 C   r+  )Nz5Unable to set ExportedProgram's state_dict attribute.r,  r-  rP   rP   rQ   r     r/  ri   c                 c       |   D ]\}}|V  qdS )zH
        Returns an iterator over original module's parameters.
        N)r   )rL   r   paramrP   rP   rQ   
parameters     zExportedProgram.parametersc                 c   s$    | j jD ]
}|| j| fV  qdS )z
        Returns an iterator over original module parameters, yielding
        both the name of the parameter as well as the parameter itself.
        N)r   r2  r   )rL   
param_namerP   rP   rQ   r     s   z ExportedProgram.named_parametersc                 c   r0  )zC
        Returns an iterator over original module buffers.
        N)r   )rL   r   bufrP   rP   rQ   buffers   r3  zExportedProgram.buffersc                 c   sJ    t | jj}| jjD ]}||v r|| j| fV  q|| j| fV  qdS )z
        Returns an iterator over original module buffers, yielding
        both the name of the buffer as well as the buffer itself.
        N)rq   r   r   r6  r   r   )rL   r   Zbuffer_namerP   rP   rQ   r     s   zExportedProgram.named_buffersc                 C   r(  rJ   )r   r)  rP   rP   rQ   r    r*  z!ExportedProgram.range_constraintsc                 C   r+  )Nz<Unable to set ExportedProgram's range_constraints attribute.r,  r-  rP   rP   rQ   r       c                 C   r(  rJ   )r!  r)  rP   rP   rQ   r
  !  r*  z!ExportedProgram.module_call_graphc                 C   r+  )Nz<Unable to set ExportedProgram's module_call_graph attribute.r,  r-  rP   rP   rQ   r
  &  r7  c                 C   r(  rJ   )r"  r)  rP   rP   rQ   r   -  r*  zExportedProgram.example_inputsc                 C   sz   |d u r	|| _ d S t|tr"t|dkr"t|d tr"t|d ts&td|\}}ddlm} |||| jj	 || _ d S )N   r   r3   zqExample inputs should be a tuple containing example arguments (as a tuple), and example kwargs (as a dictionary).)_check_inputs_match)
r"  r   r   r   rk   
ValueError_unliftr9  	call_specrG   )rL   r.  r]   r^   r9  rP   rP   rQ   r   2  s"   
c                 C   s\   t dddg}t| jdkr|d d dS | jd jdksJ || jd jj| jd jjdS )NCallSpecrG   rH   r   )rG   rH    )r   r   r
  r[   r\   rG   rH   )rL   r=  rP   rP   rQ   r<  M  s   zExportedProgram.call_specc                 C   r+  )Nz4Unable to set ExportedProgram's call_spec attribute.r,  r-  rP   rP   rQ   r<  Z  r/  c                 C   s
   | j d S Nr   r%  r)  rP   rP   rQ   verifier_  s   
zExportedProgram.verifierc                 C   r+  )Nz3Unable to set ExportedProgram's verifier attribute.r,  r-  rP   rP   rQ   rA  d  r/  c                 C   s   | j d usJ | j d jS r?  )r%  dialectr)  rP   rP   rQ   rB  i  s   zExportedProgram.dialectc                 C   r+  )Nz2Unable to set ExportedProgram's dialect attribute.r,  r-  rP   rP   rQ   rB  o  r/  c                 C   r(  rJ   r@  r)  rP   rP   rQ   r  t  r*  zExportedProgram.verifiersc                 C   r+  )Nz4Unable to set ExportedProgram's verifiers attribute.r,  r-  rP   rP   rQ   r  y  r/  c                 C   r(  rJ   r#  r)  rP   rP   rQ   tensor_constants~  r*  z ExportedProgram.tensor_constantsc                 C   r+  )Nz;Unable to set ExportedProgram's tensor_constants attribute.r,  r-  rP   rP   rQ   rD    r7  c                 C   r(  rJ   rC  r)  rP   rP   rQ   r     r*  zExportedProgram.constantsc                 C   r+  )Nz4Unable to set ExportedProgram's constants attribute.r,  r-  rP   rP   rQ   r     r/  c                 C   sP   | j j}|durt||}t||f\}}| | tdd |D }||fS )a  Flatten args, kwargs using pytree, then, check specs.

        Args:
            args: List[Any] original args passed to __call__
            kwargs: Dict[str, Any] original kwargs passed to __call

        Returns:
            A tuple of (flat_args, received_spec)
            flat_args is flattend args / kwargs
            received_spec is the pytree spec produced while flattening the
            tuple (args, kwargs)
        Nc                 s   s    | ]}|d  V  qdS )r3   NrP   )r   r  rP   rP   rQ   r    s    z<ExportedProgram._get_flat_args_with_check.<locals>.<genexpr>)r<  rG   r-   rX   Ztree_flatten_with_path_check_input_constraintsr   )rL   r]   r^   rG   flat_args_with_pathreceived_spec	flat_argsrP   rP   rQ   _get_flat_args_with_check  s   

z)ExportedProgram._get_flat_args_with_checkr]   r^   c                 C   s   | j j}| ||\}}|dur t||ts td| d| g }| jjD ]=}|jt	j
kr/q&|jt	jt	jfv rQ|jdu rG|| j|j  q&|| j|j  q&|jt	jt	jfv rc|| j|j  q&t|}|| S )a,  Transform args, kwargs of __call__ to args for graph_module.

        self.graph_module takes stuff from state dict as inputs.
        The invariant is for ep: ExportedProgram is
        ep(args, kwargs) ==
          ep.postprocess(ep.graph_module(ep.graph_module_flat_inputs(args, kwargs)))
        Nz>Trying to flatten user inputs with exported input tree spec: 
z-
but actually got inputs with tree spec of: 
F)r<  rG   rI  r,   rl   r:  r   r   r   r8   r   r   r   r   r   r   r   r   ZCONSTANT_TENSORZ
CUSTOM_OBJr   )rL   r]   r^   rG   rH  rG  Zadditional_inputsZinput_rP   rP   rQ   _graph_module_flat_inputs  s>   	

z)ExportedProgram._graph_module_flat_inputsc                 O   r+  )Nz\Unable to call ExportedProgram directly. You should use `exported_program.module()` instead.r,  )rL   r]   r^   rP   rP   rQ   __call__  s   zExportedProgram.__call__c                    sF  ddl m  m} | ||\}}| jjdur!| jj}| jj}t	|t	| }	|d|	 }
| jj
}|durDtt| }|d| }||	d }z~z
t|| jj}W n typ   t|\}}|d| jj d| w W dd | jjD }t|
D ]G\}}| jj|   jtjkr jdusJ || j j< q jtjkr jdusJ t fddt|D }|| | qtd	 j |S dd | jjD }t|
D ]I\}}| jj|   jtjkr jdusJ || j j< qֈ jtjkr jdusJ t fddt|D }|| | qtd	 j w |S )
zProcess potential mutations to the input.

        Because self.graph_module is functional, so mutations has to be written
        back after execution of graph_module.
        r   Nz@Trying to flatten user outputs with exported output tree spec: 
z.
but actually got outputs with tree spec of: 
c                 S   s   g | ]
}|j tjkr|qS rP   r   r8   r   )r   r   rP   rP   rQ   r      s
    zEExportedProgram._postprocess_graph_module_outputs.<locals>.<listcomp>c                 3   s&    | ]\}}|j j jkr|V  qd S rJ   )r   rK   r   r   Zoutput_specrP   rQ   r    s    zDExportedProgram._postprocess_graph_module_outputs.<locals>.<genexpr>zUnexpected kind: )Ztorch._export.errorZ_exporterrorrI  r<  rH   r   r  r   r   assertion_dep_tokennextiterr   rX   r   	Exceptionr   ZInternalErrorr   r   r   r   r:   r   r   r   r   Zcopy_r   )rL   resr   Zorig_kwargsrN  rH  r   Zbuffer_mutationZuser_input_mutationZnum_mutatedZmutated_valuesrO  Zassertion_dep_token_indexrG  r   rN   r.  indexrP   rM  rQ   !_postprocess_graph_module_outputs  st   
z1ExportedProgram._postprocess_graph_module_outputsc                 C   s8   | j jddddd}d| d| j d| j d}|S )NF)Zprint_outputZcolored
z
    zExportedProgram:
    z
Graph signature: z
Range constraints: )r   Zprint_readablereplacer   r  )rL   r   stringrP   rP   rQ   __str__  s   zExportedProgram.__str__c                 C   sT   ddl m} || }d
dtfdd}d
dtfdd}t|||_t|||_|S )z_
        Returns a self contained GraphModule with all the parameters/buffers inlined.
        r3   )&_unlift_exported_program_lifted_statesTmodec                 S   r+  )Nz%Calling train() is not supported yet.NotImplementedErrorrL   r[  rP   rP   rQ   _train*     z&ExportedProgram.module.<locals>._trainc                 S   r+  )Nz$Calling eval() is not supported yet.r\  r^  rP   rP   rQ   _eval-  r`  z%ExportedProgram.module.<locals>._evalNT)r;  rZ  booltypes
MethodTypetraineval)rL   rZ  r   r_  ra  rP   rP   rQ   r   "  s   zExportedProgram.modulec                 C   s$   t dd t| jjD t| jjS )Nc                 s   s$    | ]\}}|j tjkr|V  qd S rJ   rL  )r   rN   srP   rP   rQ   r  6  s    z=ExportedProgram._num_lifted_params_buffers.<locals>.<genexpr>)rP  r   r  r   r   r)  rP   rP   rQ   _num_lifted_params_buffers4  s   

z*ExportedProgram._num_lifted_params_buffersr   r   c                 C   sF   |du rt  nt|}t|tr| }t|\}}t| ||d|dS )a  
        Run a set of decompositions on the exported program and returns a new
        exported program. By default we will run the Core ATen decompositions to
        get operators in the
        `Core ATen Operator Set <https://pytorch.org/docs/stable/torch.compiler_ir.html>`_.

        For now, we do not decompose joint graphs.

        Args:
            decomp_table:
             An optional argument that specifies decomp behaviour for Aten ops
             (1) If None, we decompose to core aten decompositions
             (2) If empty, we don't decompose any operator


        Some examples:

        If you don't want to decompose anything

        .. code-block:: python

            ep = torch.export.export(model, ...)
            ep = ep.run_decompositions(decomp_table={})

        If you want to get a core aten operator set except for certain operator, you can do following:

        .. code-block:: python

            ep = torch.export.export(model, ...)
            decomp_table = torch.export.default_decompositions()
            decomp_table[your_op] = your_custom_decomp
            ep = ep.run_decompositions(decomp_table=decomp_table)
        Nr  )rD   rk   r   r/   Zmaterializer   r  )rL   r   r   Z_decomp_tabler   r   rP   rP   rQ   run_decompositions>  s   (
z"ExportedProgram.run_decompositionspassesc                 G   s   t t|}ddlm} |  || j}W d    n1 sw   Y  |d ur+|jn| j}|d us4J || ju r>|js>| S dtdtjj	dtfdd}t
||j|| j|| jt|| jt| j| j| j| jd	}|jj| jj |jj|jj |S )	Nr   )r   old_signaturenew_gmri   c                 S   s.  g }t |jjD ];\}}|jdkr n1|t| jk sJ d| j| }t|jtt	fr.|jnt
|j|j}|t|j||j|j qt|jjd }|jdksSJ g }t |jd D ]2\}}|t| jk skJ d| j| }	t|	jtt	fr{|	jnt
|	j|j}|t|	j||	j q\t||d}
|
S )zO
            Update the graph signature's user_input/user_outputs.
            r   z-Number of inputs changed after transformationr   r   r   z.Number of outputs changed after transformationr   )r   r   r   rn   r   r   r   r   r5   r6   r   rK   r   r9   r   r   r   rV   r]   r   r;   r7   )rl  rm  Znew_input_specsrN   r   Zold_input_specr   Zoutput_nodeZnew_output_specsZold_output_specZnew_signaturerP   rP   rQ   _get_updated_graph_signature  s^   


	

zKExportedProgram._transform_do_not_use.<locals>._get_updated_graph_signature	r  r   r   r   r  r
  r   r   r  )r2   rV   r   r   r   modifiedr7   rv   r   r  rA   r   r   r   r  r  rs   r  r!  r   r   r  r   r|   )rL   rk  pmr   rS  Ztransformed_gmrn  Ztransformed_eprP   rP   rQ   _transform_do_not_use  sF   
9
z%ExportedProgram._transform_do_not_usec                 C   sH   ddl m} dd | jjD }dd t|| jjD }|||| j d S )Nr   )"_check_input_constraints_for_graphc                 S   r   r   r   )r   r   rP   rP   rQ   r     r   z<ExportedProgram._check_input_constraints.<locals>.<listcomp>c                 S   s    g | ]\}}|j tjkr|qS rP   rL  )r   r   rh  rP   rP   rQ   r     s
    )torch._export.utilsrs  r   r   r   r   r   r  )rL   rF  rs  ZplaceholdersZinput_placeholdersrP   rP   rQ   rE    s   z(ExportedProgram._check_input_constraintsc                 C   s   |    d S rJ   )	_validater)  rP   rP   rQ   r&    s   zExportedProgram.validatec                 C   s2   t | jdksJ d| jD ]}| |  qd S )Nr   z0ExportedProgram must have at least one verifier.)r   r  check)rL   r   rP   rP   rQ   ru    s   
zExportedProgram._validate)r   r   r  c                C   s\   t ||j||d ur|n| jt| jt| j| j|d ur|n| j|d ur)|d	S | j	d	S )Nro  )
rA   r   r   rs   r  r  r!  r   r   r  )rL   r   r   r   r   r  rP   rP   rQ   _update  s   	


	zExportedProgram._update)NN)NF)ri   rA   )CrS   rT   rU   __doc__r
   rv   r   Modulerk   rZ   r   r   Graphr7   r   r   rV   rB   r   r   r   rw   ZScriptObjectr   r'   r'  propertyr0   r   setterr   r   r   r   r2  r   r6  r   r  r
  r   r<  rA  rB  r  rD  r   rI  rJ  rK  rU  rY  r   ri  rd   _opsOperatorBaser   rc  rj  PassTyperr  rE  r&  r   ru  rw  rP   rP   rP   rQ   rA     s   	
' .7
F\

rA   c                 C   sZ   dd | j jD }ddlm} ||}|d ur|jS |D ]}t|tjr*|jj  S qd S )Nc                 S   s(   g | ]}|j d ddur|j d  qS )r   N)r   r   r   rP   rP   rQ   r     s
    z"_get_shape_env.<locals>.<listcomp>r   r(   )	r   r   torch._guardsr)   r   r   rv   ZSymIntr   )r   valsr)   r   r   rP   rP   rQ   r     s   r   old_range_constraintsz!Optional[dict[sympy.Symbol, Any]]r  c                    sr   |d usJ t |   d u ri S t|} fdd| D } j D ]\}}| jvr6||vr6|||< q%|S )Nc                    s    i | ]\}}| j vr||qS rP   )replacements)r   r   r   r   rP   rQ   r   -  s    z2_get_updated_range_constraints.<locals>.<dictcomp>)r   rs   rr   Zvar_to_ranger  )r   r  r  r   r   rP   r  rQ   r  "  s   

r  c                 C   sN   z
t j| |}W |S  ty&   td t j| t j }||_Y |S w )NzUnable to execute the generated python source code from the graph. The graph module will no longer be directly callable, but you can still run the ExportedProgram, and if needed, you can run the graph module eagerly using torch.fx.Interpreter.)rv   r   r  SyntaxErrorwarningswarnrz  Z_graph)r  r   r   rP   rP   rQ   r  9  s   r  rb  )ri   r/   rJ   )r   rs   dataclassesrb   r  rd  r  collectionsr   collections.abcr   r   typingr   r   r   r   r	   r
   Ztorch._higher_order_ops.utilsr   Z"torch._library.fake_class_registryr   Ztorch._subclasses.fake_implsr   r   r   Ztorch._subclasses.fake_tensorr   Ztorch.fx._utilsr   Ztorch.fx.graphr   r   Ztorch.fx.immutable_collectionsr   r   Ztorch.fx.passes.runtime_assertr   ZsympyZtorch.utils._sympy.value_rangesr   rv   Ztorch.utils._pytreeutilsZ_pytreerX   rt  r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   Ztorch._export.verifierr'   r  r)   r+   Ztorch.export._tree_utilsr,   r-   Ztorch.export.decomp_utilsr/   Ztorch.fx._compatibilityr0   Ztorch.fx.passes.infra.pass_baser1   Z"torch.fx.passes.infra.pass_managerr2   r   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   __all__r   r  r  	dataclassrC   rB   rd   r   Contextrc  rl   rw   rx   ZAutogradCPUZAutogradCUDAZAutogradMetaZAutogradXLAZAutogradLazyZAutogradIPUZAutogradXPUZAutogradMPSZAutogradHPUZAutogradPrivateUse1ZAutogradPrivateUse2ZAutogradPrivateUse3ru   ZCPUCUDAZMetaZXLAZLazyZIPUZXPUZMPSZHPUrz   r   r   rk   r}  r~  r   r   rD   intr   r   r  rV   r  r  rA   r   r  r  rP   rP   rP   rQ   <module>   s   D<	
[


,	
   5



4     
