
    is                     t   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  S SK	J
r
JrJrJrJrJrJr  S SKJs  Js  Js  Jr  S SKJr  S SK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$J%r%J&r&  S S
K'J(r(J)r)J*r*J+r+J,r,J-r-J.r.J/r/J0r0J1r1J2r2J3r3J4r4J5r5  S SK6J7r7J8r8  S SK9J:r:J;r;  S SK<J=r=  S SKJ>r>J?r?J@r@  S SKAJBrB  S SKCJDrD  S SKEJFrFJGrG  S SKHJHrH  S SKIJJrJJKrK  S SKLJMrM  S SKNJOrO  S SKPJQrQ  S SKRJSrS   " S S\Q5      rTS rUS\R|                  4S jrVS\R                  R                  4S jrYS\\Z   4S jr[S \M\\D   -  4S! jr\S" r]S\\R                  R                  \4   4S# jr`         SiS\\R                  R                  \R                  R                  \\Z\R                  R                  4   \\Z\R                  R                  4   4   S%\\\R                     \\Z\\R                     4   4   S&\\\
   \\Z\\
   4   4   S'\\\Z\
4      S(\\   S)\\   S*\\\\\Z\4   4      S+\\d   S,\\d   S-\\e   S.\\e   S/\\e   S\F4S0 jjrf   SjS\\R                  R                  \R                  R                  4   S%\\R                     S)\\   S*\S(\S\R~                  4S1 jjrgS2 rhS3 ri   SkS5\R                  R                  S6\\R                  S74   S8\\R                  R                  /S4   S9\dS:\dS;\e4S< jjrj\*R                  S4S=\Z\l-  S>\ZS?\*S@\4SA jjrm " SB SC\5      rn\nR                  4SD\R                  R                  4SE jjrp\.R                  S4S4S4S$4SF\.SG\eSH\eSI\eSJ\eS\+4SK jjrr    SlSL\eSM\eSN\eSJ\eSO\eS\+4SP jjrs          SmS?\*SQ\+SR\eSS\eST\eSU\eSV\eSW\eSX\eSY\eSZ\3S[\eS\\B   4S\ jjrtS] ruS^ rvS_\R                  R                  4S` jrwS_\R                  R                  Sa\4Sb jrxSD\R                  R                  Sc\\Z\R                  R                  4   4Sd jrySe rzSf r{Sg r|S\}4Sh jr~g)n    N)defaultdictOrderedDict)Enum)AnyCallableDictListOptionalTupleUnion)AnnotateStackAnnotateUnbind)QnnPassManager)QNN_QUANT_TYPE_MAPQNN_TENSOR_TYPE_MAP)OpContextLoader)generate_qnn_executorch_optionget_skip_decomp_tableQnnPartitioner)_soc_info_tableHtpArchQcomChipsetQnnExecuTorchBackendOptionsQnnExecuTorchBackendTypeQnnExecuTorchGpuBackendOptionsQnnExecuTorchGpuPrecisionQnnExecuTorchHtpBackendOptionsQnnExecuTorchHtpPerformanceModeQnnExecuTorchHtpPrecisionQnnExecuTorchLogLevelQnnExecuTorchOpPackageOptionsQnnExecuTorchOptionsQnnExecuTorchProfileLevel)flatbuffer_to_optionoption_to_flatbuffer)QCOM_QNN_COMPILE_SPECQCOM_QUANTIZED_IO)QnnManagerContext)EdgeCompileConfigExirExportedProgramto_edge)CompileSpec)LoweredBackendModule)EdgeProgramManagerto_edge_transform_and_lower)tabulate)core_aten_decompositionsremove_decompositions)ExportedProgram)passes)OperatorSupportBase)Libraryc                       \ rS rSrSr   SS\S\S\4S jjrS\R                  R                  4S	 jrS\R                  R                  4S
 jrS\R                  R                  S\4S jrSrg)_AnnotationSkipperI   a  
Class used to partition out unwanted graph nodes.
e.g. - nodes are prevented from quantization annotation
     - nodes have been grouped together as a submodule

Attributes
----------
fp_node_id_set : set
    a set contains nodes' name to be left in fp precision
fp_node_op_set : set
    a set contains nodes' target (aten dialect) to be left in fp precision
skip_annotated_submodule : bool
    flag to skip annotated submodule or not

Methods
-------
should_delegate(n: torch.fx.Node)
    identify the residual nodes haven't be lowered with fixed-precision
should_skip(n: torch.fx.Node)
    identify the nodes should be kept out with fixed-precision or not
is_node_supported(_, node: torch.fx.Node)
    overridden method for graph partitioning
