
    iE                     p   S SK r S SKrS SKJrJrJr  S SKrS SK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  S SKJr  S S	KJr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5      r#      SS\$S\\$   S\\$   S\\\$      S\%S\%S\%S\\   4S jjr&\ " S S\5      5       r' " S S5      r(g)    N)finalListOptional)RemoveGetItemPass)
DataFormat)EdgeProgramToIRConverter)ConversionConfig)NeutronConverterManager)NeutronTargetSpec)#extract_artifacts_from_neutron_nodeNeutronNodeArtifacts)NeutronPassManager)BackendDetailsPreprocessResult)CompileSpec)EXIREdgeDialectVerifier)ExportedProgramc                       \ rS rSr% \\S'   S rS\S\4S jr     SS\S\	\   S	\	\
\      S
\S\S\4S jjrS rSrg)NeutronCompileSpecBuilder'   configc                 f    / U l         / U l        S U l        / U l        SU l        SU l        SU l        g )NTF)compile_speccompiler_flagsoutput_formatoperators_not_to_delegate!use_neutron_for_format_conversionfetch_constants_to_sramdump_kernel_selection_codeselfs    b/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/nxp/nxp_backend.py__init__"NeutronCompileSpecBuilder.__init__*   s:    /1 !46&15.',$*/'    operatorreturnc                 &    UR                  SS5      $ )z
Replace '::' with '_'
z::_)replace)r!   r&   s     r"   _replace_colons)NeutronCompileSpecBuilder._replace_colons3   s     c**r%   Nextra_flagsr   r   r   r   c                 @   [        U5      U l        U R                  b   SU R                   35       eSU l        / U l        Ub  U R                  R	                  U5        Ub&  U Vs/ s H  opR                  U5      PM     snU l        X@l        XPl        X`l	        U $ s  snf )a=  
Generate compile spec for Neutron NPU

Args:
    config: Neutron accelerator configuration, e.g. "imxrt700"
    extra_flags: Extra flags for the Neutron compiler
    operators_not_to_delegate: List of operators that should not be delegated
    use_neutron_for_format_conversion: If True, the EdgeProgramToIRConverter will insert `Transpose` ops to
                                        ensure that the IO matches the executorch partition, which will be
                                        delegated to Neutron.
    fetch_constants_to_sram: If True, the Neutron Converter will insert microinstructions to prefetch weights
                             from FLASH to SRAM. This should be used when the whole model does not fit into SRAM.
    dump_kernel_selection_code: Whether Neutron converter dumps kernel selection code.
