
    Ph|                        d dl Z d dlZ d dlmZmZ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 d d
lmZ d dlZd dlZd dlmZmZmZmZmZmZm Z  d dl!Z!dZ"dZ#e jH                  e jJ                  jH                  e!jH                  e jL                  e jJ                  jL                  e!jL                  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 j\                  j^                  fdZ0de j\                  j^                  dededefdZ1	 	 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%Z2	 	 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)Z3ded*ee+ee   f   d+ed,ee+ef   ddf
d-Z4de j\                  j^                  fd.Z5d/ede
fd0Z6d1e
defd2Z7defd3Z8	 	 d6d4Z9y)7    N)NodeGraphModuleGraph)get_target_type_strget_normalized_nth_input)NSSingleResultValuesTypeNSResultsType)_maybe_get_fqn)QConfigMapping)
QConfigAny)getattr_from_fqn)_MatchResult)tree_map)ListDictSetTupleCallableAnyOptionalshadowshadow_wrapperc                     t          d|  d| S N_)SHADOW_NODE_NAME_PREFIXsubgraph_idxsubgraph_candidate_idxs     iC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\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__<   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>F   s    s166{r"   )torchfxr+   map_arg)ar6   s    r    load_argz&OutputProp.propagate.<locals>.load_argE   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)r=   target_atomsattr_itriatomr/   s        r    
fetch_attrz(OutputProp.propagate.<locals>.fetch_attrH   sq    !<<,LxxH$\24x.&)LSXXVbcedeVfMgLh'ijj"8T2 3 Or"   placeholderget_attrcall_functioncall_methodcall_module)iterstrr+   nodesopnextr=   argskwargsrE   r.   
isinstancer8   Tensortraced_resultr4   )
r/   rU   	args_iterr<   rJ   noderesultself_objrV   r6   s
   `        @r    	propagatezOutputProp.propagateA   sJ   J	 "	D	 	 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2HTYY4Ga8TXT_T_K`a&%,,/%+"#C		N# %& r"   N)__name__
__module____qualname____doc__r0   r^    r"   r    r'   r'   2   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   re   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   )rU   rT   rP   users)
node_anode_bnode_crR   
first_nodemid_node	last_noder5   prev_nnext_ns
             r    _order_nodesz*_get_dedup_subgraphs.<locals>._order_nodes   s    0!
 	AVVAYF!$qww-0FU*%&
