
    Vh                        d dl Z d dlZd dlZd dlmZmZmZ d dlZd dlZd dl	m
Z
 d dlmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZ d dlmZ dZdZej@                  ejB                  j@                  ej@                  ejD                  ejB                  jD                  ejD                  hZ#d Z$d Z% G d d      Z&de'e(ef   de'e(e)e   f   fdZ*dededede+de+de(dedee(   dejX                  jZ                  fdZ.dejX                  jZ                  dededefdZ/	 	 d5dede+de+dededee(   d e)e'e(ef      d!ed"e)ee      d#ee   d$ee'e(ef      ddfd%Z0	 	 d5dede+d&e(d'e)e   d(e)e   d e)e'e(ef      d#ee   d$ee'e(ef      ddfd)Z1ded*e'e(e)e   f   d+ed,e'e(ef   ddf
d-Z2dejX                  jZ                  fd.Z3d/edefd0Z4d1edefd2Z5defd3Z6	 	 d6d4Z7y)7    N)AnyCallableOptional)_maybe_get_fqn)NSResultsTypeNSSingleResultValuesType)get_normalized_nth_inputget_target_type_str)QConfigMapping)_MatchResult)
QConfigAny)getattr_from_fqn)GraphGraphModuleNode)tree_mapshadowshadow_wrapperc                     t          d|  d| S N_)SHADOW_NODE_NAME_PREFIXsubgraph_idxsubgraph_candidate_idxs     N/home/dcms/DCMS/lib/python3.12/site-packages/torch/ao/ns/fx/n_shadows_utils.py_get_attr_namer   %   s    %&a~Q7M6NOO    c                     t          d|  d| S r   )SHADOW_WRAPPER_NODE_NAME_PREFIXr   s     r   _get_attr_wrapper_namer!   )   s    -.a~Q?U>VWWr   c                       e Zd ZdZd Zd Zy)
OutputPropa  
    Output propagation (modeled from shape propagation).

    Given a GraphModule and an example input, saves the output flowing
    through each node on `node.traced_result`.

    Code based on the example from
    https://pytorch.org/docs/stable/fx.html#the-interpreter-pattern
    c                     || _         |j                  | _        t        | j                   j                               | _        y N)modgraphdictnamed_modulesmodules)selfr&   s     r   __init__zOutputProp.__init__8   s-    YY