zOutput format already set to ftflite)
r   r   r   r   appendr+   r   r   r   r   )r!   r   r-   r   r   r   r   ops           r"   neutron_compile_spec.NeutronCompileSpecBuilder.neutron_compile_spec9   s    0 (/ &	A+D,>,>+?@	A&% "&&{3$03L.3LR$$R(3L.D* 2S.'>$*D'.s   %Bc                    U R                   S:X  Ga/  U =R                  [        SSR                  5       5      [        SSR	                  U R
                  5      R                  5       5      [        SU R                  R                  5       R                  5       5      [        SSR	                  U R                  5      R                  5       5      [        SU R                   R                  5       5      [        S	U R                   R                  5       5      [        S
U R                   R                  5       5      /-  sl        U R                  $ )z:
Generate a list of compile spec objects from the builder
r/   r   compile_flags targetr   ,r   r   r   )r   r   r   encodejoinr   r   get_namer   r   r   r   r    s    r"   buildNeutronCompileSpecBuilder.buildg   s    )OX__->?OSXXd6I6I-J-Q-Q-STHdkk&:&:&<&C&C&EF/HHT;;<CCE 7==>FFH -334<<> 0667??A!" ,    r%   )r   r   r   r   r   r   r   r   )NNTFF)__name__
__module____qualname____firstlineno__r   __annotations__r#   strr+   r   r   boolr2   r<   __static_attributes__ r%   r"   r   r   '   s    0+ + + &*9=26(-+0,, c], $,DI#6	,
 ,0, "&, %),\!r%   r   r   system_configr-   r   r   r   r   r'   c           	      V    [        5       R                  U UUUUUS9R                  5       $ )N)r-   r   r   r   r   )r   r2   r<   )r   rG   r-   r   r   r   r   s          r"   generate_neutron_compile_specrI      s:     	"#		#&?.O$;'A 
 

 
r%   c                   :    \ rS rSr\S\S\\   S\4S j5       r	Sr
g)NeutronBackend   edge_programr   r'   c                 B   [         R                  " S5        [         R                  " SU R                   35        Sn/ n[	        5       nSnS nSnS nU GH  n	U	R
                  S:X  a  U	R                  R                  5       nU	R
                  S:X  a  U	R                  R                  5       nU	R
                  S:X  a)  UR                  U	R                  R                  5       5        U	R
                  S:X  a  U	R                  R                  5       S	:H  nU	R
                  S
:X  a  U	R                  R                  5       S	:H  nU	R
                  S:X  d  M  U	R                  R                  5       S	:H  nGM     U(       d  [        S5      eU R                  R                   H8  n
U
R                  S:X  d  M  [         R                  " SU
R                   35        M:     US:X  Ga  [        S[        R                  R                   R"                  R$                  [        R                  R                   R&                  R$                  /S9/U l        [+        U [,        /5      R/                  5       n S nU R                  R                   H2  nSUR0                  R3                  5       ;   d  M#  UR0                  S   n  O   Uc   e[5        Ub  SU0O0 5      n[7        5       R9                  U [;        U5      US9u  p[=        U5      R?                  XX5      n[         R@                  RC                  [         RD                  5      (       a  SS K#n[         R                  " SU SURI                  5        35        [K        U S3S5       nURM                  [	        U5      5        S S S 5        [K        U S3S5       nURM                  [	        U5      5        S S S 5        [O        5       RQ                  UU5      nO[        SU 35      e[S        US9$ ! , (       d  f       Nr= f! , (       d  f       NQ= f)NzNeutronBackend::preprocessz$NeutronBackend preprocessing graph:
 Fr   r7   r5   r   Truer   r   zoutput format is requiredcall_functionzOperator to be processed: r/   T)
class_onlycore_aten_ops_exception_listdelegation_tag)neutron_target_specconversion_configr   z%Serializing converted graph with tag z to z_pure.et.tflitewbz_neutron.et.tflitezUnknown format )processed_bytes)*logginginfodebuggraphbyteskeyvaluedecoder0   RuntimeErrornodesr1   r7   r   torchopsaten
max_pool2ddefaultprelu
_verifiersr   r   	transformmetakeysr	   r   convert_programr   r
   convertrootisEnabledForDEBUGosgetcwdopenwritePayloadComposerget_binary_payloadr   )rM   r   r   r5   binaryr7   r   r   r   specnoderT   nrV   tflite_model
io_formatsneutron_modelrr   fs                      r"   
preprocessNeutronBackend.preprocess   s   
 	12=l>P>P=QRS,0)"'%)" Dxx?* $

 1 1 3xx8#**,xx?*$$TZZ%6%6%89xx>>48JJ4E4E4G64Q1xx44*.***;*;*=*G'xx77-1ZZ->->-@F-J* ! :;; &&,,Dww/) :4;;-HI -
 H$ (#		1199		,,442'L# .01ik 
 "N!''--#qvv{{}4%&VV,<%=N . "--- !14@ 56WX!
 (@'A'Q'Q$5f$="3 (R ($L 44NOWWnM
 ||((77;N;K4PRPYPYP[}] ^,O<dCqGGE,/0 D^,,>?F!GGE-01 G %&99*mTF@AA77 DCFFs   8O?*P?
P
PrF   N)r>   r?   r@   rA   staticmethodr   r   r   r   r   rE   rF   r%   r"   rK   rK      s:     `8%`8;'`8 
`8 `8r%   rK   c                       \ rS rSrSrS\R                  S\4S jrS\R                  S\4S jr	S\
\\\   4   S\R                  4S jrS	\R                  S
\S\4S jrS\
\\\   4   S\4S jrSrg)rv   i     arrayr'   c                     UR                   [        R                   " S5      :X  d   eUR                  U R                  -  nUS:X  a  gU R                  U-
   S3$ )zCreate a padding format string for the given array, which will add 0s at the end for correct alignment.
E.g. the string '10x' represents adding 10 bytes of '0' padding.
uint8r   rO   x)dtypenpsize	ALIGNMENT)r!   r   overflows      r"    _padding_format_string_for_array0PayloadComposer._padding_format_string_for_array  sT     {{bhhw////::.q= ..8+,A..r%   c                     UR                   [        R                   " S5      :X  d   eUR                   SU R                  U5       3$ )a  Create a format string which will represent the provided array. It also handles the necessary alignment.
E.g. for array [1,2,3] we get '3s13x', because '3s' means string of 3 bytes, and `13x` means adding 13 bytes
 of '0' padding at the end (for 16B alignment).
r   s)r   r   r   r   )r!   r   s     r"   _format_string_for_array(PayloadComposer._format_string_for_array  s@    
 {{bhhw////**QtDDUKLMMr%   r}   c                    US   nUS   n[        UR                  5      S:  d   S5       e[        UR                  5      S:  d   S5       e[        UR                  5      /nUR                  [        UR                  5      5        UR                  [        U5      5        UR                   H;  n UR                  X6R                  5          [        R                  :X  a  SOS5        M=     UR                   H;  n UR                  XGR                  5          [        R                  :X  a  SOS5        M=     UR                  UR                  5        UR                  UR                  5        UR                  UR                  5        [        R                  " U[        R                  S9$ ! [         a    [        SUR                  5        S	35      ef = f! [         a    [        S
UR                  5        S	35      ef = f)ar  
Create bytes header for returned payload. It contains information about
input and output tensor formats. Tensors are ordered based on graph signature
of ExportedProgram. Header schema:

+----------------------------+-----------------------------+------------------------+
| Neutron inputs length (1B) | Neutron outputs length (1B) | Input args length (1B) |
+----------------------------+-----------+-----------------+------------------------+
| 1st input tensor format (1B)           | [nth* input tensor format (1B)]          |
+----------------------------------------+------------------------------------------+
| 1st output tensor format (1B)          | [nth* output tensor format (1B)]         |
+----------------------------------------+------------------------------------------+
| 1st input map (1B)                     | [nth* input map (1B)]                    |
+----------------------------------------+------------------------------------------+
| 1st output map (1B)                    | [nth* output map (1B)]                   |
+----------------------------------------+------------------------------------------+
| Payload version (1B)                                                              |
+-----------------------------------------------------------------------------------+

:param io_formats: IO tensors formats.
:return: Bytes representation of payload header.
inputsoutputs   z3Models with more than 255 inputs are not supported.z4Models with more than 255 outputs are not supported.   r   zInput tensor `z#` not found in the converted model.zOutput tensor `)r   )leninput_indicesoutput_indicesr0   input_namesr`   r   CHANNELS_LASTKeyErrorAssertionErroroutput_namesextendpayload_versionr   r   r   )r!   r}   neutron_artifactsr   r   header_data
input_nameoutput_names           r"   _create_payload_header&PayloadComposer._create_payload_header  s   2 H%Y' !//036	A@	A6 !001C7	BA	B7 ,::;<30??@A3v;'+77J"" 1 1 34
8P8PPAVW 8 -99K	""1134
8P8PP  : 	,::;,;;<,<<= xx28844-  $$Z%6%6%8$99\]   $%k&8&8&:%;;^_ s   /7F):7G)(G(G<headerr   c                    [         R                  " U R                  U5      U R                  UR                  5      -   U R                  UR                  5      -   U R                  UR
                  5      -   UR                  5       UR                  R                  5       UR                  R                  5       UR
                  R                  5       5      $ )z
Packs provided data into serialized binary data of the following C struct:
 struct NeutronBinary {
     uint8[] header;
     uint8[] microcode;
     uint8[] weights;
     uint8[] kernels;
 }
The individual components must be aligned to 16 bytes.
)structpackr   	microcodeweightskernelstobytes)r!   r   r   s      r"   _pack_with_alignment$PayloadComposer._pack_with_alignment`  s     {{))&1++,=,G,GHI++,=,E,EFG ++,=,E,EFG NN''//1%%--/%%--/	
 		
