o
    }oi                     @   sb   d dl mZ d dlZd dlm  mZ d dlmZ ddgZG dd dejZ	G dd dej
ZdS )    )UnionN)nnCausalConv2DCausalConv1Dc                       sp   e Zd ZdZ								ddeded	ed
edeeef dededededdf fddZ fddZ	  Z
S )r   z
    A causal version of nn.Conv2d where each location in the 2D matrix would have no access to locations on its right or down
    All arguments are the same as nn.Conv2d except padding which should be set as None
       r   TzerosNin_channelsout_channelskernel_sizestridepaddingdilationgroupsbiaspadding_modereturnc                    sP   |d urt d|d | _|d | _d}tt| |||||||||	|
| d S )Nz8Argument padding should be set to None for CausalConv2D.r   r   )
ValueError_left_padding_right_paddingsuperr   __init__selfr   r	   r
   r   r   r   r   r   r   devicedtype	__class__ f/home/ubuntu/.local/lib/python3.10/site-packages/nemo/collections/asr/parts/submodules/causal_convs.pyr      s$   


zCausalConv2D.__init__c                    s.   t j|| j| j| j| jfd}t |}|S )Npad)Fr    r   r   r   forward)r   xr   r   r   r"   @   s   zCausalConv2D.forwardr   r   r   r   Tr   NN)__name__
__module____qualname____doc__intr   strboolr   r"   __classcell__r   r   r   r   r      s@    

	
"c                       s|   e Zd ZdZ								ddeded	ed
edeeef dededededdf fddZdddZ	d fdd	Z
  ZS )r   a  
    A causal version of nn.Conv1d where each step would have limited access to locations on its right or left
    All arguments are the same as nn.Conv1d except padding.

    If padding is set None, then paddings are set automatically to make it a causal convolution where each location would not see any steps on its right.

    If padding is set as a list (size of 2), then padding[0] would be used as left padding and padding[1] as right padding.
    It would make it possible to control the number of steps to be accessible on the right and left.
    This mode is not supported when stride > 1. padding[0]+padding[1] should be equal to (kernel_size - 1).
    r   r   Tr   Nr   r	   r
   r   r   r   r   r   r   r   c                    s   d | _ |d u r|d | _|d | _nD|dkr ||d kr tdt|tr,|| _|| _n*t|trNt|dkrN|d |d  |d krN|d | _|d | _ntd| d| j| _t	t
| j||||d||||	|
|d d S )Nr   z3No striding allowed for non-symmetric convolutions!   r   zInvalid padding param: !)r   r	   r
   r   r   r   r   r   r   r   r   )cache_drop_sizer   r   r   
isinstancer)   listlen_max_cache_lenr   r   r   r   r   r   r   r   T   s6   

.


zCausalConv1D.__init__c                 C   s   |d u rt j|| j| jfd}|}||fS t j|d| jfd}tj||gdd}| jdkr=|d d d d d | j f }n|}|d d d d |d d f }||fS )Nr   r   )dim)r!   r    r   r   torchcatr/   size)r   r#   cachenew_x
next_cacher   r   r   update_cache   s   	
 "zCausalConv1D.update_cachec                    s2   | j ||d\}}t |}|d u r|S ||fS )N)r9   )r<   r   r"   )r   r#   r9   r   r   r   r"      s
   zCausalConv1D.forwardr$   )N)r%   r&   r'   r(   r)   r   r*   r+   r   r<   r"   r,   r   r   r   r   r   H   sB    
	

.)typingr   r6   torch.nn.functionalr   
functionalr!   __all__Conv2dr   Conv1dr   r   r   r   r   <module>   s   0