DHH2245r   c                    	 t        |      }i 		fd}dt        f fd} j                  j                  D ]S  }|j                  dk(  rt        |      }n|j                  dk(  r ||j                        }n|j                  dk(  r3 |j                   ||j                        i  ||j                        }n|j                  dk(  rC ||j                        ^}} ||j                        } t        ||j                        |i |}nN|j                  dk(  r?  j                  |j                      ||j                        i  ||j                        }t        t        j                        r||_        |	|j                  <   V y )	Nc                 ^    t         j                  j                  j                  | fd      S )Nc                 "    | j                      S r%   )name)nenvs    r   <lambda>z8OutputProp.propagate.<locals>.load_arg.<locals>.<lambda>B   s    s166{ r   )torchfxr'   map_arg)ar2   s    r   load_argz&OutputProp.propagate.<locals>.load_argA   s    88>>))!-BCCr   targetc           	          | j                  d      }j                  }t        |      D ]=  \  }}t        ||      s t	        ddj                  |d |              t        ||      }? |S )N.z#Node referenced nonexistent target )splitr&   	enumeratehasattrRuntimeErrorjoingetattr)r9   target_atomsattr_itriatomr+   s        r   
fetch_attrz(OutputProp.propagate.<locals>.fetch_attrD   s{    !<<,LxxH$\2 34x.&=chh|TVUVGW>X=YZ  #8T23 Or   placeholderget_attrcall_functioncall_methodcall_module)iterstrr'   nodesopnextr9   argskwargsrA   r*   
isinstancer4   Tensortraced_resultr0   )
r+   rQ   	args_iterr8   rF   noderesultself_objrR   r2   s
   `        @r   	propagatezOutputProp.propagate=   sT   J	!	D		s 		 JJ$$ 	$Dww-'iJ&#DKK0O+$htyy&9SXdkk=RSM)"*499"54!$++.74;;7HHM)2dkk2dii(,4T[[,A &%,,/%+"#C		N'	$* r   N)__name__
__module____qualname____doc__r,   rZ    r   r   r#   r#   -   s    6
'r   r#   matchesreturnc                 Z   t               }i }g }| j                         D ]  \  }}|j                  d||f        |D ]j  \  }}d}|d   D ]l  }t        |t              r||v rd}|j                  |       +t        |t              sJ |D ]+  }t        |t              sJ ||v rd}|j                  |       - n |rg }	t        |d         dk(  r|d   }	nt        |d         dk(  sJ dt        t           fd}
t        |d   d   t              rt        |d   d   t              r|d   }	ngt        |d   d   t              r|d   d   \  }}|d   d   } |
|||      }	n3t        |d   d   t              r|d   d   \  }}|d   d   } |
|||      }	|	j                          |	||<   m |S )Nr   F   T   ra   c                    | ||g}d }d }d }|D ]?  }|j                   d   }t        t        |j                              }	||vr|}7|	|vr|}>|}A |||J |j                   d   |u sJ |j                   d   |u sJ |||gS )Nr   )rQ   rP   rL   users)
node_anode_bnode_crN   
first_nodemid_node	last_noder1   prev_nnext_ns
             r   _order_nodesz*_get_dedup_subgraphs.<locals>._order_nodes   s    0!
 	 %AVVAYF!$qww-0FU*%&
u,$%	#$% * ,!-.  }}Q':555 ~~a(H444!8Z88r   )
setitemsinsertrS   r   addtuplelenlistreverse)r`   
seen_nodessubgraphs_dedupmatches_items_reversedr0   	cur_matchwas_seennode_or_tuplerW   list_of_nodesro   rg   rh   ri   s                 r   _get_dedup_subgraphsr   g   s    JO
 >@"==? <i%%a$	):;< 2 W.i&q\ 	)M  -. J.#H}- "-777) )D%dD111z)#'NN4(	)/	):  y|!%aLMy|$)))9T
 9. )A,q/40Z	!QQU5V )!IaLOU3!*1a"1a ,VVV DIaLOU3!*1a"1a ,VVV D 	 -oW.r r   modelrj   rl   r   r   qconfig_str
logger_clsfqnc                     |d} ||j                   |j                   d| d| dt        ||       t        ||       t        j                  j                  dd||      }d|_        |S )z
    Given a model and a linear subgraph starting from `first_node` and
    ending with `last_node`, creates a logger for the end of this
    subgraph.
     	subgraph_r   r   r   F)r0   r
   r   NODE_OUTPUTvalueenabled)	r   rj   rl   r   r   r   r   r   logger_mod_origs	            r   _get_logger_for_subgraphr      sz     { 
L>#9":;Iu-J. ,,22		O  $Or   c           
      &	    G d dt         j                  j                        } |       }t         j                  j	                  |      }|j
                  }t        |j
                  j                        D ]  }|j                  |        |}d}	d}