Nfp_node_id_setfp_node_op_setskip_annotated_submodulec                 (    Xl         X l        X0l        g Nr:   r;   r<   )selfr:   r;   r<   s       g/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/qualcomm/utils/utils.py__init___AnnotationSkipper.__init__b   s     -,(@%    nc                 h    UR                   S:H  =(       a    UR                  [        R                  :g  $ )Ncall_function)optargetoperatorgetitemr@   rE   s     rA   should_delegate"_AnnotationSkipper.should_delegatel   s%    tt&G188x7G7G+GGrD   c                 t    UR                   U R                  ;   =(       d    UR                  U R                  ;   $ r>   )namer:   rI   r;   rL   s     rA   should_skip_AnnotationSkipper.should_skipo   s+    vv,,,OD<O<O0OOrD   nodereturnc                   ^  T R                   (       a@  UR                  S:X  a  [        U 4S jUR                   5       5      $ T R	                  U5      $ [        UR                  S;   T R                  U5      UR                  S:H  =(       a    [        U 4S jUR                   5       5      /5      (       a  [        SUR                   S35        gg)	Nget_attrc              3   F   >#    U  H  nTR                  U5      v   M     g 7fr>   )rM   .0userr@   s     rA   	<genexpr>7_AnnotationSkipper.is_node_supported.<locals>.<genexpr>u   s     M*$4//55*   !)placeholderoutputc              3   F   >#    U  H  nTR                  U5      v   M     g 7fr>   )rQ   rX   s     rA   r[   r\      s     JztD,,T22zr]   z[QNN Quantizer Annotation]: z
 | SkippedFT)	r<   rH   allusersrM   anyrQ   printrP   )r@   _rS   s   `  rA   is_node_supported$_AnnotationSkipper.is_node_supportedr   s    ((ww*$M$**MMM''--44  & GGz) KJtzzJJ

 

 0:FGrD   r?   )NNF)__name__
__module____qualname____firstlineno____doc__setboolrB   torchfxNoderM   rQ   rf   __static_attributes__ rD   rA   r8   r8   I   s~    4 #").	AA A #'	AH HPUXX]] P 4 rD   r8   c                  *    [         R                  " SS9$ )NT)
enable_aot)exirCaptureConfigrs   rD   rA   qnn_capture_configrx      s    ..rD   rT   c                  *    [         R                  " SS9$ )NF)_check_ir_validity)rv   r)   rs   rD   rA   qnn_edge_configr{      s    !!  rD   modulec                    ^^  " S S[         R                  R                  5      mS[         R                  R                  4UU4S jjmT" U 5      $ )Nc                   2   ^  \ rS rSrSU 4S jjrS rSrU =r$ )(convert_linear_to_conv2d.<locals>.Conv2D   c                   > [         TU ]  5         US Ln[        R                  R	                  UR
                  S   UR
                  S   SSUS9U l        [        R                  R                  UR                  " / UR
                  QSPSP76 5      U R                  l	        U(       a/  [        R                  R                  U5      U R                  l
        g g )Nr      )in_channelsout_channelskernel_sizepaddingbias)superrB   ro   nnConv2dshapeconv	Parameterreshapeweightr   )r@   r   r   use_bias	__class__s       rA   rB   1convert_linear_to_conv2d.<locals>.Conv2D.__init__   s    G4'H"LLO#\\!_ ( DI  %xx11&..2U&,,2UPQ2UST2UVDII!&!3!3D!9		 rD   c                    UR                  5       nUS:X  a  UR                  " / UR                  QSP76 OUR                  " S/UR                  QSP76 n[        R                  " USS5      nU R                  U5      n[        R                  " USS5      nUS:X  a  UR                  S5      nU$ UR                  " UR                  SS 6 nU$ )N   r      )dimr   r   ro   	transposer   squeeze)r@   xrankress       rA   forward0convert_linear_to_conv2d.<locals>.Conv2D.forward   s    557D*.!)		&177&A&19Rqww9RPQ9RA1a(A))A,C//#q!,C%)QY#++b/CJ 58KK1Q4PCJrD   )r   r>   )rh   ri   rj   rk   rB   r   rr   __classcell__)r   s   @rA   Conv2Dr      s    	:	 	rD   r   r|   c           	        > [        U 5      n[        U [        R                  R                  5      (       a1  U[        [        U 5      5       Vs/ s H  n[        U5      PM     sn-  nU H`  n[        X5      n[        U[        R                  R                  5      (       d  M9  [        XT" UR                  UR                  5      5        Mb     U R                  5        H  u  pVT" U5      nM     U $ s  snf r>   )dir
isinstancero   r   
ModuleListrangelenstrgetattrLinearsetattrr   r   named_children)	r|   	attr_strsiattr_strtarget_attrre   
sub_moduler   replace_linears	          rA   r   0convert_linear_to_conv2d.<locals>.replace_linear   s    K	fehh1122%F*<=*<Q#a&*<==I!H!&3K+uxx77&1C1C[EUEU*VW "
 $224MA'
3J 5 >s   C0)ro   r   Module)r|   r   r   s    @@rA   convert_linear_to_conv2dr      s=     0uxx   &!!rD   c                    SSK nSSKJn  [        U S5       nUR	                  5       nSSS5        U" W5      R
                  nUR                  R                  U 5      n/ nUR                   H  n[        UR                  5       H  u  pU
R                  S:X  d  M  UR                  U
R                  R                     R                  n[         R"                  " U5      nSn[%        U5      S:X  a  UnSnU SUR&                   S	U	 U 3n[        US
5       nUR)                  U5        SSS5        UR+                  U5        M     M     U$ ! , (       d  f       GN(= f! , (       d  f       N;= f)ae  
Dump compiled binaries under the same directory of pte_path.
For partitioned graph, there will be multiple files with names f"{method_name}_{index}".
'method_name' refers to the name of a method in the nn.Module that was traced to
generate this program, while 'index' indicates the order of execution.

Args:
    pte_path (str): The path of generated pte.
r   N)deserialize_pte_binaryrb
QnnBackendz.binz.dlc/re   wb)os#executorch.exir._serialize._programr   openreadprogrampathdirnameexecution_plan	enumerate	delegatesidbackend_delegate_data	processedindexdataPyQnnManagerAdaptorStripProtocolr   rP   writeappend)pte_pathr   r   fprogram_datar   ctx_path	dumpfilesr   r   delegateprocessed_bytesbinaryfile_extension	dump_files                  rA   dump_context_from_pter      s<    J	h	vvx 
 %\2::Gwwx(HI!00$^%=%=>KA{{l*")"?"?&&,,#$   -::?K!'v;!#,F%+N'j.*=*=)>as>BRS	)T*aGGFO +  + ? 1 - 
	& +*s   E	E	
E
E)exported_programc                     S nS nS0 pC[        U [        5      (       a0  U  H)  nU" U5      u  pg[        X65      nUR                  U5        M+     O
U" U 5      u  p7U" UW5        U$ )Nc                 R    S nS n[         U[        U0nU[        U 5         " U 5      $ )Nc                    S0 p!U R                   R                  R                  5        GH(  u  p4[        UR                  S   R
                  5      nUR                  R                  [        R                  :X  d  MR  UR                  R                  R                  (       d  My  [        R                  " UR                  S   R
                  UR                  5      nUR                  5       R
                  S:X  d   S5       eUR!                  5       R
                  S:X  d   S5       e[#        XR%                  5       5      nXRU'   UR'                  5         GM+     X4$ Nr   zfailed to initialize backendzfailed to init context cache)graph_module_modulesitemsr$   compile_specsvaluebackend_optionsbackend_typer   kHtpBackendhtp_optionsuse_multi_contextsr   
QnnManagerr   InitBackendInitContextCachemaxGetSpillFillBufferSizeDestroy)progmax_sf_buf_size
module_mapre   moptionsqnn_mgrs          rA   process_exported_programRupdate_spill_fill_size.<locals>.get_program_info.<locals>.process_exported_program   s(   *+RZ))2288:.qq/A/G/GH++88/;;<//;;NNN1<<*00!2C2CG  ++-33q86568  00288A=656=&)')G)G)I'O %,qMOO%+ ;, #..rD   c                    [         R                  " U R                  S   R                  U R                  5      nUR                  5       R                  S:X  d   S5       eUR                  5       R                  S:X  d   S5       eUR                  5       nUR                  5         UU [        U R                  S   R                  5      04$ r   )
r   r   r   r   r   r   r   r   r   r$   )r|   r   spill_fill_sizes      rA   process_lowered_modulePupdate_spill_fill_size.<locals>.get_program_info.<locals>.process_lowered_module  s    )44$$Q'--v/E/EG &&(..!3S5SS3++-33q8X:XX8%<<>OOO",V-A-A!-D-J-JK%  rD   )r3   r-   type)r   r   r   dispatchs       rA   get_program_info0update_spill_fill_size.<locals>.get_program_info   s7    	/4
	 5 "8
 W&w//rD   c                     S nUR                  5        H'  u  p4XR                  R                  l        U" X45        M)     g )Nc                     [        [        [        U5      5      n[        U [        5      (       a  X R
                  S'   g X R                  S'   g )Nr   )r,   r&   r%   r   r3   r   _compile_specs)r|   r   specs      rA   set_spec@update_spill_fill_size.<locals>.update_program.<locals>.set_spec  s>    46J76STD&/22*.$$Q'+/%%a(rD   )r   r   r   r   )r   r   r  r|   r   s        rA   update_program.update_spill_fill_size.<locals>.update_program  s8    	0  *//1OFBQ##//?V%  2rD   r   )r   listr   update)r   r   r  max_sf_sizemodules_mapr   r   r   s           rA   update_spill_fill_sizer
     ss    
+0Z
&  !""D))$D*:4*@'Ok;Kz* %
 #33C"D;
+rD   c                     [        U 5        g r>   )r
  )objs    rA   canonicalize_programr  /  s
    3rD   c                     [        5       n[        5       nU (       a9  U Vs/ s H,  nU[        R                  [        R                  -   ;  d  M*  UPM.     nn[        X5        U$ s  snf r>   )r1   r   r   
decomp_opsr   r2   )
passes_jobsource_decompositionsskip_decompositionsskip_decomp_ops       rA   get_decomp_tabler  3  sn    46/1  #6
"5 ++n.G.GGH "5 	 
 /E  
s   )A"A"Finputscompiler_specsconstant_methodsdynamic_shapes	dep_tabler  skip_node_id_setskip_node_op_setskip_mutable_buffergenerate_etrecordr   c                 p   S n[        U [        5      (       d  SU 0n U R                  5       nU" X5      nU" X-5      nU" XM5      nU" X]5      nU" Xm5      n0 n0 nU Vs0 s H  nU[        UU   UUU	S9/_M     nnU R	                  5        Hi  u  nn[
        R                  R                  UUU   UU   SS9n[        5       R                  UUS9UU'   [        5       R                  UUU   UU   S9UU'   Mk     [        U5         [        UUUU[        5       U
S9sS	S	S	5        $ s  snf ! , (       d  f       g	= f)
a$  
Transforms and lowers a given PyTorch module to the QNN backend.

Args:
    module (Union[torch.nn.Module, torch.fx.GraphModule,Dict[str, torch.nn.Module], Dict[str, torch.fx.GraphModule]]):
        The PyTorch module or fx.GraphModule to be transformed.
    inputs (Union[Tuple[torch.Tensor], Dict[str, Tuple[torch.Tensor]]]):
        The input tensors for the module.
    compiler_specs (Union[List[Any], Dict[str, List[Any]]]):
        Compiler specifications for Qualcomm AI Engine Direct.
    constant_methods (Optional[Dict[str, Any]]):
        An optional dictionary mapping method names to constant values returned by those methods in eager mode.
        Often used to store configuration information on Edge models.
    dynamic_shapes (Optional[Dict]):
        Information about dynamic shapes.
    dep_table (Optional[Dict]):
        Dependency table for the transformation passes.
    passes_job (Optional[Union[OrderedDict, Dict[str, OrderedDict]]]):
        Ordered dictionary of transformation passes.
    skip_node_id_set (Optional[set]):
        Set of node IDs to skip during partitioning.
    skip_node_op_set (Optional[set]):
        Set of node operations to skip during partitioning.
    skip_mutable_buffer (Optional[bool]):
        Whether to skip delegating the mutable buffer in QNN backend.
    convert_linear_to_conv2d (Optional[bool]):
        Whether to convert linear to conv2d in some cases to improve performance in HTP backend.

Returns:
    EdgeProgramManager:
        The manager for the edge program after transformation and lowering.
c                     U c  U Vs0 s H  o"S_M     sn$ [        U [        5      (       a  XR                  5       :X  a  U $ U Vs0 s H  o"U _M     sn$ s  snf s  snf )a  
Ensures the input value is a dictionary with keys matching the provided graph names.
If the input is not a dictionary or its keys do not match the graph names, a new dictionary
is created with the graph names as keys and the input value assigned to each key.

Examples:
    1. Input is None:
        >>> ensure_graph_specific_dict(None, ["forward1", "forward2"])
        {'forward1': None, 'forward2': None}

    2. Input is a single value:
        >>> ensure_graph_specific_dict(input, ["forward1", "forward2"])
        {'forward1': input, 'forward2': input}

    3. Input is a non-graph specific dict:
        >>> ensure_graph_specific_dict({Any: input}, ["forward1", "forward2"])
        {'forward1': {Any: input}, 'forward2': {Any: input}}
N)r   dictkeys)r   graph_names
graph_names      rA   ensure_graph_specific_dictFto_edge_transform_and_lower_to_qnn.<locals>.ensure_graph_specific_dicty  sb    & =7BC{${CCeT""{jjl'BL4?@KjE!K@@ D As   AAr   )r  r  r  Tr  strict)r   r  r  )transform_passespartitionerr  compile_configr  N)r   r   r!  r   r   ro   exportr   transform_for_export_pipelineget_to_edge_transform_passesr(   r/   r{   )r|   r  r  r  r  r  r  r  r  r  r  r   r$  r"  aten_programsr)  r#  qnn_partitionersr   eps                       rA   "to_edge_transform_and_lower_to_qnnr2  E  s   hA2 fd##V$ ++-K'<F/LN/LN*9BI+JDJ M &
 &J 	z*!1!1$7	
 	
 &  
  
A\\  :)*5	 ! 
 %3$4$R$R)A %S %
j! (6'7'T'T:j1Yz=R (U (
$# (( 
>	**-(-*,/
 
+	*A
@ 
+	*s   D"D''
D5c                    [         R                  " S[        SS9  [        R                  R	                  XUSS9n[        5       R                  U5      nUR                  [        U5      5      n[        US5      nUR                  [        5       5      n[        5       R                  UR                  UUS9n	UR                  " U	6   U$ )a  
TODO: Deprecated capture_program with to_edge_transform_and_lower_to_qnn

Captures and transforms a PyTorch module into an Exir exported program.

Args:
    module (Union[torch.nn.Module, torch.fx.GraphModule]): The PyTorch module or fx.GraphModule to be captured.
    inputs (Tuple[torch.Tensor]): The input tensors for the module.
    dep_table (Optional[Dict]): Dependency table for the transformation passes.
    passes_job (OrderedDict, optional): Ordered dictionary of transformation passes.
    dynamic_shapes (Dict, optional): Information about dynamic shapes.

Returns:
    exir.ExirExportedProgram: The transformed Exir exported program ready for lowering to QNN backend.
zNcapture_program is deprecated. Use to_edge_transform_and_lower_to_qnn instead.r   
stacklevelTr&  Fr(  )warningswarnDeprecationWarningro   r,  r   r-  run_decompositionsr  r*   r+   r{   r.  r   	transform)
r|   r  r  r  r  r1  decomposed_epcore_epedge_epr)  s
             rA   capture_programr>    s    , MMX
 
		VNSW		XB			7	7	;B ))*::*FGM!-7Gooo/0G%'DD   E 
 '(NrD   c                    SSK JnJnJnJnJn  UR                  5       n	[        U	5       H&  u  pUR                   H  nXR                  U'   M     M(     [        [        U	5      5       H  n
U R                  R                   Vs/ s H&  oR                  R                  US5      U
:X  d  M$  UPM(     nnU" U5      nU SU
 3nU" XU5      u  nnnU" U U" UU5      UU5      n U" X5        U" U 5        M     U R                  5         U $ s  snf )Nr   )erase_nodesfuse_as_graphmoduleinsert_subgmlegalize_graph	topo_sort re   )!torch.fx.passes.utils.fuser_utilsr@  rA  rB  rC  rD  propose_partitionsr   nodesmetar   r   graphget	recompile)gm	subgm_tagsubgm_cbptnr@  rA  rB  rC  rD  
partitionsr   	partitionrS   	node_listsorted_nodessubmodule_namesubgmorig_inputsorig_outputss                      rA    _partition_graph_into_submodulesrY    s     '')J!*-OOD#$IIi  $ . 3z?#  XX^^
+Tyy}}Y/Kq/PD^ 	 
 !+%;as++>n,
({L UN+	
 	B%r' $* LLNI)
s   #D*Dc           	         / nU R                   R                   GH  nUR                  S:X  d  M  XR                  ;   d  M'  UR                   Vs/ s HF  n[
        R                  " UR                  S   R                  UR                  S   R                  S9PMH     nnUR                  [        U R                  UR                  5      [        U5      U5      5        U R                  UR                  US   R                  5       R                   5        [#        S UR$                   5       5      (       d  GM  U R                   R'                  U5         U R                   R)                  [*        R,                  US45      nUR                  Ul        UR/                  US S9  S S S 5        GM     U R1                  5         X4$ s  snf ! , (       d  f       GM  = f)	Ncall_modulevaldtyper   c              3   Z   #    U  H!  oR                   [        R                  :g  v   M#     g 7fr>   rI   rJ   rK   )rY   rE   s     rA   r[   :_canonicalize_graph_with_lowered_module.<locals>.<genexpr>6  s     DA88x///s   )+r   c                 <    U R                   [        R                  :g  $ r>   r`  )rZ   s    rA   <lambda>9_canonicalize_graph_with_lowered_module.<locals>.<lambda>?  s    DKK8CSCS4SrD   )replace_withdelete_user_cb)rJ  rH  rH   rP   argsro   onesrI  r   r^  r   r2  get_submoduletupleset_submoduler   r   ra   rb   inserting_afterrG   rJ   rK   replace_all_uses_withrL  )rM  rN  r  edge_prog_mgrsrS   argsubgm_inputgetitem_nodes           rA   '_canonicalize_graph_with_lowered_modulerr    sz   N77m#	YY(>  99$C 

388E?008M8MN$  
 !!2$$TYY/{1C^ 		r"335BB
 DDDDXX--d3#%88#9#9 ((q	$L )-		L%..%1'S /  43) > LLN;" 43s   AG AG
G	T	nn_modulesample_input.calibration_cbr:   r;   fallback_to_cpuc           	      r  ^^ SSK Jn  SSKJn	  SSKJn
  SSKJnJm  UU4S jnUb  UO	[        5       nUb  UO	[        5       n[        R                  R                  XSS9R                  5       nU
" U[        XV5      SS	9nS
n[        UUUUS9nU" U5        UR                  R                    HP  nUR"                  S:X  d  M  UR%                  UR&                  U" UR)                  UR&                  5      5      5        MR     [+        UUUS9u  nnU(       d   [-        U5      nU	" U5      nUR.                  R0                  nUR2                  Ul        [7        U5      US   l        U
" U[        SS9SS	9nSn[        UUS US9n[+        UUUS9u  nnUR=                  U5        UU4$ !   [;        S5        UU4s $ = f)a  
Exclude speific operators from quantizer annotation.
Skipped operators will defaultly stay in CPU, set 'fallback_to_cpu'
to False for trying to delegate them with FP16 precision.

e.g.: consider following graph:
bias_1 weight_1 input_1   bias_2 weight_2 input_2
  | (placeholder) |         | (placeholder) |
   \      |      /           \      |      /
    \     |     /             \     |     /
     \    |    /               \    |    /
       conv2d_1                 conv2d_2
       (torch.ops.aten.conv2d.default)
           \                       /
            \                     /
             \_______     _______/
                     add_1
         (torch.ops.aten.add.default)
                       |
                     output

If user wants to skip convolution op by names with
'skip_node_id_set' = {"conv2d_1"}
"bias_1 / weight_1 / input_1 / input_2 / conv2d_1"
will be partitioned out and not annotated / lowered with QNN.

[Generated graph]
bias_1 weight_1 input_1   input_2
  | (placeholder) |          |
   \      |      /           |
    \     |     /            |
     \    |    /             |
       conv2d_1              |
          \                 /
           \               /
            \             /
           lowered_module_1
        (QNN fixed precision)
                  |
                output

If user wants to skip convolution op by target with
'skip_node_op_set' = {torch.ops.aten.conv2d.default}
"bias_1 / weight_1 / input_1 / conv2d_1,
 bias_2 / weight_2 / input_2 / conv2d_2"
will be partitioned out and not annotated / lowered with QNN.

[Generated graph]
bias_1 weight_1 input_1   bias_2 weight_2 input_2
  | (placeholder) |         | (placeholder) |
   \      |      /           \      |      /
    \     |     /             \     |     /
     \    |    /               \    |    /
       conv2d_1                 conv2d_2
       (torch.ops.aten.conv2d.default)
           \                       /
            \                     /
             \__               __/
                lowered_module_1
             (QNN fixed precision)
                       |
                     output

If user wants to delegate the skipped conv2d from above graph
with 'fallback_to_cpu' = False:

[Generated graph]
   input_1         input_2
(placeholder)   (placeholder)
      |               |
      \               /
      lowered_module_2
     (QNN fp16 precision)
              |
              |
      lowered_module_1
     (QNN fixed precision)
              |
            output

Args:
    nn_module (torch.nn.Module): The module to be lowered.
    quantizer (QnnQuantizer): Instance of QnnQuantizer.
    compiler_specs (List[CompileSpec]): Compiler specs for Qualcomm AI Engine Direct.
    sample_input ((torch.Tensor, ...)): Sample input tensors for graph exporting.
    calibration_cb (callable): Callback function for user-defined calibration.
    fp_node_id_set ({str, ...}): Set of operator names to be left in fp precision.
    fp_node_op_set ({torch.ops.aten.xxx, ...}): Set of operator targets to be left in fp precision.
    fallback_to_cpu (bool): Whether to lower skipped nodes to fp16 or not.

Returns:
    exported_programs: List of programs lowered to QnnBackend (quantized graphs only).
r   )r   )r$   )CapabilityBasedPartitioner)convert_pt2eprepare_pt2ec                 :   > T" U T5      nXR                   l        U$ r>   )r   rh   )rV  
subgm_namesubgm_preparedrz  	quantizers      rA   prepare_subgm&skip_annotation.<locals>.prepare_subgm  s#    %eY7 -7  )rD   Tr'  )allows_single_node_partitionannotated_group)rM  rN  rO  rP  r[  )rM  rN  r  zcFailed to change HTP compiler spec with 'use_fp16' as True, skipped operators will fallback to cpu,)r<   skipped_groupc                     U $ r>   rs   )rV  re   s     rA   rc  !skip_annotation.<locals>.<lambda>  s    erD   )4executorch.backends.qualcomm.serialization.qc_schemar   >executorch.backends.qualcomm.serialization.qc_schema_serializer$   !torch.fx.passes.infra.partitionerrx  'torchao.quantization.pt2e.quantize_pt2ery  rz  rm   ro   r,  r|   r8   rY  rJ  rH  rH   rk  rP   ri  rr  r   r   r   kHtpFp16	precisionr%   r   rd   extend)rs  r~  r  rt  ru  r:   r;   rv  r   r$   rx  ry  r  r   capability_partitionerrN  rS   rn  
qnn_optioncompile_optionr   edge_prog_mgrs_fprz  s    `                    @rA   skip_annotationr  F  s   N MR (6'A^suN'5'A^suN<<&&yt&LSSUL7>:%)
 "I3"	L < ""((77m#&&		\77		BC ) $K%$ L. 	07GJ1*=N(88DDK$=$F$FK!&:>&JN1# "<=)-"

 $	7+&	
 +R)+
''
 	/0''7	0;  //s   AF# #F6r   op_name	soc_modelcustom_infoc           	        ^^ SSK Jn  S m   SS[        [        [              S[        [        [              S[        [        [              4UU4S jjjnS nS	 n[        S
S9n[        UUSS9n	[        U [        5      (       d  U OU" U" U  5      R                  5       U	5      n
0 n[        [        4 H-  nUR                  5        H  u  pUR                  X5        M     M/     Su  nnnUbT  U" US   U5      nU" US   U5      nUR                  SS 5      nUR                  SS 5      nUR                  SS 5      nUS   nO[        R                   " [#        U	5      U
5      nUR%                  5       R&                  S:X  d   S5       eUR)                  5       S   nUR+                  U5        U" UR-                  U5      U5      nU" UR/                  U5      U5      nUR1                  5         U" UUUUU5      nUR3                  UUS.5        [5        UUS   0[7        S
S9S9nUR8                  U   R:                  R<                   H[  nUR>                  S:X  d  M  [@        RB                  [        URD                  5      ;   d  M>  U
URF                  [@        RH                  '     O   URK                  [M        U	5      5      US'   U$ )Nr   )Pathc                    ^ [         R                  R                  U [        U5      SS9S[        [         R
                     4U4S jj5       ng )NCompositeExplicitAutograd)dispatch_keyr  c                 D   > [        S TR                  5        5       5      $ )Nc              3      #    U  H8  n[         R                  " [        UR                  5      S UR                  S9v   M:     g7f)rI  )devicer^  N)ro   zerosrj  r   r^  )rY   vs     rA   r[   Mfrom_context_binary.<locals>.implement_op.<locals>.op_impl.<locals>.<genexpr>  s0      )A E!''N6I)s   A Arj  valuesr  outputss    rA   op_impl:from_context_binary.<locals>.implement_op.<locals>.op_impl  s&       )  rD   )ro   libraryimplr   r	   Tensor)	custom_opr  r  r  s     ` rA   implement_op)from_context_binary.<locals>.implement_op  sE    			s7|2M 
 

	D. 	

	rD   qnn_in_orderexecutorch_in_orderexecutorch_out_orderc                   >^  SnT SU S3n[        [        R                  S5      nUR                  U5        T" UTU5         " U4S jS[        R
                  R                  5      nU(       a  [        U 4S jU 5       5      O[        T R                  5       5      m U" X$5      n	[        R                  R                  U	T SS	9n
UU	U
S
.$ )NzTensor[] inputs(z) -> AnyFRAGMENTc                   :   >^  \ rS rSrSrU 4S jrU4S jrSrU =r$ )7from_context_binary.<locals>.build_graph.<locals>.Modeli&  a  
The args of forward() can be thought of as what executorch is accepting as input.
The getattr inside the forward() can be thought of as qnn context binary.
When we first pass in the input, we need to use the executorch's(nn.module) input order.
After we get into forward(), we then need to convert input order to qnn's input order.
Same as return, when qnn returns the value, we need to reorder them back to executorh's output order.
c                 :   > [         TU ]  5         Xl        X l        g r>   )r   rB   r  r  )r@   r  r  r   s      rA   rB   @from_context_binary.<locals>.build_graph.<locals>.Model.__init__/  s     "$0!,@)rD   c                 V  >^ U R                   (       a  [        U4S jU R                    5       5      m[        [        [        R                  [
        R                  5      T5      R                  T5      nU R                  (       a  U R                   Vs/ s H  o2U   PM	     sn$ U$ s  snf )Nc              3   .   >#    U  H
  nTU   v   M     g 7fr>   rs   rY   r   r  s     rA   r[   Rfrom_context_binary.<locals>.build_graph.<locals>.Model.forward.<locals>.<genexpr>6  s     "H6G6!96Gs   )	r  rj  r   ro   opsr   	namespacedefaultr  )r@   r  retidxr  s    `  rA   r   ?from_context_binary.<locals>.build_graph.<locals>.Model.forward4  s    $$""Hd6G6G"HHFEII'@'@A7'&/ 
 00 *.)B)BC)B#X)BC Cs   B&)r  r  )	rh   ri   rj   rk   rl   rB   r   rr   r   )r   r  s   @rA   Modelr  &  s    A

 
rD   r  c              3   \   >#    U  H!  n[        TR                  5       5      U   v   M#     g 7fr>   r  r  s     rA   r[   ;from_context_binary.<locals>.build_graph.<locals>.<genexpr>A  s#     I5H%(+5Hs   ),Tr  )r  custom_moduler   )
r6   r   r  definero   r   r   rj  r  r,  )r  r  r  r  r  
inputs_str
func_protor  r  modelr   r  r  s   `          rA   build_graph(from_context_binary.<locals>.build_graph  s     '
y*X6
O55zB	$Y1	EHHOO 	8 # I5HIIv}}' 	 l9||""5&"> #" $
 	
rD   c                    [        5       nU  Hn  nUR                  5       nUR                  US 5      nUc
   SU 35       e[        R                  " [        UR                  5       5      US9X#R                  5       '   Mp     U$ )Nzunknown qnn data type r]  )r   GetDataTyperK  ro   r  rj  GetDimsGetName)tensors	dtype_mapr  tr^  dtype_torchs         rA   build_tensor)from_context_binary.<locals>.build_tensorO  sr    mAMMOE#--t4K*L.DUG,LL*${{5+=[QC			  
rD   c                 t    [         R                  " [        U5      5      n[        UR	                  U 5      5      $ r>   )r   r   r   bytesMakeBinaryInfo)ctx_binr  r   s      rA   preprocess_binary.from_context_binary.<locals>.preprocess_binaryY  s2    %00*>:
 W++G455rD   F)use_fp16T)r  r   is_from_context_binaryNNNgraph_inputsgraph_outputsr#  zfailed to load context binaryr  r   )_use_edge_ops)r+  rG   edge_program_manager)'pathlibr  r
   r	   intgenerate_htp_compiler_spec%generate_qnn_executorch_compiler_specr   r   
read_bytesr   r   r   
setdefaultrK  r   r   r   Initr   GetGraphNamesAllocateTensorGetGraphInputsGetGraphOutputsr   r  r+   r)   _edge_programsrJ  rH  rH   r   r  rI   rI  meta_ctx_bin
to_backendr   )r   r  r  r  r  r  r  r  r   r  r  r  type_mapkr  r  r  r  r  r  r#  r   bundle_progedge_prog_mgrrE   r  s    `                       @rA   from_context_binaryr    s     -137487
 tCy)7
 &d3i0	7

 'tCy17
 7
r6 1%@O:'#N (C(( 	txj2==?P  I')<=NN$DA  & % > ?O;L%';
 k.99E{?;YG"~t<)oo.CTJ*/EtL .
 &00*>:
 ||~##q(I*II(**,Q/
z*g44Z@)Lw66zBIN':<PK &W=>
 	[!345(u=M ))*5;;AA44?"'@'@CM'Q3:AFF?//0 B
 +8*B*B~&+K&' rD   c                       \ rS rSrSrSrSrg)
DrawFormati  r   r   rs   N)rh   ri   rj   rk   SVGPYDOTrr   rs   rD   rA   r  r    s    
CErD   r  r   c                    [         R                  R                  X 5      n[        R                  " SSS9  U[
        R                  :X  aI  [        U SU  S3S5       nUR                  UR                  5       R                  5       5        S S S 5        g U[
        R                  :X  a&  UR                  5       R                  U SU  S35        g [        SU S	35      e! , (       d  f       g = f)
NzMFor large models such as LLM, it is strongly recommended to use PYDOT format.r   r4  r   z.svgr   z.dotzUnknown format .)r4   graph_drawerFxGraphDrawerr6  r7  r  r  r   r   get_dot_graph
create_svgr  	write_rawRuntimeError)titler   r   formatrJ  r   s         rA   
draw_graphr    s    --lBEMMW TF!E7$'.!GGE'')4467 /.	:##	#''4&%(=>_VHA677 /.s   .C
C)r  use_memory_optimizationsuse_node_optimizationsuse_queue_recordinguse_weight_sharingc                     [        5       nXl        Xl        X%l        X5l        XEl        [        [        R                  US9$ )a  
Helper function generating backend options for QNN HTP

Args:
    precision:
        kGpuPrecisionFp32 - Sets the precision mode to floating point 32-bit (FP32).
        kGpuPrecisionFp16 - Sets the precision mode to floating point 16-bit (FP16).
        kGpuPrecisionHybrid - Sets the precision mode to FP16 for storage and FP32 for calculations.
        kGpuPrecisionUserProvided - Uses the tensor data type provided by the user.
    use_memory_optimizations: If true, backend will share NATIVE tensor memory
        based upon analysis of the network topology.
    use_node_optimizations: If true, backend will fuse compatible operations into
        one operation to improve performance.
    use_queue_recording: If true, backend will use queue recording to improve performance.
    use_weight_sharing: Used with multiple_graphs, where model size will be
        reduced when operations have the same weights across multiple graphs.

Returns:
    QnnExecuTorchGpuBackendOptions: backend options for QNN GPU.
)r   gpu_options)	r   r  r  r  r  r  r   r   kGpuBackend)r  r  r  r  r  r	  s         rA   generate_gpu_compiler_specr    sC    8 12K%+C()?&&9#%7"&-99 rD   r  use_dlbcr   use_slc_allocatorc                     [        5       nU (       a  [        R                  O[        R                  Ul        [
        R                  Ul        X%l        X5l	        Xl
        XEl        [        [        R                  US9$ )a5  
Helper function generating backend options for QNN HTP

Args:
    use_fp16: If true, the model is compiled to QNN HTP fp16 runtime.
        Note that not all SoC support QNN HTP fp16. Only premium tier SoC
        like Snapdragon 8 Gen 1 or newer can support HTP fp16.
    use_dlbc: Deep Learning Bandwidth Compression allows inputs to be
        compressed, such that the processing bandwidth can be lowered.
    use_multi_contexts: When multiple contexts are generated inside the same
        pte, it is possible to reserve a single spill-fill allocation that
        could be re-used across all the splits.
    use_weight_sharing: Used with multiple_graphs, where model size will be
        reduced when operations have the same weights across multiple graphs.
    use_slc_allocator: Allows user to enable the usage of the System Level Cache Allocator for a given graph.
        It will help the by reducing overall bandwith on the use case.
        The feature is only supported by specific SOCs.

Returns:
    QnnExecuTorchHtpBackendOptions: backend options for QNN HTP.
)r   r   )r   r   r  kHtpQuantizedr  r   	kHtpBurstperformance_moder   r  r  r  r   r   r   )r  r  r   r  r  r   s         rA   r  r    so    8 12K  	"**&44  $C#L#LK %7"%7"#$5!&-99 rD   r   debugsaveronline_preparedump_intermediate_outputsprofileoptraceshared_bufferr  op_package_optionsuse_mha2shac                 ^   [          V s1 s H  o R                  iM     nn W U;  a  [        SU  35      eU(       a  U(       a  [        R                  " SSS9  [        [        U    U5      nU(       a  [        R                  O[        R                  Ul
        X]l        U(       a  SUl        SUl        SUl        U(       a  [        R                   Ul        O2U(       a  [        R$                  Ul        O[        R&                  Ul        U(       aD  UR(                  [*        R,                  :X  a&  UR.                  R0                  (       a  [        S5      eXl        XMl        Xl        U
(       a  [9        U
R:                  5      S	:  a  Xl        Xl        [A        [B        [E        U5      5      /$ s  sn f )
aM  
Helper function generating compiler specs for Qualcomm AI Engine Direct

Args:
    soc_model: The SoC you plan to run the compiled model. Please check
        QcomChipset for supported SoC.
        SM8450 (Snapdragon 8 Gen 1)
        SM8475(Snapdragon 8 Gen 1+)
        SM8550(Snapdragon 8 Gen 2)
        SM8650(Snapdragon 8 Gen 3)
        SM8750(Snapdragon 8 Elite)
        SM8850(Snapdragon 8 Elite Gen 5)
    backend_options: Options required by different backends.
    debug: Enable verbose logging. Disclaimer: this option must change in
        the near future.
    online_prepare: Compose QNN graph on device if set to True
    saver: Instead of compiling the model, run QNN Saver. Please check
        documents of Qualcomm AI Engine Direct SDK. This feature is usually
        for debugging purpose.
    dump_intermediate_outputs: If tensor dump is enabled, all intermediate tensors output will be dumped.
        This option exists for debugging accuracy issues
    profile: Enable profile the performance of per operator.
        Note that for now only support kProfileDetailed to
        profile the performance of each operator with cycle unit.
    shared_buffer: Enables usage of shared buffer between application
        and backend for graph I/O.
    is_from_context_binary: True if current graph comes from pre-built context binary.
    op_package_options: Optional structure to specify op packages
        loaded and used by the backend.
    use_mha2sha: This experimental parameter is used to decide whether to enable multi-head attention to single-head attention pass, aiming to reduce time consumption in AOT and improve performance on HTP.

Returns:
    List[CompileSpec]: Compiler specs for Qualcomm AI Engine Direct.

Raises:
    ValueError: The value QcomChipset is currently not supported.
    ValueError: Confliction between compiler specs.
zunknown SoC model for QNN: zIt is not recommended to turn on both profiling and dump_intermediate_outputs the same time, because dump_intermediate_outputs will cause performance drop.r   r4  zlibQnnSaver.soTsaver_outputzc'use_multi_context' could not function in online prepare mode, please set 'online_prepare' to Falser   )#r   r   
ValueErrorr6  r7  r"   r   r    kLogLevelDebugkLogLevelError	log_levelr  library_pathr  saver_output_dirr#   kProfileOptraceprofile_levelkProfileDetailedkProfileOffr   r   r   r   r   r  r  r  r   op_package_infosr  r  r,   r&   r%   )r  r   r  r  r  r  r  r  r  r  r  r  _supported_soc_modelsqnn_executorch_optionss                 rA   r  r    s   h ?JJk__kJ--6ykBCC,O	
 2	"O
  	,,"11 $ 8Q4.>+'+$2@//H/X/X,	%66 	, 0I/T/T, 	((,D,P,PP''::3
 	

 ,9(,:)4J1c"4"E"EFJ4F1)4& 	)+?@V+WX o Ks   F*c                     0 S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R
                  _S	[         R                  _S
[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _[         R                  [         R                  [         R                  S.E$ NSA8295SA8797SM8350SM8450SM8475SM8550SA8255SM8650SM8750SM8850SSG2115PSSG2125PSXR1230PSXR2230PSXR2330PQCS9100SAR2230P)SW6100QCM6490SM8845)r   V68V81V69V73V75V79rs   rD   rA   get_soc_to_arch_maprF    s4   '++'++ 	'++ 	'++	
 	'++ 	'++ 	'++ 	'++ 	'++ 	'++ 	GKK 	GKK 	GKK 	GKK 	GKK  	7;;!" 	GKK#$ ++;;++) rD   c                     0 S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R
                  _S[         R                  _S[         R                  _S[         R                  _S	[         R                  _S
[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                  _S[         R                   _S[         R"                  _[         R$                  [         R&                  [         R(                  S.E$ r+  )r   r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  r>  r?  rs   rD   rA   get_soc_to_chipset_maprH    s\   +$$+$$ 	+$$ 	+$$	
 	+$$ 	+$$ 	+$$ 	+$$ 	+$$ 	+$$ 	K(( 	K(( 	K(( 	K(( 	K((  	;&&!" 	K((#$ $$&&$$) rD   rM  c                 ^   0 nU R                   R                   H  nUR                  nSnUR                  S:X  a<  SUR                  ;   a,  [        UR                  S   R                  5       5      S   S   nUR                  U;   d  Mo  UR                  XE4/ 5      R                  U5        M     / nUR                  5        HO  u  u  pGnSR                  U Vs/ s H  o3R                  PM     sn5      n	UR                  [        U5      Xy/5        MQ     [        [        U/ SQSS	95        gs  snf )
z
Print a quick preview of op targets and module stack.

Use this to inspect the FX graph and identify module stack, which helps you craft regex or op-target for quantization recipe.

NrG   nn_module_stackr   r   z, )z	Op TargetzModule StackNodesgrid)headerstablefmt)rJ  rH  rI   rH   rI  r  r  r  r   r   joinrP   r   rd   r0   )
rM  supported_opsmodule_metadatarS   rI   deepest_module
table_rowsmodule_stackrH  
node_namess
             rA   %show_nn_module_stack_for_quant_reciperV    s    O77o%*;tyy*H!$)),=">"E"E"GHLQON;;-'&&'?DKKDQ  J)8)>)>)@%YYe<ed		e<=
3v;AB *A 
 FQW	
  =s   D*
get_quant_io_dtype_fnc                     U R                   R                   H&  nU" U5      =n(       d  M  X2R                  [        '   M(     g)zZ
Tag io nodes which get/output quantized tensor. No need to insert q/dq in qnn_preprocess
N)rJ  rH  rI  r'   )rM  rW  rS   r^  s       rA   tag_quant_iorY    s3     )$//5/+0II'( rD   name_obs_dictc                     [        [        5      nU R                  SS9 H  u  p4X$   R                  U5        M     UR	                  5        H@  u  p5[        XS5      nU(       d  [        SU S35        M)  X&    H  n[        XU5        M     MB     g)a  
Rewrite the observer of the specified observer module name in the graph_module.

Example:
Consider the following graph_module after prepare_pt2e:
gm = prepare_pt2e(gm)
print(gm)

GraphModule(
  (activation_post_process_0): MinMaxObserver(min_val=inf, max_val=-inf)
  (activation_post_process_1): MinMaxObserver(min_val=inf, max_val=-inf)
  (activation_post_process_2): MinMaxObserver(min_val=inf, max_val=-inf)
  (activation_post_process_3): MinMaxObserver(min_val=inf, max_val=-inf)
)

new_observer = observer.FixedQParamsObserver(
    scale=0.125,
    zero_point=42,
    dtype=torch.uint8,
    quant_min=0,
    quant_max=255,
    qscheme=torch.per_tensor_affine,
)

Calling rewrite_prepared_observer(gm, {"activation_post_process_0": new_observer})
is equivalent to:
gm.activation_post_process_0 = new_observer

Note:
If the rewritten observer is a SharedQuantizationSpec, all other shared observers will also be rewritten.
F)remove_duplicateNz [WARNING], No observer named as z$ found, please check the moudle name)r   r  named_modulesr   r   r   rd   r   )r   rZ  module_name_listrP   r|   new_observer
old_moduletarget_names           rA   rewrite_prepared_observerrb    s    D #4($22E2J ''- K ,113\6
24&8\] +7KL|< 8 4rD   c                  x    [         R                  R                  SS 5      S-   n [        R                  " U 5      nU$ )NQNN_SDK_ROOTz$/lib/x86_64-linux-clang/libQnnHtp.so)r   environrK  r   GetQnnSdkBuildId)htp_library_pathsdk_build_ids     rA   get_sdk_build_idri    s8    


~t,/UU  '778HILrD   c                    [        5       n[        R                  " SU5      nU(       a$  [        [        UR                  5       S S 5      u  p4O[        SU 35      e[        [        U R                  S5      S S 5      u  pVX5:H  =(       a    XF:  $ Nzv(\d+)\.(\d+)r   zDFailed to get current major and minor version from QNN SDK Build id r  ri  researchmapr  groupsr  splittarget_versioncurrent_versionmatchcurrent_majorcurrent_minortarget_majortarget_minors          rA   is_qnn_sdk_version_less_thanrz        &(OII&8E'*3r0B'C$}RSbRcd
 	
 "%S.*>*>s*CBQ*G!HL(I]-IIrD   c                    [        5       n[        R                  " SU5      nU(       a$  [        [        UR                  5       S S 5      u  p4O[        SU 35      e[        [        U R                  S5      S S 5      u  pVX5:H  =(       a    XF:  $ rk  rl  rr  s          rA   is_qnn_sdk_version_greater_thanr}  &  r{  rD   c                  ,    [         R                  " 5       $ r>   )r   GetQNNCtxBinAlignmentrs   rD   rA    get_qnn_context_binary_alignmentr  6  s    4466rD   )	NNNNNNFFFr  )NNT)FFFF)
FFFFFFFFNF)rJ   r   rm  r6  collectionsr   r   enumr   typingr   r   r   r	   r
   r   r   7executorch.backends.qualcomm.python.PyQnnManagerAdaptorbackendsqualcommpythonr   executorch.exirrv   ro   $executorch.backends.qualcomm._passesr   r   5executorch.backends.qualcomm._passes.qnn_pass_managerr   2executorch.backends.qualcomm.builders.node_visitorr   r   3executorch.backends.qualcomm.builders.qnn_constantsr   6executorch.backends.qualcomm.partition.qnn_partitionerr   r   r   r  r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r  r$   r%   ,executorch.backends.qualcomm.utils.constantsr&   r'   8executorch.backends.qualcomm.utils.qnn_manager_lifecycler(   r)   r*   r+   +executorch.exir.backend.compile_spec_schemar,   &executorch.exir.lowered_backend_moduler-    executorch.exir.program._programr.   r/   r0   torch._decompr1   r2   torch.export.exported_programr3   torch.fxr4    torch.fx.passes.operator_supportr5   torch.libraryr6   r8   rx   r{   r   r   r   r   r   r
  r  _opsOperatorBaser  rp   GraphModuler  rm   rn   r2  r>  rY  rr  r  r3  r  r  r  r  r  kGpuPrecisionUserProvidedr  r  r  rF  rH  rV  rY  rb  ri  rz  r}  r  r  rs   rD   rA   <module>r     s    	 	  0  D D D U U   N P P 
     W K K C G  I 9  @ !=, =@/// '"UXX__ '"T$tCy $NH%-A(BBHV !D)@)@()J$K !6 26%) $GK&*&**/(-/4#C
S%((//!"S%((&&&'	)C
 %%tCu||1D,D'EEFC
 $s)T#tCy.%99:C
 tCH~.C
 TNC
 ~C
 {Dk1A,BBCDC
 smC
 smC
 "$C
   ~!C
" 'tn#C
$ %C
R !%")%((//588#7#778)%,,) ~) 	)
 ) 
)X%P$Z  {(xx{( c)*	{(
 ehh223T9:{( {( {( {(B )//	_Ek__ _ 	_D 
 HR~~ 8%((*>*> 8  ,E+^+^%)#' $$&(&"& !& 	&
 & !&V $$#--- - 	-
 - !-f  &+#(8<mm0m m 	m
 m  $m m m m !m 6m m 
+m`22ehh.B.B :1UXX)) 1( 1/=((&&/=7;C<P7Q/=dJ J 7# 7rD   