o
    2h*                     @   s   d dl Zd dlmZ 								d!ddZ					d"ddZd	d
 Zdd Zdd Zdd Z	d#ddZ
dd Zdd Zdd Zdd Z	d$ddZ				d%ddZdd  ZdS )&    N)treeFTc           *   	      s  pj d dd }|st|t}|d j d }|du r,t |d d n||D ]}|j d q0|dur^|jtjkrJt|tj}t	|j dkrXtj
|dd	}|s^||}du rdg d2d
d |r|srtdt}g }g }fdd}trt|n|ffdd}|durIt|}r|  t|D ]l}||}|| 	|t|t \}} 	|}|st|}n|d }t|||}t|}t|}t 	fdd|D }tdd t|||D }t||}r|| || q|g}|g}q|d }|d }t|}rGt |d ||t|}t ||dd|t|}nzt|D ])}||}|t|t \}}ro|| || qM|g}|g}qM|d }|d }t|}n=t}tfddt|D tfddt|D tdd |D } | tt \}!}"rndtfddtt|!D }#tjdddd}$du r}%nt}%fdd|%dd d!}&|durrt|dg}tjtjd"d#

|

fd$d% fd&d'n-ttjrIr>tjdd	}'t|'d fd(d%nfd)d%d*d' nddurtd+d t|!D f	d,d-}(tjd3|(|$|#f| d.|&})|)dd }n fd/d-}(tjd3|(|$|#f| d.|&})|)dd }|)d }#td0d |#D }td1d |D }t|!|}t|!|}|st||}|||fS )4aS  Iterates over the time dimension of a tensor.

    Args:
        step_function: RNN step function.
            Args;
                `input`; Tensor with shape `(samples, ...)` (no time dimension),
                    representing input for the batch of samples at a certain
                    time step.
                `states`; List of tensors.
            Returns;
                `output`; Tensor with shape `(samples, output_dim)`
                    (no time dimension).
                `new_states`; List of tensors, same length and shapes
                    as 'states'. The first state in the list must be the
                    output tensor at the previous timestep.
        inputs: Tensor of temporal data of shape `(samples, time, ...)`
            (at least 3D), or nested tensors, and each of which has shape
            `(samples, time, ...)`.
        initial_states: Tensor with shape `(samples, state_size)`
            (no time dimension), containing the initial values for the states
            used in the step function. In the case that state_size is in a
            nested shape, the shape of initial_states will also follow the
            nested structure.
        go_backwards: Boolean. If `True`, do the iteration over the time
            dimension in reverse order and return the reversed sequence.
        mask: Binary tensor with shape `(samples, time, 1)`,
            with a zero for every element that is masked.
        constants: List of constant values passed at each step.
        unroll: Whether to unroll the RNN or to use a symbolic `while_loop`.
        input_length: An integer or a 1-D Tensor, depending on whether
            the time dimension is fixed-length or not. In case of variable
            length input, it is used for masking in case there's no mask
            specified.
        time_major: Boolean. If `True`, the inputs and outputs will be in shape
            `(timesteps, batch, ...)`, whereas in the False case, it will be
            `(batch, timesteps, ...)`. Using `time_major = True` is a bit more
            efficient because it avoids transposes at the beginning and end of
            the RNN calculation. However, most TensorFlow data is batch-major,
            so by default this function accepts input and emits output in
            batch-major form.
        zero_output_for_mask: Boolean. If `True`, the output for masked timestep
            will be zeros, whereas in the `False` case, output from previous
            timestep is returned.
        return_all_outputs: Boolean. If `True`, return the recurrent outputs for
            all timesteps in the sequence. If `False`, only return the output
            for the last timestep (which consumes less memory).

    Returns:
        A tuple, `(last_output, outputs, new_states)`.
            - `last_output`: the latest output of the rnn,
                with shape `(samples, ...)`.
            - `outputs`:
                - If `return_all_outputs=True`: a tensor with shape
                  `(samples, time, ...)` where each entry `outputs[s, t]` is the
                  output of the step function at time `t` for sample `s`
                - Else, a tensor equal to `last_output` with shape
                  `(samples, 1, ...)`
            - `new_states`: list of tensors, latest states returned by
                the step function, of shape `(samples, ...)`.
       c                 S   s.   t tt| j}d\|d< |d< t| |S )Nr   r   r   r   )listrangelenshapetf	transpose)input_taxes r   [/var/www/html/chatgem/venv/lib/python3.10/site-packages/keras/src/backend/tensorflow/rnn.pyswap_batch_timestepQ   s   z rnn.<locals>.swap_batch_timestepr   N      axisc                 S   s   t | rtd|  t |rtd| t|jt| j }t|D ]}t| d} q&dg| |j |d   }t	| |S )Nz)mask_t is expected to be tensor, but got z*input_t is expected to be tensor, but got r   r   )
