
    iS                       % S r SSKrSSKrSSKrSSKrSSKrSSKJrJr  SSKJ	r	J
r
JrJrJrJrJrJrJr  SSKJs  Jr  SSKJs  Jr  SSKrSSKrSSKJrJr  SSKJr  SSK J!r!  SSK"J#r#J$r$J%r%  SS	K&J'r'  SS
K(J)r)  SSK*J+r+J,r,  SSK-J.r.J/r/J0r0J1r1J2r2J3r3J4r4J5r5J6r6J7r7J8r8J9r9J:r:J;r;J<r<J=r=J>r>J?r?J@r@JArAJBrBJCrCJDrDJErEJFrFJGrGJHrHJIrIJJrJJKrKJLrLJMrM  SSKNJOrOJPrPJQrQJRrRJSrSJTrTJUrUJVrV  SSKWJXrXJYrY  SSKZJ[r[  SSK\J]r]J^r^  SSK_J`r`  SSKaJbr  SSKcJdrd  \ " S S5      5       re\ " S S5      5       rf\ " S S5      5       rg\\g\\g   \\gS4   4   rh\d\iS'   \\j\k\l\R                  \S   4   rm\d\iS'   \\R                  \R                  \R                  \R                  \R                  \R                  \R                  4   ru\d\iS'   \\
S\m4   \v4   rw\d\iS'   \\h\S   \S    \\vS 4   \v\k\l\j\x\R                  \R                  \R                  \R                  S4   r|\d\iS '   \\\k\\k   4   \\v\\k   4   4   r}\d\iS!'    " S" S#\R                  R                  5      r " S$ S%\5      rg)&a  Takes an ExportedArtifact, or a collection of ExportedArtifacts, in execution dialect, and turns
them into a single ExecuTorch Program.

The provided ExportedArtifact's graph modules are in execution dialect and the emitter parses and
converts them into executorch instructions. The emitter walks the provided graphs and as it
encounters concrete values such as tensors or ints, it converts them to the serialized format and
stores them in a list for later use. The emitter walks the graph by traversing fx.nodes, these can
come in a variety of forms and are the primitives of execution at the graph module level. The most
common 3 we care about are 'call_function', 'place_holder', and 'output'. 'placeholder' and 'output'
handle io for the module and 'call_function' handles everything else. Within 'call_function' we may
encounter an operator or delegate call, in such case we parse the schema and emit all the inputs and
outputs (unless they have already previously been emitted), and then we convert the actual function
call into an executorch instruction such as KernelCall or DelegateCall.

When control flow is present in the graphmodule it will take the form of a few different types of
'call_function'. Today (June 14th 2023) only cond and map are supported. The actual operations of
these, such as the true/false branches of cond, or the mapping function of map, are stored as sub
graphmodules. When these are encountered during emission, the emitter will recursively emit them and
their instructions.
    N)	dataclassfield)	AnyCallablecastDictListMappingOptionalTupleUnion)executorch_call_delegateis_lowered_module)BackendOpOverload)EdgeOpOverload)ExportErrorExportErrorTypeInternalError)is_out_variant)	is_sym_op)_stacktrace_to_framelistinspect_node) AllocationDetailsBackendDelegateBackendDelegateDataReferenceBackendDelegateInlineDataBoolBoolListBufferChainContainerMetadataDataLocationDelegateCallDouble
DoubleListEValueExecutionPlanExtraTensorInfoFreeCallInstructionIntIntListJumpFalseCall
KernelCallMoveCallNullOperatorOptionalTensorList
ScalarTypeStringTensorTensorDataLocation
TensorListTensorShapeDynamism)AddressSpaceOverflowExceptiondim_order_from_stridelayout_enummake_allocation_infomake_tensor_valuememory_format_enumscalar_type_enum
TensorSpec)LeafValueSpec	ValueSpec)
FakeTensor)ExportedProgramExportGraphSignature)Node)_pytree)	TypeAliasc                   T   \ rS rSr% Sr\" \S9r\\	   \
S'   \" \S9r\\\4   \
S'   \" \S9r\\\4   \
S'   \" S S9r\\   \
S'   \" S	 S9r\\   \
S
'   \" \S9r\\   \
S'   \" \S9r\\\4   \
S'   \" \S9r\\   \
S'   \" \S9r\\\4   \
S'   \" \S9r\\\\\4   4   \
S'   Srg)_ProgramStatef   zState shared between all methods of a program and the graph module it represents.

Initialized once within emit_program and then shared across each entry point as they are
emitted.
default_factoryallocated_specscached_spec_hash_valuescached_spec_mutable_hash_valuesc                      [        SS9/$ N    storager    rS   \/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/exir/emit/_emitter.py<lambda>_ProgramState.<lambda>w   s    6RUCVBWrS   constant_bufferc                      [        SS9/$ rR   rV   rW   rS   rX   rY   rZ   y   s    &QTBUAVrS   mutable_bufferbackend_delegate_databackend_delegate_data_cacheexternal_constant_bufferexternal_constant_hashexternal_constant_maprW   N)__name__
__module____qualname____firstlineno____doc__r   listrN   r	   r@   __annotations__dictrO   r   strintrP   r[   r   r]   r^   r   r_   r`   bytesra   rb   __static_attributes__rW   rS   rX   rJ   rJ   f   s     ).d(COT*%C /4D.IT#s(^I6;D6Q#T#s(^Q$):W$XOT&\X#(9V#WNDLW >CSW=X4 9:X272Mc3hM -2$,Gd5kG-24-HDcNH 8=T7R4T#s(^ 34RrS   rJ   c                       \ rS rSr% Sr\\   \S'   \\   \S'   \\	   \S'   \
\\\4   \4   \S'   \\S'   \\S'   \" \S	9r\
\\4   \S
'   S\S\4S jrSrg)_EmitterState   zState of a single emitter.

Local to at least the entry point, and may be local to a subgraph of an entry point originating
from control flow.
values	operators	delegatesoperator_cacheemit_stacktraceemit_mutable_buffer_namesrL   spec2id_dictspecreturnc                 n    XR                   ;   d   SUR                  5        35       eU R                   U   $ )z4Map a TensorSpec to value index in the values array.zSpec is not found: )rx   debugselfry   s     rX   spec2id_EmitterState.spec2id   s8    (((N,?

~*NN(  &&rS   rW   N)rc   rd   re   rf   rg   r	   r&   ri   r1   r   r   r   rk   rl   boolr   rj   rx   r@   r   rn   rW   rS   rX   rp   rp      sw     LH~O$$sCx#-..##*/*EL$z3'E'J '3 'rS   rp   c                   4    \ rS rSr% Sr\\S'   \\   \S'   Sr	g)_AbstractValue   z$Represents an already emitted EValueidtensorrW   N)
rc   rd   re   rf   rg   rl   ri   r   r5   rn   rW   rS   rX   r   r      s    . 	G VrS   r   ._EmitterValue_PythonValue_SchemaType_Target)	_Argument.r   _DelegateDebugIdentifierMapc                     ^  \ rS rSr% Sr\R                  R                  \S'      SQS\R                  R                  S\
S\S\S	\\\      S
\\\      SS4U 4S jjjrS\R                  R                  S\S\4S jrS\S\R                  R                  S\SS4S jrS\\   S\4S jrS\\   S\S\4S jrS\S\4S jrS\S\S\SS4S jr  SRS\S\S\S\\   S\\   S\4S jjr SSS\S\\   S\4S  jjr S\!\"\   \\   4   S\4S! jr#S\S\\   S\4S" jr$S\S\4S# jr%S\&S\'4S$ jr(S%\)SS4S& jr*S'\"\S(4   S)\\\      S\\   4S* jr+S'\"\S(4   S)\\   S\\   4S+ jr,S'\"\S(4   S)\\   S\\   4S, jr-S-\.S'\"\S(4   S.\/\\4   S\'4S/ jr0S'\"\S(4   S\'4S0 jr1 SSS1\S-\.S2S3SS4S4 jjr2S2S5S6\SS4S7 jr3S8\S9\\   S\4S: jr4S\"\!\Rj                  \Rl                  \Rn                  \84      S\\   4S; jr9S\"\!\Rj                  \Rl                  \Rn                  \84      S\S\!\\   \\"\S(4   4   4S< jr:S2S5S'\"\S(4   S.\/\\4   S\'4S= jr;STS>\S?\S\"\\<4   4S@ jjr=S-\.S'\"\S(4   S.\/\\4   S\'4SA jr>S\S\4SB jr?SC\/\\@4   S\\A   4SD jrBS-\.S\4U 4SE jjrCS-\.S'\"\S(4   S.\/\\4   SS4SF jrDS-\.S'\"\S(4   S.\/\\4   S\'4SG jrES-\.S'\"\S(4   S.\/\\4   S\4SH jrFS-\.S'\"\S(4   S.\/\\4   SS4SI jrGS-\.S'\"\S(4   S.\/\\4   S\'4SJ jrHSSK.S'\SL\\/\R                  R                  \4      SS4U 4SM jjjrISN\R                  R                  SS4U 4SO jjrJSPrKU =rL$ )U_Emitter   zAn abstract interpreter (https://wiki.mozilla.org/Abstract_Interpretation) used to emit the
given traced torch.fx.GraphModule to the flatbuffer schema.nodeNgraph_moduleemitter_stateprogram_stateinstruction_start_offsetbinding_input_valuesbinding_output_valuesrz   c                   > [         TU ]  U5        X l        X0l        / U l        [        / / / S S9U l        SUR                  R                  5       ;  a  [        S5      eX@l
        XPl        X`l        Xl        [        U R                  R                  R                   5      U l        SU l        / U l        0 U l        0 U l        0 U l        g )Ninputsoutputsinstructions
stacktracenon_const_buffer_sizeszGMust set 'non_const_buffer_sizes' in graph meta in memory planning passr   )super__init__r   r   r   r    chainmetakeysRuntimeErrorr   r   r   r   rh   graphnodesplaceholder_countconcrete_output_idsdebug_handle_mapinstruction_id_to_num_outs_map!instr_id_to_delegate_debug_id_map)r~   r   r   r   r   r   r   	__class__s          rX   r   _Emitter.__init__   s     	&**"$	

 $<+<+<+A+A+CCY  )A%$8!%:"2>*.t/@/@/F/F/L/L*M
 "#9; BD>@+  	.rS   err_msgc                 f    S[        U5       S3[        U R                  R                  U5      -   nU$ )z:Returns 'err_msg' with node specific information attached.zFailed with error: 
)rk   r   r   r   )r~   r   r   s      rX   _emit_node_specific_error"_Emitter._emit_node_specific_error  s8    'G~R8<##T<
 
 rS   pred
