
    Vh              
          d dl Z d dlZd dlmZ d dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dlmZ d dlmZ g dZd!ded	ed
edefdZ ede      d!ded	ed
edefd       Zd Z G d dej                  j0                        Z G d dej                  j0                        Z G d de      Z G d de      Z G d dej                  j0                        Z G d de      Z G d de      Z G d d e      Z y)"    N)
deprecated)Tensor)DictListOptionalTupleUnion)_quantize_weight)PackedSequence)
pack_weight_biasPackedParameterRNNBaseLSTMGRURNNCellBaseRNNCellLSTMCellGRUCellapply_permutationtensorpermutationdimreturnc                 &    | j                  ||      S N)index_selectr   r   r   s      Y/home/dcms/DCMS/lib/python3.12/site-packages/torch/ao/nn/quantized/dynamic/modules/rnn.py_apply_permutationr      s    sK00    z]`apply_permutation` is deprecated, please use `tensor.index_select(dim, permutation)` instead)categoryc                     t        | ||      S r   r   r   s      r   r   r   !   s    
 fk377r    c                     |t         j                  k(  r,t         j                  j                  j	                  | |      }|S t         j                  j                  j                  | |      }|S r   )torchqint8ops	quantizedlinear_prepacklinear_prepack_fp16)qweightbiasdtypepacked_weights       r   r   r   )   sV    
 		++::7DI 		++??Nr    c                   2     e Zd Z fdZ fdZ fdZ xZS )r   c                 0    t         |           || _        y r   )super__init__param)selfr3   	__class__s     r   r2   zPackedParameter.__init__=   s    
r    c                 L    t         |   |||       | j                  ||dz   <   y )Nr3   )r1   _save_to_state_dictr3   r4   destinationprefix	keep_varsr5   s       r   r7   z#PackedParameter._save_to_state_dictA   s'    #KC(,

FW$%r    c           	      J    ||dz      | _         t        | 	  |||d|||       y )Nr3   F)r3   r1   _load_from_state_dict	r4   
state_dictr:   local_metadatastrictmissing_keysunexpected_keys
error_msgsr5   s	           r   r=   z%PackedParameter._load_from_state_dictE   s8       01
%	
r    )__name__
__module____qualname__r2   r7   r=   __classcell__r5   s   @r   r   r   <   s    3
 
r    r   c            	       B    e Zd Zej                  ZdZdddddej                  f fd	Z	d Z
d Zd	 Zd
edee   ddfdZd
edee   deeeef   fdZ	 ddedeeeef   deddfdZd
ededee   ddfdZdedee   defdZ fdZd Zedd       Zd Zd Zd Z xZS ) r         TFg        c
           	         t         |           || _        || _        || _        || _        || _        || _        t        |      | _	        || _
        |	| _        d| _        d| _        |rdnd}