r   	is_nested
ValueErrorr   r   r   r	   expand_dimsas_listtile)mask_tr   	fixed_dim	rank_diff_	multiplesr   r   r   _expand_maskt   s   

zrnn.<locals>._expand_maskz/Unrolling requires a fixed number of timesteps.c                    s   t | }  r|   | S N)r	   unstackreverse)r   go_backwardsr   r   _process_single_input_t   s   
z$rnn.<locals>._process_single_input_tc                    s    fddD }t |S )Nc                    s   g | ]}|  qS r   r   ).0t_timer   r   
<listcomp>       z2rnn.<locals>._get_input_tensor.<locals>.<listcomp>)r   pack_sequence_as)r)   inp)inputsprocessed_inputr(   r   _get_input_tensor   s   zrnn.<locals>._get_input_tensorc                 3   s    | ]} |V  qd S r    r   )r&   sr   r   r   r   	<genexpr>       

zrnn.<locals>.<genexpr>c                 s   $    | ]\}}}t |||V  qd S r    r	   where)r&   mr1   psr   r   r   r3      
    
r   c                 3   s,    | ]\}}t j|j d | dV  qdS )	input_ta_dtypesizetensor_array_nameN)r	   TensorArrayr>   )r&   ir-   time_steps_tr   r   r3      s    
c                 3   s6    | ]\}} s| |n	| t|d gV  qdS )r   N)r!   r	   r"   )r&   tainput_r#   r   r   r3      s    
c                 S   s   g | ]}|d  qS )r   r   )r&   r-   r   r   r   r*     r+   zrnn.<locals>.<listcomp>c                 3   s0    | ]\}}t j|j |jd | dV  qdS )
output_ta_)r>   r?   element_shaper@   N)r	   rA   r>   r   )r&   rB   out)output_ta_sizer   r   r3     s    
int32r)   )r>   namec                    s   |  k S r    r   )r)   r   rC   r   r   <lambda>  s    zrnn.<locals>.<lambda>    T)condmaximum_iterationsparallel_iterationsswap_memorymask_tar=   c                    s
     | S r    readr(   )rS   r   r   
masking_fn+  s   
zrnn.<locals>.masking_fnc                    s2   t  fdd|D }t dd t|||D S )Nc                 3   s$    | ]} |t jd V  qdS )r;   N)r   r   r&   or2   r   r   r3   /  s
    
5rnn.<locals>.compute_masked_output.<locals>.<genexpr>c                 s   r5   r    r6   )r&   r8   rX   fmr   r   r   r3   3  r:   tuplezip)r   flat_out	flat_masktiled_mask_t)r   r   r   compute_masked_output.  s   
z"rnn.<locals>.compute_masked_outputc                       t  | S r    )r	   lessr(   )rev_input_lengthr   r   rV   =     c                    rc   r    )r	   greaterr(   )input_lengthr   r   rV   B  rf   c                    s   t  fddt||D S )Nc                 3   s"    | ]\}}t  ||V  qd S r    r6   )r&   rX   zora   r   r   r3   F  s
    