u,$%	#$  "-(2F)* *}}Q':555 ~~a(H444!8Z88r"   )
setitemsinsertrW   r   addtuplelenr   reverse)rd   
seen_nodessubgraphs_dedupmatches_items_reversedr4   	cur_matchwas_seennode_or_tupler[   list_of_nodesrs   rk   rl   rm   s                 r    _get_dedup_subgraphsr   f   s   
 JO
 >@"==?i%%a$	):; + 2i&q\M" -. J.#H}- "-777)D%dD111z)#'NN4(	 *1 *<  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 	 -k 2n r"   modelrn   rp   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)r4   r   r   NODE_OUTPUTvalueenabled)	r   rn   rp   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                  |        |}|j                  }	|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nt+        |jN                  jQ                               dk(  s
J | d       tS        tU        |jN                  jQ                                     }|j                  }	|j                  }
|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)   rc   )r/   xs     r    forwardz1create_submodule_from_subgraph.<locals>.M.forward  s    r"   N)r_   r`   ra   r   rc   r"   r    Mr     s    	r"   r   r   d   gr[   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   rg   )r4   rQ   rw   rK   )r   r[   
seen_namesold_name_to_new_nodecountercur_namerK   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"   rg   Nmod_zarg of type z not handled yetrO   rM   rN   z not supported yetz) has more than 1 users, not supported yetziteration limit exceeded)-r8   nnModuler9   symbolic_tracer+   reversedrR   
erase_noderU   rV   rt   r   r   rW   appendlistrx   ru   r=   BINARY_FUNCTIONSry   	ParameterclonedetachsetattrrK   floatintdtypeAssertionErrortyperS   r   copydeepcopyrO   rM   rN   rj   keysrT   rP   output	recompile) r   rn   rp   r   mgmr   r[   cur_node_origcur_args_origcur_kwargs_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!&&M#**OLOM
J& M O#&5J46 ## $# %))c4((3
,@BA!((+dE]3 G%(	%i6#NN+; !9j:N,P Q $NN95 &) "((1!((- *$ &3%9%9%?%?%A!
EeT*2B5*.B3DOJ/e}5 "I',,{J8LN!((+ (- 3<OJ/27OJ/ &B "-0M !''/???? +OM=%%&*(--ab1C!#uxx'9'9:"%))+"4"4"6%),#8$)Hg6.0nnX.F+%,,-@A#C%ekk)BC%,,S1,|DI;FV-WXX 2 "-0M },'}/C/CDH MM(3Ml^,HB-0ALMM(M?SM0OO$$m_FM .MM$$m_FM !M$4$4#55G!HIII% =&&++-.!3 	HoFG	H3T-"5"5":":"<=>%**'..?* !;<<w | 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 ]  }t-        |t.              r|j1                  |       %t-        |t2        t4        f      s<t7        |      sHt-        |d   t.              s\|D ]$  }t-        |t.              s|j1                  |       &  i }|j8                  j;                         D ]V  \  }}t-        |t.              r|||<   t-        |t2        t4        f      s3t7        |      s?|D ]  }|j1                  |        X t5        |      }| j                  j                  |||      }ddd       t        | ||||t=        |      ||      }t	        ||      }t        | |      rJ t        | ||       | j                  j                        5  | j                  j                  |||fi       }||d<   ddd       | j?                          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   OutputLoggerOutputComparisonLoggerr   rU   rV   Nrg   )r   )r   prepare_custom_configqconfig_mappingzcannot specify z in custom_prepare_kwargs)r   r   ) torch.ao.ns._numeric_suite_fxr   r   r   r!   rB   r   r+   inserting_afterrO   r4   r   
set_globalr   r8   aoquantizationquantize_fx
prepare_fxupdater%   rU   rW   r   r   r   rx   ry   rV   ru   rQ   r   ) r   r   r   rn   rp   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   r   
new_kwargsr4   	old_kwarginner_old_kwargloggers                                    r    2create_one_transformed_and_logged_copy_of_subgraphr     s   2 S" 2
I|5Ks, #<1GH	2y)))I/XX%%i0xx++IYLQS+TH-5'* 10 ))?!)CD 	&z7
 ?(*55g> !?
I!' $$)HH$9$9$E$E$P$P%~ %Q %W! %,(*%\
!)>>w/R\Q]]v@ww> ] #1#2.N !!"78$5%%" %"!
 +<9OP	2y)))I45 8:XX%%&78 H!c4(OOC(dE]3CZPSTUPVX\E]%(	%i6$OOI6 &)	 ' J#-#4#4#:#:#<ii.'0Jt$	D%=9c)n+4 8 ,5	 $= XHxx++ , =H5 9< 3
I|5KL0#7 #<1GH	2y)))I/XX%%h/XX)))8Y:OXZ)[F-3'* 0 LLN} 10j 98J 0/sK   $%M$A
M0M0#M07M0A#M01M0=AM0%&M<$M-0M9<N
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)   )rW   r   ).0r[   s     r    	<genexpr>zEcreate_n_transformed_and_logged_copies_of_subgraph.<locals>.<genexpr>N  s"      *D tT""*s   Nr   c              3   4   K   | ]  }|j                     y wr)   )rY   )r   r   s     r    r   zEcreate_n_transformed_and_logged_copies_of_subgraph.<locals>.<genexpr>]  s     =9a!//9s   rY   z%unable to get example input for node z
, skippingFrg   Tz-unable to find at least one qconfig for node )anyr   rW   r   rY   rx   rB   printformat_noderangery   r4   r
   r   )r   r   r   r   r   r   r   r   rn   rp   	prev_noder   r   found_at_least_one_qconfigr   r   r   r   r   s                      r    2create_n_transformed_and_logged_copies_of_subgraphr   :  s   (  *  	'*J&r*I )R;I)T"3<=9a!//9=	Iu	%=9= 9o.'557N7))+,J789  "'"',<(=(A"B!Q& ))?!)CD 	&z7)-&! #C" &='')**56 	7