t        |t        j                         r(d|cxk  rdk  rn t%        d      t        |t"              rt%        d      |dkD  r |dk(  rt'        j(                  d| d|        |dk(  rd	|z  }n|d
k(  rd|z  }nt%        d|z         g }t+        |      D ]  }t+        |
      D ]  }|dk(  r|n||
z  }t-        j.                  ||      j1                  t,        j                        }t-        j.                  ||      j1                  t,        j                        }t-        j.                  |      j1                  t,        j                        }t-        j.                  |      j1                  t,        j                        }|	t,        j2                  k(  rt-        j4                  |ddt,        j2                        }t-        j4                  |ddt,        j2                        }t,        j6                  j8                  j;                  ||      }t,        j6                  j8                  j;                  ||      }| j                  | j                  dk  r-t,        j6                  j8                  j=                  ||||      }nt,        j6                  j8                  j=                  ||||d      }n~t,        j6                  j8                  j?                  ||      }t,        j6                  j8                  j?                  ||      }t,        j6                  j8                  jA                  ||      }|jC                  tE        |               t,        jF                  jI                  |      | _%        y )NrK   FrL   r   zbdropout should be a number in range [0, 1] representing the probability of an element being zeroedzdropout option adds dropout after all but last recurrent layer, so non-zero dropout expects num_layers greater than 1, but got dropout=z and num_layers=r      r      zUnrecognized RNN mode: g?scale
zero_pointr-   T)&r1   r2   mode
input_sizehidden_size
num_layersr,   batch_firstfloatdropoutbidirectionalr-   versiontraining
isinstancenumbersNumberbool
ValueErrorwarningswarnranger%   randntor&   quantize_per_tensorr'   r(   r)   "make_quantized_cell_params_dynamicr*   make_quantized_cell_params_fp16appendr   nn
ModuleList_all_weight_values)r4   rS   rT   rU   rV   r,   rW   rY   rZ   r-   num_directions	gate_sizerm   layer_layer_input_sizew_ihw_hhb_ihb_hh	packed_ih	packed_hhcell_paramsr5   s                          r   r2   zRNNBase.__init__`   sW    		$&$	&W~*
+
 7GNN3$1$   '4( 
 Q;:?MM>>EY G(\+ 6>KIU]KI6=>>:& &	HE>* %H"'1*J+2N ! {{9.>?BB5;;O{{9k:==ekkJ{{9-00={{9-00=EKK' 44CAU[[D !44CAU[[D !&		 3 3 B B4 NI %		 3 3 B B4 NI||+t||a/?!II//RR )9dD $ "II//RR )9dD$ $ !&		 3 3 G Gd SI %		 3 3 G Gd SI"'))"5"5"U"U!9#K #))/+*FGK%H&	HN #((("5"56H"Ir    c                      y)NDynamicQuantizedRNN r4   s    r   	_get_namezRNNBase._get_name       $r    c                     d}| j                   dk7  r|dz  }| j                  dur|dz  }| j                  dur|dz  }| j                  dk7  r|d	z  }| j                  dur|d
z  } |j
                  di | j                  S )N{input_size}, {hidden_size}rL   z, num_layers={num_layers}T, bias={bias}Fz, batch_first={batch_first}r   z, dropout={dropout}z, bidirectional={bidirectional}r|   )rV   r,   rW   rY   rZ   format__dict__r4   ss     r   
extra_reprzRNNBase.extra_repr   s    )??a,,A99D  A5(..A<<1&&AU*22Aqxx($--((r    c                    g }| j                         }|r|j                  d      }g }| j                  j                         D ]u  \  }}t	        |t
        t        j                  f      r't        |      }t        j                  j                  j                  |d      }|j                  d|z   dz   |z          w ||z   }| j                         dz   }|r3t        |      dk(  r|s	||d   z  }n|ddj                  |      z   dz   z  }|dz  }|S )	N
rK   (z): rL   r   z
  ))r   split_modulesitemsr]   r   rk   rl   reprmodulesmodule
_addindentrj   r~   lenjoin)	r4   extra_linesr   child_lineskeyr   mod_strlinesmain_strs	            r   __repr__zRNNBase.__repr__   s   
 __&
$**40K==..0 	<KC&?BMM"BC6lGjj''227A>GsSy507:;	< k)>>#c);1$[KN*FV[[%77$>>Cr    inputbatch_sizesr   Nc                    |dnd}|j                         |k7  rt        d| d|j                                | j                  |j                  d      k7  r*t        d| j                   d|j                  d             y )NrK   rO   zinput must have z dimensions, got z5input.size(-1) must be equal to input_size. Expected z, got )r   RuntimeErrorrT   size)r4   r   r   expected_input_dims       r   check_inputzRNNBase.check_input   s    "-"9Qq99;,,"#5"66G		}U  ??ejjn,GGXX^_d_i_ijl_m^no  -r    c                     |t        |d         }n.| j                  r|j                  d      n|j                  d      }| j                  rdnd}| j                  |z  || j
                  f}|S )Nr   rL   rK   )intrW   r   rZ   rV   rU   )r4   r   r   
mini_batchrn   expected_hidden_sizes         r   get_expected_hidden_sizez RNNBase.get_expected_hidden_size   sn     "[^,J*.*:*:A

1J"00aOOn, 

 $#r    hxr   msgc           	          |j                         |k7  r2t        |j                  |t        |j                                           y r   )r   r   r   list)r4   r   r   r   s       r   check_hidden_sizezRNNBase.check_hidden_size	  s9     779,,szz*>RWWYPQQ -r    hiddenc                 t    | j                  ||       | j                  ||      }| j                  ||d       y )NExpected hidden size {}, got {})r   r   r   r   r4   r   r   r   r   s        r   check_forward_argszRNNBase.check_forward_args  sC     	,#<<UKP(.O 	 	
r    r   c                 "    ||S t        ||      S r   r#   r4   r   r   s      r   permute_hiddenzRNNBase.permute_hidden      I!"k22r    c           	      b    |j                  dd       }|| _        t        	|   |||d|||       y )Nr[   F)getr[   r1   r=   )
r4   r?   r:   r@   rA   rB   rC   rD   r[   r5   s
            r   r=   zRNNBase._load_from_state_dict   s@     !$$Y5%	
r    c           	      >   d }| j                   rdnd}g }t        | j                        D ]  }t        |      D ]  }|dk(  rdnd} |d||      \  }}	 |d||      \  }
}||   }||	   }||
   }||   }|j                  t        j
                  k(  rt        j                  j                  j                  ||      }t        j                  j                  j                  ||      }| j                  | j                  dk  r-t        j                  j                  j                  ||||      }nt        j                  j                  j                  ||||d      }n~t        j                  j                  j                  ||      }t        j                  j                  j                  ||      }t        j                  j                  j                  ||      }|j                  t        |               t        j                  j!                  |      | _        y )	Nc                 2    d|  d| | }d|  d| | }||fS Nweight__lbias_r|   )ihhhrp   suffixweight_name	bias_names        r   weight_bias_namez1RNNBase.set_weight_bias.<locals>.weight_bias_name7  s9    #D6E76(;KvRwvh7I	))r    rK   rL   _reverse ihhhT)rZ   rd   rV   r-   r%   r&   r'   r(   r)   r[   rh   r*   ri   rj   r   rk   rl   rm   )r4   weight_bias_dictr   rn   rm   rp   	directionr   	w_ih_name	b_ih_name	w_hh_name	b_hh_namers   ru   rt   rv   rw   rx   ry   s                      r   set_weight_biaszRNNBase.set_weight_bias6  s   	*
 #00a4??+ 	HE">2 H	'0A~2'7eV'L$	9'7eV'L$	9'	2'	2'	2'	2::, %		 3 3 B B4 NI %		 3 3 B B4 NI||+t||a/?!II//RR )9dD $ "II//RR )9dD$ $ !&		 3 3 G Gd SI %		 3 3 G Gd SI"'))"5"5"U"U!9#K #))/+*FG=H	H@ #((("5"56H"Ir    c           
         t              t        j                  j                  t        j                  j                  hv sJ d       t        d      sJ d       j                  -j                  j                  j                  j                  nddlm	} |j                          j                  }t        j                  t        j                  g}||vrt        d|       j                  dk(  rYt        j                  j                   j"                  j$                  j&                  j(                  j*                  |      }nsj                  dk(  rYt	        j                  j                   j"                  j$                  j&                  j(                  j*                  |      }nt-        d	      j*                  rd
nd}j$                  sJ g }t/        |j"                        D ]  t/        |      D ]  }	|	dk(  rdndfd}
 |
d      \  }} |
d      \  }}|t        j                  k(  rfd} |||      } |||      }|j0                  |j0                  d
k  r-t        j2                  j4                  j7                  ||||      }nt        j2                  j4                  j7                  ||||d      }n|t        j                  k(  rt        j2                  j4                  j9                  |j;                         |      }t        j2                  j4                  j9                  |j;                         |      }t        j2                  j4                  j=                  ||      }nt        d      |j?                  tA        |               t        j                  jC                  |      |_"        |S )NzInn.quantized.dynamic.RNNBase.from_float only works for nn.LSTM and nn.GRUqconfig,Input float module must have qconfig definedr   default_dynamic_qconfig0Unsupported dtype for dynamic RNN quantization: r   r   z3Only LSTM/GRU is supported for QuantizedRNN for nowrK   rL   r   r   c                 d    d|  d  }d|  d  }t        |      }t        |      }||fS r   )getattr)r   r   r   weightr,   rp   modr   s        r   retrieve_weight_biasz0RNNBase.from_float.<locals>.retrieve_weight_bias  sQ    $+D6E76("CK"'vRwvh ?I$S+6F"3	2D!4<'r    r   r   c                             } ||        t        | j                         |      }t        j                  j                  j                  ||      }|S r   )r
   rX   r%   r'   r(   r)   )wbweight_observerr+   r.   weight_observer_methods        r   quantize_and_packz-RNNBase.from_float.<locals>.quantize_and_pack  sH    *@*B'*"21779o"N(-		(;(;(J(J7TU(V,,r    Tz7Unsupported dtype specified for dynamic quantized LSTM!)#typer%   rk   r   r   hasattrr   r   torch.ao.quantization.qconfigr   r-   r&   float16r   rS   rT   rU   rV   r,   rW   rY   rZ   NotImplementedErrorrd   r[   r'   r(   rh   r*   rX   ri   rj   r   rl   rm   )clsr   use_precomputed_fake_quantr   r-   supported_scalar_typesqRNNBasern   rm   r   r   	weight_ihbias_ih	weight_hhbias_hhr   rw   rx   ry   rp   r   r   s    `                 @@@r   
