
    ieD                        S r SSKrSSKJr  SSKJrJrJrJr  SSK	r	SSK
rSSKJr  SSKJr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  SSK J!r!  SSK"J#r#  SSK$J%r%  SSK&J'r'J(r(J)r)  \RT                  " \+5      r,S\'S\\-\.4   4S jr/S\(S\0\-\.4   4S jr1S\)4S jr2S\-4S jr3\ " S S\5      5       r4g)a  Provide TOSA backend entry points for the Arm ExecuTorch integration.

Implement the Ahead-of-Time (AoT) preprocessing path that lowers an
``ExportedProgram`` to a TOSA flatbuffer using Arm's lowering pipeline. Use
this module either as a standalone backend that produces a TOSA artifact or as
part of a composed pipeline for hardware backends that consume TOSA as an
intermediate form.

Use ``TOSABackend.preprocess`` to return the serialized TOSA flatbuffer that
subsequent stages (for example, JIT or hardware-specific compilers) consume.

    N)count)castDictfinalList)ArmCompileSpec)
debug_faildebug_tosa_dump)	DebugHook)process_call_functionprocess_outputprocess_placeholder)TosaCompileSpec)TOSA_TENSOR_NAME_META)BackendDetailsPreprocessResult)CompileSpec)get_memory_format)get_cond_while_submodules)ExportedProgram)GraphGraphModuleNodeep_graphreturnc                    ^ 0 nU4S jmU R                  5       n/ nT" UR                  S   U5        [        U5       VVs0 s H  u  pEUR                  U_M     nnnU$ s  snnf )aP  Assign deterministic output IDs to leaf outputs.

Flattens the output structure and assigns the external ID
based on the leaf position in the exported output tuple/list.

Args:
    ep_graph (Graph): FX graph produced by export preprocessing.

Returns:
    dict[str, int]: Mapping from *leaf output node name* to external output index.

