
    iȒ                        S SK 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
JrJr  S SKJs  Js  J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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*J+r+J,r,  S SK-J.r.J/r/  S SK0J1r1J2r2  S SK3J4r4  S SK5J6r6  S SK7J8r8  S SK9J:r:  S SK;J<r<  S SK=J>r>  S SK?J@r@  S SKAJBrBJCrC   " S S\@5      rD " S S\+5      rE   SJS\R                  R                  S \HS!\HS"\I4S# jjrJ SKS$\R                  R                  S%\:S"\IS&\:4S' jjrK " S( S)\5      rLSS\LR                  4S&\R                  R                  4S* jjrNSLS+ jrO  SMS,\:S-\PS.\PS&\\R                  S/4   4S0 jjrRSSSSSS\LR                  4S1 jrSSSSSS\LR                  4S2 jrT SNS3 jrU SOS4 jrV   SPS5\R                  R                  S6\%S7\\R                     S&\Y4S8 jjrZS7\\	   S&\\	   4S9 jr[          SQS:\R                  R                  S7\\R                     S&\Y4S; jjr\ SRS6\%S7\\R                  S/4   S<\
\	   S=\IS&\]4
S> jjr^    SSS:\R                  R                  S7\\R                     S?\IS=\IS@\\%   S&\I4SA jjr_S6\%S?\IS&\I4SB jr`SC\
4SD jra     STS:\R                  R                  S7\\R                     S&\b4SE jjrcSF rdSUSG\HSH\H4SI jjreg)V    N)OrderedDict)deepcopy)autoEnum)AnyListOptionalTuple)VulkanPartitioner)VulkanBackend)XnnpackPartitioner)!get_symmetric_quantization_configXNNPACKQuantizer)XnnpackBackend)BundledProgram)MethodTestCaseMethodTestSuite),serialize_from_bundled_program_to_flatbuffer)ExecutorchProgramManagerto_edge_transform_and_lower)_get_node_list_with_same_tag)DelegationSpecPartitionerPartitionResult)tag_constant_datatag_mutated_buffer)&create_exported_program_from_submodulecreate_submodule_from_nodes) _load_for_executorch_from_buffer)tree_flatten)export)ExportedProgram)	InputKind)CapabilityBasedPartitioner)OperatorSupportBase)convert_pt2eprepare_pt2ec                      ^  \ rS rSrSrS\SS4U 4S jjrS\R                  R                  S\
4S jrS\R                  R                  S\
4S	 jrS
rU =r$ )NodeFlagIsSetChecker:   zE
Check if a node is marked with a given field in node.meta["custom"]
fieldreturnNc                 .   > [         TU ]  5         Xl        g N)super__init__r+   selfr+   	__class__s     d/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/vulkan/test/utils.pyr0   NodeFlagIsSetChecker.__init__?   s    
    nodec                     SUR                   ;  a  gUR                   S   nU R                  U;  a  gX R                     $ )NcustomF)metar+   )r2   r7   
custom_maps      r4   check_field NodeFlagIsSetChecker.check_fieldC   s;    499$YYx(
::Z'**%%r6   c                     UR                   S:X  d  UR                   S:X  a  gU R                  U5      (       a  gUR                   H  nU R                  U5      (       d  M    g   g)NplaceholderoutputFT)opr<   users)r2   
submodulesr7   users       r4   is_node_supported&NodeFlagIsSetChecker.is_node_supportedM   s[    77m#tww(': D!! JJD%%  r6   )r+   )__name__
__module____qualname____firstlineno____doc__strr0   torchfxNodeboolr<   rE   __static_attributes____classcell__r3   s   @r4   r)   r)   :   sV    c d & &$ &%((-- D  r6   r)   c                   J   ^  \ rS rSrSrS\SS4U 4S jjrS\S\4S jr	S	r
U =r$ )
FlagBasedPartitioner]   zY
Partitioner that partitions based on whether node.meta["custom"][field] is set to
True.
r+   r,   Nc                 P   > [         TU ]  5         Xl        [        S/ 5      U l        g )Ncustom_partition)r/   r0   r+   r   delegation_specr1   s     r4   r0   FlagBasedPartitioner.__init__c   s#    
-.@"Er6   exported_programc                 B   [        UR                  [        U R                  5      SS9nUR	                  5       n0 nU HA  nUR
                   H.  nSUR                   3nXvR                  S'   U R                  XG'   M0     MC     [        U5        [        U5        [        XS9$ )NT)allows_single_node_partitiontagdelegation_tag)tagged_exported_programpartition_tags)r$   graph_moduler)   r+   propose_partitionsnodesidr:   rY   r   r   r   )r2   r[   capability_partitionerpartition_listra   	partitionr7   r^   s           r4   rh   FlagBasedPartitioner.partitionh   s    !;)) ,)-"

 0BBD'I!ILL>*.1		*+&*&:&:# ( ( 	*++,$4
 	
r6   )rY   r+   )rG   rH   rI   rJ   rK   rL   r0   r"   r   rh   rQ   rR   rS   s   @r4   rU   rU   ]   s6    
Fc Fd F

/ 
o 
 
r6   rU   rb   end_idx	start_idxr+   c                    SnU R                   R                   Hk  nSUR                  ;  a  0 UR                  S'   SUR                  S   U'   UR                  S:w  a  MF  US-  nXB:  d  MR  XA:  d  MY  SUR                  S   U'   Mm     g )Nr   r9   Fcall_function   T)graphrd   r:   rA   )rb   rj   rk   r+   call_fn_countr7   s         r4   mark_node_rangerq      s     M""((499$"$DIIh%*		(E"77o%%-*A)-DIIh& )r6   tagged_graph_moduleowning_programr,   c                    U R                   R                  5       n[        U5      nUR                  U5      n[	        [        UR                  R                  5       5      5      u  pg[        XU5      nU R                  UR                  R                  5       5      n	U	   [        XU5      u  pS S S 5        W
R                   R                  5       nUR                  Ul        [        U
UUWS5      u  nnnU$ ! , (       d  f       NN= f)NF)ro   output_noderU   rh   nextiterra   itemsr   _set_replace_hookgraph_signatureget_replace_hookr   r:   r   )rr   rs   r+   tagged_graph_module_output_nodepartitionerpartition_resultr^   rY   	node_listreplace_ctx	submodulecall_module_nodesubmodule_output_nodesubmodule_program_s                  r4   extract_submodule_programr      s    
 ':&?&?&K&K&M#&u-K",,^<%5%D%D%J%J%L MNC,-@~VI%77&&779K 
&AC'
#	 

 &OO779 "A!E!E 	/				 - 
s   C33
Dc                   4    \ rS rSrSr\" 5       r\" 5       rSrg)QuantizationMode   z1Enum to describe how a model should be quantized. N)	rG   rH   rI   rJ   rK   r   NONEINT8_STATIC_PER_CHANNELrQ   r   r6   r4   r   r      s    ;6D"fr6   r   c                     [        U UUUSS9R                  5       nU[        R                  :X  a  U$ [	        5       n[        SS9nUR                  U5        [        XV5      nU" U6   [        U5      n	U	$ )NTkwargsdynamic_shapesstrict)is_per_channel)	r!   moduler   r   r   r   
set_globalr'   r&   )
modelsample_inputssample_kwargsr   qmodeexport_training_graph	quantizeroperator_configprepared_graphconverted_graphs
             r4   get_exported_graphr      s     #% fh   %%%$$ "I7tLO)!"7CNM"">2Or6   c                    Uc  [         R                  nU[         R                  [         R                  [         R                  [         R
                  [         R                  [         R                  [         R                  4;   a6  [        U5      n[        U5      nXe::  a  US-   n[         R                  " XVXUS9$ U[         R                  4;   a@  [        S[        U5      5      n[        U5      nXe::  a  US-   n[         R                  " XVXUS9$ U[         R                  :X  a3  [         R                  " SSX[         R                  S9R                  5       $ [         R                  " XUS9R                  X5      $ )Nrn   )devicedtyper      )rM   float32intint8int16int32int64longshortrandintuint8maxrP   emptyuniform_)shapelowhighr   r   low_inthigh_ints          r4   random_uniform_tensorr      s   } 		



  c(t9{H}}WERR aS"t9{H}}WERR 

}}Q5uzzJOOQQ ;;u59BB3MMr6   r[   r   r   .c                 T   / n[        5       nU R                  R                   He  nUR                  [        R
                  :X  d  M#  [        UR                  S5      (       d  M@  UR                  UR                  R                  5        Mg     U R                  R                   H  nUR                  S:w  a  M  UR                  U;  a  M'  SUR                  ;   d  M9  UR                  S   nSnSn	[        U[        R                   5      (       a"  [#        UR$                  5      nUR&                  n	OC[        US5      (       a2  [        US5      (       a!  [#        UR$                  5      nUR&                  n	Uc  M  U	c  M  [)        XX)S9n
UR+                  U
5        M     [-        U5      u  pU$ )a  
Analyze the exported program graph to determine input shapes and dtypes,
then generate random sample inputs.

Uses the graph signature to identify only user inputs (excluding parameters,
buffers, and other non-input placeholders).

Args:
    exported_program: The exported program to analyze
    low: Lower bound for random uniform values (default: -1.0)
    high: Upper bound for random uniform values (default: 1.0)

Returns:
    Tuple of randomly generated tensors matching the input specs
namer?   valNr   r   )r   r   r   )setrz   input_specskindr#   
USER_INPUThasattrargaddr   ro   rd   rA   r:   
isinstancerM   Tensortupler   r   r   appendr    )r[   r   r   r   user_input_namesspecr7   r   r   r   tensorinputs_flattenedr   s                r4   generate_sample_inputsr     sR   ( M u 00<<99	,,,txx(( $$TXX]]3 =
 !&&,,77m# 99,,DII))E"CEE#u||,,cii(		g&&73+@+@cii(		 U%6.uDV$$V,/ -2 '}5r6   c	                    0 n	[        U UUUUS9n
[        U
UUUSS9n[        U[        U	UUUUS9/S S S9nUR	                  5       nUR
                  R                  S   R                  S   R                  [        R                  :w  aM  [        S[        R                   SUR
                  R                  S   R                  S   R                   35      eU$ )	N)r   r   r   Tr   operator_blocklistoperator_allowlistnn_module_blocklistnn_module_allowlistr}   transform_passescompile_configr   Expected delegate ID 
, but got )r   r!   r   r   to_executorchexecutorch_programexecution_plan	delegatesre   r   rG   RuntimeError)r   r   r   r   r   r   r   r   r   compile_optionsexported_graphprogramedge_programr   s                 r4   export_model_to_vulkanr   A  s)    O'#%N %G /#5#5$7$7
 L &335 	--<<Q?II!LOO!!	" #M$:$:#;:FXFkFkFzFz{|F}  GH  GH  IJ  GK  GN  GN  FO  P
 	
 r6   c                    0 n[        XUS9n	[        U	UUSS9n
[        U
[        U5      /S S S9nUR	                  5       nUR
                  R                  S   R                  S   R                  [        R                  :w  aM  [        S[        R                   SUR
                  R                  S   R                  S   R                   35      eU$ )N)r   Tr   r   r   r   r   r   )r   r!   r   r   r   r   r   r   re   r   rG   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   s                r4   export_model_to_xnnpackr   y  s    O'EJN%	G /'89	L &335 	--<<Q?II!LOO""	# #N$;$;#<JGYGlGlG{G{|}G~  HI  HI  JK  HL  HO  HO  GP  Q
 	
 r6   c                     [        U [        [        45      (       a  [        U[        [        45      (       ay  [        U 5      [        U5      :w  a$  [	        S[        U 5       S[        U5       35        g[        [        X5      5       H$  u  nu  pg[	        SU S35        [        XgX#U5        M&     g[        U [        R                  5      (       a  [        U[        R                  5      (       d  [	        S5        gU R                  UR                  :w  a&  [	        SU R                   SUR                   35        g[        R                  " X-
  5      nU[        R                  " U5      S-   -  n	X:  X:  -  n
U
R                  5       (       d  [	        S	5        g[        R                  " U
S
S9nUR                  S   n[	        SU SU SU S35        [	        S[        XL5       S35        [	        S5        [        [        XL5      5       H  n[        X   R!                  5       5      nX   R#                  5       nX   R#                  5       nX   R#                  5       nX   R#                  5       n[	        U SUS SUS SUS SUS 3	5        M     g)aM  
Print the first max_errors tensor indexes that exceed the absolute/relative tolerance
and the error at each of those locations.

Args:
    tensor1: First tensor to compare
    tensor2: Second tensor to compare
    atol: Absolute tolerance
    rtol: Relative tolerance
    max_errors: Maximum number of errors to print (default: 10)
zTensor count mismatch:  vs Nz
=== Tensor z comparison ===z/Error: Both inputs must be torch.Tensor objectszShape mismatch: g:0yE>zAll values are within toleranceF)as_tupler   Found z" values exceeding tolerance (atol=z, rtol=)zShowing first z errors:z;Index -> tensor1_value, tensor2_value, abs_error, rel_errorz -> z.6fz, z
, abs_err=z
, rel_err=)r   listr   lenprint	enumeratezipprint_tensor_comparison_errorsrM   r   r   absanynonzerominrangetolistitem)tensor1tensor2atolrtol
max_errorsit1t2abs_diffrel_difftolerance_maskerror_indicestotal_errorsidxval1val2abs_errrel_errs                     r4   r   r     sJ    'D%=))j4-.P.Pw<3w<'+CL>c'l^LM$S%:;KAxM!O45*24zJ < 	 gu||,,Jw4U4U?@}}% tGMM?CD yy*+H		'T!H
 o(/:N/0 MM.5AM &&q)L	F<. B4&PTvUV
WX	N3z89
BC	
GH 3z01M$++-.|  "|  "-$$&-$$&e4SzD:Z}JwWZm\	
 2r6   c           
         [        U[        5      (       a  [        UR                  5       5      n[        U[        5      (       d  [        U[        5      (       GaP  [        U5      [        U 5      :w  a  [        XX#5        gU(       a8  [        R                  " U S   US   X#S9nU(       d  [        U S   US   X#5        U$ Sn[        [        U5      5       H  n[        X   [        R                  5      (       aE  [        R                  " X   X   X#S9(       d$  [        SU S35        [        X   X   X#5        SnMg  Mi  [        X   [        5      (       a4  X   X   :X  d(  [        SU S35        [        X    SX/    35        SnM  M  [        SU S	[        X   5       35        M     U$ [        R                  " U S   XUS9nU(       d  [        U S   XU5        U$ )
z
Helper function that checks if model output and reference output are equal with some tolerance.
Returns True if equal, False otherwise.
Fr   )r   r   Tz
=== Output z comparison failed ===r   zWARNING: Output z
 has type )r   r   r   valuesr   r   r   rM   allcloser   r   r   r   type)model_output
ref_outputr   r   first_output_onlyresultr   s          r4   check_outputs_equalr    s    *k***++-.
 *e$$
:t(D(Dz?c,//*<TP^^QATF . OZ]D MF3z?+jmU\\:: >>$T aS0FGH6(OZ]D "'  
s33'?jm;aS0FGH 1jo5FGH!& <
 ,QCz$z}:M9NOP! ," M QTR*<?JdSr6   reference_modelr   r   c                     [        UR                  5      n[        U5      u  pxUR                  S[	        U5      5      n	[        U " U6 5      u  p[        U	U
UUUS9$ )a^  
Utility function that accepts an already lowered ExecuTorch program, executes it with
the provided sample input, and checks the output for correctness.

Args:
    executorch_program: Already lowered ExecutorchProgramManager
    sample_inputs: Sample inputs to run the program with
    reference_model: Reference model to generate reference outputs for comparison
    atol: Absolute tolerance for output comparison
    rtol: Relative tolerance for output comparison
    first_output_only: Whether to compare only the first output

Returns:
    bool: True if outputs match within tolerance, False otherwise
forwardr   r   r  )r   bufferr    
run_methodr   r  )r  r   r   r   r   r  executorch_moduler   r   r	  r
  s              r4   run_and_check_outputr    sq    0 99K9R9RS '}5 %//	5AQ;RSL !-!@AMJ + r6   c                     / nU  H]  n[        U[        R                  5      (       a!  UR                  UR	                  5       5        MC  UR                  [        U5      5        M_     [        U5      $ r.   )r   rM   r   r   cloner   r   )r   sample_inputs_copy	input_vals      r4   make_copy_of_inputsr  H  sY    "	i..%%ioo&78%%hy&9:	 #
 #$$r6   r   c           
         U(       a  [        U [        U5      UUUU
U	5      nO[        U [        U5      UUUU
U	S9n[        UR                  5      n[        U5      u  pUR                  S[        U5      5      nU " [        U5      6 n[        UUUUUS9(       d  gUbK  U HE  n[        U5      u  nnUR                  S[        U5      5      nU " U6 n[        UUUUUS9(       a  ME    g   g)a  
Helper testing function that takes a torch.nn.Module and lowers it to Vulkan with
the given sample inputs. It then runs the lowered module and compares its
outputs with the outputs of the eager module.

Returns:
    bool: True if all comparisons pass, False otherwise.
r   r  r  FT)	r   r  r   r   r  r    r  r   r  )r   r   r   r   r   test_inputsr  r   r   r   r   xnnpackr   r  r   r   r	  r
  
test_inputtest_inputs_flatteneds                       r4   lower_module_and_test_outputr   R  s&   . 4.
 4.11 3 3
 99K9R9RS&}5$//	5AQ;RSL+M:;J+ %J'3J'?$!1,775!67L 
+J&"3   &  r6   expected_outputsmethod_namec                 t    [        U5      u  pE[        U[        UUS9/S9/n[        X5      n[	        U5      nU$ )a  
Create a bundled program containing the model and test cases for correctness testing.

Args:
    executorch_program: The ExecutorchProgramManager to bundle
    sample_inputs: Sample inputs for the model
    expected_outputs: Expected outputs from running the model with sample_inputs
    method_name: Name of the method to test (default: "forward")

Returns:
    Serialized bundled program as bytes
)inputsr!  )r"  
test_cases)r    r   r   r   r   )	r   r   r!  r"  r   r   test_suitesbundled_programbundled_buffers	            r4   create_bundled_programr)    sY    & '}5 	#+%5	

K %%7EO B/RNr6   output_path
et_programc                 B   Uc  [        U UUUS9nUc  0 n[        X5      " U0 UD6/n[        X45      u  p[        U[	        U5      UU5      n
UR                  S5      (       d  US-   n[        US5       nUR                  U
5        SSS5        U$ ! , (       d  f       U$ = f)a	  
Export a bundled .pte file containing the model and test cases.

Args:
    model: The PyTorch model to export
    sample_inputs: Sample inputs for the model
    output_path: Path where the bundled .pte file should be saved (should end with .bpte)
    method_name: Name of the method to test (default: "forward")
    et_program: Optional pre-exported ExecutorchProgramManager. If None, will export to Vulkan
    dynamic_shapes: Optional dynamic shapes for export

Returns:
    str: Path to the saved bundled program file
N)r   r   z.bptewb)r   getattrr    r)  r   endswithopenwrite)r   r   r*  r"  r   r+  r   r!  r   r   	bp_bufferfiles               r4   save_bundled_programr4    s    0 +')	

   3]TmTU ''EF '	I ((!G+ 
k4	 D

9 
! 
!	 s   3B
Bc                     UR                  S5      (       d  US-   n[        US5       nU R                  U5        SSS5        U$ ! , (       d  f       U$ = f)z
Save an ExecutorchProgramManager as a .pte file.

Args:
    executorch_program: The ExecutorchProgramManager to save
    output_path: Path where the .pte file should be saved (should end with .pte)

Returns:
    str: Path to the saved .pte file
z.pter-  N)r/  r0  write_to_file)r   r*  r3  s      r4   save_executorch_programr7    sY     ''!F* 
k4	 D((. 
!  
!	  s   A
Aoperator_listc                 *   [         R                  " S5      nUR                  [         R                  5        UR	                  S[        U5       S35        SnU R                  5       R                  R                   GH;  n[        R                  " U5      (       d  M!  UR                  nUR                  [        R                  R                  R                  :X  d2  UR                  [        R                  R                  R                   :X  aN  UR"                  S   n[%        US5      (       a  UR'                  5       nO[%        US5      (       a  UR(                  nXQ;   d  M  US-  nUR	                  SU S	UR+                  5        35         [        R,                  " U5      nUR	                  S
U 35        GM>     US:X  a  UR	                  S5        gUR	                  SU S35        g! [.         a   nUR	                  SU 35         SnAGM  SnAff = f)z
Print the input/output information for all occurrences of specified operators in the edge program.

Args:
    edge_program: The edge program created by to_edge_transform_and_lower
    operator_list: List of operators to search for in the graph
 zSearching for occurrences of z operators in the graph...r   r   rG   rn   zOccurrence :   z  Error getting I/O string: Nz=No occurrences of the specified operators found in the graph.r   z. total occurrences of the specified operators.)logging	getLoggersetLevelINFOinfor   r[   ro   rd   utilsis_torch_op_nodetargetrM   opshigher_orderauto_functionalizedauto_functionalized_v2argsr   r   rG   format_nodenode_io_str	Exception)	r   r8  loggeroccurrence_countr7   rD  	first_argio_stres	            r4   print_occurrencesrR  !  s    r"F
OOGLL!
KK
'M(:';;UV --/55;;!!$''[[F uyy55III;;%))"8"8"O"OO IIaL	9f--&^^-FY
33&//F & A% k*:);2d>N>N>P=QRSD"..t4FKK"VH.- <4 1ST%&&TU	
 ! DKK">qc BCCDs   *G((
H2HHc           
      B  ^ ^^^^^^^^^^^ [         R                  " S5      mTR                  [         R                  5        TR	                  S5        [        T TSS9R                  5       n[        UTTSS9n[        U/ SSS9n	0 mU	R                  5       R                  R                   H  n
[        R                  " U
5      (       d  M   U
R                  nU
R                  [        R                  R                   R"                  :X  d2  U
R                  [        R                  R                   R$                  :X  aN  U
R&                  S   n[)        US	5      (       a  UR+                  5       nO[)        US
5      (       a  UR,                  nUT;   a  TU==   S-  ss'   M  STU'   M     [/        TR1                  5       5      nTR	                  S[3        U5       S35        [5        UU4S jSS9nTR	                  S5        U H,  nTR	                  SUR+                  5        STU    S35        M.     SmS[6        S[6        S[8        4UUUUU UUUU4	S jjmS[6        S[6        S[:        [6        [6        4   4UUU4S jjmTR	                  S[3        U5       S35        T" U/ 5      u  nnTR	                  ST S35        TR	                  S[3        U5       S35        U H,  nTR	                  SUR+                  5        S TU    S!35        M.     TR	                  S"[3        U5       S35        U H,  nTR	                  S#UR+                  5        S TU    S!35        M.     [=        U	U5        [3        U5      T-
  nTR	                  S$T S%[3        U5       S&U S'35        UUTUTS(.$ ))a  
Fast binary search utility function to determine which operators work correctly when delegated to Vulkan.

This function uses a binary search approach to efficiently find bad operators:
1. Split operators into two halves (least frequent first, most frequent second)
2. Test each half to see if it produces correct output
3. Add good halves to known_good_ops and recursively search bad halves
4. Continue until all operators are classified

Args:
    model: The PyTorch model to test
    sample_inputs: Sample inputs for the model
    atol: Absolute tolerance for output comparison
    rtol: Relative tolerance for output comparison
    dynamic_shapes: Optional dynamic shapes for export
    test_inputs: Optional additional test inputs
    first_output_only: Whether to compare only the first output

Returns:
    dict: Dictionary with keys:
        - 'good_operators': List of operators that work correctly
        - 'bad_operators': List of operators that cause failures
        - 'operator_frequencies': Dictionary mapping operators to their occurrence count
        - 'all_operators': List of all unique operators found in the graph
        - 'test_count': Number of tests performed
r:  z5Starting fast binary search operator ablation test...T)r   r   Nr   r   r   rG   rn   r   z unique operators in the graphc                    > TU    $ r.   r   )rA   operator_frequenciess    r4   <lambda>"op_ablation_test.<locals>.<lambda>  s    &:2&>r6   )keyreversezAOperator frequencies (sorted by occurrence, most frequent first):r<  r;  z occurrencesops_to_testknown_good_opsr,   c                   >	 TS-  mX-   nT	R                  ST S[        U 5       S[        U5       S35         [        T
TTTTTTUS9nT	R                  SU(       a  SOS	 35        T	R                  S
5        U H%  nT	R                  SUR                  5        35        M'     T	R                  S5        U  H%  nT	R                  SUR                  5        35        M'     U$ ! [         a  nT	R                  SU 35         SnAgSnAff = f)zSTest if a set of operators works correctly when combined with known good operators.rn   zTest z
: Testing z operators with z known good)r   r   r   r   r   r  r  r   r<  u   ✓ PASSu   ✗ FAIL  Known good:  * z  Tested ops:z  ! Error: NF)rA  r   r   r   rL  )rZ  r[  test_allowlistsuccessrA   rQ  r   r   r  rM  r   r   r   
test_countr  s         r4   test_operator_set+op_ablation_test.<locals>.test_operator_set  s    	a
'5J<z#k*:);;KCP^L_K``kl	
	2+-'"3#1	G KK"7Z
CDE KK($d2779+./ % KK(!d2779+./ " N 	KK+aS)*	s   B&C   
D*DDc           
        > U (       d  / / 4$ [        U 5      S:X  ad  U S   nT" U/U5      (       a(  TR                  SUR                  5        S35        U// 4$ TR                  SUR                  5        S35        / U/4$ [        U 5      S-  nU SU nXS nTR                  S[        U 5       S	[        U5       S
[        U5       35        TR                  S5        U H%  nTR                  SUR                  5        35        M'     TR                  S5        U H%  nTR                  SUR                  5        35        M'     TR                  S5        U H%  nTR                  SUR                  5        35        M'     / n/ nT" XA5      nU(       a@  TR                  S[        U5       S35        UR                  U5        UR                  U5        T" XQ5      n	U	(       a/  TR                  S[        U5       S35        UR                  U5        U(       d[  TR                  S[        U5       S35        T" XA5      u  pUR                  U
5        UR                  U5        UR                  U
5        U	(       dJ  TR                  S[        U5       S35        T" XQ5      u  pUR                  U
5        UR                  U5        Xg4$ )z}
Recursively find bad operators using binary search.

Returns:
    Tuple of (good_operators, bad_operators) from ops_to_test
rn   r   z  Single operator z is GOODz is BADr   Nz
Splitting z operators: z + r]  r^  z  First half ops:z  Second half ops:zFirst half (z$ ops) is good - adding to known goodzSecond half (z ops) is bad - recursing)r   rA  r   extend)rZ  r[  rA   mid
first_halfsecond_halfgood_opsbad_opsfirst_half_goodsecond_half_goodsub_goodsub_badfind_bad_operatorsrM  rb  s               r4   ro  ,op_ablation_test.<locals>.find_bad_operators  s    r6M{q QB "~6608DEtRx07CDB4x +!# #&
!$'[)*,s:6Gs3{K[J\]	

 	O$ BKK$rwwyk*+ ! 	'(BKK$rwwyk*+  	()BKK$rwwyk*+  +JGKKs://ST OOJ'!!*-,[IKKK 011UV OOK(KK,s:&77OPQ 2: NHOOH%NN7#!!(+KK-K(8'99QRS 2; OHOOH%NN7#  r6   z
=== Starting binary search on z operators ===z"
=== Binary search complete after z
 tests ===zGood operators (z):u     ✓ z (frequency: r   zBad operators (u     ✗ zEfficiency: z tests instead of z (saved z tests))good_operatorsbad_operatorsrU  all_operatorsra  )r=  r>  r?  r@  rA  r!   r   r   r[   ro   rd   rB  rC  rD  rM   rE  rF  rG  rH  rI  r   r   rG   r   keysr   sortedr   rP   r
   rR  )r   r   r   r   r   r  r  r   r   r   r7   rD  rO  rs  operators_by_frequencyrA   rq  rr  efficiency_gainro  rM  rU  ra  rb  s   ```````            @@@@@r4   op_ablation_testrx  T  s   F r"F