r%   c                 \    [        U5      nU R                  X5      nU R                  XC5      $ )a  
Get binary payload for provided input/output tensor formats and neutron_model. Returned data have
following structure:

+----------------------------------------------------------------------------------------------------------------+
|                                            16 bytes aligned blocks                                             |
+================================================================================================================+
|                                                     Header                                                     |
+----------------------------------------------------------------------------------------------------------------+
|                                                Neutron microcode                                               |
+----------------------------------------------------------------------------------------------------------------+
|                                                 Neutron weights                                                |
+----------------------------------------------------------------------------------------------------------------+
|                                                 Neutron kernels                                                |
+----------------------------------------------------------------------------------------------------------------+

Tensor format definition: '0x1' == CHANNELS_LAST, '0x0' == FORMATLESS (no format).

:param io_formats: Dictionary with keys 'inputs' and 'outputs' that contains dictionaries
    mapping tensor name to DataFormat.
:param neutron_model: Neutron model with single NeutronGraph node.
:return: 16 bytes aligned binary payload.
)r   r   r   )r!   r}   r~   r   r   s        r"   rw   "PayloadComposer.get_binary_payloady  s1    6 @N,,ZK((CCr%   rF   N)r>   r?   r@   rA   r   r   ndarrayrC   r   r   dictlistr   r   r   r]   r   rw   rE   rF   r%   r"   rv   rv     s    I/bjj /S /Nbjj NS NB5sD$445B5	B5H
jj
5I
	
2DsD$445D	Dr%   rv   )NNNTFF))rY   r   typingr   r   r   numpyr   rc   3executorch.backends.nxp._passes.remove_getitem_passr   +executorch.backends.nxp.backend.data_formatr   6executorch.backends.nxp.backend.edge_program_converterr   4executorch.backends.nxp.backend.ir.conversion_configr	   9executorch.backends.nxp.backend.neutron_converter_managerr
   3executorch.backends.nxp.backend.neutron_target_specr   /executorch.backends.nxp.neutron_node_extractionr   r   ,executorch.backends.nxp.neutron_pass_managerr   'executorch.exir.backend.backend_detailsr   r   +executorch.exir.backend.compile_spec_schemar   %executorch.exir.verification.verifierr   torch.export.exported_programr   r   rC   rD   rI   rK   rv   rF   r%   r"   <module>r      s     ( (   Q B R R L T C I 9[! [!@ $(!%59.2$)',C= #  (S	2	
 (, " !% 
+. c8^ c8 c8LUD UDr%   