o
    i@                     @   s   d Z ddlZddlmZ ddlZddlZdd Zdd Zdd	d
Z	dddZ
dddZdd Zdd Zdd Zdededeeejf fddZdd ZdS )zNetwork related utility tools.    N)Dictc                 C   sN   t | tjjrt|  j}nt | tjr| j}n	tdt	|  |
|S )zSend tensor into the device of the module.

    Args:
        m (torch.nn.Module): Torch module.
        x (Tensor): Torch tensor.

    Returns:
        Tensor: Torch tensor located in the same place as torch module.

    z3Expected torch.nn.Module or torch.tensor, bot got: )
isinstancetorchnnModulenext
parametersdeviceTensor	TypeErrortypeto)mxr	    r   Z/home/ubuntu/.local/lib/python3.10/site-packages/espnet/nets/pytorch_backend/nets_utils.py	to_device   s   
r   c                 C   sx   t | }tdd | D }| d j||g| d  dd R  |}t|D ]}| | ||d| | df< q(|S )a  Perform padding for the list of tensors.

    Args:
        xs (List): List of Tensors [(T_1, `*`), (T_2, `*`), ..., (T_B, `*`)].
        pad_value (float): Value for padding.

    Returns:
        Tensor: Padded tensor (B, Tmax, `*`).

    Examples:
        >>> x = [torch.ones(4), torch.ones(2), torch.ones(1)]
        >>> x
        [tensor([1., 1., 1., 1.]), tensor([1., 1.]), tensor([1.])]
        >>> pad_list(x, 0)
        tensor([[1., 1., 1., 1.],
                [1., 1., 0., 0.],
                [1., 0., 0., 0.]])

    c                 s   s    | ]}| d V  qdS r   N)size.0r   r   r   r   	<genexpr>7   s    zpad_list.<locals>.<genexpr>r      N)lenmaxnewr   fill_range)xs	pad_valuen_batchmax_lenpadir   r   r   pad_list"   s   . r$   c           
         s2   dkrt d t| ts|   } tt| }|du r1|du r+tt| }n|	 }n|du s7J |tt| ksAJ t
jd|t
jd}|d||}|| d}||k}|dur|	d|kssJ |	d|f dk r}|    t fddt| D }	||	 ||j}|S )a  Make mask tensor containing indices of padded part.

    Args:
        lengths (LongTensor or List): Batch of lengths (B,).
        xs (Tensor, optional): The reference tensor.
            If set, masks will be the same shape as this tensor.
        length_dim (int, optional): Dimension indicator of the above tensor.
            See the example.

    Returns:
        Tensor: Mask tensor containing indices of padded part.
                dtype=torch.uint8 in PyTorch 1.2-
                dtype=torch.bool in PyTorch 1.2+ (including 1.2)

    Examples:
        With only lengths.

        >>> lengths = [5, 3, 2]
        >>> make_pad_mask(lengths)
        masks = [[0, 0, 0, 0 ,0],
                 [0, 0, 0, 1, 1],
                 [0, 0, 1, 1, 1]]

        With the reference tensor.

        >>> xs = torch.zeros((3, 2, 4))
        >>> make_pad_mask(lengths, xs)
        tensor([[[0, 0, 0, 0],
                 [0, 0, 0, 0]],
                [[0, 0, 0, 1],
                 [0, 0, 0, 1]],
                [[0, 0, 1, 1],
                 [0, 0, 1, 1]]], dtype=torch.uint8)
        >>> xs = torch.zeros((3, 2, 6))
        >>> make_pad_mask(lengths, xs)
        tensor([[[0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1]],
                [[0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1]],
                [[0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1]]], dtype=torch.uint8)

        With the reference tensor and dimension indicator.

        >>> xs = torch.zeros((3, 6, 6))
        >>> make_pad_mask(lengths, xs, 1)
        tensor([[[0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [1, 1, 1, 1, 1, 1]],
                [[0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1]],
                [[0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1]]], dtype=torch.uint8)
        >>> make_pad_mask(lengths, xs, 2)
        tensor([[[0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1],
                 [0, 0, 0, 0, 0, 1]],
                [[0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1],
                 [0, 0, 0, 1, 1, 1]],
                [[0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1],
                 [0, 0, 1, 1, 1, 1]]], dtype=torch.uint8)

    r   zlength_dim cannot be 0: {}Ndtyper%   c                 3   s(    | ]}|d  fv rt dndV  qdS r   )slice)r   r#   