R
(C :>"',<(=(A"B:4js879J!		# #Co >s   Er|   r   r   c                   %& ddl m}m} d %t               }i }i &t	        | j
                  j                        }d}	|D ]'  }
|
j                  dv s|
|v r %|
      }d}|6|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 |||<   |&|<   nM||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)|}"t+        |"g|j&                  dd       } |j(                  }!| j
                  j#                  |      5  | j
                  j-                  |j                  |j                  | |!      }||}ddd       ||k7  r(t/        |j0                  j3                               dk(  sJ t5        t7        |j0                  j3                                     }|j                  j9                  t:              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   }}|D ]  }|j                  |        n|
|
}}%&fd}#||   }$|$J t?        |#|$j&                        |$_        t?        |#|$j(                        |$_        | j=                           y# 1 sw Y   x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)r[   r|   subgraphs      r    _get_subgraph_containing_nodez?create_add_loggers_graph.<locals>._get_subgraph_containing_node  s'    '..0Hx 1 r"   )rK   rL   r   FNr   Tshadow_wrapper__1rO   r   r   rg   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`.
            )rK   rL   r   )rW   r   rS   )r[   prev_subgraphprev_first_nodeprev_shadow_outputr  "orig_first_node_to_shadow_out_noder|   s       r    maybe_remap_node_to_shadowz<create_add_loggers_graph.<locals>.maybe_remap_node_to_shadowr  sa    
 dD)ww55 :o'M$!%+A.O2?C %%r"   ) r   r   r   rt   r   r+   rR   rS   rw   r4   r   r=   r
   r   r!   rB   r   r   rO   rU   rV   rx   create_nodery   rj   r   rT   rP   
