
    sg6E                     <   d Z ddlZddlZddlmZmZ ddlZddlmZ ddgZ G d dej                  j                        Z G d d	ej                  j                        Z G d
 dej                  j                        Z G d dej                  j                        Zy)z
We will recreate all the RNN modules as we require the modules to be decomposed
into its building blocks to be able to observe.
    N)OptionalTuple)TensorLSTMCellLSTMc            	            e Zd ZdZej
                  j                  Z	 	 	 ddedede	ddf fdZ
	 dded	eeeef      deeef   fd
Z	 ddede	deeef   fdZd Zedd       Zedd       Z xZS )r   a  A quantizable long short-term memory (LSTM) cell.

    For the description and the argument types, please, refer to :class:`~torch.nn.LSTMCell`

    Examples::

        >>> import torch.ao.nn.quantizable as nnqa
        >>> rnn = nnqa.LSTMCell(10, 20)
        >>> input = torch.randn(6, 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)
    N	input_dim
hidden_dimbiasreturnc                    ||d}t         |           || _        || _        || _        t        j                  j                  |d|z  fd|i|| _        t        j                  j                  |d|z  fd|i|| _	        t
        j                  j                  j                  j                         | _        t
        j                  j                         | _        t
        j                  j                         | _        t
        j                  j#                         | _        t
        j                  j                         | _        t
        j                  j                  j                  j                         | _        t
        j                  j                  j                  j                         | _        t
        j                  j                  j                  j                         | _        t
        j                  j                  j                  j                         | _        d| _        d| _        t
        j4                  | _        t
        j4                  | _        y )Ndevicedtype   r   )      ?r   )super__init__
input_sizehidden_sizer   torchnnLinearigateshgatesao	quantizedFloatFunctionalgatesSigmoid
input_gateforget_gateTanh	cell_gateoutput_gatefgate_cxigate_cgatefgate_cx_igate_cgateogate_cyinitial_hidden_state_qparamsinitial_cell_state_qparamsquint8hidden_state_dtypecell_state_dtypeselfr	   r
   r   r   r   factory_kwargs	__class__s          V/var/www/html/venv/lib/python3.12/site-packages/torch/ao/nn/quantizable/modules/rnn.pyr   zLSTMCell.__init__&   s    %+U;#%	hhooq:~
,0
4B
 hhooJ
-1
5C
 XX[[**::<
((**, 88++- 88++---==? 88;;00@@B$)HHKK$9$9$I$I$K!--==??G)=E'/4||-2\\    xhiddenc                    |
|d   |d   )| j                  |j                  d   |j                        }|\  }}| j                  |      }| j	                  |      }| j
                  j                  ||      }|j                  dd      \  }}	}
}| j                  |      }| j                  |	      }	| j                  |
      }
| j                  |      }| j                  j                  |	|      }| j                  j                  ||
      }| j                  j                  ||      }|}t!        j"                  |      }| j$                  j                  ||      }||fS )Nr      r   )initialize_hiddenshapeis_quantizedr   r   r   addchunkr!   r"   r$   r%   r&   mulr'   r(   r   tanhr)   )r0   r5   r6   hxcxr   r   r   r!   r"   r$   out_gater&   r'   r(   cytanh_cyhys                     r3   forwardzLSTMCell.forwardL   s?    >VAY.&)2C++AGGAJGFBQR

vv.7<{{1a7H4
KH__Z0
&&{3NN9-	##H-==$$["5&&**:yA#88<<X{S! **R.]]x12vr4   
batch_sizer;   c                 Z   t        j                  || j                  f      t        j                  || j                  f      }}|rd| j                  \  }}| j                  \  }}t        j
                  |||| j                        }t        j
                  |||| j                        }||fS )Nscale