assert_msgc                 F    U(       d  [        U R                  X#5      5      eg)zDIf pred is False, construct and raise a node specific error message.N)r   r   )r~   r   r   r   s       rX   _internal_assert_emitter!_Emitter._internal_assert_emitter
  s"      > >t PQQ rS   valc           	         / nU H  n[        U[        5      (       a  UR                  UR                  5        M5  [        U[        5      (       a<  UR                  U R                  U R                  US5      5      R                  5        M  U R                  SU R                  S5        M     [        [        U5      5      $ )a  Emits a list of integers as a collection of EValues.

For every argument in 'val':
    - If it is a concrete value, then emit it and then place its location in the boxed list
    - If it is already an abstract value, then just place its location in the boxed list

Int lists are boxed to handle symints whose values are determined at runtime, but could
still end up inside lists for ops like view_copy(Tensor self, SymInt[] size)
NFz)Unsupported type encountered in int list.)
isinstancer   appendr   rl   _emit_evalue_constant_to_evaluer   r   r&   r,   )r~   r   
boxed_listitems       rX   _emit_int_list_Emitter._emit_int_list  s     
D$//!!$''*D#&&!!%%d&>&>tT&JKNN --499&Q  gj)**rS   val_typec                    [        U[        R                  5      (       a4  [        [	        [
        R                  " [        [           U5      5      5      $ [        U[        R                  5      (       a  U R                  U5      $ [        U[        R                  5      (       a4  [        [        [
        R                  " [        [           U5      5      5      $ [        U[        R                  5      (       az  / nU H^  n[        U[        5      (       d   eU R!                  UR"                  SLU R$                  S5        UR'                  UR(                  5        M`     [        [+        U5      5      $ [        U[        R,                  5      (       a  UR/                  5       n[        U[        R                  5      (       ag  / nU HK  nUc  UR'                  S5        M  [        U[        5      (       d   eUR'                  UR(                  5        MM     [        [1        U5      5      $ [3        [4        R6                  SU 35      e)a  Emits a list type.

Emits the list stored in val. If the list is of Tensors, Optionals, or Ints the emitted list
is boxed, otherwise the values are constant at runtime and stored inline.

NOTE: When symbool and symfloat are supported bool and float lists will be stored boxed.
NzGAbstractValue corresponding to tensor type doesn't contain tensor valuezUnknown list type: )r   torchBoolTyper&   r   typingr   r	   r   IntTyper   	FloatTyper%   float
TensorTyper   r   r   r   r   r   r7   OptionalTypegetElementTyper2   r   r   NOT_SUPPORTED)r~   r   r   rr   vactual_typevalss          rX   
_emit_list_Emitter._emit_list*  s    h//(6;;tDz3#?@AAh..&&s++h00*V[[ec%BCDDh 0 011F!!^4444--HHD(II]
 add#  *V,--h 2 233"113K+u'7'788AyB)!^<<<<ADD)  0677))-@
+K
 	
rS   ry   c                    U R                  [        UR                  [        5      =(       a    UR                  S:  U R                  SUR                   35        U R                  [        UR
                  [        5      =(       a    UR
                  S:  U R                  SUR
                   35         [        UR                  UR
                  5      nU$ ! [         a-  n[        U R                  U R                  U S35      5      eSnAff = f)z3Returns the allocation info for a given TensorSpec.r   z8Non-const tensor should be an activation tensor: mem_id z<Non-const tensor should be an activation tensor: mem_offset z
Hint: If you are using a memory pass based on dynamic shape bounds, such as ConstraintBasedSymShapeEvalPass, this may be the cause of an unbacked SymInt with its upper bound lazily set to 2^64-1 (uint64 max) during torch.export().N)
r   r   mem_idrl   r   
mem_offsetr<   r9   r   r   )r~   ry   allocation_infoes       rX   _get_allocation_info_Emitter._get_allocation_infoY  s    %%t{{C(=T[[A-=IIFt{{mT	
 	%%t,EA1EIIJ4??J[\	

	24;;PO  - 	..II# 1 1
 
	s   2 C 
D(DDfqn
buffer_idxconstant_tagc                     U[        U R                  R                  5      :  d   eX0R                  R                  ;  a  0 U R                  R                  U'   X R                  R                  U   U'   g)z%
Saves external constant to the map.
N)lenr   r`   rb   )r~   r   r   r   s       rX   _save_to_external_constant_map'_Emitter._save_to_external_constant_mapv  sd     C 2 2 K KLLLL11GGGEGD44\BFP00>sCrS   buffer_datahashedr   c                    U R                   R                  R                  U5        [        US9nUR                  b  UR                  R
                  b  UR                  R                  [        R                  :X  a  Uc   S5       e[        U R                   R                  5      nXpR                   R                  U'   U R                   R                  R                  U5        U R                  UR                  R
                  Xu5        U$ U(       a^  [        U R                   R                  5      nXpR                   R                  U'   U R                   R                  R                  U5        U$ [        U R                   R                  5      nXpR                   R                   U'   U R                   R                  R                  U5        U$ )zMSaves a new constant tensor to the constant buffer and returns the buffer idxrT   z+Constant tag is not set for external tensor)r   rN   r   r   extra_tensor_infofully_qualified_namelocationr6   EXTERNALr   r`   ra   r   r]   rP   r[   rO   )r~   ry   r   r   r   r   bufferr   s           rX   _save_new_const_tensor_Emitter._save_new_const_tensor  s    	**11$7 , "".&&;;G&&//3E3N3NN (=<=(
 T//HHIJ@J55f=77>>{K//&&;;Z  T//>>?JIS>>vF--44V< 	 T//??@JAK66v>..55f=rS   c           
         SnSnUR                   b  UR                  b  U R                  U5      nUR                  (       Ga  [        R
                  [        R                  " [        R                  UR                  5      R                  5       -  nUR                  S:w  ay  [        [        R                  " [        R                  " [        R                  UR                  5      R                  5       [        R                  " U5      5      R                   5      OSn["        R$                  " U5      R'                  5       nU(       a4  UR(                  c'  U R*                  R,                  R/                  US5      nOUR(                  b  UR(                  R0                  [2        R4                  :X  ar  U R*                  R6                  R/                  US5      nUS:w  aE  UR(                  R8                  c   eUc   eU R;                  UR(                  R8                  UU5        O&U R*                  R<                  R/                  US5      nUS:X  a  U R?                  XXsU5      nUR                  (       a_  UR                  5       [A        U5      :w  aB  [C        U RE                  U RF                  S[A        U5       SUR                  5        35      5      e[I        [K        XCU5      5      $ )z/Constructs an EValue from the given TensorSpec.Nr   rS   r   zTensor spec has buffer of size z, but expected nbytes of )&r   r   r   constctypesc_charr   r   r   UntypedStoragerU   nbytesallocated_memoryrm   data_ptrPOINTERcontentshashlibsha256	hexdigestr   r   rP   getr   r6   r   ra   r   r   rO   r   r   r   r   r   r&   r=   )r~   ry   r   r   r   spec_array_typer   r   s           rX   _tensor_spec_to_evalue_Emitter._tensor_spec_to_evalue  sk   
 

 ;;"t'B"77=O ::: E,@,@$,, O V V XX  ((A- KKE$8$8$,,GPPR7 h	   ^^K0::<F4#9#9#A!//OOSSB
 &&2**337I7R7RR!//FFJJ6SUV
#  11FFRRR'33377..CC"$ "//GGKKFTVW
 R!88v
 zzdkkms;/??#22		9#k:J9KKdeiepeperdst  '
TJKKrS   c                 Z   [        U[        [        45      (       d   S[        U5       35       e[	        S U 5       5      nU(       a  [
        R                  R                  5       $ [        US   [        5      (       a  [
        R                  R                  5       $ [        US   [        5      (       a  [
        R                  R                  5       $ [        US   [        5      (       a  [
        R                  R                  5       $ [        U R                  U R                   S5      5      e)z/Returns the JIT type for the given python type.zaInput to _get_list_tuple_jit_type was expected to be an instance of a list or tuple but received c              3   l   #    U  H*  n[        U[        5      =(       a    UR                  S Lv   M,     g 7fN)r   r   r   ).0r   s     rX   	<genexpr>4_Emitter._get_list_tuple_jit_type.<locals>.<genexpr>	  s+      
LOqJq.)Bahhd.BBCs   24r   zbCouldn't determine JitType for list/tuple of elements. Only supports int, float, bool, and Tensor.)r   rh   tupletypeallr   r   r   rl   r   r   r   r   r   r   r   r   )r~   r   is_tensor_types      rX   _get_list_tuple_jit_type!_Emitter._get_list_tuple_jit_type  s    $
 
 	{nostwoxnyz	{ 
  
LO
 
 ##''))A$$==$$&&A%%>>%%''A&&??&&((**		t
 	
rS   c           
      ^   Uc  [        [        5       5      $ [        U[        [        45      (       a  Uc%  [
        R                  " U R                  U5      5      n[        U[
        R                  5      (       a  UR                  5       n[        U[
        R                  5      (       d   eU R                  [        R                  " [        [           U5      [        R                  " [        UR                  5       5      5      $ [        U[         5      (       a  [        [#        U5      5      $ [        U[$        5      (       a  [        ['        U5      5      $ [        U[(        5      (       a  [        [+        U5      5      $ [        U[,        5      (       a  [        [/        U5      5      $ [        U[
        R0                  5      (       a  [        [+        [3        U5      5      5      $ [        U[
        R4                  5      (       a  [        [+        [7        U5      5      5      $ [        U[
        R8                  5      (       a   [        [+        [;        U5      5      5      $ [        U[
        RD                  5      (       a4  [G        [H        RJ                  U RA                  U RB                  S5      5      e[G        [H        RJ                  U RA                  U RB                  S[M        U5      RN                   35      5      e! [<         a)    [?        U RA                  U RB                  SU 35      5      ef = f)a'  Converts a constant value to an EValue.

Returns an EValue given the Python representation and JIT type. On common paths there should
always be a JIT type provided. Users can pass in a None to infer the JIT type but this
should never be the default case due to the existence of container types.
z>Tensor has a memory_format that is unsupported in ExecuTorch: zoconstant_to_evalue should not be encountering constant tensors, they should be emitted through other codepaths.zUnsupported constant type: )(r&   r0   r   rh   r  r   ListTyper  r   r   r   r   r   r	   r   r   r   r$   r   r   rl   r+   rk   r4   dtyper?   layoutr;   memory_formatr>   KeyErrorr   r   r   r5   r   r   r   r  rc   )r~   r   r   s      rX   r   _Emitter._constant_to_evalue  sp    ;$&>!cD%=))  >>11#6 (E$6$677#224h7777??DOS1K)@)@)BC 
 c5!!&+&&c4  $s)$$c3#c(##c3&+&&c5;;''#.s3455c5<<((#k#./00c5..//c"4S"9:;; c5<<((--..II F  ))**		8c9K9K8LM
 	
#  #22		XY\X]^ s   ?K9 93L,c                     U R                   R                  R                  U5        [        UR                  [
        5      (       a  UR                  OSn[        [        U R                   R                  5      S-
  U5      $ )zWrites an EValue to the emitter state.

Given an Evalue, adds it to the emitter_state's values table, and returns the AbstractValue
representing it.
N   )r   rr   r   r   r   r5   r   r   )r~   r   r   s      rX   r   _Emitter._emit_evaluef  s\     	!!((-&sww77Tc$"4"4";";<q@&IIrS   c                 X   ^  S[         S[        4U 4S jjn[        R                  " X!5      $ )zVGiven the provided spec constructs the corresponding EValue from it and then emits it.ry   rz   c                 j  > [        U [        [        45      (       a%  [        TR	                  TR
                  S5      5      eTR                  [        U [        5      TR
                  SU  35        TR                  TR                  U 5      5      nUR                  TR                  R                  U '   U$ )NzBNode spec should be either non-nested container or a scalar objectz/Invalid node spec expected TensorSpec received )r   rh   r  r   emit_node_specific_errorr   r   r@   r   r   r   r   rx   )ry   retr~   s     rX   _process%_Emitter._emit_spec.<locals>._processs  s    $u..#11		\  ))4,		A$H ##D$?$?$EFC47FFD++D1JrS   )rA   r   pytreetree_map)r~   ry   r  s   `  rX   
_emit_spec_Emitter._emit_specp  s'    	= 	^ 	, x..rS   r   c                 b    U R                   R                  R                  UR                  5        g)zvMerges the chain generated from subgraphs (like those originating from control flow) back
into the main program chain.N)r   r   extend)r~   r   s     rX   _merge_chain_Emitter._merge_chain  s"     	

&&u'9'9:rS   args. subemitter_binding_output_valuesc           
         Uu  p4pV[        U[        R                  R                  5      (       d   e[	        UU R
                  U R                  U R                  [        U R                  R                  5      -   S-   [        R                  " [        [           U5      US9nUR                  5         [        U[        5      (       d   e[!        [#        UR$                  U R                  [        U R                  R                  5      -   [        UR                  R                  5      -   S-   S95      nU R                  R                  R'                  U5        U R)                  UR                  5        [        U[        R                  R                  5      (       d   e[	        UU R
                  U R                  U R                  [        U R                  R                  5      -   S-   [        R                  " [        [           U5      US9n	U	R                  5         U R+                  [-        [/        S5      5      5      n
[!        [#        U
R$                  U R                  [        U R                  R                  5      -   [        U	R                  R                  5      -   S-   S95      nU R                  R                  R'                  U5        U R)                  U	R                  5        U$ )a^  Emits control_flow.cond.

Converts the higher order op into jumps and inlines the submodules of the true and false
branches. Control flow can be nested. The general emitted structure is: <Jump Instruction> -
decides which branch to take <True Branch> <Jump Instruction> - jumps to End Of Cond after
executing true branch <False Branch> <End Of Cond>
r  r   r   r      cond_value_indexdestination_instructionF)r   r   fxGraphModuler   r   r   r   r   r   r   r   r   r	   r   runr*   r-   r   r   r  r   r&   r   )r~   r   r!  r   true_branchfalse_branchr   true_branch_emitterjf_instruction_to_skip_truefalse_branch_emittervaluejf_instruction_to_skip_falses               rX   
_emit_cond_Emitter._emit_cond  sz    37/< +uxx';';<<<<&%)%B%B$**))*&+& "(T.-A6!J"B	
 	! $////&1!%(,(E(Edjj--.)/)//<<=)> )
'
# 	

&&'BC-334 ,(<(<===='%)%B%B$**))*&+& "(T.-A6!J"B	 
 	  " !!&e"56'2!&(,(E(Edjj--.)/*00==>)? )(
$ 	

&&'CD.445//rS   c                    [        U[        [        45      (       d   SU S35       e[        U5      S:w  a  [	        S[        U5       S35      eUu  p4n[        U[        [        45      (       d   e[        U5      nUS:w  a  [	        SU S35      eUS   n[        U[
        R                  R                  5      (       d   eU R                  [        [        S5      5      5      nU R                  SSS	9u  pU R                  [        [        S5      5      5      n[        [        U	UR                  U R                  [        [        S5      5      5      R                  UR                  /S
95      nU R                  R                   R#                  U5        U R                  SSS	9u  p[        [        U	UR                  U R                  [        [        S5      5      5      R                  UR                  SS/S
95      nU R$                  [        U R                  R                   5      -   nU R                  R                   R#                  U5        ['        UU R(                  U R*                  U R$                  [        U R                  R                   5      -   S/UQUS9nUR-                  5         U R/                  UR                  5        U R                  R                   R1                  5         UR2                  S   R                  UR4                  R6                  S'   UR4                  R6                  S   UR4                  R6                  S'   U R9                  [        UR:                  5      S:H  U R<                  S5        U R                  SSS	9u  p[        [        U	US   R                  UR:                  S   R                  UR                  /S95      nU R                  R                   R#                  U5        U R                  SSS	9u  p[        [        U	UR                  U R                  [        [        S5      5      5      R                  UR                  /S95      nU R                  R                   R#                  U5        U R                  [        [?        S5      5      5      nU R                  SSS	9u  p[        [        U	UR                  UR                  UR                  /S95      nU R                  R                   R#                  U5        [        [A        UR                  US95      nU R                  R                   R#                  U5        U R                  SSS	9u  p[        [        U	UR                  UR                  UR                  /S95      nU R                  R                   R#                  U5        U$ )ai  Emits torch.map.

Converts the higher order op into a loop constructed from jump instructions and primitive
int operations. A concat-like custom op is also injected into the submodule code to handle
the construction of the map output.

Below is what the input graph that is provided to emit_map looks like. class
TestMapCond(torch.nn.Module): def __init__(self):
    super().__init__()

def forward(self, x,y):
    return control_flow.map(map_fn, x, y)

Corresponding graph: def forward(self, arg0_1, arg1_1):
    submodule_0 = self.submodule_0 map_1 = torch.ops.higher_order.map_impl(submodule_0, arg0_1, arg1_1);
    submodule_0 = arg0_1 = arg1_1 = None return [map_1]

submodule_0: def forward(self, arg0_1, arg1_1):
    add_tensor = torch.ops.aten.add.Tensor(arg0_1, arg1_1);  arg0_1 = arg1_1 = None return
    add_tensor

Post the transformations done by emit_map this is what the submodule program looks like. def
forward(self, arg0_1, arg1_1):
    sym_size = torch.ops.aten.sym_size(arg0_1) # Emitter creates a variable here to track
    iteration index select_copy_tensor = torch.ops.aten.select(arg0_1, 0, iteration_index)
    add_tensor = torch.ops.aten.add.Tensor(select_copy_tensor, arg1_1);  arg0_1 = arg1_1 =
    None output_of_map = torch.ops.executorch.prim.et_copy_index(output_of_map, add_tensor,
    iteration_index) iteration_index = torch.ops.executorch.prim.add.int(iteration_index, 1,
    iteration_index) done_bool = torch.ops.executorch.prim.eq.int(iteration_index, sym_size,
    done_bool) # Emitter inserts a instruction here, if done_bool == False jump to
    selcect_copy op # if not continue. return add_tensor
z@Expect a list for subemitter_binding_output_values for map. Got .r  z(Multiple outputs are not supported. Got zBEmitting map with more than one mapped args is not supported. Got r   aten::sym_sizerl   nameoverloadop_indexr   aten::select_copyint_outr   r#  z"Map should return only one elementexecutorch_prim::et_copy_indexr   r   executorch_prim::addScalarFexecutorch_prim::eqr%  executorch_prim::sub)!r   rh   r  r   r   r   r(  r)  r   r&   r+   _get_operatorr*   r.   r   r   r   r   r   r   r   r   r*  r  popr   
instr_argsr   r   r   r   r   r-   )r~   r   r!  fmapped_argsr   num_mapped_argsxiter_idxr;  opsym_sizekerneljump_to_instructionmap_emitterjump_bool_valuejf_beginning_loops                    rX   	_emit_map_Emitter._emit_map  s`   J ,tUm
 
 	rMNnMoopq	r 
 /0A5:3?_;`:aabc  "&+e}5555";/aTUdTeefg  N!UXX112222 $$VCF^4 ))! * 
 $$VCF^4!ddD--fSVn=@@(++N
 	

&&v. ))$ * 
 !DD%%fSVn588KK	
 #;;cJJ##?
 
 	

&&v. %)%B%B$**))*&+ #%v"B	
 	 	+++,

##% &1%E%Ea%H%K%Kr"%+%6%6%;%;B%?r"%%//0A5II0	
 ))1 * 
 4Q7::33A699KK	
 	

&&v. ))' * 
 kk4#4#4VCF^#D#G#GU
 	

&&v.++F4;,?@
 ))& * 
 kk8;;0B0BC
 	

&&v.'!0!3!3(;
 	

&&'89 ))' * 
 kk8;;<
 	

&&v.//rS   c                    Uu  p4pV[        U[        [        45      (       d!   S[        U5      R                   SU S35       e[        U[
        R                  R                  5      (       d   e[        U[        [        45      (       d   e[        U[        [        45      (       d   e[        U[        [        45      (       d   e[        U5      n[        U5      n[        USU 5      n	[        X'S 5      n
US:  a  [        SU 35      eU R                  [        [        S5      5      5      nU R                  SS	S
9u  pU R                  [        [        S5      5      5      n[        [        UUS   R                   U R                  [        [        S5      5      5      R                   UR                   /S95      nU R"                  R$                  R'                  U5        U R                  SS9u  nn[)        XI5       H  u  nn[        [        UUR                   UR                   U R                  [        [+        S5      5      5      R                   UR                   /S95      nU R"                  R$                  R'                  U5        M     U R                  SSS
9u  nn/ nU Hk  n[        [        UUR                   U R                  [        [        S5      5      5      R                   UR                   SS/S95      nUR'                  U5        Mm     U R,                  [        U R"                  R$                  5      -   nU H(  nU R"                  R$                  R'                  U5        M*     / nUR/                  U	5        UR/                  S/U-  5        UR/                  U5        [1        UU R2                  U R4                  U R,                  [        U R"                  R$                  5      -   USS9nUR7                  5         U R9                  UR"                  5        [;        U5       HT  u  nnUR<                  UU-      R                   nUUR>                  R@                  S'   UUR>                  R@                  S'   MV     URB                  nUSU nUUS nU RE                  [        U5      U:H  U RF                  SU S[        U5       35        U RE                  [        U5      [        U
5      :H  U RF                  S[        U
5       S[        U5       35        [)        UU	5       H  u  nn[        [        UUR                   UR                   U R                  [        [+        S5      5      5      R                   UR                   /S95      nU R"                  R$                  R'                  U5        M     U R                  SSS
9u  n n[)        UU
5       H_  u  n!n"[        [        U U"R                   U!R                   UR                   /S95      nU R"                  R$                  R'                  U5        Ma     U R                  SSS
9u  n#n[        [        U#UR                   U R                  [        [        S5      5      5      R                   UR                   /S95      nU R"                  R$                  R'                  U5        U R                  [        [+        S5      5      5      n$U R                  SSS
9u  n%n[        [        U%UR                   UR                   U$R                   /S95      nU R"                  R$                  R'                  U5        [        [I        U$R                   US95      n&U R"                  R$                  R'                  U&5        U R                  SSS
9u  n'n[        [        U'UR                   UR                   UR                   /S95      nU R"                  R$                  R'                  U5        U$ )aW  Emits torch.scan.

Converts the higher order scan op into a loop constructed from jump instructions
and primitive operations. Scan differs from map in that it maintains a carry state
that evolves across iterations.

Scan signature: scan(combine_fn, init, xs, additional_inputs)
    - combine_fn: GraphModule that takes (carry, x_slice, *additional_inputs)
                  and returns (next_carry, y_slice)
    - init: Initial carry state (list of tensors)
    - xs: Input tensors to scan over (list of tensors, scanned along dim 0)
    - additional_inputs: Additional arguments passed to combine_fn

Output: (final_carry, stacked_ys)
    - final_carry: The carry state after the last iteration
    - stacked_ys: All y outputs stacked along dim 0

Memory Layout:
    - carry_outputs (subemitter_binding_output_values[:num_carry]):
      Working carry buffers, initialized from init, updated each iteration
    - y_outputs (subemitter_binding_output_values[num_carry:]):
      Pre-allocated stacked output buffers, filled via et_copy_index

The combine_fn writes to its own temporary output buffers (concrete_output_ids).
After each iteration:
    1. Copy combine_fn's carry output -> carry_outputs (for next iteration)
    2. et_copy_index(y_outputs, combine_fn's y output, iter_idx)

This explicit copy approach is used because in-place op.out(x, out=x) is unsafe.
z8Expected list for subemitter_binding_output_values. Got z: r5  Nr  z:Scan requires at least one xs tensor to scan over but got r   r6  rl   r7  r:  zaten::copy_)r8  Fr<  r=  r   r#  r>  zScan combine_fn should output z carry values, got z y values, got r?  r   rA  rB  rC  r%  rD  )%r   rh   r  r  rc   r   r(  r)  r   r   r   r&   r+   rE  r*   r.   r   r   r   r   zipr   r   r  r   r   r   r*  r  	enumerater   rG  r   r   r   r   r-   )(r~   r   r!  
combine_fninitxsadditional_inputs	num_carrynum_xscarry_outputs	y_outputsrL  r;  rM  rN  rO  op_index_copy_init_val	carry_outop_index_selectxs_slice_instructionsrK  rP  r   scan_emitterixs_placeholder_idconcrete_outputs
carry_tempy_tempcarry_top_index_copy_indexy_ty_outop_index_addrR  op_index_eqrS  op_index_subs(                                           rX   
_emit_scan_Emitter._emit_scan  sf   F 37/
":T5MJJ 	
89BBC2/03	
J *ehh&:&:;;;;$u...."tUm,,,,+dE];;;;I	R=jyIJ9*EF	A:LVHU  $$VCF^4))! * 
 $$VCF^4!ehh 1 1&Q. A D DhkkR
 	

&&v.  --=-Aq#&t#;Hi *! ))&e*=>AA!	
F JJ##**62 $< "//$ 0 
 !#A ,))&Q.9<< 	F "((0  #;;cJJ##?
 
 ,FJJ##**62 , +-##M2##RD6M2##$56%)%B%B$**))*&+!5"&
 	,,,-"#89IAv , A A)a- P S S):F""2&):F""2& :
 (;;%jy1
!)*-%%
Oy(II,YK7J3z?J[\	

 	%%K3y>)II,S^,<OCPVK=Y	
 #&j-"@GY *!

))&e*=>AA!	
F JJ##**62 #A "&!3!31 "4 "
Q fi0JC 0((CFFHKK8F JJ##**62 1 ,,' - 
a %kk4#4#4VCF^#D#G#GU
 	

&&v. ++F4;,?@++& , 
Q $kk8;;0B0BC
 	

&&v.'!0!3!3(;
 	

&&'89 ,,' - 
a %kk8;;<
 	

&&v.//rS   targetkwargsc                   ^  T R                   R                  S   nU[        R                  R                  R
                  L ae  Uu  pVpx[        U5      n	[        U[        [        45      (       a9  XIS n
U
 H/  n[        U[        5      (       d  M  [        R                  Ul        M1     OjU[        R                  R                  R                  L aC  [        U5      S:X  d   e[        US   [        5      (       d   e[        R                  US   l        [        R                   " U 4S jU5      nU[        R                  R                  R"                  L a  T R%                  X,5      $ U[        R                  R                  R                  L a  T R'                  X,5      $ U[        R                  R                  R
                  L a  T R)                  X,5      $ [+        T R-                  T R                   SU 35      5      e)zWraps common logic for emitting all control flow operations.

See the more specific emission functions for more details on how cond, map, or scan get emitted.
ry   Nr  r   c                 &   > TR                  U 5      $ r   )r  )ry   r~   s    rX   rY   -_Emitter._emit_control_flow.<locals>.<lambda>  s    .rS   z#Unsupported control flow operator: )r   r   r   opshigher_orderscanr   r   rh   r  r@   r8   DYNAMIC_BOUNDshape_dynamismmap_implr  r  condr2  rT  rt  r   r   )r~   rv  r   rw  specsrY  rZ  r[  r\  r]  y_specsy_specr!  s   `            rX   _emit_control_flow_Emitter._emit_control_flow  s    		v& UYY++0006:3JbD	I%$//
+%F!&*550C0Q0Q- & uyy--666u:?"?eAh
3333&9&G&GE!H#+1??.,
(
 UYY++000??4JJuyy--666>>$IIuyy--222??4JJ..II!DVHM rS   c                 T   [        U5      S:X  d   eU R                  R                  S   nUR                  nUR                  S L=(       a    UR
                  S LnU=(       d!    UR                  =(       a    UR                  S LnU(       a  U(       a  U R                  U5      $ U R                  US   [        R                  5      nU R                  US   [        R                  R                  5       5      nU R                  U R                  U R                  R                  S   5      [        R                  5      nU R                  SSS9u  p[        [!        UUR"                  UR"                  UR"                  /S95      n
U R$                  R&                  R)                  U
5        U$ )	Nr$  ry   r   r  zexecutorch_prim::et_viewdefaultr7  r@  )r   r   r   is_static_shape_tensorr   r   r   rU   r  _emit_argumentr   r   r	  ofIntsrE  r*   r.   r   r   r   r   )r~   r   ry   	is_staticis_memory_plannedself_argsize_argout_argop_idxrM  rO  s              rX   
_emit_view_Emitter._emit_view  sg   4yA~~ yy~~f%//	![[4W4??RV;V- 
JJ34<<t3 	 *??4((&&tAw0@0@A&&tAw0E0E0GH%%OODIINN623U5E5E
 ''+ ( 

 KKKKJJ	
 	

&&v.rS   
emitter_idlowered_modulezOptional[LoweredBackendModule]c                 "   U[         :X  Ga  / nUR                  R                  R                   H]  nUR                  S:X  d  M  UR
                  R                  S5      c  M3  UR                  UR
                  R                  S5      5        M_     UR                  R                  R                  5       nUR                  S   n[        U[        [        45      (       a  [        U5      OSnX@R                  U'   XR                  U'   XR                   R
                  S'   gU R                   R
                  R                  S5      bK  U R                   R
                  R                  S5      U R                  U'   XR                   R
                  S'   gg)aX  Updates the debug handle information for the current node.

If the current node is a delegate we agregate the debug handles of the subgraph and store
them in the map. If the current node is any other type we store the original information in
the debug handle map and replace it with the executorch instruction index corresponding to
this node.
call_functiondebug_handleNr   r  )r   original_moduler   r   rM  r   r   r   output_noder   r   rh   r  r   r   r   r   )	r~   r  rv  r  debug_handle_listr   r  r   num_outputss	            rX   _add_debug_handle_Emitter._add_debug_handle  s8     -- " '66<<BBGG.		n5A%,,TYY]]>-JK C )88>>JJLK!&&q)G*4WtUm*L*L#g,RSK0A!!*->I//
; .8IINN>*99>>n-904		0B0B>0RD!!*- .8IINN>* :rS   LoweredBackendModuledelegate_instruction_idc                     0 nUR                   b  UR                   R                  S0 5      nUR                  US.U R                  U'   g)z
Store the delegate map from this lowered module into the dictionary of delegate maps. It
will later be used for various debugging purposes such as linking back to original source
code, module hierarchy etc.
Nr   )r8  delegate_map)r   r   
backend_idr   )r~   r  r  r  s       rX   _add_delegate_map_Emitter._add_delegate_map  sP     *)..223ErJL #--(K
../FGrS   argarg_typec                 p    [        U[        5      (       a  U$ U R                  U R                  X5      5      $ )zEmit an argument to an operator or delegate if it had not already been emitted otherwise
return the previously emitted location)r   r   r   r   )r~   r  r  s      rX   r  _Emitter._emit_argument/  s2    
 c>**J  !9!9#!HIIrS   c                    Sn[        U[        R                  5      (       a%  U R                  [	        [        S5      5      5      nU$ [        U[        R                  5      (       a%  U R                  [	        [        S5      5      5      nU$ [        U[        R                  5      (       a#  U R                  [	        [        S5      5      5      nU$ )z%
Returns the emit ret for sym value.
Nr   F)
r   r   SymIntr   r&   r+   r   r   r   r$   )r~   r   r  s      rX   _get_sym_ret_Emitter._get_sym_ret8  s     c5<<((##F3q6N3C
 
	 U^^,,##F4;$78C 
 U__--##F6!9$56C
rS   c                 d    U R                  U5      nUc  U R                  U5      nUc   S5       eU$ )NzCan't have a None ret)r  r  )r~   r   ry   r  s       rX   _get_sym_and_fake_tensor_ret%_Emitter._get_sym_and_fake_tensor_retH  s<     $;//$'C7 77
rS   c           	      	   UR                   n[        R                  " U5      R                  5       nU R                  R
                  R                  U5      nSn[        U R                  R                  S   [        5      (       a  / n[        U R                  R                  S   5       H\  u  pU R                  U R                  R                  S   U   U R                  R                  S   U   5      n
UR                  U
5        M^     GO[        U R                  R                  S   [        5      (       Ga  [        U R                  R                  S   [        5      (       aH  U R                  U R                  R                  S   U R                  R                  S   S   5      n
U
4nGO./ n[        U R                  R                  S   5       H\  u  pU R                  U R                  R                  S   U   U R                  R                  S   U   5      n
UR                  U
5        M^     [        U5      nO[        U R                  R                  S   [         5      (       aC  U R                  U R                  R                  S   U R                  R                  S   5      n
U
nO/[#        S[%        U R                  R                  S   5       S35      eUc   S5       eUcc  ['        U R                  R
                  5      nX`R                  R
                  U'   U R                  R(                  R                  [+        US95        [-        UR.                  [1        [2        R4                  US	9UR6                  S
9nU R8                  R:                  R                  U5        [<        R>                  " [@        [B           U5       Vs/ s H  nU RE                  US5      RF                  PM!     nn[H        RJ                  " U5      S    H  nUR                  URF                  5        M      U RL                  RN                  R                  [Q        [S        ['        U R8                  R:                  5      S-
  US95      5        U$ s  snf )z`Emit the delegates inputs and outputs as specified by the schema, then emit the
delegate's blob.Nry   r   r   zself.node.meta['spec'] z is not supportedzCan't have a None delegate_ret)data)r   index)r   	processedcompile_specsr  )delegate_indexr   )*processed_bytesr   r   r   r   r_   r   r   r   r   rh   rX  r  r   r  rC   r@   NotImplementedErrorr  r   r^   r   r   r  r   r"   INLINEr  r   rt   r   r   r	   r   r  r   r  tree_flattenr   r   r*   r#   )r~   r  r   rw  r  r   r  delegate_retr  rb  r  backend_delegater  delegate_argselems                  rX   _emit_delegate_Emitter._emit_delegateU  s    )880::<++GGKKFSdiinnV,d33L%diinnU&;<77IINN5)%0$))..2H2O ##C(	 =
 		v.66$))../<<77IINN5)499>>&+A!+D !$v! )$))..*? @HE;;		u-e4diinnV6LU6SC !'',	 !A
  %\2		v.
;;33		u%tyy~~f'=C L%)$tyy~~f/E*F)GGXY  'I)II'! !!3!3!O!OPNES::6B44;;)? +((2%,,N )66
 	$$++,<= {{4	?D9
9 T*--9 	 

 ''5a8D  ) 9 	

&&#&t'9'9'C'C#Dq#H&	
 #
s   &Rr8  r9  c                 Z   X4nU R                   R                  R                  U5      nUb  X@R                   R                  U   4$ [	        U R                   R                  5      [        XS9pTU R                   R                  R                  U5        X@R                   R                  U'   XE4$ )zuGiven a fully qualified name, lookups the operator in the ExecuTorch Program, or adds it
if it is not already presentr7  )r   ru   r   rs   r   r1   r   )r~   r8  r9  keyr;  operators         rX   rE  _Emitter._get_operator  s     %%4488=//99(CCC !3!3!=!=>A
( 	$$++H519))#.!!rS   c                 
   [        U[        R                  R                  [        [
        45      (       d
   SU 35       eUR                  R                  nSnUR                  S:w  a  UR                  nS[        4S jnU R                  XES9u  px/ n	/ n
[        UR                  R                  5       H  u  pUR                  U;   a  X<R                     nO1UR                  (       d  U[!        U5      :  a  X+   nOUR"                  nUc?  [        UR$                  [        R&                  5      (       a  U R)                  U" 5       5      nU	R+                  U R-                  XR$                  5      R.                  5        UR0                  (       d  M  U
R+                  UR                  U45        M     [3        XE5      (       a.  U
 VVs/ s H  u  pUPM	     nnn[!        U5      S:X  a  US   OUnGOS[5        U5      (       Ga  [!        UR                  R6                  5      S:X  d   S	5       e[%        UR                  R6                  S   R$                  5      [        R8                  [        R:                  [        R<                  [        R>                  4;   d5   S
[%        UR                  R6                  S   R$                  5       S35       eU RA                  UR                  R6                  S   5      nUc#  U R)                  [        [C        S5      5      5      nO(U RE                  U RF                  RH                  S   5      n[        U[J        5      (       aL  U R)                  [        [M        U Vs/ s H  n[O        [P        U5      R.                  PM     sn5      5      5      OUn
[R        RT                  " U
5      S    H,  nU	R+                  [O        [P        U5      R.                  5        M.     U RV                  RX                  R+                  [[        []        XyS95      5        U R_                  [!        U RV                  RX                  5      S-
  U5        U R`                  Rb                  (       a  U RF                  RH                  S   nU RV                  Rd                  =(       d    / nUR+                  [g        U5      5        U Ri                  [!        U5      [!        U RV                  RX                  5      :H  U RF                  S[!        U RV                  RX                  5       S[!        U5       S35        UU RV                  l2        [O        [j        U5      $ s  snnf s  snf )zUEmits an operator (aten or custom), directly translates to a call_kernel instruction.z
target is  r  rz   c                  r    [        [        [        R                  SS/S/SSSS[        R
                  S9	5      $ )z)Constructs an EValue for an empty tensor.r   FN)	scalar_typestorage_offsetsizes	dim_orderrequires_gradr  data_buffer_idxr   r  )r&   r5   r3   BYTEr8   STATICrW   rS   rX   _get_empty_tensor_evalue9_Emitter._emit_operator.<locals>._get_empty_tensor_evalue  s@     *#$# c"'$%$(#6#=#= rS   r7  r  r   zEOnly returning a single Sym from symbolic ops is supported currently.zKOnly symbolic ops that return a Int Bool Float are supported currently got r5  ry   r:  stack_tracez?Each instruction should have corresponding stacktrace received z"                 instructions and z stacktraces)6r   r   _ops
OpOverloadr   r   _overloadpacket_qualified_op_name_overloadnamer&   rE  rX  _schema	argumentsr8  
kwarg_onlyr   default_valuer  r   r   r   r  r   is_outr   r   returnsr   r   r   
NumberTyper  r+   r  r   r   rh   r7   r   r   r  r  r   r   r*   r.   r  r   rv   r   r   r   r   )r~   rv  r   rw  op_nameop_overloadr  r;  r  kernel_argsout_argsrh  
schema_arg
kernel_argrb  r   r  r  r  chain_stacktraces                       rX   _emit_operator_Emitter._emit_operator  s    UZZ**N<MN
 
 	!x 	! 

 ((;;9, ..K	& 	" "//W/S &v~~'?'?@MA&(#OO4
**q3t9}!W
 (55
!j%BRBR&S&S!../G/IJ
t22:ORRS   * => A" '//%-.X613XC.HM#a&sCvFNN**+q0WVW0..q1667  	<  E
 ]]abhbpbpbxbxyzb{  cA  cA  ^B  ]C  CD  EE  ##FNN$:$:1$=>C{ ''s1v7//$)).."89C #t$$ z3"O3C4#<#?#?3"OPQ  	 ''1!4DtND9<<= 5 	

&&
HGH	
 	s4::#:#:;a?H --))..7K#zz44:##$<[$IJ))$%TZZ-D-D)EE		QRUVZV`V`VmVmRnQo p""%&6"7!8F %5DJJ!M3''e /, #Ps   U0$Uc           	          U R                   R                  R                  [        [	        U R
                  R                  U5      S95      5        [        SS5      $ )zJEmits a FreeCall instruction to release a given Unbounded Tensor's memory.)value_indexN)r   r   r   r*   r)   r   r   r   r}   s     rX   
_emit_free_Emitter._emit_free"  sG    

&&T-?-?-G-G-MNO	
 dD))rS   prim_gettersc                 R   / nUR                  5        GH  u  p4[        R                  " U5      u  pVUR                  5       n[	        / / / SS9n/ nU GH  n	[        U	[        5      (       a%  UR                  [        [        U	5      5      5        M>  [        U	[        5      (       a%  UR                  [        [        U	5      5      5        Mx  [        U	[        5      (       a%  UR                  [        [        U	5      5      5        M  [        U	[        5      (       a%  UR                  [        [        U	5      5      5        M  [        U	[         R"                  5      (       a/  UR                  [        [        [%        U	5      5      5      5        GM:  [        U	[         R&                  5      (       a/  UR                  [        [        [)        U	5      5      5      5        GM  [        U	[         R*                  5      (       a6  UR                  U R-                  [.        R0                  " U	SS95      5        GM  [3        [4        R6                  SU S[9        U	5       S35      e   UR                  [;        UU/ [=        [?        S[A        U5      5      5      U// / S/[C        S	U5      S
9	5        GM     U$ )z
Given a mapping of function names to return values, emit simple execution
plans that just return these constant values.

Precondition: All the values are primitives (bool, float, int, str, enum)
or structures (list, dict) of them.
Nr   Tr   zError emitting z which returns a value of type z$. which is not a supported primitiver   r  	r8  rr   r   r   chainsrs   rt   r   container_meta_type)"items	ex_pytreer  to_strr    r   r   r   r&   r$   r   r   rl   r+   rk   r4   r   r
  r?   r  r;   r5   r   r@   from_tensorr   r   r   r  r'   rh   ranger   r!   )
r~   r  plansmethodr   flattened_outputry   r   rr   r   s
             rX   _emit_prim_getters_Emitter._emit_prim_getters*  s    (..0LF%.%;%;D%A";;=D	E F'c5))MM&"56T**MM&c"34S))MM&S"23S))MM&"56U[[11MM&-=c-B)C"DEU\\22MM&[-=)>"?@U\\22MM33&223dC &'55)&1PQUVYQZP[[  A 7 (B LL! q#f+!67!7  ,-3(9"d(C
] 1v rS   c           	      X  > [         TU ]  U5      n[        U[        R                  5      (       a3  U R                  U R                  [        R                  " USS95      5      $ [        U[        R                  R                  5      (       a  [        [        R                  SU S35      eU$ )zQFetch weights and other module parameters. If the attribute is a tensor, emit it.Tr  zCustom class z is not supported in EXIR)r   
fetch_attrr   r   r5   r   r   r@   r  _CScriptObjectr   r   r   )r~   rv  attrr   s      rX   r  _Emitter.fetch_attrq  s    w!&)dELL))$$++J,B,B4t,TU  ehh3344--v%>?  KrS   c                 L    [        U R                  U R                  S5      5      e)9Unsupported in execution IR, so unhandled by the emitter.zcall_module is not supportedr   r   r   r~   rv  r   rw  s       rX   call_module_Emitter.call_module  &     **4996TU
 	
rS   c                 L    [        U R                  U R                  S5      5      e)r  zcall_method is not supportedr  r  s       rX   call_method_Emitter.call_method  r  rS   c                    U R                   U R                     nUS:X  aO  U R                  U R                  U R                  R
                  S   5      5      nX@R                   U R                  '   U =R                  S-  sl        U$ )a  Performs actions for the placeholder node of a graph module.

The placeholder node of the top level entry point is handled by TopLevelEmitter. This
function only executes on control flow subgraphs. Takes the inputs of the subgraph that had
not previously been emitted and emits them.
r   ry   r  )r   r   r   r   r   r   )r~   rv  r   rw  r0  s        rX   placeholder_Emitter.placeholder  s|     ))$*@*@A B;%%++DIINN6,BCE AF%%d&<&<=!#rS   c                    [        [        R                  " US   5      S   5      U l        U R                  nUb  [        R                  " U5      u  pVU R                  [        U5      [        U R                  5      :H  U R                  S5        [        U R                  U5       HX  u  pxXx:w  d  M  [        [        UR                  UR                  S95      n	U R                  R                  R                  U	5        MZ     gg)aJ  Performs actions for the output node of a graph module.

The output node of the top level entry point is handled by TopLevelEmitter. This function
only executes on control flow subgraphs. Takes the outputs of the subgraph (if any) and
inserts instructions to move them to the common output location between control flow
branches.
r   NzCThe number of binding output values should match the args to output)	move_frommove_to)rh   r  r  r   r   r   r   r   rW  r*   r/   r   r   r   r   )
r~   rv  r   rw  r   binding_output_listrb  r  r  instructions
             rX   output_Emitter.output  s     $((;(;DG(DQ(G#H  $ : : ,%+%8%89N%O"))'(C0H0H,II		U '*((*='"	 '"- 9<<L#K JJ++22;?' -rS   c                 Z   U[         R                  :X  a^  [        U5      S:X  d   e[        R                  " [
        [        [        4   US   5      n[        R                  " [        US   5      nXE   $ U[        R                  :X  a9  [        U5      S:X  d   eU R                  U R                  R                  S   5      $ U[        R                  :X  a  U R                  U5      $ U[        R                  :X  a%  [        U5      S:X  d   eU R!                  US   5      $ U["        R$                  R&                  R(                  ["        R$                  R&                  R*                  ["        R$                  R&                  R,                  ["        R$                  R&                  R.                  4;   a  U R1                  XU5      $ U[2        :X  as  US   n[5        U5      (       d   eU R7                  XbSS U5      n[        U R8                  R:                  5      S-
  nU R=                  XU5        U R?                  Xh5        U$ [A        U["        RB                  RD                  [F        [H        45      (       a  U RK                  XU5      $ [M        U RO                  U R                  SU 35      5      e)a  Performs actions for the call_function node of a graph module.

Dispatches based on 'target' and emits the corresponding function. 'call_function' is a
powerful node that contains many operations ranging from control_flow, to memory management,
to delegate and operator calls.
r$  r   r  ry   Nz!invalid target for call_function )(r  getitemr   r   r   r
   rl   r   memoryallocr  r   r   viewr  freer  r   r{  r|  r  r  
while_loopr}  r  r   r   r  r   r   r  r  r   r  r  r   r   r  r   r   )	r~   rv  r   rw  headr  r  r   r  s	            rX   r  _Emitter.call_function  s,    X%%%t9>!>;;wsM'9:DGDDKKT!W-E;v||#t9>!>??499>>&#9::v{{"??4((v{{"t9>!>??47++II""''II""++II""--II""''	
 
 **6@@//!!WN$^4444##NHfEA&)$***A*A&BQ&F#""#:NS"">KHUZZ**N<MN
 
 &&vV<<  ..II!B6(K rS   )initial_envr  c                0   > [         TU ]  " / UQUP7SS06  g)zITraverses all nodes in the graph module and emits each one appropriately.enable_io_processingFN)r   r*  )r~   r  r   r   s      rX   r*  _Emitter.run  s     	CTC;CUCrS   nc           	         > Xl          [        TU ]	  U5      nU$ ! [         aQ  n[	        U[
        [        45      (       a  Ue[        U R                  U R                   [        U5      5      5      UeSnAff = f)zExecutes and emits the specified node.

For more context on what a node is and what execution means see
https://pytorch.org/docs/stable/fx.html#torch.fx.Node
N)	r   r   run_node	Exceptionr   r   r   r   rk   )r~   r#  r  r   r   s       rX   r%  _Emitter.run_node  sv     		'"1%C 
  	!m[9::#22499c!fE		s    
A5AA00A5)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   NN)NNr   )r  )Mrc   rd   re   rf   rg   r   r(  rF   ri   r)  rp   rJ   rl   r   r	   r   r   rk   r   r   r   r   r&   r   r   r   r@   r   r   r   rm   r   r   r   r   r  r   r   rB   r   r  r    r  r2  rT  rt  r   r   r  r  r  r  r  r  r   r   rC   r  r  r  r1   rE  r  r  r   r'   r  r  r  r
  r  r  r  r*  r%  rn   __classcell__r   s   @rX   r   r      s   C ((-- )*?C@D(hh**( %( %	(
 #&( 'tN';<(  (^(<=( 
( (Tehhmm c c RR %R;>R	R+$y/ +f +2-
d9o -
 -
 -
^ 8I :QQ Q 	Q
 
Q( 8<&*-- - 	-
 ""34- sm- 
-` ?CLLLL.6smLL	LL\
y)4	?:;
	
4H
H
 ;'H
 
	H
TJ J> J/y /] /6;% ;D ;
M0IsN#M0 +343G*HM0 
n		M0^Q0IsN#Q0 +/~*>Q0 
n		Q0fj0IsN#j0 +/~*>j0 
n		j0X**%*9c>%:*DHiDX*	*X"uY^4 " "R <@,8,8 ,8
 9,8 
,8\
.
 "%
 
	
&JJ(0(=J	J5u~~u
RST 
.	! 5u~~u
RST  
tN#^U>3;N5OO	P	R.R IsN#R S)^$	R
 
Rh"# " "eCM>R "h(h(%*9c>%:h(DHiDXh(	h(T*z *n *EtCH~ E$}BU EN ^ $

%*9c>%:
DHiDX
	


%*9c>%:
DHiDX
	
%*9c>%:DHiDX	,@@%*9c>%:@DHiDX@	@<::%*9c>%::DHiDX:	:~ AEDD d588==)#;<=D 
	D D%((-- D  rS   r   c                      ^  \ rS rSrSrS\S\S\R                  R                  S\
S\SS	4U 4S
 jjrS\S\S\\\   \4   4S jrS\S\\S4   S\\\4   S\4S jrS\S\\S4   S\\\4   SS	4S jrS\4S jrSrU =r$ )_TopLevelEmitteri  zAn emitter that manages the root level operations within a graph module.

Exists as a separate class so that 'Emitter' can handle the special behavior of 'placeholder'
and 'output' nodes in control flow submodules.
r8  exported_programr   r   r   rz   Nc                 <  > [         T	U ]  X5U5        Xl        X l        / U l        / U l        SU l        S[        [        R                     S[        4S jnU" UR                  R                  5      nU" UR                  R                  5      n[        Xx5      U l        g )NFry   rz   c                 *   U c  g[        U [        R                  5      (       d   [        U 5      5       eS/U R                  -  n[
        R                  R                  R                  X5      n[        R                  " U5      u  p2UR                  5       $ )Nr  r   )r   r  TreeSpecr  
num_leavesr   utilsrG   tree_unflattenr  r  r  )ry   dummy_leavestreerb  s       rX   create_container_str7_TopLevelEmitter.__init__.<locals>.create_container_str5  sr    |dFOO44@d4j@430L;;&&55lID,,T2GA;;= rS   )r   r   r8  r,  r   r   given_mutable_buffer_warningr   r  r/  rk   	call_specin_specout_specr!   r  )
r~   r8  r,  r   r   r   r5  inp_container_strout_container_strr   s
            rX   r   _TopLevelEmitter.__init__%  s     	mD	 0!#"$,1)	!x'@ 	!S 	! 11A1K1K1S1ST01A1K1K1T1TU#4$
 rS   rv  ry   c                    S nSnXR                   R                  R                  ;   a&  U R                   R                  R                  U   nX44$ XR                   R                  R                  ;   a  U R                   R                  R                  U   nX0R                   R                  R                  R                  5       ;   a4  SnU R                  (       d!  [        R                  " S[        SS9  SU l        X44$ UU R                   R                  R                  ;   a#  U R                   R                  R                  U   nX44$ )NFTa  Mutation on a buffer in the model is detected. ExecuTorch assumes buffers that are mutated in the graph have a meaningless initial state, only the shape and dtype will be serialized, unless a pass which sets meta["et_init_buffer"] to True such as InitializedMutableBufferPass is run.r  )
stacklevel)r,  graph_signatureinputs_to_parametersinputs_to_buffersbuffers_to_mutaterr   r7  warningswarnUserWarning!inputs_to_lifted_tensor_constants)r~   rv  ry   r   is_mutable_buffers        rX   _find_fqn_for_placeholder*_TopLevelEmitter._find_fqn_for_placeholderF  s4    !**::OOO''77LLVTC8 %%5 ,,<<NNN''77II&QC ++;;MMTTVV$(!88MMf $#$ 9=D5 %% $$44VVW %%55WW 
 %%rS   r   .rw  c           	        ^ U R                   R                  S   nU R                   R                  R                  SS5      nU R                   R                  R                  SS5      nSn[        U[        5      (       Gai  [        U[
        5      (       GaS  U R                  X5      u  mnS[        S[        S[        4S	 jn	UU	" U R                   U R                  R                  5      =(       a#    UR                  SL=(       a    UR                  SL-  nUbe  Tc   S
5       eUR                  c  [        T[         R"                  S9Ul        O0TUR                  l        [         R"                  UR                  l        U(       a  U R(                  R*                  (       a=  UR                  c  [        T[         R,                  S9Ul        OXTUR                  l        OFUR                  b  UR                  c,  [/        U R1                  U R                   SUSS  S35      5      eSn
TU R                  R2                  ;   a  U R                  R2                  T   n
SnOTU R                  R4                  ;   a  U R                  R4                  T   n
SnOdTba  U R                  R7                  5       n[9        U4S jU 5       S5      nUb  Un
SnO)[/        U R1                  U R                   ST S35      5      eU
b  U
R;                  5       (       d2  U
R;                  [<        R>                  S9(       d  U
RA                  5       n
U
RB                  U
RE                  5       RC                  5       :w  a  U
RG                  5       n
U
RE                  5       Ul$        U
RK                  5       Ul%        [M        URJ                  5      Ul'        U(       a  U(       a  SUl(        OU=(       d    U(       + Ul(        [        U[
        5      (       a  U RS                  XE5      OU RU                  US5      nU RW                  U5      nU(       a%  U RX                  R[                  UR\                  5        U$ )zEmits the value within the placeholder node.

For more information on placeholder nodes see
https://pytorch.org/docs/stable/fx.html#torch.fx.Graph.placeholder
ry   r   Net_init_bufferTr   r@  rz   c                     U R                   S:X  a:  [        U R                  [        5      (       a  U R                  UR                  ;   a  gg)zl
Check if the node is buffer according to the provided graph signature.
If it is one return its fqn as well
r  TF)rM  r   rv  rk   rB  )r   r@  s     rX   
_is_buffer0_TopLevelEmitter.placeholder.<locals>._is_buffer{  s9    
 77m+!$++s33;;/*K*KK#'rS   z6constant tagged tensors require a fully qualified name)r   r   zMutable buffer "r$  z" must have a memory id and offset if we are emitting it without a name. Please either memory plan your mutable buffers or call to_executorch with config=ExecutorchBackendConfig(emit_mutable_buffer_names=True)Fc              3   B   >#    U  H  oS    T:X  d  M  US   v   M     g7f)r   r  NrW   )r   rK  r   s     rX   r   /_TopLevelEmitter.placeholder.<locals>.<genexpr>  s     A'QqTS[DAaD's   zCould not find buffer with fqn z in state_dict or named_buffers)r  )/r   r   r   r   rk   r@   rI  rF   rE   r   r,  r@  r   r   r   r(   r6   r   r   r   r   rw   SEGMENTr   r   
state_dict	constantsnamed_buffersnextis_contiguousr   channels_last
contiguousr   untyped_storageclonerU   strider:   r  r   r   r   r   r   r   r   )r~   rv  r   rw  ry   r   initialize_bufferis_user_inputrH  rN  real_tensorbuffersbufevaluer0  r   s                  @rX   r  _TopLevelEmitter.placeholderk  s    yy~~f%yy~~)).$? IINN../?Ffc""z$
'C'C%)%C%CF%Q"C"	 	8L 	QU 	  499d&;&;&K&KL 0KKt+0OO4/ 'OLKL#))1-<-0;M;V;V.D* CFD**?6H6Q6QD**3 %%??--51@14%7%?%?2.
 GJ..C[[(DOO,C'66 II.vabzl  ;L  M  Kd++666"33>>sC %--777"33==cB %//==?A'A4H?"%K$)M'66 II=cUBab  &  --//"00u?R?R0S"-"8"8":K %%)D)D)F)M)M)OO"-"3"3"5K*::<)002!6t{{!C %6!
"/"D3DE
 $
++ '';))$5 	
 !!&) KKuxx(rS   c           
         [        US   [        5      (       a  [        R                  " US   5      u  pEO'[        R
                  " [        [        S4   US   5      n[        U[        5      (       a&  U R                  R                  UR                  5        gU H  n[        U[        [        [        [        S5      45      (       a"  U R                  U R!                  US5      5      nOU[        U["        5      (       a)  [%        U R'                  U R(                  SU S35      5      e[        U[        5      (       d   eU R                  R                  UR                  5        M     g)zJRecords the ExecutionPlan's outputs based on the output node in the graph.r   .Nz
Returning z% is not yet supported in the emitter.)r   rj   r  r  r   r   r   r   r   r   r   rl   r   r   r  r   r   rk   r   r   r   )r~   rv  r   rw  
args_tuplerb  r  s          rX   r  _TopLevelEmitter.output  s    d1gt$$"//Q8MJU>3+>%?aIJj.11LL
.!cCd4j#ABB++D,D,DS$,OPCS))'66 II(-RS  &c>::::##CFF+ "rS   c                 p   [        U R                  U R                  R                  U R                  U R
                  U R                  /U R                  R                  U R                  R                  [        R                  " [        [           U R                  R                  S   5      U R                  S9	$ )z9Returns the execution plan emitted from this entry point.r   r  )r'   r8  r   rr   r   r   r   rs   rt   r   r   r	   rl   moduler   r  )r~   s    rX   plan_TopLevelEmitter.plan	  s    %%,,;;LLJJ<((22((22 $*;;S	  !9:$
 !% 8 8!
 	
rS   )r  r,  r7  r   r8  r   )rc   rd   re   rf   rg   rk   rD   r   r(  r)  rJ   rp   r   r   r   r   r   r   rI  r   r   r   r  r  r'   ri  rn   r(  r)  s   @rX   r+  r+    s   

 *
 hh**	

 %
 %
 

B#&#&%(#&	x}d"	##&J@@%*9c>%:@DHiDX@	@D,,%*9c>%:,DHiDX,	,8
m 
 
rS   r+  )rg   r   r   r  r   rD  dataclassesr   r   r   r   r   r   r	   r
   r   r   r   executorch.exir.memoryexirr  executorch.extension.pytree	extensionr  r  r   torch.fxexecutorch.exir.delegater   r   %executorch.exir.dialects.backend._opsr   "executorch.exir.dialects.edge._opsr   executorch.exir.errorr   r   r    executorch.exir.operator.convertr   3executorch.exir.passes.executorch_prim_ops_registryr   executorch.exir.print_programr   r   executorch.exir.schemar   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   executorch.exir.tensorr9   r:   r;   r<   r=   r>   r?   r@   executorch.exir.typesrA   rB   torch._subclasses.fake_tensorrC   torch.export.exported_programrD   rE   torch.fx.noderF   torch.utilsrG   typing_extensionsrH   rJ   rp   r   r   ri   r   rl   r   r   r   r	  r   r   r   
StringTyper   r   rk   r   complexr
  r  r  r   r   r(  Interpreterr   r+  rW   rS   rX   <module>r     ss  0      ( S S S ' ' / /   P C = M M ; I P! ! ! ! ! ! ! ! !D	 	 	 ; 4 O  ) ' S S SD ' ' ',    !D(%0C*DDy   c5%,,^@T TUi U		NN	OO	NN	MM		Y  8C$56;< <	
k			KK	LL		LL
	9 " */eCj4U3Z00* Y 
Iuxx## IX2~
x ~
rS   