length_dimr   r   r      s    
z make_pad_mask.<locals>.<genexpr>)
ValueErrorformatr   listlongtolistintr   r   r   r   arangeint64	unsqueezeexpandr   dimtupler   	expand_asr   r	   )
lengthsr   r*   maxlenbs	seq_rangeseq_range_expandseq_length_expandmaskindr   r)   r   make_pad_mask@   s0   V
 
r@   c                 C   s   t | || S )a  Make mask tensor containing indices of non-padded part.

    Args:
        lengths (LongTensor or List): Batch of lengths (B,).
        xs (Tensor, optional): The reference tensor.
            If set, masks will be the same shape as this tensor.
        length_dim (int, optional): Dimension indicator of the above tensor.
            See the example.

    Returns:
        ByteTensor: mask tensor containing indices of padded part.
                    dtype=torch.uint8 in PyTorch 1.2-
                    dtype=torch.bool in PyTorch 1.2+ (including 1.2)

    Examples:
        With only lengths.

        >>> lengths = [5, 3, 2]
        >>> make_non_pad_mask(lengths)
        masks = [[1, 1, 1, 1 ,1],
                 [1, 1, 1, 0, 0],
                 [1, 1, 0, 0, 0]]

        With the reference tensor.

        >>> xs = torch.zeros((3, 2, 4))
        >>> make_non_pad_mask(lengths, xs)
        tensor([[[1, 1, 1, 1],
                 [1, 1, 1, 1]],
                [[1, 1, 1, 0],
                 [1, 1, 1, 0]],
                [[1, 1, 0, 0],
                 [1, 1, 0, 0]]], dtype=torch.uint8)
        >>> xs = torch.zeros((3, 2, 6))
        >>> make_non_pad_mask(lengths, xs)
        tensor([[[1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0]],
                [[1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0]],
                [[1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0]]], dtype=torch.uint8)

        With the reference tensor and dimension indicator.

        >>> xs = torch.zeros((3, 6, 6))
        >>> make_non_pad_mask(lengths, xs, 1)
        tensor([[[1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [0, 0, 0, 0, 0, 0]],
                [[1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0]],
                [[1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 1],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0]]], dtype=torch.uint8)
        >>> make_non_pad_mask(lengths, xs, 2)
        tensor([[[1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0],
                 [1, 1, 1, 1, 1, 0]],
                [[1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0],
                 [1, 1, 1, 0, 0, 0]],
                [[1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0],
                 [1, 1, 0, 0, 0, 0]]], dtype=torch.uint8)

    )r@   )r8   r   r*   r   r   r   make_non_pad_mask   s   VrA   c                 C   s^   |  dt|ksJ | jj|    |}t|D ]\}}| |d|f ||d|f< q|S )a}  Mask tensor according to length.

    Args:
        xs (Tensor): Batch of input tensor (B, `*`).
        lengths (LongTensor or List): Batch of lengths (B,).
        fill (int or float): Value to fill masked part.

    Returns:
        Tensor: Batch of masked input tensor (B, `*`).

    Examples:
        >>> x = torch.arange(5).repeat(3, 1) + 1
        >>> x
        tensor([[1, 2, 3, 4, 5],
                [1, 2, 3, 4, 5],
                [1, 2, 3, 4, 5]])
        >>> lengths = [5, 3, 2]
        >>> mask_by_length(x, lengths)
        tensor([[1, 2, 3, 4, 5],
                [1, 2, 3, 0, 0],
                [1, 2, 0, 0, 0]])

    r   N)r   r   datar   r   	enumerate)r   r8   fillretr#   lr   r   r   mask_by_length  s
   rG   c                 C   sb   |  |d|d| dd}||k}t||||k}t|}t|t| S )a  Calculate accuracy.

    Args:
        pad_outputs (Tensor): Prediction tensors (B * Lmax, D).
        pad_targets (LongTensor): Target label tensors (B, Lmax, D).
        ignore_label (int): Ignore label id.

    Returns:
        float: Accuracy value (0.0 - 1.0).

    r   r      )viewr   argmaxr   summasked_selectfloat)pad_outputspad_targetsignore_labelpad_predr>   	numeratordenominatorr   r   r   th_accuracy0  s   