zero_pointr   )r   zerosr   r*   r+   quantize_per_tensorr-   r.   )	r0   rG   r;   hch_scaleh_zpc_scalec_zps	            r3   r9   zLSTMCell.initialize_hiddenh   s     {{J(8(89:EKK))*=
1 "??OWd"==OWd))T9P9PA ))T9N9NA !tr4   c                      y)NQuantizableLSTMCell r0   s    r3   	_get_namezLSTMCell._get_namey   s    $r4   c                    |du |du k(  sJ |j                   d   }|j                   d   } | |||du      }t        j                  j                  |      |j                  _        |.t        j                  j                  |      |j                  _        t        j                  j                  |      |j                  _        |.t        j                  j                  |      |j                  _        |S )zUses the weights and biases to create a new LSTM cell.

        Args:
            wi, wh: Weights for the input and hidden layers
            bi, bh: Biases for the input and hidden layers
        Nr8   )r	   r
   r   )r:   r   r   	Parameterr   weightr   r   )clswiwhbibhr   r   cells           r3   from_paramszLSTMCell.from_params|   s     d
d
+++XXa[
hhqkZKrQU~W"XX//3>$xx11"5DKK"XX//3>$xx11"5DKKr4   c                 f   t        |      | j                  k(  sJ t        |d      sJ d       | j                  |j                  |j
                  |j                  |j                        }|j                  |_        |j                  |j                  _        |j                  |j                  _        |S )Nqconfigz$The float module must have 'qconfig')type_FLOAT_MODULEhasattrrb   	weight_ih	weight_hhbias_ihbias_hhrd   r   r   )r\   otheruse_precomputed_fake_quantobserveds       r3   
from_floatzLSTMCell.from_float   s    E{c/////ui(P*PP(??OOU__emmU]]
 !=="'--"'--r4   TNNN)FNN)__name__
__module____qualname____doc__r   r   r   rf   intboolr   r   r   r   rF   r9   rX   classmethodrb   ro   __classcell__r2   s   @r3   r   r      s      HH%%M $:$: $: 	$: 
$:N DH!)%*?!@	vv~	: 5:-1	vv~	"%  & 	 	r4   c            	       n     e Zd ZdZ	 	 	 ddedededdf fdZdded	ee	eef      fd
Z
ed        Z xZS )_LSTMSingleLayerzA single one-directional LSTM layer.

    The difference between a layer and a cell is that the layer can process a
    sequence, while the cell only expects an instantaneous value.
    Nr	   r
   r   r   c                 T    ||d}t         |           t        ||fd|i|| _        y Nr   r   )r   r   r   ra   r/   s          r3   r   z_LSTMSingleLayer.__init__   s2     %+U;Y
PPP	r4   r5   r6   c                     g }|j                   d   }t        |      D ]+  }| j                  ||   |      }|j                  |d          - t	        j
                  |d      }||fS )Nr   )r:   rangera   appendr   stack)r0   r5   r6   resultseq_leniresult_tensors          r3   rF   z_LSTMSingleLayer.forward   sh    ''!*w 	%AYYqtV,FMM&)$	% FA.f$$r4   c                     t        j                  |i |} | |j                  |j                  |j                        }||_        |S rq   )r   rb   r   r   r   ra   )r\   argskwargsra   layers        r3   rb   z_LSTMSingleLayer.from_params   s?    ##T4V4DOOT%5%5tyyA
r4   rp   rq   )rs   rt   ru   rv   rw   rx   r   r   r   r   rF   ry   rb   rz   r{   s   @r3   r}   r}      sx     
Q
Q 
Q 	
Q 

Q% %%2G)H %  r4   r}   c                   |     e Zd ZdZ	 	 	 	 	 ddedededededdf fd	Zdd
edee	eef      fdZ
edd       Z xZS )
_LSTMLayerz#A single bi-directional LSTM layer.Nr	   r
   r   batch_firstbidirectionalr   c                     ||d}t         	|           || _        || _        t	        ||fd|i|| _        | j                  rt	        ||fd|i|| _        y y r   )r   r   r   r   r}   layer_fwlayer_bw)
r0   r	   r
   r   r   r   r   r   r1   r2   s
            r3   r   z_LSTMLayer.__init__   s|     %+U;&*(z
(,
0>
 ,:,04BDM r4   r5   r6   c                    | j                   r|j                  dd      }|d\  }}n|\  }}d }| j                  r&|d }n