d}	 ||u rpg }i }t               }i }dt        dt        fd}|j                  D ]  }t        |t              r |||||      }|j                  |       0t        |t        t         f      rWg }|D ]>  }t        |t              r|j                   |||||             .|j                  |       @ |j                  |       |j                  |        |j"                  j%                         D ]j  \  }}t        |t              r |||||      ||<   %t        |t        t         f      r+g }|D ]  } |||||      }|j                  |         |||<   f|||<   l t!        |      }n|j&                  t(        vsJ g}t+        |j                        dkD  r|j                  dd	 D ]  }t        |t         j                  j,                        rX|j/                         j1                         }d
|	 }|	dz  }	t3        |||       |j5                  |      }|j                  |       t        |t6        t8        t         j:                  f      r|j                  |       t=        dt?        |       d       t!        |      }|j@                  dk(  rVtC        | |j&                        }tE        jF                  |      }d
|	 }t3        |||       |	dz  }	|jI                  ||      }nr|j@                  dk(  r|jK                  |j&                  |      }nE|j@                  dk(  r|jM                  |j&                  |      }nt=        |j@                   d      ||u rnst+        |jN                  jQ                               dk(  s
J | d       tS        tU        |jN                  jQ                                     }|dz  }||
kD  rt=        d      |jW                  |       |jY                          |S )aa  
    Input: a model, and a linear subgraph within the model from first_node to
      last_node.

    Output: a new submodule containing a copy of the subgraph, with the inputs
      to the first node becoming the inputs to the submodule, and all other
      nodes in the subgraph being copied.

    Example inputs:

    `model`: a module with graph

      x0 -> op1 -> x1 -> op2 -> x2
             |
            arg1

    `first_node`: op1
    `last_node`: op2

    Example output: a new module with graph

      input1 -> op1_copy -> x1 -> op2_copy -> output1
                   |
                  arg1
    c                       e Zd Zd Zy))create_submodule_from_subgraph.<locals>.Mc                      y r%   r_   )r+   xs     r   forwardz1create_submodule_from_subgraph.<locals>.M.forward  s    r   N)r[   r\   r]   r   r_   r   r   Mr     s    	r   r   r   d   grW   c                 "   d}|j                   dz   t        |      z   |v r#|dz  }|j                   dz   t        |      z   |v r#|j                   dz   t        |      z   }|j                  |       | j                  |      }|||j                   <   |S )Nr   r   rc   )r0   rM   rs   rG   )r   rW   
seen_namesold_name_to_new_nodecountercur_namerG   s          r   _add_placeholderz8create_submodule_from_subgraph.<locals>._add_placeholder;  s     ii#oG4
BqLG ii#oG4
B99s?S\9x(mmH52=$TYY/""r   rc   Nmod_zarg of type z not handled yetrK   rI   rJ   z not supported yetz) has more than 1 users, not supported yetziteration limit exceeded)-r4   nnModuler5   symbolic_tracer'   reversedrN   
erase_noderp   r   r   rQ   rS   appendrv   rt   rR   rq   r9   BINARY_FUNCTIONSru   	ParameterdetachclonesetattrrG   floatintdtypeAssertionErrortyperO   r   copydeepcopyrK   rI   rJ   rf   keysrP   rL   output	recompile)r   rj   rl   r   mgmr   rW   cur_node_origcur_name_idxiteration_limitcur_iterationcur_args_copycur_kwargs_copyr   r   r   argpnew_arg	inner_arg
kwarg_namekwarg	new_kwarginner_kwargcur_node_copymod_namenew_arg_placeholderorig_modorig_mod_copys                                 r   create_submodule_from_subgraphr      s   FEHHOO  	
A		 	 	#B
A( 	T MLOM
J& M O#&5J46 ## $# %)) .c4((C=QRA!((+dE]3 G%( 6	%i6#NN 0$%y*>R!" $NN956 "((1!((-#.( &3%9%9%?%?%A 8!
EeT*2B5*.B3OJ/  e}5 "I', ,,{J8L "((+	,
 3<OJ/27OJ/8  "-0M !''/???? +OM=%%&*(--ab1 YC!#uxx'9'9:"%**,"4"4"6%),#8$)Hg6.0nnX.F+%,,-@A#C%ekk)BC%,,S1,|DI;FV-WXXY "-0M },'}/C/CDH MM(3Ml^,HB-0ALMM(M?SM0OO$$M .MM$$M !M$4$4#55G!HIII% ##((*+q0	G_EF	G0T-"5"5":":"<=>?* !;<<G L HH]LLNIr   mtlist_of_node_name_to_qconfigexample_inputslast_added_shadow_node_listcustom_prepare_fncustom_prepare_kwargsc           
         ddl m}m} |dk(  rd}t        | |||||||      }t	        ||      }t        | |      rJ t        | ||       | j                  j                  |      5  | j                  j                  ||fi       }||d<   ddd       n||dz
     }||j                     }|yt               j                  |      }t        | ||      }|	7t        j                  j                   j"                  j%                  |||      }n9|