from_floatzRNNBase.from_floata  sb   CyHHMMHHLL
 
 	W W	W 
 sI&V(VV&;;"s{{'9'9'E%([[%7%7"
 N%<%C%C"&(.."'++u}}!=..B5'J 
 88v!!	H XX!!	H &E  "//Qxxx8../ 6	HE">2 5H	'0A~2( &:$%?"	7%9$%?"	7EKK'- !2)W EI 1)W EI''/83C3Ca3G!II//RR )9gw $ "II//RR )9gw $ emm+ %		 3 3 G G!)7!I !&		 3 3 G G!)7!I #())"5"5"U"U!9#K 'Q  #))/+*FGk5H6	Hn ',hh&9&9:L&M#r    c                 .   i i d}d}| j                   rdnd}t        | j                        D ]  }t        |      D ]  }|dk(  rdnd}d| | }d| | }| j                  |   j                  j                         d   d	   }	|	d   j                         d   d   |d
   |<   |	d   j                         d   d   |d
   |<   d| | }d| | }|	d   j                         d   d   |d   |<   |	d   j                         d   d   |d   |<   |dz   }  |S )Nr   r,   r   rK   rL   r   r   weight_ih_lweight_hh_lrN   r   	bias_ih_l	bias_hh_lr,   )rZ   rd   rV   rm   r3   __getstate__)
r4   r   countrn   rp   r   r   	key_name1	key_name2packed_weight_biass
             r   _weight_biaszRNNBase._weight_bias  s   792,F"00a4??+ 	"E">2 "	'0A~2)%9	)%9	 &*%<%<&%q&**+&-" 9K9,.9$$%9' *95 9K9,.9$$%9' *95 (wvh7	'wvh7	6H7,.7$$%7' (3 7I7,.7$$%7' (3 	/"	"2  r    c                 (    | j                         d   S Nr   r   r}   s    r   
get_weightzRNNBase.get_weight        "8,,r    c                 (    | j                         d   S Nr,   r   r}   s    r   get_biaszRNNBase.get_bias        "6**r    )r   F)rE   rF   rG   rk   r   _FLOAT_MODULE_versionr%   r&   r2   r~   r   r   r   r   r   tupler   r   strr   r   r   r=   r   classmethodr   r   r   r  rH   rI   s   @r   r   r   [   sH   JJMH kk^J@%)<	 	hv6F 	4 	$$*26*:$	sC}	$& 5	RR $CcM2R 	R
 
R

%+
:B6:J
	
3 3hv6F 36 3

,)JV r rh @-+r    r   c                   .    e Zd ZdZej
                  ZdddgiZ fdZd Z	de
deee
e
f      d	ee
   d
edee
   dee
ee
e
f   f   fdZej                   j"                  	 dde
deee
e
f      dee
ee
e
f   f   fd       Zej                   j"                  	 ddedeee
e
f      deeee
e
f   f   fd       Zdee
e
f   dee
   dee