|d   }|d   }|d }n
|d   }|d   }||||f}||d }n>t        j                  j                  |      t        j                  j                  |      f}| j                  ||      \  }	}t        | d      r| j                  r|j                  d      }
| j                  |
|      \  }}|j                  d      }t        j                  |	|g|	j                         dz
        }||d }d }n|#t        j                  j                  |      \  }}n|#t        j                  j                  |      \  }}nat        j                  |d   |d   gd      }t        j                  |d   |d   gd      }n$|	}t        j                  j                  |      \  }}| j                   r|j                  dd       |||ffS )Nr   r8   rr   r   )r   	transposer   r   jit_unwrap_optionalr   rg   flipr   catdimr   
transpose_)r0   r5   r6   hx_fwcx_fw	hidden_bwhx_bwcx_bw	hidden_fw	result_fw
x_reversed	result_bwr   rN   rO   s                  r3   rF   z_LSTMLayer.forward   s   Aq!A>'LE5!LE559	}aa}aa U%6!5L	=U]I		2259599;U;U< I  $}}Q	:	94$););J#'==Y#G Iy!q)IYY	95y}}7JKF Y%6"33I>A"33I>AKK1y| <a@KK1y| <a@F99--i8DAqa#1v~r4   c                    t        |d      s|J |j                  d|j                        }|j                  d|j                        }|j                  d|j                        }|j                  d|j
                        }|j                  d|j                        }	 | |||||	      }