startswithr   r   r   )'r   r|   r   r   r   r   nodes_to_skip!orig_first_node_to_shadow_in_node
orig_nodescur_subgraph_idxr5   maybe_subgraphinsert_submodule_copyrn   rp   node_to_skipr   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4488A<N6q/J %%$21$5~b7I	J .!!,/ !/*:??;G"(,%$%q	J #J>'^ !$8#9d (77G6H%K"!N$)KK$5$5 #&&-7(//3II%5N	 %6
 "---<J-j9=K.z:
 1?0Jn \  K%&" U3C6z9.>@V\30O ''79OPIui000E9o6'O,,_=00YL 1 ="( > 'M M"O?2 J.,11H!.!5!5J)6&$&8%R=;M;Mab;Q%RSH!.!5!5J[[00A$)KK$;$;%((%,, "	%M '.*7 B !I-}22779:a??? $T-*=*=*B*B*D%E F(--889PQQQ"/5  ?2: &'"6z9.>@V3S:O ''79OPIui000E9o6,,_=00]I$>r 1 K >
 =L-j9=J.z:AU X 
OO. EM4488A<N6q/J%$21$5~b7I	J .!!,/ !/ %&q	J	&: .j9 	+++ (&(8(=(=!?"*&(8(?(?#A 	a _ >=& BA4 >=s$   "P(7P50!Q(P2	5P?	Q	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   rK   rg   rh   )r+   rR   rS   ry   rj   rT   rP   r   r=   r8   quantize_per_channelrU   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*    sU    "((..;;-'Q! 8>>"a'''$x~~22456
 : ::8B5GZ$(
 1 13I%0F!647H$$(A(AAAA2<///GZ%(
 1 13I%0F!651H!!8,,K /N 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   rM   r   rO   r   rg   _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  )r8   r   
functionallinearr   WEIGHTr   r+   rR   rS   r=   rU   rj   r  r   r*  r   r4   r   rB   r,  r   nsr9   utilscompute_sqnrr@   )r   weighted_opsresultsr5   	first_argshadow_wrapper_nodeuserr   weight_infow_nodew_objquant_fnquant_fn_args_except_firstr   w_obj_qr1  r/  ref_node_typeprev_node_typer   
comparisonresult_fp32result_qr  _2node_idx_3	name_fp32name_qs                                r    extract_weight_comparisonrS    s   . 	""L
 	*1177<G WW]]'AHH,D
 FF1I	"OODww-'KK**+;<&*# $ &)"))+:  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) M 	188>>?	J J 	188>>?Ga f 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   r1  r2  r   r  r   r5  r6  )r1  r2  r   r  r   r5  r6  )collectionsdefaultdictr,   rT   rP   r   ru   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_subgraphr^  @  s   r .9-D-DT-J% d77+00234J GZ(..0 	; :
 #((- 	;l$:'.,8 8:?K$>q$ABX$Y-a0703H=5a8G5a8G"<Q"?@T"U
  	*-89OP# 1( 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': ...,
          },
          ...,
        },
      },
    }
    0r5  r   r6  )r   r6  cmp_rawcmp_meanr1  r2  r   )r1  r2  r   
candidates)ru   r8   stackmean)	results_groupedresults_comparisonr\  r]  rc  subgraph_inner_namesubgraph_inner_resultra  cmp_raw_tensors	            r    create_results_comparisonrk    s    ` +:+@+@+B''
:J:P:P:R6!6"c) ,M:G"[[1N  5]C&;<P&Q)!JJ~6	/J*+ ;S$ .c2?C$4S$9:P$Q#C(/$	-
=)) ,C6 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.Nrc  rb  r1  r2  r   r   rg   	node_name	node_type)headers)
rm  ImportErrorr   r  ru   r   maxry   r   rQ   )rg  rm  r?  subgraph_datacandidate_name	candidatemean_all_candidatesdata_rowmax_candidate_idx_lenr   candidate_idx_headersrp  s               r    print_n_shadows_summaryrz    s0   :% G+224 .;<-H-N-N-P
-P)	 j!-P 	 
 /*01% 
 !	
 	x  5  #$93x{;K L -23H-IJ-ISV-IJKG1FGG	(7G
,-7   : 	; 		
  Ks   C CC%CC)NN)re   N):r8   torch.fxr   r   r   torch.ao.ns.fx.utilsr   r   torch.ao.ns.fx.ns_typesr   r	   torch.ao.ns.fx.graph_passesr
   torch.ao.quantizationr   torch.ao.quantization.qconfigr   torch.ao.quantization.utilsr   $torch.ao.quantization.fx.match_utilsr   torch.utils._pytreer   rU  r   typingr   r   r   r   r   r   r   operatorr   r$   rw   rX   mulr   r!   r%   r'   rQ   r   r   r   r   r   r   r   r   r  r*  rS  r^  rk  rz  rc   r"   r    <module>r     sz     
 7 0 4 8 = (   B B B " "2  
II	LLLL	II	LLLL PX2 2hj#|#$j	#tDz/jX""" " 	"
  " " " 
#" XX__"H{88??{{ { 	{N -16:EEE  E 	E
 E 
#E #'tCO'<"=E E "&htn!5E  )E $DcN3E 
E\ -16:^#^#^# ^# !I	^#
 >*^# #'tCO'<"=^#  )^# $DcN3^# 
^#@||#tDz/*| $| sJ/	|
 
||1 1hq q qhS3} S3 S3lMM`:.	:.r"   