rT   c                 C   s   t | tjr| jjdkrddlm} || S t| S t | t	r@ddlm} d| vs.d| vr7t
dt| || d | d S t | tjrH| S dt| }zddlm} W n tyb   t
|w t | |rj| S t
|)a{  Change to torch.Tensor or ComplexTensor from numpy.ndarray.

    Args:
        x: Inputs. It should be one of numpy.ndarray, Tensor, ComplexTensor, and dict.

    Returns:
        Tensor or ComplexTensor: Type converted inputs.

    Examples:
        >>> xs = np.ones(3, dtype=np.float32)
        >>> xs = to_torch_tensor(xs)
        tensor([1., 1., 1.])
        >>> xs = torch.ones(3, 4, 5)
        >>> assert to_torch_tensor(xs) is xs
        >>> xs = {'real': xs, 'imag': xs}
        >>> to_torch_tensor(xs)
        ComplexTensor(
        Real:
        tensor([1., 1., 1.])
        Imag;
        tensor([1., 1., 1.])
        )

    cr   )ComplexTensorrealimagzhas 'real' and 'imag' keys: {}zox must be numpy.ndarray, torch.Tensor or a dict like {{'real': torch.Tensor, 'imag': torch.Tensor}}, but got {})r   npndarrayr'   kindtorch_complex.tensorrV   r   
from_numpydictr+   r,   r-   r
   r   	Exception)r   rV   errorr   r   r   to_torch_tensorG  s.   



ra   c                 C   s  |dkr
t dgS |dkr3|dkr3t j| jd t jd}td tddd	d
 |D   |S |dkr;|dv sK|dkrC|dksK|dkr|dkrt j| jd t jd}| j	
dr| j	ds| jd}tt| jd t|D ]
}t|| ||< qtntd tdddd
 |D   |S |dkr|dkrt j| j| j d t jd}| j	
dr| j	ds| jd}tt| j| j d t|D ]
}t|| ||< qntd tdddd
 |D   |S |dkrd|dkrdg }t| jD ]a}t j| j| d t jd}| j	| 
drD| j	| dsD| j| d}tt| j| d t|D ]}t|| ||< q7ntd|d  tdddd
 |D   || q |S td||)a\  Parse the subsampling factors from the args for the specified `mode` and `arch`.

    Args:
        train_args: argument Namespace containing options.
        mode: one of ('asr', 'mt', 'st')
        arch: one of ('rnn', 'rnn-t', 'rnn_mix', 'rnn_mulenc', 'transformer')

    Returns:
        np.ndarray / List[np.ndarray]: subsampling factors.
    transformerr   mtrnnr&   z5Subsampling is not performed for machine translation.zsubsample:  c                 S      g | ]}t |qS r   strr   r   r   r   
<listcomp>      z!get_subsample.<locals>.<listcomp>asr)rd   zrnn-tstpvgg_zTSubsampling is not performed for vgg*. It is performed in max pooling layers at CNN.c                 S   rf   r   rg   r   r   r   r   ri     rj   rnn_mixc                 S   rf   r   rg   r   r   r   r   ri     rj   
rnn_mulencz`Encoder %d: Subsampling is not performed for vgg*. It is performed in max pooling layers at CNN.c                 S   rf   r   rg   r   r   r   r   ri     rj   z!Invalid options: mode={}, arch={})rY   arrayoneselayersr2   loggingwarninginfojoinetypeendswith
startswith	subsamplesplitr   minr   r0   
elayers_sdnum_encsappendr+   r,   )
train_argsmodearchr|   ssjsubsample_listidxr   r   r   get_subsample  st   
 r   
old_prefix
new_prefix
state_dictc                    s`    fdd|D }t |dkrtd  d|  |D ]}||}| |}|||< qdS )z9Replace keys of old prefix with new prefix in state dict.c                    s   g | ]	}|  r|qS r   )r{   )r   kr   r   r   ri     s    z%rename_state_dict.<locals>.<listcomp>r   zRename: z -> N)r   ru   rv   popreplace)r   r   r   old_keysr   vnew_kr   r   r   rename_state_dict  s   

r   c                 C   s6   ddl m} tjjtjjtjjtjj|d}||   S )zReturn activation function.r   )Swish)hardtanhtanhreluseluswish)+espnet.nets.pytorch_backend.conformer.swishr   r   r   HardtanhTanhReLUSELU)actr   activation_funcsr   r   r   get_activation  s   
r   )Nr%   N)Nr%   )r   )__doc__ru   typingr   numpyrY   r   r   r$   r@   rA   rG   rT   ra   r   rh   r
   r   r   r   r   r   r   <module>   s*   

x
YDQ