t        |d|      |
_        t        |d|       }t        |d	|       }t        |d
| d      }t        |d| d      }t        j                  ||||      |
_        |j                  r_t        |d| d      }t        |d	| d      }t        |d
| dd      }t        |d| dd      }t        j                  ||||      |
_        |
S )z
        There is no FP equivalent of this class. This function is here just to
        mimic the behavior of the `prepare` within the `torch.ao.quantization`
        flow.
        rd   Nr   r   r   r   r   weight_ih_lweight_hh_l	bias_ih_l	bias_hh_l_reverse)rg   getr   r   r   r   r   getattrrd   r}   rb   r   r   )r\   rl   	layer_idxrd   r   r   r   r   r   r   r   r]   r^   r_   r`   s                  r3   ro   z_LSTMLayer.from_float  s    ui(W-@AAZZe.>.>?
jj0A0ABzz&%**-jj0A0AB

?E4G4GHJT;Ny':Uk)56Uk)56Ui	{3T:Ui	{3T:)55b"b"E+i[ ABB+i[ ABB)I;h ?FB)I;h ?FB-99"b"bIENr4   )TFFNNrq   )r   N)rs   rt   ru   rv   rw   rx   r   r   r   r   rF   ry   ro   rz   r{   s   @r3   r   r      s    . !#  	
   
,4 4%2G)H 4l  r4   r   c                        e Zd ZdZej
                  j                  Z	 	 	 	 	 	 	 ddededede	de	de
d	e	d
df fdZddedeeeef      fdZd Zedd       Zed        Z xZS )r   aX  A quantizable long short-term memory (LSTM).

    For the description and the argument types, please, refer to :class:`~torch.nn.LSTM`

    Attributes:
        layers : instances of the `_LSTMLayer`

    .. note::
        To access the weights and biases, you need to access them per layer.
        See examples below.

    Examples::

        >>> import torch.ao.nn.quantizable as nnqa
        >>> rnn = nnqa.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))
        >>> # To get the weights:
        >>> # xdoctest: +SKIP
        >>> print(rnn.layers[0].weight_ih)
        tensor([[...]])
        >>> print(rnn.layers[0].weight_hh)
        AssertionError: There is no reverse path in the non-bidirectional layer
    Nr   r   
num_layersr   r   dropoutr   r   c
           	      6   ||	d}
t         |           || _        || _        || _        || _        || _        t        |      | _        || _	        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  r5t!        j"                  d       |dk(  rt!        j"                  d| d	|        t%        | j                  | j                  | j
                  fd| j                  d
|
g}t'        d|      D ]J  }|j)                  t%        | j                  | j                  | j
                  fd| j                  d
|
       L t*        j,                  j/                  |      | _        y )Nr   F   r8   r   zbdropout should be a number in range [0, 1] representing the probability of an element being zeroedz|dropout option for quantizable LSTM is ignored. If you are training, please, use nn.LSTM version followed by `prepare` step.zdropout 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   )r   r   r   r   r   r   r   floatr   r   training
isinstancenumbersNumberrx   
ValueErrorwarningswarnr   r   r   r   r   
ModuleListlayers)r0   r   r   r   r   r   r   r   r   r   r1   num_directionsr   r   r2   s                 r3   r   zLSTM.__init__N  s    %+U;$&$	&W~*+ 7GNN3$1$   '4( 
 Q;MM.
 QBBI K&&0\3   		 ""00 !	
 1j) 
	EMM$$$$II !&"&"4"4 %	
	 hh))&1r4   r5   r6   c                    | j                   r|j                  dd      }|j                  d      }| j                  rdnd}|t	        j
                  ||| j                  t        j                  |j                        }|j                  d       |j                  r#t	        j                  |dd|j                        }t        | j                        D cg c]  }||f }}nt        j                  j!                  |      }t#        |d   t$              r|d   j'                  | j                  ||| j                        }	|d   j'                  | j                  ||| j                        }
t        | j                        D cg c]*  }|	|   j)                  d      |
|   j)                  d      f, }}n|}g }g }t+        | j,                        D ]s  \  }} ||||         \  }\  }}|j/                  t        j                  j!                  |             |j/                  t        j                  j!                  |             u t	        j0                  |      }t	        j0                  |      }|j'                  d|j2                  d   |j2                  d         }|j'                  d|j2                  d   |j2                  d         }| j                   r|j                  dd      }|||ffS c c}w c c}w )	Nr   r8   r   )r   r   r   rI   )r   r   sizer   r   rL   r   r   r   squeeze_r;   rM   r   r   r   r   r   r   r   reshapesqueeze	enumerater   r   r   r:   )r0   r5   r6   max_batch_sizer   rL   _hxcxhidden_non_optr@   rA   idxhx_listcx_listr   rN   rO   	hx_tensor	cx_tensors                      r3   rF   zLSTM.forward  s   Aq!A"00a>KK  kkxxE NN1~~11!'' -2$//,BCqUENCDC"YY77?N.+V4#A&..OO^^TEUEU $A&..OO^^TEUEU
  %T__5 W__Q'C);< 
 &#DKK0 	:JCac+IAv1NN59955a89NN59955a89	: KK(	KK(	 %%b)//"*=yr?RS	%%b)//"*=yr?RS	Aq!A9i(((E Ds   K-/K2c                      y)NQuantizableLSTMrV   rW   s    r3   rX   zLSTM._get_name  s     r4   c           	         t        || j                        sJ t        |d      s|sJ  | |j                  |j                  |j
                  |j                  |j                  |j                  |j                        }t        |d|      |_        t        |j
                        D ](  }t        j                  |||d      |j                  |<   * |j                   r=|j#                          t$        j&                  j(                  j+                  |d      }|S |j-                          t$        j&                  j(                  j/                  |d      }|S )Nrd   F)r   T)inplace)r   rf   rg   r   r   r   r   r   r   r   r   rd   r   r   ro   r   r   trainr   r   quantizationprepare_qatevalprepare)r\   rl   rd   rn   r   s        r3   ro   zLSTM.from_float  s+   %!2!2333ui(G33JJMM
 #5)W=))* 	C#-#8#8sG $9 $HOOC 	 >>NNxx,,8848PH  MMOxx,,44Xt4LHr4   c                     t        d      )NzuIt looks like you are trying to convert a non-quantizable LSTM module. Please, see the examples on quantizable LSTMs.)NotImplementedError)r\   rl   s     r3   from_observedzLSTM.from_observed  s     "1
 	
r4   )r8   TFg        FNNrq   )rs   rt   ru   rv   r   r   r   rf   rw   rx   r   r   r   r   r   rF   rX   ry   ro   r   rz   r{   s   @r3   r   r   1  s    4 HHMMM !#E2E2 E2 	E2
 E2 E2 E2 E2 
E2N5) 5)%2G)H 5)n!  6 
 
r4   )rv   r   r   typingr   r   r   r   __all__r   Moduler   r}   r   r   rV   r4   r3   <module>r      s      "   v
Guxx GT!uxx !Hm m`B
588?? B
r4   