OOGLL!
KKGH #5-ELLN%	G /	L --/55;;!!$''[[F uyy55III;;%))"8"8"O"OO IIaL	9f--&^^-FY
33&//F--$V,1,/0$V,# <& -2245M
KK&]+,,JKL $> KKST$b2&:2&>%?|LM % J$t $T $d $ $LL!L!+/L!	tTz	L! L!^ KK
*3/E+F*G~V %77Mr$R!NM KK5j\LM
KK"3~#6"7r:;fRWWYK}5I"5M4NaPQ  KK/#m"4!5R89fRWWYK}5I"5M4NaPQ  lM2-(:5O
KK
zl"4S5G4HQ`Paahi
 )& 4&  r6   c                 8    Sn[        U 5       H  nUS-  nM
     U$ )Nr:   )r   )indent_level
indent_strr   s      r4   make_indentr}  C  s&    J< c
 !r6   nr{  c                    [        U [        [        45      (       aK  [        [	        U5       SU S[        U 5       35        US-   n[        U 5       H  u  p[        XAU5        M     g [        U [        R                  5      (       as  [        [	        U5       SU SU R                   SU R                  5       R                  5        SU R                  5       R                  5        SU R                   S35        g [        U [        5      (       a  [        [	        U5       SU SU  35        g [        [	        U5       SU S[        U 5       35        g )	Noutput_z = r   z$ = test_utils.random_uniform_tensor(z, low=z, high=z	,  dtype=r   )r   r   r   r   r}  r  r   print_outputrM   r   r   r   r   r   r   r   )outputsr~  r{  new_indent_leveltest_outs        r4   r  r  J  sy   'D%=))\*+71#SgHI'!+$W-KA&67 .	GU\\	*	*<()3WX_XeXeWfflmtmxmxmzmm  nB  mC  CJ  KR  KV  KV  KX  K]  K]  K_  J`  `i  jq  jw  jw  ix  xy  z	
 
GS	!	!\*+71#S	BC\*+71#SgHIr6   )ir   _in_target_subgraph)r  )g              ?NN)g      r  )MbP?r  
   )r  r  F)r  皙?F)
r  r  NNFNNNNF)r  )r  NNN)r  r  NNF)r   r   )fr=  collectionsr   copyr   enumr   r   typingr   r   r	   r
    executorch.backends.vulkan.utilsbackendsvulkanrB  rM   9executorch.backends.vulkan.partitioner.vulkan_partitionerr   ,executorch.backends.vulkan.vulkan_preprocessr   9executorch.backends.xnnpack.partition.xnnpack_partitionerr   7executorch.backends.xnnpack.quantizer.xnnpack_quantizerr   r   .executorch.backends.xnnpack.xnnpack_preprocessr   executorch.devtoolsr   *executorch.devtools.bundled_program.configr   r   -executorch.devtools.bundled_program.serializer   executorch.exirr   r   #executorch.exir.backend.backend_apir   #executorch.exir.backend.partitionerr   r   r   executorch.exir.backend.utilsr   r   &executorch.exir.lowered_backend_moduler   r   ,executorch.extension.pybindings.portable_libr   executorch.extension.pytreer    torch.exportr!   torch.export.exported_programr"   torch.export.graph_signaturer#   !torch.fx.passes.infra.partitionerr$    torch.fx.passes.operator_supportr%   'torchao.quantization.pt2e.quantize_pt2er&   r'   r)   rU   rN   GraphModuler   rL   rq   r   r   r   r   r   floatr   r   r   r   r   r  nnModulerP   r  r  r   bytesr)  r4  r7  rR  dictrx  r}  r  r   r6   r4   <module>r     s    #   - - 0 0  W F X J . V R L  P 5  9 2 H @ N .  F
; 
H &	.((&&.. . 	.0 '&--&#& & 	&R%t % 


 XX<"NN 7%7	7 7 5<<	7z 


5v 


%R :<A
J IN3t 
	*XX__*0* &* 
*Z%uSz %eCj % 
	M88??M&M 
Mh !	(0(s*+( 3i( 	(
 (^ !59888??8&8 8 	8 128 	8v0 	20
4 0
l 
	l88??l&l 
l^JS JC Jr6   