rY   r[   )r   r^   r_   r   ra   r   rb   E  s   c                 s   s    | ]}t |V  qd S r    )r	   
zeros_likerW   r   r   r   r3   Q  r4   c                    s   t fddD }t|}}	|t |t  \}}t|}
r+nt|}	|||	}
t|}t|}|||}t||}rPnd t  fddt||
D }d |t |
ft | S )as  RNN step function.

                Args:
                    time: Current timestep value.
                    output_ta_t: TensorArray.
                    prev_output: tuple of outputs from time - 1.
                    *states: List of states.

                Returns:
                    Tuple: `(time + 1, output_ta_t, output) + tuple(new_states)`
                c                 3       | ]}|  V  qd S r    rT   r&   rE   r(   r   r   r3   a      %rnn.<locals>._step.<locals>.<genexpr>r   c                 3        | ]\}}|  |V  qd S r    writer&   rE   rI   ta_index_to_writer   r   r3   |  
    

r   r\   r   r,   flattenr]   )r)   output_ta_tprev_outputstatescurrent_inputr   output
new_statesflat_outputflat_mask_outputflat_new_output
flat_stateflat_new_stateflat_final_state)	rb   	constantsflat_zero_outputinput_tar.   rV   return_all_outputsstep_functionzero_output_for_maskrt   r)   r   _stepU  s6   


zrnn.<locals>._step)body	loop_varsc                    s   t fddD }t|}|t |t  \}}t|}t|}r,nd t  fddt||D }t|}d |ft | S )a)  RNN step function.

                Args:
                    time: Current timestep value.
                    output_ta_t: TensorArray.
                    *states: List of states.

                Returns:
                    Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
                c                 3   rk   r    rT   rl   r(   r   r   r3     rm   rn   r   c                 3   ro   r    rp   rr   rs   r   r   r3     ru   r   rv   )r)   rx   rz   r{   r|   r}   r   r~   )r   initial_statesr   r.   r   r   r   r   r     s   

