o
    Gi%                     @   sN   d dl mZ d dlZd dlZddlmZ G dd deZdedefd	d
ZdS )    )UnionN   )Fsac                	       s   e Zd Z	ddejdejdeddfddZedejfd	d
Ze	de
jdejdd f fddZdefddZdefddZedejfddZdefddZdefddZdeejef dd fddZ  ZS )DenseFsaVecr   	log_probssupervision_segmentsallow_truncatereturnNc                 C   s>  |j dksJ |jtjksJ |j dksJ |jtjksJ |jjdks&J |dks,J |j\}}}tdg}g }g }	d}
|	 D ]_}|\}}}d|  krT|k sWJ  J d|  krb|k seJ  J |dkskJ || || ksuJ || }t
|| |}|| }|t|||  || |
|7 }
|	|
 |
d7 }
qB|j}t||}tj|
|d |j|d}|d|d||ddddf< td	|dddf< tjdgtd	g|  |d
||	< tj|dd dtjd}t|	d |dd< |dd |dd  d | _||}t||| _|| _dS )a  Construct a DenseFsaVec from neural net log-softmax outputs.

        Args:
          log_probs:
            A 3-D tensor of dtype `torch.float32` with shape `(N, T, C)`,
            where `N` is the number of sequences, `T` the maximum input
            length, and `C` the number of output classes.
          supervision_segments:
            A 2-D **CPU** tensor of dtype `torch.int32` with 3 columns.
            Each row contains information for a supervision segment. Column 0
            is the `sequence_index` indicating which sequence this segment
            comes from; column 1 specifies the `start_frame` of this segment
            within the sequence; column 2 contains the `duration` of this
            segment.

            Note:
              - `0 < start_frame + duration <= T + allow_truncate`
              - `0 <= start_frame < T`
              - `duration > 0`

            Caution:
              If the resulting dense fsa vec is used as an input to
              `k2.intersect_dense`, then the last column, i.e., the duration
              column, has to be sorted in **decreasing** order.
              That is, the first supervision_segment (the first row) has the
              largest duration.
              Otherwise, you don't need to sort the last column.

              `k2.intersect_dense` is often used in the training stage, so
              you should usually sort dense fsa vecs by its duration
              in training. `k2.intersect_dense_pruned` is usually used in the
              decoding stage, so you don't need to sort dense fsa vecs in
              decoding.
          allow_truncate:
            If not zero, it truncates at most this number of frames from
            duration in case start_frame + duration > T.
              cpur   r   )dtypedeviceNz-inf)r   )r   r   )ndimr   torchfloat32int32r   typeshapetensortolistminappendarangecattoemptyreshapeindex_selectfloatzerossize	_duration_k2r   dense_fsa_vecscores)selfr   r   r   NTCplaceholderindexeslast_frame_indexescursegmentsegment_indexstart_framedurationoffset	end_framer   r&   
row_splits r6   D/home/ubuntu/.local/lib/python3.10/site-packages/k2/dense_fsa_vec.py__init__+   sT   )



$


zDenseFsaVec.__init__c                 C   sF   t | ds | j d}|dd |dd  d }| | _| jS )z2Return the duration (on CPU) of each seq.
        r#   r   Nr   )hasattrr%   r   r5   r   r#   )r'   r5   r2   r6   r6   r7   r2      s
   

zDenseFsaVec.durationr%   r&   c                    s(   |  | }tt|  ||_||_|S )aj  Construct a DenseFsaVec from `_k2.DenseFsaVec` and `scores`.

        Note:
          It is intended for internal use. Users will normally not use it.

        Args:
          dense_fsa_vec: An instance of `_k2.DenseFsaVec`.
          scores: The `scores` of `_k2.DenseFsaVec` for back propagation.

        Return:
          An instance of DenseFsaVec.
        )__new__superr   r8   r%   r&   )clsr%   r&   ans	__class__r6   r7   _from_dense_fsa_vec   s
   
zDenseFsaVec._from_dense_fsa_vecc                 C   
   | j  S )z&Return number of supervision segments.)r%   dim0r'   r6   r6   r7   rB      s   
zDenseFsaVec.dim0c                 C   rA   N)r%   to_strrC   r6   r6   r7   __str__   s   
zDenseFsaVec.__str__c                 C   s   | j jS rD   )r&   r   rC   r6   r6   r7   r      s   zDenseFsaVec.devicec                 C      | j jdkS )zReturn true if this DenseFsaVec is on CPU.

        Returns:
          True if the DenseFsaVec is on CPU; False otherwise.
        r   r   r   rC   r6   r6   r7   is_cpu      zDenseFsaVec.is_cpuc                 C   rG   )zReturn true if this DenseFsaVec is on GPU.

        Returns:
          True if the DenseFsaVec is on GPU; False otherwise.
        cudarH   rC   r6   r6   r7   is_cuda   rJ   zDenseFsaVec.is_cudar   c                 C   sV   t |tr
t|}|jdv sJ || jjkr| S | j|}| j|}t	||S )a  Move the DenseFsaVec onto a given device.

        Args:
          device:
            An instance of `torch.device` or a string that can be used to
            construct a `torch.device`, e.g., 'cpu', 'cuda:0'.
            It supports only cpu and cuda devices.

        Returns:
          Returns a new DenseFsaVec which is this object copied to the given
          device (or this object itself, if the device was the same).
        )r   rK   )

isinstancestrr   r   r   r&   r   r%   r   r@   )r'   r   r&   r%   r6   r6   r7   r      s   

zDenseFsaVec.to)r   )__name__
__module____qualname__r   Tensorintr8   propertyr2   classmethodr$   r   r@   rB   rN   rF   r   boolrI   rL   r   r   __classcell__r6   r6   r>   r7   r      s4    
h
$r   r%   r	   c                 C   s   t | j}t|S )a   Convert a DenseFsaVec to an FsaVec.

    Caution:
      Intended for use in testing/debug mode only. This operation is NOT
      differentiable.

    Args:
      dense_fsa_vec:
        DenseFsaVec to convert.

    Returns:
      The converted FsaVec .
    )r$   convert_dense_to_fsa_vecr%   r   )r%   
ragged_arcr6   r6   r7   rX      s   rX   )	typingr   r   r$   fsar   objectr   rX   r6   r6   r6   r7   <module>   s    P