
    VhP                        d Z ddlmZ ddlZ	 ddlmZ n# e$ r dZY nw xY wddlm	Z
 ddlmZmZ ddlmZ dej        fd	Zdej        fd
Zdej        defdZdej        defdZeeZeZneZeZdej        dej        fdZ	 	 ddej        dej        deej                 dededefdZ G d dej        j                  ZdS )ab  
Implementation of a FFT based 1D convolution in PyTorch.
While FFT is used in CUDNN for small kernel sizes, it is not the case for long ones, e.g. 512.
This module implements efficient FFT based convolutions for such convolutions. A typical
application is for evaluationg FIR filters with a long receptive field, typically
evaluated with a stride of 1.
    )OptionalN)
functional   )pad_tounfold)simple_reprxc                 V    t          j        | d          }t          j        |          S Ndim)new_fftrffttorchview_as_real)r	   zs     T/var/www/html/movieo_spanner_bot/venv/lib/python3.11/site-packages/julius/fftconv.py	_new_rfftr      s'    QBAa       c                 ,    t          j        | d          S )Nr   )r   r   )r	   s    r   	_old_rfftr      s    :ar   lengthc                 6    t          j        | d|f          }|S )Nr   )signal_sizes)r   irfft)r	   r   results      r   
_old_irfftr   "   s    [AVI666FMr   c                 X    t          j        |           } t          j        | |d          S r   )r   view_as_complexr   r   )r	   r   s     r   
_new_irfftr!   '   s)    a  A=F++++r   abc           
      B   d}t          j        t          j        || d         |d                   t          j        || d         |d                   z   t          j        || d         |d                   t          j        || d         |d                   z
  gd          S )z
    Given a and b two tensors of dimension 4
    with the last dimension being the real and imaginary part,
    returns a multiplied by the conjugate of b, the multiplication
    being with respect to the second dimension.

    zbcft,dct->bdft).r   ).r   r   r   )r   stackeinsum)r"   r#   ops      r   _compl_mul_conjugater(   4   s     
B;R6AfI..b!F)QvY1W1WWR6AfI..b!F)QvY1W1WW 	   r      inputweightbiasstridepaddingblock_ratioc                    t          j        | ||f          } | j        \  }}}|j        \  }	}
}||k     rt          d| d| d          |dk     rt          d          t	          t          ||z            |          }||z
  dz   }t          ||          }t          |          }t          | ||          }t          |          }t          ||          }t          ||          }|dd| dz   f         }|                    ||	d          }|ddd|f         }||z
  |z  dz   }|dd|f         }|||dddf         z  }|S )	a  
    Same as `torch.nn.functional.conv1d` but using FFT for the convolution.
    Please check PyTorch documentation for more information.

    Args:
        input (Tensor): input signal of shape `[B, C, T]`.
        weight (Tensor): weight of the convolution `[D, C, K]` with `D` the number
            of output channels.
        bias (Tensor or None): if not None, bias term for the convolution.
        stride (int): stride of convolution.
        padding (int): padding to apply to the input.
        block_ratio (float): can be tuned for speed. The input is splitted in chunks
            with a size of `int(block_ratio * kernel_size)`.

    Shape:

        - Inputs: `input` is `[B, C, T]`, `weight` is `[D, C, K]` and bias is `[D]`.
        - Output: `(*, T)`


    ..note::
        This function is faster than `torch.nn.functional.conv1d` only in specific cases.
        Typically, the kernel size should be of the order of 256 to see any real gain,
        for a stride of 1.

    ..Warning::
        Dilation and groups are not supported at the moment. This function might use
        more memory than the default Conv1d implementation.
    z5Input should be at least as large as the kernel size z, but it is only z samples long.r   z#Block ratio must be greater than 1..Nr   )FpadshapeRuntimeErrorminintr   _rfftr   r(   _irfftreshape)r*   r+   r,   r-   r.   r/   batchchannelsr   out_channels_kernel_size
block_sizefold_strideweight_zframesframes_zout_zouttarget_lengths                       r   
fft_conv1drG   G   s   B E%'7+,,E#kE8V#)< L![ DS^ D D-3D D D E E 	EQ@AAA #kK788&AAJ{*Q.KFJ''FV}}H E:{33FV}}H 844E


#
#C
c$[L1$$$
%C
++e\2
.
.C
c88V8m
Ck)f4q8M
c>M>!
"CtAAAtG}Jr   c                   \     e Zd ZdZ	 ddedededed	ed
ef fdZdej        fdZ	d Z
 xZS )	FFTConv1da  
    Same as `torch.nn.Conv1d` but based on `fft_conv1d`.
    Please check PyTorch documentation for more information.

    Args:
        in_channels (int): number of input channels.
        out_channels (int): number of output channels.
        kernel_size (int): kernel size of convolution.
        stride (int): stride of convolution.
        padding (int): padding to apply to the input.
        bias (bool): if True, use a bias term.

    ..note::
        This module is faster than `torch.nn.Conv1d` only in specific cases.
        Typically, `kernel_size` should be of the order of 256 to see any real gain,
        for a stride of 1.

    ..warning::
        Dilation and groups are not supported at the moment. This module might use
        more memory than the default Conv1d implementation.

    >>> fftconv = FFTConv1d(12, 24, 128, 4)
    >>> x = torch.randn(4, 12, 1024)
    >>> print(list(fftconv(x).shape))
    [4, 24, 225]
    r   r   Tin_channelsr<   r>   r-   r.   r,   c                    t                                                       || _        || _        || _        || _        || _        t          j        	                    ||||          }|j
        | _
        |j        | _        d S )N)r,   )super__init__rJ   r<   r>   r-   r.   r   nnConv1dr+   r,   )	selfrJ   r<   r>   r-   r.   r,   conv	__class__s	           r   rM   zFFTConv1d.__init__   sp    &(&x{L+DQQkI			r   r*   c                 P    t          || j        | j        | j        | j                  S )N)rG   r+   r,   r-   r.   )rP   r*   s     r   forwardzFFTConv1d.forward   s*    4;	4;F F 	Fr   c                 6    t          | d| j        d ui          S )Nr,   )	overrides)r   r,   )rP   s    r   __repr__zFFTConv1d.__repr__   s!    4FDIT4I+JKKKKr   )r   r   T)__name__
__module____qualname____doc__r6   boolrM   r   TensorrT   rW   __classcell__)rR   s   @r   rI   rI      s         6 BF C s  +.:>     FU\ F F F FL L L L L L Lr   rI   )Nr   r   r)   )r[   typingr   r   	torch.fftfftr   ImportErrortorch.nnr   r1   corer   r   utilsr   r]   r   r   r6   r   r!   r7   r8   r(   floatrG   rN   ModulerI    r   r   <module>ri      s             GGG $ $ $ $ $ $                      ! ! ! ! !
    %,     
,%, , , , , ,
 ?EFFEFEL U\    * NO@ @|@%*\@u|$@58@GJ@ @ @ @ @F-L -L -L -L -L -L -L -L -L -Ls    