c                 s   s    | ]}|  V  qd S r    )stackrW   r   r   r   r3         c                 s   s    | ]}|d  V  qdS )r   Nr   rW   r   r   r   r3     r   )r   r   )r   r   map_structurerw   r	   with_rank_at_leastr>   boolcastr   r   r   r\   r   r!   r"   r   rj   r7   r]   r,   appendr   	enumerateconstant
reduce_maxrA   
isinstanceTensorsubtract
while_loop)*r   r.   r   r$   maskr   unrollrh   
time_majorr   r   r   flattened_inputs
time_stepsrF   rz   successive_statessuccessive_outputsr%   r0   	mask_listrB   r-   r|   r}   r`   ry   flat_statesflat_new_statesflat_final_stateslast_outputoutputsinput_time_zerooutput_time_zeror   	output_tar)   max_iterationswhile_loop_kwargsmax_lenr   final_outputsr   )r   rb   r   r   r$   r   rh   r   r.   r   rS   rV   rJ   r/   r   re   r   rD   r   r   rnn   sF  I





















0

r   c              
   C   s   t |||
|d u|d}|stddlm} t||r|j}t||r%|j}t||r-|j}zt| |||||||	|	W S  tjj	yE   t tjj
yO   tw )N)use_biasreset_afterr   Variable)cudnn_okNotImplementedErrorkeras.src.backend.tensorflowr   r   value
_cudnn_grur	   errorsInvalidArgumentErrorNotFoundError)r.   initial_stater   kernelrecurrent_kernelbias
activationrecurrent_activationreturn_sequencesr$   r   r   r   cudnn_supportedr   r   r   r   gru  sB   


r   c                 C   sN   ddl m} ddl m} | |jtj|jfv o&||jtj|jfv o&| o&|o&|S Nr   )activations)ops	keras.srcr   r   tanhr	   sigmoid)r   r   r   r   r   r   r   r   r   r   _do_gru_arguments_support_cudnn  s   r   c                 C   sJ   ddl m} ddl m} | |jtj|jfv o$||jtj|jfv o$| o$|S r   r   )r   r   r   r   r   r   r   r   r    _do_lstm_arguments_support_cudnn  s   r   c              	   C   s$   t t jt t j| ddddS )Nr   r>   r   r   )r	   
reduce_any
reduce_alllogical_notr   )r   r   r   r   _has_fully_masked_sequence  s   r   c                 C   s,   t t t| t| }t |dg d S )Na  You are passing a RNN mask that does not correspond to right-padded sequences, while using cuDNN, which is not supported. With cuDNN, RNN masks can only be used for right-padding, e.g. `[[True, True, False, False]]` would be a valid mask, but any mask that isn't just contiguous `True`'s on the left and contiguous `False`'s on the right would be invalid. You can pass `use_cudnn=False` to your RNN layer to stop using cuDNN (this may be slower).)r	   logical_andr   r   _is_sequence_right_paddedAssert)r   validr   r   r   _assert_valid_mask(  s   r   c                    sD   fdd  fdd| D } fdd|D }t j| | ddS )a  Utility function convert variable to cuDNN compatible parameter.

    Note that Keras weights for kernels are different from the cuDNN format.
    Eg.:

    ```
      Keras                 cuDNN
      [[0, 1, 2],  <--->  [[0, 2, 4],
       [3, 4, 5]]          [1, 3, 5]]
    ```

    If the input weights need to be in a unified format, then set
    `transpose_weights=True` to convert the weights.

    Args:
        weights: list of weights for the kernels and recurrent kernels.
        biases: list of biases for individual gate.
        shape: the shape for the converted variables that will be feed to cuDNN.
        transpose_weights: boolean, whether to transpose the weights.

    Returns:
        The converted weights that can be feed to cuDNN ops as param.
    c                    s    rt | S | S r    )r	   r
   )w)transpose_weightsr   r   convertW  s   z+_standardize_cudnn_weights.<locals>.convertc                    s   g | ]
}t  |qS r   r	   reshaper&   x)r   r   r   r   r*   Z  s    z._standardize_cudnn_weights.<locals>.<listcomp>c                    s   g | ]}t | qS r   r   r   )r   r   r   r*   [  s    r   r   )r	   concatweightsbiasesr   r   r   )r   r   r   r   _standardize_cudnn_weights>  s   r   c              	   C   sZ   t | d }t jt | t jdd}t j||d}t t t j| ddt j|ddS )aJ  Check the mask tensor and see if it right padded.

    cuDNN uses the sequence length param to skip the tailing
    timestep. If the data is left padded, or not a strict right padding (has
    masked value in the middle of the sequence), then cuDNN won't work
    properly in those cases.

    Left padded data: [[False, False, True, True, True]].
    Right padded data: [[True, True, True, False, False]].
    Mixture of mask/unmasked data: [[True, False, True, False, False]].

    Note that for the mixed data example above, the actually data RNN should see
    are those 2 Trues (index 0 and 2), the index 1 False should be ignored and
    not pollute the internal states.

    Args:
        mask: the Boolean tensor with shape [batch, timestep]

    Returns:
        boolean scalar tensor, whether the mask is strictly right padded.
    r   r   )maxlenr   r   )r	   r   
reduce_sumr   rK   sequence_maskr   equal)r   max_seq_lengthcount_of_trueright_padded_maskr   r   r   r   _  s   r   c                 C   s$   |rdnd}t jt | t j|dS )a^  Calculate the sequence length tensor (1-D) based on the masking tensor.

    The masking tensor is a 2D boolean tensor with shape [batch, timestep]. For
    any timestep that should be masked, the corresponding field will be False.
    Consider the following example:
      a = [[True, True, False, False],
           [True, True, True, False]]
    It is a (2, 4) tensor, and the corresponding sequence length result should
    be 1D tensor with value [2, 3]. Note that the masking tensor must be right
    padded that could be checked by, e.g., `is_sequence_right_padded()`.

    Args:
        mask: Boolean tensor with shape [batch, timestep] or [timestep, batch]
            if time_major=True.
        time_major: Boolean, which indicates whether the mask is time major or
            batch major.

    Returns:
        sequence_length: 1D int32 tensor.
    r   r   r   )r	   r   r   rK   )r   r   timestep_indexr   r   r   "_compute_sequence_length_from_mask  s   r   c                   C   s   t tjdS )NGPU)r   r	   configlist_logical_devicesr   r   r   r   _is_gpu_available  s   r   c	              
   C   sD  |durt | t||}	n&|rt| d }
t| d }nt| d }
t| d }t|
g|}	|sF|	du rFtj| dd} d\}}n|rJdnd\}}tj||d}tj|d	dd}|tj|d	dd7 }tt|d
gd}tj	
 d r|d |d |d< |d< |d |d	 |d	< |d< |d |d |d< |d< |d |d	 |d	< |d< t||td
gdd}|rtj| |	||d} tjj| |d|dd|	|d\}}}}}|rtj||	||d}tj||gd}|d
 }|s|	du r|rtj|g dd}tj||d}|	dur|}|stj||rdndd}|||gfS )z>GRU with cuDNN implementation which is only available for GPU.Nr   r   r   r   r   permr   r   r   r   r   r      is_cuda_build   Tr   seq_axis
batch_axisr   inputinput_hinput_cparamsis_trainingrnn_modesequence_lengthsr   )r   r   r	   r   fillr
   r   splitr   	sysconfigget_build_infor   r   reverse_sequenceraw_ops
CudnnRNNV3r"   squeeze)r.   r   r   r   r   r   r   r$   r   r  	batch_dimmax_sequence_lengthr   r   init_hr   r  r   hr   r   stater   r   r   r     s   



r   c                 C   s6   |d u rt | |||d}n	t| ||||d}|ot S )N)r   r   r   r   )r   r   r   r   r   )r   r   r   )r   r   r   r   r   args_supportedr   r   r   r     s   
r   c                 C   s   t ||||d ud}|stddlm} t||r|j}t||r$|j}t||r,|j}zt| ||||||||
|	
W S  tjj	yE   t tjj
yO   tw )N)r   r   r   )r   r   r   r   r   r   _cudnn_lstmr	   r   r   r   )r.   initial_state_hinitial_state_cr   r   r   r   r   r   r   r$   r   r   r   r   r   r   r   lstm*  s<   


r  c
              
      s6  |d urt | t||}
n&|rt| d }t| d }nt| d }t| d }t|g|}
|sF|
d u rFtj| dd} d\}}n|rJdnd\}}tj||d}tj||d}tj|dddtj|ddd7 tt	||fd tj
 d	 rfd
ddD tj ddd  fdddD  tt dtdgdd}|rtj| |
||d} tjj| |||dd|
|d\}}}}}|rtj||
||d}tj||gd}|d }|s|
d u r|	rtj|g dd}tj||d}tj||d}|
d ur|}|	stj||rdndd}||||gfS )Nr   r   r   r   r   r   r   r   is_rocm_buildc                       g | ]} | qS r   r   r   )r   r   r   r*     r+   z_cudnn_lstm.<locals>.<listcomp>)r   r   r   r   r         r      c                    r  r   r   r   )	full_biasr   r   r*     r+   r   Tr   r   r  r   )r   r   r	   r   r  r
   r   r  r   rj   r  r  r   r   r	  r
  r  r"   r  )r.   r  r  r   r   r   r   r   r$   r   r  r  r  r   r   r  init_cr  r   r  cr   r   r   )r  r   r   r  ]  s~   




r  )FNNFNFFT)FFFFT)Fr    )FFFF)
tensorflowr	   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r   r   r   <module>   sJ    
   G
6
!!y
#
3