e
f   fdZde
dee
e
f   d	ee
   ddfdZej                   j.                  dd       Zed fd	       Zed        Z xZS )r   a  
    A dynamic quantized LSTM module with floating point tensor as inputs and outputs.
    We adopt the same interface as `torch.nn.LSTM`, please see
    https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM for documentation.

    Examples::

        >>> # xdoctest: +SKIP
        >>> rnn = nn.LSTM(10, 20, 2)
        >>> input = torch.randn(5, 3, 10)
        >>> h0 = torch.randn(2, 3, 20)
        >>> c0 = torch.randn(2, 3, 20)
        >>> output, (hn, cn) = rnn(input, (h0, c0))
    forwardforward_packedforward_tensorc                 ,    t        |   dg|i | y )Nr   r1   r2   r4   argskwargsr5   s      r   r2   zLSTM.__init__  s    1$1&1r    c                      y)NDynamicQuantizedLSTMr|   r}   s    r   r~   zLSTM._get_name  s    %r    r   r   r   max_batch_sizesorted_indicesr   c                    |Z| j                   rdnd}t        j                  | j                  |z  || j                  |j
                  |j                        }||f}n| j                  ||      }| j                  |||       | j                  D cg c]  }|j                   }	}|pt        j                  |||	| j                  | j                  t        | j                        | j                  | j                   | j                   | j
                  d      }
net        j                  ||||	| j                  | j                  t        | j                        | j                  | j                   | j
                  d      }
|
d   }|
dd  }||fS c c}w )NrK   rL   r-   deviceT)r-   use_dynamicr   )rZ   r%   zerosrV   rU   r-   r  r   r   rm   r3   quantized_lstmr,   rX   rY   r\   rW   r4   r   r   r   r  r  rn   r  m_all_paramsresultoutputr   s                r   forward_implzLSTM.forward_impl  so    :"&"4"4Q!NKK.0  kk||E B $$R8Br;7(,(?(?@1qww@@))		dll#""  jj F ))		dll#""jj F v~A As   F
Nc                     d }| j                   r|j                  d      n|j                  d      }d }d }| j                  |||||      \  }}|| j                  ||      fS Nr   rL   rW   r   r"  r   	r4   r   r   r   r  r  unsorted_indicesr!  r   s	            r   r  zLSTM.forward_tensorQ  m     *.*:*:A

1**2{NN
 t**63CDDDr    c                     |\  }}}}t        |d         }| j                  |||||      \  }}	t        ||||      }
|
| j                  |	|      fS Nr   r   r"  r   r   r4   r   r   input_r   r  r'  r  output_r   r!  s              r   r  zLSTM.forward_packed`  sn     AF=^-=[^,++B^^
  nFVWt**63CDDDr    r   c                 F    ||S t        |d   |      t        |d   |      fS r$  r#   r   s      r   r   zLSTM.permute_hiddeno  s8    
 I!"Q%57IqE;8
 
 	
r    r   c                     | j                  ||       | j                  ||      }| j                  |d   |d       | j                  |d   |d       y )Nr   z"Expected hidden[0] size {}, got {}rL   z"Expected hidden[1] size {}, got {}r   r   s        r   r   zLSTM.check_forward_args{  s_     	,#<<UKP1I+-Q	
 	1I+-Q	
r    c                 j    t        |t              r| j                  ||      S | j                  ||      S r   r]   r   r  r  r4   r   r   s      r   r  zLSTM.forward  2    e^,&&ub11&&ub11r    c                 &    t         |   ||      S N)r   r1   r   r   r   r   r5   s      r   r   zLSTM.from_float       w!,F " 
 	
r    c           
      *   t        |d      sJ d       	  | |j                  |j                  |j                  |j                  |j
                  |j                  |j                  |j                        }|j                  |j                                |S Nweight_ih_l0_dtypezWe are assuming weight_ih_l0 r   rT   rU   rV   r,   rW   rY   rZ   r<  r   get_quantized_weight_bias_dictr   ref_modqmods      r   from_referencezLSTM.from_reference      w 45V7VV5RLLOO!!&&

 	WCCEFr    r   r  )rE   rF   rG   __doc__rk   r   r  __overloads__r2   r~   r   r   r  r   r"  r%   jitexportr  r   r  r   r   ignorer  r	  r   rB  rH   rI   s   @r   r   r     s    GGM!13C DEM2&99 U66>*+9 f%	9
 9 !(9 
vuVV^,,	-9v YYCGEE!)%*?!@E	vuVV^,,	-E E YYKOE#E)1%2G)HE	~uVV^44	5E E	
&&.!	
 f%	
 
vv~			


 ffn%
 f%	

 

  YY2 2 
 

  r    r   c                       e Zd ZdZej
                  ZdddgiZ fdZd Z	de
de
d	ee
   d
dfdZde
dee
   d	ee
   dedee
   d
ee
e
f   fdZej"                  j$                  	 dde
dee
   d
ee
e
f   fd       Zej"                  j$                  	 ddedee
   d
eee
f   fd       Zde
dee
   d