i }
dD ]  }||
vrJ d	| d
        ||d}|j'                  |
        |	|fi |}t)        ||      }t        | |      rJ t        | ||       |d   }| j                  j                  |      5  g }|j*                  D ]s  }t-        |t.              r|j1                  |       %t-        |t2        t4        f      s<t7        |      sHt-        |d   t.              s\|j9                  d |D               u i }|j:                  j=                         D ]O  \  }}t-        |t.              r|||<   t-        |t2        t4        f      s3t7        |      s?|j9                  |       Q t5        |      }| j                  j                  |||      }ddd       t        | ||||t?        |      ||      }t	        ||      }t        | |      rJ t        | ||       | j                  j                        5  | j                  j                  |||fi       }||d<   ddd       | jA                          y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   2xY w)aj  
    Given a subgraph in `mt` and a subgraph candidate idx, inserts the
    subgraph candidate copy and instruments it with loggers.

    If subgraph_candidate_idx is 0, this is the baseline fp32 subgraph and we just
    add a logger to the end.

    If subgraph_candidate_idx is not 0, we create a copy of the subgraph and
    prepare it with `prepare_fx`.
    r   OutputComparisonLoggerOutputLoggerr   rQ   rR   Nrc   )r   )r   prepare_custom_configqconfig_mappingzcannot specify z in custom_prepare_kwargs)r   r   c              3   B   K   | ]  }t        |t              s|  y wr%   rS   r   ).0r   s     r   	<genexpr>zEcreate_one_transformed_and_logged_copy_of_subgraph.<locals>.<genexpr>6  s      $&/*YPT:U	$s   )!torch.ao.ns._numeric_suite_fxr   r   r   r   r>   r   r'   inserting_afterrK   r0   r   
set_globalr   r4   aoquantizationquantize_fx
prepare_fxupdater!   rQ   rS   r   r   rv   rt   ru   extendrR   rq   rM   r   )r   r   r   rj   rl   r   r   r   r   r   r   r   r   r   r   	attr_namenew_nodenode_name_to_qconfigqconfigr   orig_mod_copy_wrappedr   prepare_kwargsinsert_after_nodenew_argsr   
new_kwargsr0   	old_kwargloggers                                 r   2create_one_transformed_and_logged_copy_of_subgraphr     s   2 S" 2"	
 #<1GH	2y)))I/XX%%i0 	6xx++IYLQS+TH-5'*	6 	6  <<RUV<VW&z7
 ?(*55g> !?
I!

 $$)HH$9$9$E$E$P$P%~ %Q %! %,(*% K
 &;;K$ZL0IJK;K #1#2.N !!"78$5%%)7%!
 +<9OP	2y)))I45 8:XX%%&78 	Y H! 
c4(OOC(sT5M2C"3q640OO $36$ 
 J#-#4#4#:#:#< /ii.'0Jt$	D%=9c)nOOI./ XHxx++IHZ+XH;	Y@ 3"L"	
 #<1GH	2y)))I/XX%%h/ 	4XX))9 5b * F .4'*		4 LLNa	6 	6x	Y 	Y\	4 	4sD   $%MA
MM#M7A(M M,<M&M$MM!$M-
match_namenodes_in_this_subgraphqconfig_mappingsc                    t        d |D              ry|d   }|d   }	t        || d      }
t        |
t              r|
D cg c]  }|j                   }}nTt        |
t
              r
d |
D        }n:t        |
d      r|
j                  f}n t        d|j                          dz          yd	}t        t        |      d
z         D ]%  }|dk(  r	||d
z
     }||j                     }|#d} n |s t        d|j                          dz          yt        ||       }dg}t        t        |      d
z         D ]  }t        | ||||	||||||        yc c}w )z
    Given a model `mt` and a subgraph_idx, creates the needed copies
    of the subgraph for all qconfigs, and instruments them with loggers.
    c              3   >   K   | ]  }t        |t                 y wr%   r   )r   rW   s     r   r   zEcreate_n_transformed_and_logged_copies_of_subgraph.<locals>.<genexpr>r  s     
I$z$%%
Is   Nr   c              3   4   K   | ]  }|j                     y wr%   )rU   )r   r   s     r   r   zEcreate_n_transformed_and_logged_copies_of_subgraph.<locals>.<genexpr>~  s     =a!//=s   rU   z%unable to get example input for node z
, skippingFrc   Tz-unable to find at least one qconfig for node )anyr	   rS   rv   rU   rt   r>   printformat_noderangeru   r0   r   r   )r   r   r   r   r   r   r   r   rj   rl   	prev_noder   r   found_at_least_one_qconfigr   r   r   r   r   s                      r   2create_n_transformed_and_logged_copies_of_subgraphr   ^  s   ( 
I2H
II'*J&r*I )R;I)T"3<=a!//==	Iu	%=9= 9o.'557N7++-.j9:  "'"',<(=(A"B !Q&  <<RUV<VW&z7)-& &;'')**56	
 	
R
(C :>"',<(=(A"B 
:"('!	

q >s   Ery   r   r   c                 p  $% ddl m}m} d $t               }i }i %t	        | j
                  j                        }d}	|D ]  }
|
j                  dv s|
|v r $|
      }d}|/|d   |d   }}|j                  |       ||j                     }|d}n|
|
}}|rv|j                  }t        | |	|||g|gdd       d	|	 d
}d}| j
                  j                  D ]%  }|j                  dk(  s|j                  |k(  s#|} n |J |||<   |%|<   nE||n|g}d}d}t        ||       }t        | |||	||||      }t        |	|      }t        | |      rJ t!        | ||       |}| j
                  j#                  |      5  | j
                  j%                  ||fi       }|}ddd       |}d}d}||v r||u r|j&                  }|j(                  } n!|}!|!g|j&                  dd }|j(                  } | j
                  j#                  |      5  | j
                  j+                  |j                  |j                  ||       }||}ddd       ||k7  r(t-        |j.                  j1                               dk(  sJ t3        t5        |j.                  j1                                     }|j                  j7                  t8              rJ |}||v rd}t        | |||	||||      }t        |	|      }t        | |      rJ t!        | ||       | j
                  j#                  |      5  | j
                  j%                  |||fi       }ddd       |||<   |%|<   |	dz  }	 | j;                          t               }|D ]  }
|
j                  dv s|
|v r $|
      }||d   |d   }}|j                  |       n|
|
}}$%fd}"||   }#|#J t=        |"|#j&                        |#_        t=        |"|#j(                        |#_        | j;                           y# 1 sw Y   vxY w# 1 sw Y   xY w# 1 sw Y   xY w)a~  
    Given a model, a model graph partition (currently a set of matched
    subgraphs) and instructions how to transform each subgraph
    (currently quantizing it according to qconfig_mapping), modifies
    the model graph to create an alternate path through the original graph,
    with each of the subgraphs quantized.  This is useful to compare
    propagation error of a transformation such as quantization.

    For example, given layer op0 and op1, there are four cases when handling op1:
    1. op0 and op1 quantized
    2. op0 and op1 unquantized
    3. op0 quantized, op1 unquantized
    4. op0 unquantized, op1 quantized

    Example input, case 1:

    .. code::

      x0_0 -> op0_0 -> x1_0 -> log -----> op1_0 -> x2_0 -> log
       \                        \          \                 \       # noqa: W605
         ---> op0_1 -> x1_1 ----> clog    op1_1 -> x2_1 ----> clog

    Example output, case 1:

    .. code::

      x0_0 -> op0_0 -> x1_0 -> log -----> op1_0 -> x2_0 -> log
       \                        \                           \        # noqa: W605
         ---> op0_1 -> x1_1 ----> clog -> op1_1 -> x2_1 ----> clog

    r   r   c                 >    |j                         D ]
  }| |v s|c S  y r%   )values)rW   ry   subgraphs      r   _get_subgraph_containing_nodez?create_add_loggers_graph.<locals>._get_subgraph_containing_node  s,    '..0 	 Hx	  r   )rG   rH   r   FNr   Tshadow_wrapper__1rK   r   r   rc   c                 |    t        | t              s| S | j                  dv r| S  |       }|| g}|d   }|   }|S )zt
            If unshadowed `node` has a shadow version, return that. If not,
            return `node`.
            )rG   rH   r   )rS   r   rO   )rW   prev_subgraphprev_first_nodeprev_shadow_outputr   "orig_first_node_to_shadow_out_nodery   s       r   maybe_remap_node_to_shadowz<create_add_loggers_graph.<locals>.maybe_remap_node_to_shadow  s\    
 dD)ww55 :$PM$!%+A.O!CO!T%%r   )r   r   r   rp   rv   r'   rN   rO   r   r0   r   r9   r   r   r   r>   r   r   rK   rQ   rR   create_noderu   rf   r   rP   rL   
startswithr   r   r   )&r   ry   r   r   r   r   nodes_to_skip!orig_first_node_to_shadow_in_node
orig_nodescur_subgraph_idxr1   maybe_subgraphinsert_submodule_copyrj   rl   r   r   expected_shadow_targetnew_shadow_modmaybe_shadow_modsubgraph_to_user   r   r   r   r   insertion_pointr   r   r   first_node_copyr   r   first_arg_for_copyr  cur_shadow_inputr   r  s&    `                                  @@r   create_add_loggers_graphr    s   L S0 EM )+%)+&ekk''(J A4488A<N6q/J %%$21$5~b7I	J  0*:??;G"(,%$%q	J #J>  !%&	 (77G6H%K"!N$)KK$5$5  $''=8(//3II%5N "---<J-j9=K.z: #1"<:, 
 K%&" U3C6 &	O ''79OPIui000E9o6'O,,_= )00YL 1  #)	) 'M M"O?2 J.,11H!.!5!5J)6& 2L]5G5G5KLH!.!5!5J[[00A 	8$)KK$;$;%((%,, "	%M '.*7	8 !I-}22779:a??? $T-*=*=*B*B*D%E F(--889PQQQ"/5  ?2: &'"6 &&	O ''79OPIui000E9o6,,_= 00]I$>r 1  =L-j9=J.z:ACAF 
OO, EM .4488A<N6q/J%$21$5~b7I	J  0$%q	J	&4 =ZH+++ (&(8(=(=!
 #+&(8(?(?#
 	].o) )(	8 	8B s$   <"P
7P!!P,P	P)	,P5	c                    d}| j                   j                  D ]7  }|j                  dk7  r|dz  }|dk7  rt        |j                        dk(  sJ t        t        |j                  j                                     }d }|j                  t        j                  k(  rE|j                  \  }}}}}	t        | |j                        }
t        | |j                        }|
|||	f}na|j                  t        j                  k(  sJ |j                  \  }}}}	t        | |j                        }
t        | |j                        }|
||	f}|j                  |fc S  y )Nr   rG   rc   rd   )r'   rN   rO   ru   rf   rP   rL   r   r9   r4   quantize_per_channelrQ   r   quantize_per_tensor)r   placeholders_seenshadow_n
quant_noder   _weight
scale_nodezp_nodeaxisr   	scale_valzp_vals               r   $_get_weight_info_from_shadow_wrapperr%    sN    "((.. !-;;-'Q! 8>>"a'''$x~~22456
 : ::8B5GZ$(9J9JKI%ngnnEF!647H$$(A(AAAA2<///GZ%(9J9JKI%ngnnEF!651H!!8,,C!-F r   r   c                     t         j                  j                  j                  h}dt        j
                  j                  i ii}| j                  j                  D ]0  }|j                  dk(  r|j                  |v s"|j                  d   }d }|j                  D ]1  }|j                  dk(  s|j                  j                  d      s/|} n |vt        | |j                        }t        |      }||j                  d   }	t        | |	j                        j!                         }
|\  }}|
g|} || }|j"                  }|j"                  }t%        ||       }|}d }t'        | d      r| j(                  |j"                     d   }t         j*                  j,                  j.                  j0                  j3                  |
|      }t        j
                  j                  |
g||||dd|d|gd	d
}t        j
                  j                  |g||||dd|d|gd	d
}|j                  j5                  d      \  }}}}d| d}d| d}|g|d   t        j
                  j                     |<   |g|d   t        j
                  j                     |<   3 |S )Nr   rI   r   rK   r   rc   _node_name_to_scoper   sqnr)res_typer   prev_node_nameprev_node_target_typeref_node_nameref_node_target_typeindex_within_argindex_of_argr   r   comparisonscomparison_fn_namer   r   _0r  )r4   r   
functionallinearr   WEIGHTr   r'   rN   rO   r9   rQ   rf   r	  r   r%  r   r0   r
   r>   r'  r   nsr5   utilscompute_sqnrr<   )r   weighted_opsresultsr1   	first_argshadow_wrapper_nodeuserr   weight_infow_nodew_objquant_fnquant_fn_args_except_firstr   w_obj_qr,  r*  ref_node_typeprev_node_typer   
comparisonresult_fp32result_qr  _2node_idx_3	name_fp32name_qs                                r   extract_weight_comparisonrN    s   , 	""L &(@(G(G(M(Mr'RSGWW]] PU'AHH,D
 FF1I	"OO 	Dww-'DKK,B,BCS,T&*#		 &)"))
 ;>J  FMM299; 0;,,767H% +Aq1&1+,''/2CXX[[^^))66ugF
077==g,%3*$1 !&<"(
 177==i,%3*$1 !&<"(
   399??DB"z,	XJb) N
188>>?	J LT*188>>?GaPUd Nr   r:  c           	         t        j                  t              }t        t	        | d   j                                     }| d   |   j                         D ]]  \  }}|j                  d      \  }}}| d| }|d   d   |d   d   |d   d   |d   d   |d   d   |d   d	   |d   d
   d}	|	||   |<   _ t        |      S )a  
    Creates a comparison of results

    Input:

    {
      'model': {
        'node_output': {
          'subgraph_0_0': [
            'values': [torch.tensor(...), ...], ...
            'ref_node_name': ...,
            'ref_node_target_type': ...,
            'qconfig_str': ...,
            'comparisons': [], ...
            'comparison_fn_name': '',
            'fqn': '...',
          ],
          'subgraph_0_1': [
            'values': [torch.tensor(...), ...], ...
            'ref_node_name': ...,
            'ref_node_target_type': ...,
            'qconfig_str': ...,
            'comparisons': [torch.tensor(...), ...], ...
            'comparison_fn_name': '...',
            'fqn': '...',
          ],
          ...
        },
      },
    }

    Output:
    {
      'subgraph_0': {
        '0': {
          'ref_node_name': '...',
          'ref_node_target_type': ...,
          'values': [torch.tensor(...), ...],
          'qconfig_str': None,
          'comparisons': [torch.tensor(...), ...], ...
          'comparison_fn_name': '...',
          'fqn': '...',
        },
        '1': {
          'ref_node_name': '...',
          'ref_node_target_type': ...,
          'values': [torch.tensor(...), ...],
          'qconfig_str': '...',
          'comparisons': [torch.tensor(...), ...], ...
          'comparison_fn_name': '...',
          'fqn': '...',
        },
      },
    }

    r   r   r   r,  r-  r   r   r   r0  r1  )r,  r-  r   r   r   r0  r1  )collectionsdefaultdictr(   rP   rL   r   rq   r<   )
r:  !subgraph_name_to_subgraph_results
key_to_usesubgraph_name_with_idxsubgraph_candidate_resultssubgraph_strr   r   subgraph_namesubgraph_resultss
             r   group_results_by_subgraphrY  x  s   r .9-D-DT-J% d77+00234J>Eg>N?eg: : #((-		
"'.,8 8:?K$>q$A&% .a0703H=5a8G5a8G"<Q"?@T"U

  	*-8"	
/6 122r   c                 ,   i }| j                         D ]~  \  }}i }|j                         D ]H  \  }}|dk(  r|d   }t        j                  |      }|d   |d   |t        j                  |      d||<   J |d   d   |d   d   |d   d   |d	||<    |S )
a  
    Input:

    {
      'subgraph_0': {
        '0': {
          'ref_node_name': '...',
          'ref_node_target_type': ...,
          'values': [torch.tensor(...), ...],
          'qconfig_str': '',
          'comparisons': [],
          'comparison_fn_name': '',
          'fqn': '...',
        },
        '1': {
          'ref_node_name': '...',
          'ref_node_target_type': ...,
          'values': [torch.tensor(...), ...],
          'qconfig_str': '...',
          'comparisons': [torch.tensor(...), ...],
          'comparison_fn_name': 'sqnr',
          'fqn': '...',
        },
      },
    }

    Output:
    {
      'subgraph_0': {
        'ref_node_name': '...',
        'ref_node_target_type': '...',
        'fqn': '...',
        'candidates': {
          '1': {
            'qconfig_str': ...,
            'comparison_fn_name': 'sqnr',
            'cmp_raw': [..., ...],
            'cmp_mean': ...,
          },
          ...,
        },
      },
    }
    0r0  r   r1  )r   r1  cmp_rawcmp_meanr,  r-  r   )r,  r-  r   
candidates)rq   r4   stackmean)	results_groupedresults_comparisonrW  rX  r^  subgraph_inner_namesubgraph_inner_resultr\  cmp_raw_tensors	            r   create_results_comparisonrf    s    ` +:+@+@+B 
''
:J:P:P:R 	6!6"c) ,M:G"[[1N  5]C&;<P&Q)!JJ~6	/J*+	$ .c2?C$4S$9:P$Q#C(/$	-
=)'
4 r   c                    	 ddl m } g }| j                         D ]K  }|d   j	                         D cg c]
  \  }}|d    }}}|d   |d   |d	   g|}|j                  |       M d
}|D ]  }t        |t        |d               } t        |      D 	cg c]  }	t        |	       }
}	ddd	g|
}t         |||             y# t        $ r t        d       Y yw xY wc c}}w c c}	w )a  
    Input:

    {
      'subgraph_0': {
        'ref_node_name': 'linear1',
        'ref_node_target_type': '...',
        'fqn': '...',
        'candidates': {
          '1': {
            'qconfig_str': ...,
            'comparison_fn_name': ...,
            'cmp_raw': [45.0, 55.0],
            'cmp_mean': 50.0,
          },
          ...,
        },
      },
    }

    Prints:

    node_name | node_type | fqn | 0    | 1    | ...
    linear1   | ...       | ... | 45.0 | 50.0 | ...
    r   )tabulatez`print_tabular` relies on the library `tabulate`, which could not be found on this machine. Run `pip install tabulate` to install the library.Nr^  r]  r,  r-  r   r   rc   	node_name	node_type)headers)
rh  ImportErrorr   r   rq   r   maxru   r   rM   )rb  rh  r:  subgraph_datacandidate_name	candidatemean_all_candidatesdata_rowmax_candidate_idx_lenr   candidate_idx_headersrk  s               r   print_n_shadows_summaryru  %  s6   :% G+224 ! .;<-H-N-N-P
)	 j!
 
 /*01% 
 !	
 	x !  M #$93x{;K LM-23H-IJSVJJKG1FGG	(7G
,-;  8	

 	
  Ks   C CC%CC)NN)ra   N)8rP  r   operatortypingr   r   r   r4   torch.fxtorch.ao.ns.fx.graph_passesr   torch.ao.ns.fx.ns_typesr   r   torch.ao.ns.fx.utilsr	   r
   torch.ao.quantizationr   $torch.ao.quantization.fx.match_utilsr   torch.ao.quantization.qconfigr   torch.ao.quantization.utilsr   r   r   r   torch.utils._pytreer   r   r    rs   rT   mulr   r   r!   r#   r(   rM   rv   r   r   r   r   r   r   r   r   r  r%  rN  rY  rf  ru  r_   r   r   <module>r     sq      * *   6 K 1 = 4 8 - - ( # "2  
II	LLLL	II	LLLL PX7 7tj$sL'8"9 jd3T
?>S jZ""" " 	"
  " " " 
#" XX__"JA88??AA A 	A\ -16:^^^  ^ 	^
 ^ 
#^ #'tCO'<"=^ ^ "&htn!5^  )^ $DcN3^ 
^P -16:c
c
c
 c
 !I	c

 >*c
 #'tCO'<"=c
  )c
 $DcN3c
 
c
LPP#tDz/*P $P sJ/	P
 
Pf- -`m m mbY3} Y3 Y3zLL`<.	<.r   