c                    > [        U [        5      (       a  UR                  U 5        g [        U [        [        45      (       a  U  H  nT" X!5        M     g g )N)
isinstancer   appendlisttuple)argnodesa_collect_leavess      c/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/arm/tosa/backend.pyr%   /_annotate_external_ids.<locals>._collect_leaves=   sF     c4  LLdE]++)  ,    r   )output_nodeargs	enumeratename)r   node2external_idout
out_leavesidxleafr%   s         @r&   _annotate_external_idsr2   .   sl     * 


 CJCHHQK, 9B*8MN8M93		38MN Os    Agraph_modulenode_to_id_mapc                   ^^^	 S[         S[        S[        4S jm	U R                  R                  5       n[	        [
        UR                  S   5      n[        5       mS[         S[        4UU	U4S jjn[        [        X4S95      n[        U5      nXV:w  aa  [        UR                  S   [        5      (       a  [        U5      OUnU4Ul        U R                  R                  5         U R                  5         U $ )	a  Reorder graph outputs to match ascending external IDs.

Args:
    graph_module (GraphModule): Graph to reorder in place.
    node_to_id_map (dict[str, int]): Mapping from node name to output index.

Returns:
    GraphModule: Updated graph module with deterministic output ordering.

nfallbackr   c                 :    UR                  U R                  U5      $ )z=Return the external ID for ``n`` or ``fallback`` when absent.)getr,   )r6   	node_2_idr7   s      r&   _external_id#_sort_outputs.<locals>._external_id]   s    }}QVVX..r(   r   tc                 *   > T" U T[        T5      5      $ )z<Key function that orders outputs by external ID or position.)next)r=   _counterr;   r4   s    r&   	_sort_key _sort_outputs.<locals>._sort_keyf   s    A~tH~>>r(   )key)r   intgraphr)   r   r!   r*   r   sortedr   r    lint	recompile)
r3   r4   out_nodeout_listrA   orig_ordcurrent_orderreplacementr@   r;   s
    `      @@r&   _sort_outputsrN   Q   s    / /3 /3 / !!--/HE8==+,HwH?T ?c ? ? VH45H(OM (28==3CT(J(Jd8nPX$! r(   nodec                     U R                   S   nU R                   S   nUR                  [        [        U5      5      S9$ )zlReturn a fake tensor with the same properties as node, but with
.dim_order() == node.meta["tosa_dim_order"]
valtosa_dim_order)memory_format)metator   r    )rO   fake_tensordesired_dim_orders      r&   _get_matching_fake_tensorrX   v   s?     ))E"K		"23>>(9$?P:Q(R>SSr(   c                     U R                   R                   H)  nUR                  R                  S5      nU(       d  M'  Us  $    [        R                  S5        g)zReturn the first delegation tag discovered in the FX graph.

Args:
    graph_module (GraphModule): Module produced by Arm partitioning.

Returns:
    str: First non-empty delegation tag or an empty string when no tag is
    recorded.

delegation_tagz%No delegation tag found in partition. )rE   r#   rT   r9   loggerdebug)r3   rO   tags      r&   arm_get_first_delegation_tagr_      sI     ""((iimm,-3J )
 LL89r(   c                       \ rS rSrSr\S\S\\   4S j5       r	\S\S\
S\4S j5       r\S	\S
\4S j5       r\  SS\S\S\
S\R"                  S\S-  S\S-  S\S-  4S jj5       r\S\S\
4S j5       rSrg)TOSABackend   zProvide a backend for lowering programs to TOSA.

Use this class standalone to produce a TOSA representation, or as part of a
composed pipeline for hardware backends that consume TOSA.

edge_programcompile_specsc                 V    [         R                  U [        R                  " U5      5      $ )aC  Convert an exported program using the provided compile specs.

Args:
    edge_program (ExportedProgram): Program generated by Torch export.
    compile_specs (List[CompileSpec]): Raw compile specifications from
        ``executorch.apply_backend``.

Returns:
    PreprocessResult: Result containing serialized TOSA bytes.

)ra   _preprocessr   	from_list)rc   rd   s     r&   
preprocessTOSABackend.preprocess   s'     &&/33MB
 	
r(   compile_specr   c                 N   UR                  5       nUR                  nUR                  nSnUb  [        U5      n[        R                  SU 35        U(       d  SnUR                  n[        R                  " UUR                  UR                  UR                  UR                  S:  a  SOSS9nUR                  R                  [        R                  :X  a(  UR                  R                  [        R                  ::  d0  [        S[        R                   S	[        R                   S
U 35      e[        R!                  U R"                  U UUU5        UR%                  5       nU(       a  ['        U R"                  5      n	[)        UUSR+                  U	(       a  SU	 3OS5      SU 3-   S9  Uba  UR,                  [.        R0                  R2                  :X  a9  UR%                  5       n
[5        U S3S5       nUR7                  U
5        SSS5        [9        US9$ ! , (       d  f       N= f)a  Lower an exported program to a TOSA flatbuffer.

Apply Arm transformation passes to ``edge_program``, then walk the
transformed FX graph to emit a TOSA graph via the serializer. When
requested in ``compile_spec``, write additional debug artifacts.

Args:
    edge_program (ExportedProgram): Program to lower to TOSA.
    compile_spec (TosaCompileSpec): Backend options. Recognized keys:
        - output_format: Must be "tosa".
        - tosa_spec: Target TOSA version/capabilities.
        - debug_artifact_path: Directory for debug outputs.
        - compile_flags: Optional backend flags.
        - dump_debug_info: Enable extra debug JSON dump.

Returns:
    PreprocessResult: Result containing processed_bytes with the
    serialized TOSA flatbuffer.

Raises:
    ValueError: If output_format is not "tosa" or the TOSA
        specification is missing from compile_spec.
    RuntimeError: If an unsupported FX node type is encountered.

Nz$Converting ExportedProgram to TOSA: r[   r   TF)targetMajortargetMinortargetPatchtargetDraftzTOSA serializer version (.z) doesn't match specification z{}_)suffixz/debug.jsonw)processed_bytes)get_intermediate_path	tosa_spectosa_debug_moder   r\   infoversiontsTosaSerializermajorminormicroTOSA_VERSION_MAJORTOSA_VERSION_MINORRuntimeErrorra   _preprocess_moduler3   	serializer_   r
   formatmoder   	DebugModeJSONopenwriter   )rc   rj   artifact_pathrv   dump_debug_info
debug_hookry   
tosa_graphbinaryr^   json_outputfs               r&   rf   TOSABackend._preprocess   s   > %::< **	&66
&"?3J:9+FG M##&& ' 1u

 ##r'<'<<!!''2+@+@@))*!B,A,A+B C//8k;  	&&%%	
 %%'.|/H/HIC{{Qse9<!I;P %??n&>&>&C&CC","6"6"8K{;SAQ, B  77 BAs   3H
H$	submodulesubmodule_nodec                     / nU R                   R                   H5  nUR                  S:X  d  M  SUR                  S'   UR	                  U5        M7     UR
                  =[        R                  R                  R                  :X  a&    [        [        [           UR                  S   5      nO[        R                  R                  R                  :X  aC  [        [        [           UR                  S   5      [        [        UR                  S   5      -   nO [        SUR
                   35      e[!        X$SS9 H  u  pV[#        U5      UR                  S'   M     U R                   R%                  5       n['        UR                  S	   [        5      (       a   UR)                  S	UR                  S	   /5        [        [        [           UR                  S	   5      n[!        XR*                  5       H  u  p[#        U
5      U	R                  S'   M     g
)ap  To make a submodule fit into the normal flow of a graph_module, we
need to do some regularizations.

- Buffers created before passes are treated as input to the submodule. Buffers created during passes
    are treated as "normal" buffers, i.e. gathered from the state_dict.
    To make it easy to tell them apart, mark all placeholders with "is_input = True" before running passes.
- Make sure output node args[0] is always iterable.
- Match the dim_order() of the input tensors with the dim orders of the submodule_node inputs.
- Match the dim_order() of the out tensors with the dim orders of the submodule_node outputs.

placeholderTis_inputz Unexpected control flow target: )strictrQ   r   N)rE   r#   oprT   r   targettorchopshigher_ordercondr   r    r   r*   
while_loopr   ziprX   r)   r   
update_argusers)r   r   submodule_inputsrO   r*   submodule_inputsubmodule_argr)   output_argssubmodule_outputsubmodule_users              r&   _regularize_submodule!TOSABackend._regularize_submodule  s    (*OO))Dww-'(,		*% ''- * ##,'',,DJ(;(;B(?@''22DJ(;(;B(?@4.--b1D  "6~7L7L6MN  /22BQU.V*O*CM*RO  ' /W  oo113k&&q)400""1{'7'7':&;<4:{'7'7':; 14KAUAU0V,+D^+T!!%( 1Wr(   Nr3   r   r   submodule_namecontaining_graph_modulec                 6   UR                   n[        U R                  5      nUR                  5       n	UR	                  5       n
SSKJn  U" U5      R                  XS9n SSKJ	n  U" XU5      nU
(       a!  [        R                  S5        [        X5      n O[        R                  S5        Ub`  UR                  U5        UR                  R                  U5        SU 3nU R                  R                    H  nXR"                  [$        '   M     U R                  R                    GH  n['        [(        U5      n UR*                  S	:X  a  [-        UX=U5        M4  UR*                  S
:X  a/  [/        UR0                  5      S:X  a  Uc  Mb  [3        UUUUU5        Ms  UR*                  S:X  a  [5        UX75        M  UR*                  S:X  aP  [7        U [9        UR:                  5      S5      nUc  [=        S5      e[?        U[@        5      (       d  [=        S5      eM  [=        URB                   SUR*                   35      e   [I        U 5       H6  u  nnn[J        RM                  UU5        [J        RO                  UUUUUUU S9  M8     g! [D         a    [G        UXU	5        e f = f)a#  Convert an FX ``graph_module`` to TOSA serializer calls.

Args:
    graph_module (GraphModule): Module to lower recursively.
    edge_program (ExportedProgram): Original exported program.
    compile_spec (TosaCompileSpec): Backend options with TOSA settings.
    tosa_graph (ts.TosaSerializer): Serializer receiving operators.
    debug_hook (DebugHook | None): Optional debug instrumentation.
    submodule_name (str | None): Name used when visiting nested blocks.

Raises:
    RuntimeError: If an FX node with an unsupported op kind is found.

r   )ArmPassManager)exported_programr3   )get_node_visitorsz(Re-sorting outputs during TOSA lowering.z8No re-sorting outputs (workaround) during TOSA lowering.Nrq   call_functionr   outputget_attrz8get_attr node is not targeting anything in graph module.z-get_attr node is not targeting a GraphModule.z is unsupported op )r   r   )(rv   r2   rE   ru   get_output_order_workaroundexecutorch.backends.arm._passesr   transform_to_backend_pipeline.executorch.backends.arm.operators.node_visitorr   r\   r]   rN   startRegion
currRegionaddBasicBlockr#   rT   r   r   r   r   r   lenr   r   r   getattrstrr   r   r   r   r,   	Exceptionr	   r   ra   r   r   )r3   rc   rj   r   r   r   r   rv   r4   r   output_order_workaroundr   r   node_visitorsrr   	loop_noderO   attrr,   r   control_flow_nodes                        r&   r   TOSABackend._preprocess_module2  s~   0 !**	/0B0BC$::<"."J"J"L 	C%l3QQ) R 

 	U),:N"LLCD(FLLLST%"">2!!//?()F)//55	8>45 6 !&&,,Dd#D$77o-)$
9UWW-4::!+0F !'"$/! WW("4?WW
*"<T[[1A4HD|*V  &dK88*K  9 '$))4Gy'QRRG -R 3L3
.D). --i9JK**#(4 + 	3
  4=Is+   7I?,I?I?I?3AI?$I??Jc                    U R                  5       n[        U R                  5      nUR                  U5        UR	                  U R                  5       5      R                  U R                  5      R                  U R                  5      $ )a&  Extract the TOSA-specific settings from a composite compile spec.

Args:
    compile_spec (ArmCompileSpec): Compile specification that may
        include both TOSA and hardware-specific options.

Returns:
    TosaCompileSpec: TOSA-only specification ready for
    ``TOSABackend.preprocess``.

)
get_pass_pipeline_configr   rv   set_pass_pipeline_configdump_intermediate_artifacts_toru   r   rw   set_output_order_workaroundr   )rj   pipeline_configtosa_compile_specs      r&   filter_tosa_compile_specs%TOSABackend.filter_tosa_compile_specs  ss      '??A+L,B,BC22?C<<224 _\99:(()M)MN	
r(    )NN)__name__
__module____qualname____firstlineno____doc__staticmethodr   r   r   rh   r   r   rf   r   r   r   rz   r{   r   r   r   r   r   __static_attributes__r   r(   r&   ra   ra      s)    
 
kAR 
 
  W8%W8%W8 
W8 W8r (U (Ud (U (UT  &*6:j!j%j &j %%	j
 $j d
j "-t!3j jX 
$
	
 
r(   ra   )5r   logging	itertoolsr   typingr   r   r   r   r   tosa_serializerrz   /executorch.backends.arm.common.arm_compile_specr   $executorch.backends.arm.common.debugr	   r
   $executorch.backends.arm.debug.schemar   $executorch.backends.arm.process_noder   r   r   )executorch.backends.arm.tosa.compile_specr   $executorch.backends.arm.tosa.mappingr   'executorch.exir.backend.backend_detailsr   r   +executorch.exir.backend.compile_spec_schemar   executorch.exir.dim_order_utilsr   executorch.exir.graph_moduler   torch.export.exported_programr   torch.fxr   r   r   	getLoggerr   r\   r   rD   r2   dictrN   rX   r_   ra   r   r(   r&   <module>r      s   
   * *   J L : 
 F F T C = B 9 - - 
		8	$ U  tCH~  F" "T#s(^ "JTD T# ( d
. d
 d
r(   