e
fdZej"                  j.                  dd       Zed fd	       Zed        Z xZS )r   ax  Applies a multi-layer gated recurrent unit (GRU) RNN to an input sequence.


    For each element in the input sequence, each layer computes the following
    function:

    .. math::
        \begin{array}{ll}
            r_t = \sigma(W_{ir} x_t + b_{ir} + W_{hr} h_{(t-1)} + b_{hr}) \\
            z_t = \sigma(W_{iz} x_t + b_{iz} + W_{hz} h_{(t-1)} + b_{hz}) \\
            n_t = \tanh(W_{in} x_t + b_{in} + r_t \odot (W_{hn} h_{(t-1)}+ b_{hn})) \\
            h_t = (1 - z_t) \odot n_t + z_t \odot h_{(t-1)}
        \end{array}

    where :math:`h_t` is the hidden state at time `t`, :math:`x_t` is the input
    at time `t`, :math:`h_{(t-1)}` is the hidden state of the layer
    at time `t-1` or the initial hidden state at time `0`, and :math:`r_t`,
    :math:`z_t`, :math:`n_t` are the reset, update, and new gates, respectively.
    :math:`\sigma` is the sigmoid function, and :math:`\odot` is the Hadamard product.

    In a multilayer GRU, the input :math:`x^{(l)}_t` of the :math:`l` -th layer
    (:math:`l >= 2`) is the hidden state :math:`h^{(l-1)}_t` of the previous layer multiplied by
    dropout :math:`\delta^{(l-1)}_t` where each :math:`\delta^{(l-1)}_t` is a Bernoulli random
    variable which is :math:`0` with probability :attr:`dropout`.

    Args:
        input_size: The number of expected features in the input `x`
        hidden_size: The number of features in the hidden state `h`
        num_layers: Number of recurrent layers. E.g., setting ``num_layers=2``
            would mean stacking two GRUs together to form a `stacked GRU`,
            with the second GRU taking in outputs of the first GRU and
            computing the final results. Default: 1
        bias: If ``False``, then the layer does not use bias weights `b_ih` and `b_hh`.
            Default: ``True``
        batch_first: If ``True``, then the input and output tensors are provided
            as (batch, seq, feature). Default: ``False``
        dropout: If non-zero, introduces a `Dropout` layer on the outputs of each
            GRU layer except the last layer, with dropout probability equal to
            :attr:`dropout`. Default: 0
        bidirectional: If ``True``, becomes a bidirectional GRU. Default: ``False``

    Inputs: input, h_0
        - **input** of shape `(seq_len, batch, input_size)`: tensor containing the features
          of the input sequence. The input can also be a packed variable length
          sequence. See :func:`torch.nn.utils.rnn.pack_padded_sequence`
          for details.
        - **h_0** of shape `(num_layers * num_directions, batch, hidden_size)`: tensor
          containing the initial hidden state for each element in the batch.
          Defaults to zero if not provided. If the RNN is bidirectional,
          num_directions should be 2, else it should be 1.

    Outputs: output, h_n
        - **output** of shape `(seq_len, batch, num_directions * hidden_size)`: tensor
          containing the output features h_t from the last layer of the GRU,
          for each `t`. If a :class:`torch.nn.utils.rnn.PackedSequence` has been
          given as the input, the output will also be a packed sequence.
          For the unpacked case, the directions can be separated
          using ``output.view(seq_len, batch, num_directions, hidden_size)``,
          with forward and backward being direction `0` and `1` respectively.

          Similarly, the directions can be separated in the packed case.
        - **h_n** of shape `(num_layers * num_directions, batch, hidden_size)`: tensor
          containing the hidden state for `t = seq_len`

          Like *output*, the layers can be separated using
          ``h_n.view(num_layers, num_directions, batch, hidden_size)``.

    Shape:
        - Input1: :math:`(L, N, H_{in})` tensor containing input features where
          :math:`H_{in}=\text{input\_size}` and `L` represents a sequence length.
        - Input2: :math:`(S, N, H_{out})` tensor
          containing the initial hidden state for each element in the batch.
          :math:`H_{out}=\text{hidden\_size}`
          Defaults to zero if not provided. where :math:`S=\text{num\_layers} * \text{num\_directions}`
          If the RNN is bidirectional, num_directions should be 2, else it should be 1.
        - Output1: :math:`(L, N, H_{all})` where :math:`H_{all}=\text{num\_directions} * \text{hidden\_size}`
        - Output2: :math:`(S, N, H_{out})` tensor containing the next hidden state
          for each element in the batch

    Attributes:
        weight_ih_l[k] : the learnable input-hidden weights of the :math:`\text{k}^{th}` layer
            (W_ir|W_iz|W_in), of shape `(3*hidden_size, input_size)` for `k = 0`.
            Otherwise, the shape is `(3*hidden_size, num_directions * hidden_size)`
        weight_hh_l[k] : the learnable hidden-hidden weights of the :math:`\text{k}^{th}` layer
            (W_hr|W_hz|W_hn), of shape `(3*hidden_size, hidden_size)`
        bias_ih_l[k] : the learnable input-hidden bias of the :math:`\text{k}^{th}` layer
            (b_ir|b_iz|b_in), of shape `(3*hidden_size)`
        bias_hh_l[k] : the learnable hidden-hidden bias of the :math:`\text{k}^{th}` layer
            (b_hr|b_hz|b_hn), of shape `(3*hidden_size)`

    .. note::
        All the weights and biases are initialized from :math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})`
        where :math:`k = \frac{1}{\text{hidden\_size}}`

    .. note::
        The calculation of new gate :math:`n_t` subtly differs from the original paper and other frameworks.
        In the original implementation, the Hadamard product :math:`(\odot)` between :math:`r_t` and the
        previous hidden state :math:`h_{(t-1)}` is done before the multiplication with the weight matrix
        `W` and addition of bias:

        .. math::
            \begin{aligned}
                n_t = \tanh(W_{in} x_t + b_{in} + W_{hn} ( r_t \odot h_{(t-1)} ) + b_{hn})
            \end{aligned}

        This is in contrast to PyTorch implementation, which is done after :math:`W_{hn} h_{(t-1)}`

        .. math::
            \begin{aligned}
                n_t = \tanh(W_{in} x_t + b_{in} + r_t \odot (W_{hn} h_{(t-1)}+ b_{hn}))
            \end{aligned}

        This implementation differs on purpose for efficiency.

    .. include:: ../cudnn_persistent_rnn.rst

    Examples::

        >>> # xdoctest: +SKIP
        >>> rnn = nn.GRU(10, 20, 2)
        >>> input = torch.randn(5, 3, 10)
        >>> h0 = torch.randn(2, 3, 20)
        >>> output, hn = rnn(input, h0)
    r  r  r  c                 ,    t        |   dg|i | y )Nr   r  r  s      r   r2   zGRU.__init__,  s    000r    c                      y)NDynamicQuantizedGRUr|   r}   s    r   r~   zGRU._get_name/  r   r    r   r   r   r   Nc                 r    | j                  ||       | j                  ||      }| j                  ||d       y )Nr   r   r   s        r   r   zGRU.check_forward_args2  s>     	,#<<UKP(*K	
r    r   r  r  c                    |X| j                   rdnd}t        j                  | j                  |z  || j                  |j
                  |j                        }|}n| j                  ||      }| j                  |||       | j                  D cg c]  }|j                   }	}|Zt        j                  |||	| j                  | j                  | j                  | j                  | j                   | j                  	      }
nOt        j                  ||||	| j                  | j                  | j                  | j                  | j                   	      }
|
d   }|
d   }||fS c c}w )NrK   rL   r  r   )rZ   r%   r  rV   rU   r-   r  r   r   rm   r3   quantized_grur,   rY   r\   rW   r  s                r   r"  zGRU.forward_impl<  sJ    :"&"4"4Q!NKK.0  kk||E B $$R8Br;7(,(?(?@1qww@@((		""  
F ((		""
F v~9 As   Ec                     d }| j                   r|j                  d      n|j                  d      }d }d }| j                  |||||      \  }}|| j                  ||      fS r$  r%  r&  s	            r   r  zGRU.forward_tensors  r(  r    c                     |\  }}}}t        |d         }| j                  |||||      \  }}	t        ||||      }
|
| j                  |	|      fS r*  r+  r,  s              r   r  zGRU.forward_packed  sn     AF=^-=[^,++B^^
  nFVWt**63CDDDr    r   c                 "    ||S t        ||      S r   r#   r   s      r   r   zGRU.permute_hidden  r   r    c                 j    t        |t              r| j                  ||      S | j                  ||      S r   r2  r3  s      r   r  zGRU.forward  r4  r    c                 &    t         |   ||      S r6  r7  r8  s      r   r   zGRU.from_float  r9  r    c           
      *   t        |d      sJ d       	  | |j                  |j                  |j                  |j                  |j
                  |j                  |j                  |j                        }|j                  |j                                |S r;  r=  r?  s      r   rB  zGRU.from_reference  rC  r    r   r  )rE   rF   rG   rD  rk   r   r  rE  r2   r~   r   r   r   r   r  r"  r%   rF  rG  r  r   r  r   rH  r  r	  r   rB  rH   rI   s   @r   r   r     s   {x FFM!13C DEM1%

%+
:B6:J
	
55 V5 f%	5
 5 !(5 
vv~	5n YY48EE!)&!1E	vv~	E E YY<@
E#
E)1&)9
E	~v%	&
E 
E3 3hv6F 36 3
 YY2 2 
 

  r    r   c            	            e Zd Zg dZddej
                  f fd	Zd Zd Zd Z		 dde
d	e
d
eddfdZedd       Zed        Zd Zd Zd Zd Z fdZ fdZ xZS )r   )rT   rU   r,   TrN   c                    t         
|           || _        || _        || _        || _        |rwt        j                  ||z        j                  t        j                        | _
        t        j                  ||z        j                  t        j                        | _        n$| j                  dd        | j                  dd        t        j                  ||z  |      j                  t        j                        }t        j                  ||z  |      j                  t        j                        }|t        j                  k(  rNt        j                  |ddt        j                        }t        j                  |ddt        j                        }|t        j                  k(  rit        j                  j                   j#                  || j                        }t        j                  j                   j#                  || j                        }	nht        j                  j                   j%                  || j                        }t        j                  j                   j%                  || j                        }	|| _        |	| _        y )Nr-   r   r   rL   r   rP   )r1   r2   rT   rU   r,   weight_dtyper%   re   rf   rX   r   r   register_parameterr&   rg   r'   r(   r)   r*   _packed_weight_ih_packed_weight_hh)r4   rT   rU   r,   
num_chunksr-   r   r   packed_weight_ihpacked_weight_hhr5   s             r   r2   zRNNCellBase.__init__  s    	$&	! ;;zK'?@CC%++CVDL ;;zK'?@CC%++CVDL##It4##It4KK
[ 8*EHHU	KK
[ 8+FII%++V	EKK11qI 11qI EKK
  %yy22AA4<<   %yy22AA4<<   %yy22FF4<<   %yy22FF4<<  "2!1r    c                      y)NDynamicQuantizedRNNBaser|   r}   s    r   r~   zRNNCellBase._get_name      (r    c                     d}d| j                   v r| j                  dur|dz  }d| j                   v r| j                  dk7  r|dz  } |j                  di | j                   S )	Nr   r,   Tr   nonlinearitytanhz, nonlinearity={nonlinearity}r|   )r   r,   rd  r   r   s     r   r   zRNNCellBase.extra_repr  sd    )T]]"tyy'< AT]]*t/@/@F/J00Aqxx($--((r    c                     |j                  d      | j                  k7  r*t        d|j                  d       d| j                         y )NrL   z'input has inconsistent input_size: got , expected )r   rT   r   )r4   r   s     r   check_forward_inputzRNNCellBase.check_forward_input  sH    ::a=DOO+9%**Q-TXTcTcSde  ,r    r   r   hidden_labelr   Nc           
      D   |j                  d      |j                  d      k7  r2t        d|j                  d       d| d|j                  d             |j                  d      | j                  k7  r-t        d| d|j                  d       d| j                         y )	Nr   zInput batch size z doesn't match hiddenz batch size rL   r   z# has inconsistent hidden_size: got rg  )r   r   rU   )r4   r   r   ri  s       r   check_forward_hiddenz RNNCellBase.check_forward_hidden  s     ::a=BGGAJ&#EJJqM?2G~Uabdbibijkblamn  771:)))&I"''RS*U`aeaqaq`rs  *r    c                    t        |      t        j                  j                  t        j                  j                  t        j                  j
                  hv sJ d       t        |d      sJ d       |j                  -|j                  j                  |j                  j                  nddl	m
} |j                          j                  t        j                  t        j                  g}|vrt        d       t        |      t        j                  j                  k(  r.t        |j                  |j                   |j"                        }nt        |      t        j                  j                  k(  r.t	        |j                  |j                   |j"                        }njt        |      t        j                  j
                  k(  r9t        |j                  |j                   |j"                  |j$                        }nt'        d	      |j"                  sJ fd
}t)         ||j*                        |j,                        |_        t)         ||j0                        |j2                        |_        |S )Nznn.quantized.dynamic.RNNCellBase.from_float                                  only works for nn.LSTMCell, nn.GRUCell and nn.RNNCellr   r   r   r   r   )r,   r-   )r,   rd  r-   zUOnly LSTMCell, GRUCell and RNNCell             are supported for QuantizedRNN for nowc                     t         j                  k(  r+        } ||        t        | j                         |      }|S | j                         S r   )r%   r&   r
   rX   )r   r   r+   r-   r   s      r   _observe_and_quantize_weightz<RNNCellBase.from_float.<locals>._observe_and_quantize_weight>  sB    #"8":'*6<<>?K||~%r    )r   r%   rk   r   r   r   r   r   r   r   r   r-   r&   r   r   rT   rU   r,   rd  r   r   r   r   r[  r   r   r\  )	r   r   r   r   r   qRNNCellBasern  r-   r   s	          @@r   r   zRNNCellBase.from_float	  s   CyHHHHHH
 
 	XX		X 
 sI&V(VV&;;"s{{'9'9'E%([[%7%7"
 N%<%C%C"&(.."'++u}}!=..B5'J  9)))#chheL #Y%((***"chheL #Y%((***"XX --L &4 
 xxx	& *:(7e*
& *:(7e*
& r    c                    t        |d      sJ d       	 t        |d      r@ | |j                  |j                  |j                  |j                  |j
                        }n4 | |j                  |j                  |j                  |j
                        }|j                         |j                         d|j                  |j                  dd}|j                  |       |S )Nweight_ih_dtypezWe are assuming weight_ih rd  rX  )r   r   )r   r   r   )r   rT   rU   r,   rd  rq  get_quantized_weight_ihget_quantized_weight_hhr   r   r   )r   r@  rA  r   s       r   rB  zRNNCellBase.from_referenceO  s    w 12P4PP2^7N+""##$$--D ""##--	D %<<>$<<>
 #??"??	
 	-.r    c                     i i d}| j                   j                         d   \  }}| j                  j                         d   \  }}||d   d<   ||d   d<   ||d   d<   ||d   d<   |S )	Nr   r   r   r   r   r,   r   r   )r[  r   r\  )r4   r   w1b1w2b2s         r   r   zRNNCellBase._weight_biaso  s    792,F''446q9B''446q9B 35";/24";/.0 +.0 +r    c                 (    | j                         d   S r   r   r}   s    r   r   zRNNCellBase.get_weight|  r   r    c                 (    | j                         d   S r  r   r}   s    r   r  zRNNCellBase.get_bias  r  r    c                     t        |d   d   |d   d   | j                        | _        t        |d   d   |d   d   | j                        | _        y )Nr   r   r,   r   r   r   )r   rY  r[  r\  )r4   r   s     r   r   zRNNCellBase.set_weight_bias  sf     "2X&{3V$Y/"

 "2X&{3V$Y/"
r    c                 p    t         |   |||       | j                  ||dz   <   | j                  ||dz   <   y )Nr[  r\  )r1   r7   r[  r\  r8   s       r   r7   zRNNCellBase._save_to_state_dict  s@    #KC484J4JF001484J4JF001r    c           	          |j                  |dz         | _        |j                  |dz         | _        t        |   |||d|||       y )Nr[  r\  F)popr[  r\  r1   r=   r>   s	           r   r=   z!RNNCellBase._load_from_state_dict  sU     ",9L0L!M!+9L0L!M%	
r    )r   r  )rE   rF   rG   __constants__r%   r&   r2   r~   r   rh  r   r  rk  r	  r   rB  r   r   r  r   r7   r=   rH   rI   s   @r   r   r     s    9M -1Qekk12f)) >@!'7:	 C CJ  > -+
K

 
r    r   c                   ~     e Zd ZdZg dZddej                  f fd	Zd Zdde	de
e	   d	e	fd
Zed fd	       Z xZS )r   ae  An Elman RNN cell with tanh or ReLU non-linearity.
    A dynamic quantized RNNCell module with floating point tensor as inputs and outputs.
    Weights are quantized to 8 bits. We adopt the same interface as `torch.nn.RNNCell`,
    please see https://pytorch.org/docs/stable/nn.html#torch.nn.RNNCell for documentation.

    Examples::

        >>> # xdoctest: +SKIP
        >>> rnn = nn.RNNCell(10, 20)
        >>> input = torch.randn(6, 3, 10)
        >>> hx = torch.randn(3, 20)
        >>> output = []
        >>> for i in range(6):
        ...     hx = rnn(input[i], hx)
        ...     output.append(hx)
    )rT   rU   r,   rd  Tre  c                 <    t         |   |||d|       || _        y )NrL   r]  r-   )r1   r2   rd  )r4   rT   rU   r,   rd  r-   r5   s         r   r2   zRNNCell.__init__  s%     	[$1ER(r    c                      y)NDynamicQuantizedRNNCellr|   r}   s    r   r~   zRNNCell._get_name  rb  r    r   r   r   c                    | j                  |       |Ft        j                  |j                  d      | j                  |j
                  |j                        }| j                  ||d       | j                  dk(  rXt        j                  j                  j                  ||| j                  | j                  | j                  | j                        }|S | j                  dk(  rXt        j                  j                  j!                  ||| j                  | j                  | j                  | j                        }|S |}t#        d| j                         )Nr   r  r   re  reluzUnknown nonlinearity: )rh  r%   r  r   rU   r-   r  rk  rd  r'   r(   quantized_rnn_tanh_cell_dynamicr[  r\  r   r   quantized_rnn_relu_cell_dynamicr   )r4   r   r   rets       r   r  zRNNCell.forward  s#     ':

1t//u{{5<<B 	!!%R0&))%%EE&&&&C( 
 &())%%EE&&&&C 
 C!78I8I7JKLLr    c                 &    t         |   ||      S r6  r7  r8  s      r   r   zRNNCell.from_float  r9  r    r   r  )rE   rF   rG   rD  r  r%   r&   r2   r~   r   r   r  r	  r   rH   rI   s   @r   r   r     sZ      JM -1vU[[))V &)9 V < 
 
r    r   c            	       p     e Zd ZdZ fdZd Z	 d	dedeeeef      deeef   fdZ	e
d
 fd	       Z xZS )r   a  A long short-term memory (LSTM) cell.

    A dynamic quantized LSTMCell module with floating point tensor as inputs and outputs.
    Weights are quantized to 8 bits. We adopt the same interface as `torch.nn.LSTMCell`,
    please see https://pytorch.org/docs/stable/nn.html#torch.nn.LSTMCell for documentation.

    Examples::

        >>> # xdoctest: +SKIP
        >>> rnn = nn.LSTMCell(10, 20)
        >>> input = torch.randn(6, 3, 10)
        >>> hx = torch.randn(3, 20)
        >>> cx = torch.randn(3, 20)
        >>> output = []
        >>> for i in range(6):
        ...     hx, cx = rnn(input[i], (hx, cx))
        ...     output.append(hx)
    c                 (    t        |   |ddi| y )Nr]  rN   r  r  s      r   r2   zLSTMCell.__init__  s    $7177r    c                      y)NDynamicQuantizedLSTMCellr|   r}   s    r   r~   zLSTMCell._get_name  s    )r    r   r   r   c                    | j                  |       |Jt        j                  |j                  d      | j                  |j
                  |j                        }||f}| j                  ||d   d       | j                  ||d   d       t        j                  j                  j                  ||| j                  | j                  | j                  | j                        S )Nr   r  z[0]rL   z[1])rh  r%   r  r   rU   r-   r  rk  r'   r(   quantized_lstm_cell_dynamicr[  r\  r   r   )r4   r   r   r  s       r   r  zLSTMCell.forward  s     	  ':KK

1t//u{{5<<E B!!%A6!!%A6yy"">>""""LLLL
 	
r    c                 &    t         |   ||      S r6  r7  r8  s      r   r   zLSTMCell.from_float  r9  r    r   r  )rE   rF   rG   rD  r2   r~   r   r   r  r  r	  r   rH   rI   s   @r   r   r     sa    &8* DH

!)%*?!@
	vv~	
( 
 
r    r   c                   t     e Zd ZdZdej
                  f fd	Zd Zd
dede	e   defdZ
ed fd		       Z xZS )r   aU  A gated recurrent unit (GRU) cell

    A dynamic quantized GRUCell module with floating point tensor as inputs and outputs.
    Weights are quantized to 8 bits. We adopt the same interface as `torch.nn.GRUCell`,
    please see https://pytorch.org/docs/stable/nn.html#torch.nn.GRUCell for documentation.

    Examples::

        >>> # xdoctest: +SKIP
        >>> rnn = nn.GRUCell(10, 20)
        >>> input = torch.randn(6, 3, 10)
        >>> hx = torch.randn(3, 20)
        >>> output = []
        >>> for i in range(6):
        ...     hx = rnn(input[i], hx)
        ...     output.append(hx)
    Tc                 .    t         |   |||d|       y )NrO   r  r  )r4   rT   rU   r,   r-   r5   s        r   r2   zGRUCell.__init__5  s    [$1ERr    c                      y)NDynamicQuantizedGRUCellr|   r}   s    r   r~   zGRUCell._get_name8  rb  r    r   r   r   c                    | j                  |       |Ft        j                  |j                  d      | j                  |j
                  |j                        }| j                  ||d       t        j                  j                  j                  ||| j                  | j                  | j                  | j                        S )Nr   r  r   )rh  r%   r  r   rU   r-   r  rk  r'   r(   quantized_gru_cell_dynamicr[  r\  r   r   r3  s      r   r  zGRUCell.forward;  s      ':

1t//u{{5<<B 	!!%R0yy""==""""LLLL
 	
r    c                 &    t         |   ||      S r6  r7  r8  s      r   r   zGRUCell.from_floatK  r9  r    r   r  )rE   rF   rG   rD  r%   r&   r2   r~   r   r   r  r	  r   rH   rI   s   @r   r   r   "  sQ    $ 6: S)
V 
&)9 
V 
  
 
r    r   )rL   )!r^   rb   typing_extensionsr   r%   torch.nnrk   r   torch._jit_internalr   r   r   r   r	   #torch.ao.nn.quantized.modules.utilsr
   torch.nn.utils.rnnr   __all__r   r   FutureWarningr   r   Moduler   r   r   r   r   r   r   r   r|   r    r   <module>r     s     (    B B @ -1v 1F 1 1V 1 c8f 86 8 8F 8	8&
ehhoo 
>_+ehhoo _+Dk7 k\F' FRu
%((// u
p>
k >
B2
{ 2
j-
k -
r    