o
    ih!                     @   s   d dl Z d dlZd dlZd dl mZmZmZmZ d dlmZ d dl	m
Z
 	 G dd dejZG dd dejZdd	d
ZG dd dejZdS )    N)cudafunction_nodelinkvariable)normal)
type_checkc                   @   s.   e Zd Zd
ddZdd Zdd Zdd	 ZdS )EmbedIDFunctionNc                 C   s   || _ d | _d S N)ignore_label_w_shape)selfr
    r   f/home/ubuntu/.local/lib/python3.10/site-packages/espnet/nets/chainer_backend/deterministic_embed_id.py__init__   s   
zEmbedIDFunction.__init__c                 C   sR   t | dk |\}}t |jjdk|jdk t |jtjk|jdk d S )N   i   )r   expectsizedtypekindndimnumpyfloat32)r   in_typesx_typew_typer   r   r   check_type_forward   s   
z"EmbedIDFunction.check_type_forwardc              
   C   s   |  d |\}}|j| _tj| stdt|t|tj	| }t
 rI|d|k|t|k }| jd urA|||| jk}| sItd| jd urd|| jk}||d d|||d| fS || fS )Nr   zCnumpy and cupy must not be used together
type(W): {0}, type(x): {1}r   z;Each not ignored `x` value need to satisfy`0 <= x < len(W)`.N)retain_inputsshaper   r   
same_types
ValueErrorformattyper   get_array_modulechaineris_debuglogical_andlenr
   
logical_orallwhere)r   inputsxWxpvalid_xmaskr   r   r   forward    s*   





"
zEmbedIDFunction.forwardc                 C   s,   |   }t| j| j|| d }d |fS )Nr   )get_retained_inputsEmbedIDGradr   r
   apply)r   indexesgrad_outputsr.   gWr   r   r   backward;   s
   zEmbedIDFunction.backwardr	   )__name__
__module____qualname__r   r   r4   r;   r   r   r   r   r      s
    
	r   c                   @   s&   e Zd ZdddZdd Zdd ZdS )	r6   Nc                 C   s   || _ || _d | _d S r	   )w_shaper
   	_gy_shape)r   r?   r
   r   r   r   r   D   s   
zEmbedIDGrad.__init__c           
      C   s  |  d tj| }|\}}|j| _|j| j|jd}|tu rCt	j
| ||jdD ]\}}|| jkr7q-||  |7  < q-|fS 	 |j|jt|ftjd}|j|jtjdt| |  }	d| |	< | jd urvd|d d | jf< |j||jdj|jdd}|fS )Nr   )r         ?g        F)copy)r    r   r&   r!   r@   zerosr?   r   r   sixmoveszipravelreshaper   r
   r*   r   arangeint32Tdotastype)
r   r.   r1   r/   gyr:   ixigyxiidxr   r   r   r4   I   s&   

$
!"
"zEmbedIDGrad.forwardc           
      C   s   t j| }|  d j}|d }| jd ur0|| jk}d| j  kr(| jd k s0n ||d|}|| }| jd urR||d |dd|j\}}}	t	j
|||}d |fS )Nr   r   r   r   f)r   r&   r5   datar
   r?   r-   broadcast_arraysrD   r'   	functions)
r   r8   gradsr1   r/   ggWr3   ggyzero_r   r   r   r;   y   s   




zEmbedIDGrad.backwardr	   )r<   r=   r>   r   r4   r;   r   r   r   r   r6   C   s    
0r6   c                 C   s   t |d| |fd S )a  Efficient linear function for one-hot input.

    This function implements so called *word embeddings*. It takes two
    arguments: a set of IDs (words) ``x`` in :math:`B` dimensional integer
    vector, and a set of all ID (word) embeddings ``W`` in :math:`V \\times d`
    float32 matrix. It outputs :math:`B \\times d` matrix whose ``i``-th
    column is the ``x[i]``-th column of ``W``.
    This function is only differentiable on the input ``W``.

    Args:
        x (chainer.Variable | np.ndarray): Batch vectors of IDs. Each
            element must be signed integer.
        W (chainer.Variable | np.ndarray): Distributed representation
            of each ID (a.k.a. word embeddings).
        ignore_label (int): If ignore_label is an int value, i-th column
            of return value is filled with 0.

    Returns:
        chainer.Variable: Embedded variable.


    .. rubric:: :class:`~chainer.links.EmbedID`

    Examples:

        >>> x = np.array([2, 1]).astype('i')
        >>> x
        array([2, 1], dtype=int32)
        >>> W = np.array([[0, 0, 0],
        ...               [1, 1, 1],
        ...               [2, 2, 2]]).astype('f')
        >>> W
        array([[ 0.,  0.,  0.],
               [ 1.,  1.,  1.],
               [ 2.,  2.,  2.]], dtype=float32)
        >>> F.embed_id(x, W).data
        array([[ 2.,  2.,  2.],
               [ 1.,  1.,  1.]], dtype=float32)
        >>> F.embed_id(x, W, ignore_label=1).data
        array([[ 2.,  2.,  2.],
               [ 0.,  0.,  0.]], dtype=float32)

    r
   r   )r   r7   )r/   r0   r
   r   r   r   embed_id   s   ,r^   c                       s.   e Zd ZdZdZd fdd	Zdd Z  ZS )EmbedIDa  Efficient linear layer for one-hot input.

    This is a link that wraps the :func:`~chainer.functions.embed_id` function.
    This link holds the ID (word) embedding matrix ``W`` as a parameter.

    Args:
        in_size (int): Number of different identifiers (a.k.a. vocabulary size).
        out_size (int): Output dimension.
        initialW (Initializer): Initializer to initialize the weight.
        ignore_label (int): If `ignore_label` is an int value, i-th column of
            return value is filled with 0.

    .. rubric:: :func:`~chainer.functions.embed_id`

    Attributes:
        W (~chainer.Variable): Embedding parameter matrix.

    Examples:

        >>> W = np.array([[0, 0, 0],
        ...               [1, 1, 1],
        ...               [2, 2, 2]]).astype('f')
        >>> W
        array([[ 0.,  0.,  0.],
               [ 1.,  1.,  1.],
               [ 2.,  2.,  2.]], dtype=float32)
        >>> l = L.EmbedID(W.shape[0], W.shape[1], initialW=W)
        >>> x = np.array([2, 1]).astype('i')
        >>> x
        array([2, 1], dtype=int32)
        >>> y = l(x)
        >>> y.data
        array([[ 2.,  2.,  2.],
               [ 1.,  1.,  1.]], dtype=float32)

    Nc                    sf   t t|   || _|   |d u rtd}t|||f| _	W d    d S 1 s,w   Y  d S )NrB   )
superr_   r   r
   
init_scoper   Normalr   	Parameterr0   )r   in_sizeout_sizeinitialWr
   	__class__r   r   r      s   

"zEmbedID.__init__c                 C   s   t || j| jdS )zExtracts the word embedding of given IDs.

        Args:
            x (chainer.Variable): Batch vectors of IDs.

        Returns:
            chainer.Variable: Batch of corresponding embeddings.

        r]   )r^   r0   r
   )r   r/   r   r   r   __call__   s   
zEmbedID.__call__)NN)r<   r=   r>   __doc__r
   r   ri   __classcell__r   r   rg   r   r_      s
    %	r_   r	   )r'   r   rE   r   r   r   r   chainer.initializersr   chainer.utilsr   FunctionNoder   r6   r^   Linkr_   r   r   r   r   <module>   s    1
L/