U
    f»{j®/  ã                   @   s²   d dl ZddlmZmZmZmZmZmZm	Z	m
Z
 daddd„Zed dd	„ƒZed!d
d„ƒZed"dd„ƒZd#dd„Zdd„ Zdd„ Zd$dd„Zd%dd„Ze	d&dd„ƒZd'dd„ZdS )(é    Né   )Ú
sizeof_fmtÚloggerÚ
get_configÚwarnÚ_explain_exceptionÚverboseÚfill_docÚ_check_optionFÚ	availablec                 C   s>   t stdƒ d}n$ddl}|jj ¡ tddd�|   }t|ƒS )a  Get the amount of free memory for CUDA operations.

    Parameters
    ----------
    kind : str
        Can be "available" or "total".

    Returns
    -------
    memory : str
        The amount of available or total memory as a human-readable string.
    z+CUDA not enabled, returning zero for memoryr   Nr   )r   Útotal)Ú_cuda_capabler   ÚcupyÚcudaÚruntimeZ
memGetInfoÚdictr   )ÚkindZmemr   © r   úG/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/cuda.pyÚget_cuda_memory   s    r   c                 C   s¶   t rdS | s,tddƒ ¡ dkr,t d¡ dS da zddl}W n tk
rZ   tdƒ Y dS X ttd	d
ƒƒ}zt	||ƒ W n$ t
k
rœ   tdtƒ  ƒ Y dS X da t dtƒ  ¡ dS )aP  Initialize CUDA functionality.

    This function attempts to load the necessary interfaces
    (hardware connectivity) to run CUDA-based filtering. This
    function should only need to be run once per session.

    If the config var (set via mne.set_config or in ENV)
    MNE_USE_CUDA == 'true', this function will be executed when
    the first CUDA setup is performed. If this variable is not
    set, this function can be manually executed.

    Parameters
    ----------
    ignore_config : bool
        If True, ignore the config value MNE_USE_CUDA and force init.
    %(verbose)s
    NÚMNE_USE_CUDAÚfalseÚtruez3CUDA not enabled in config, skipping initializationFr   z'module cupy not found, CUDA not enabledZMNE_CUDA_DEVICEÚ0zPso CUDA device could be initialized, likely a hardware error, CUDA not enabled%sTz&Enabling CUDA with %s available memory)r   r   Úlowerr   Úinfor   ÚImportErrorr   ÚintÚ_set_cuda_deviceÚ	Exceptionr   r   )Zignore_configr   r   Ú	device_idr   r   r   Ú	init_cuda$   s.    ÿ
ÿr!   c                 C   s@   t rt| |ƒ n,tddƒ ¡ dkr4tƒ  t| |ƒ ntdƒ dS )zÊSet the CUDA device temporarily for the current session.

    Parameters
    ----------
    device_id : int
        Numeric ID of the CUDA-capable device you want MNE-Python to use.
    %(verbose)s
    r   r   r   z�Could not set CUDA device because CUDA is not enabled; either run mne.cuda.init_cuda() first, or set the MNE_USE_CUDA config variable to "true".N)r   r   r   r   r!   r   )r    r   r   r   r   Úset_cuda_deviceS   s    
r"   c                 C   s,   ddl }|j | ¡ ¡  t d | ¡¡ dS )zSet the CUDA device.r   NzNow using CUDA device {})r   r   ZDeviceZuser   r   Úformat)r    r   r   r   r   r   r   h   s    r   úFFT FIR filteringc           
   
   C   sÎ   ddl m}m} t||||||d�d�}t| tƒrÆtd| dƒ d} tƒ  tr¼ddl	}z | 
|d	 ¡}t d
| ¡ W n4 tk
r¨ }	 zt dt|	ƒ ¡ W 5 d}	~	X Y nX |j|ttd� n
t d¡ | |fS )aa  Set up repeated CUDA FFT multiplication with a given filter.

    Parameters
    ----------
    n_jobs : int | str
        If n_jobs == 'cuda', the function will attempt to set up for CUDA
        FFT multiplication.
    h : array
        The filtering function that will be used repeatedly.
    n_fft : int
        The number of points in the FFT.
    kind : str
        The kind to report to the user.

    Returns
    -------
    n_jobs : int
        Sets n_jobs = 1 if n_jobs == 'cuda' was passed in, otherwise
        original n_jobs is passed.
    cuda_dict : dict
        Dictionary with the following CUDA-related variables:
            use_cuda : bool
                Whether CUDA should be used.
            fft_plan : instance of FFTPlan
                FFT plan to use in calculating the FFT.
            ifft_plan : instance of FFTPlan
                FFT plan to use in calculating the IFFT.
            x_fft : instance of gpuarray
                Empty allocated GPU space for storing the result of the
                frequency-domain multiplication.
            x : instance of gpuarray
                Empty allocated GPU space for the data to filter.
    h_fft : array | instance of gpuarray
        This will either be a gpuarray (if CUDA enabled) or ndarray.

    Notes
    -----
    This function is designed to be used with fft_multiply_repeated().
    r   ©ÚrfftÚirfft)Ún)Ún_fftr&   r'   Úh_fftÚn_jobs©r   r   Nr*   zUsing CUDA for %szhCUDA not used, could not instantiate memory (arrays may be too large: "%s"), falling back to n_jobs=None)r*   r&   r'   úICUDA not used, CUDA could not be initialized, falling back to n_jobs=None)Ú	scipy.fftr&   r'   r   Ú
isinstanceÚstrr
   r!   r   r   Úarrayr   r   r   ÚupdateÚ_cuda_upload_rfftÚ_cuda_irfft_get)
r+   Úhr)   r   r&   r'   Ú	cuda_dictr   r*   Úexpr   r   r   Ú!_setup_cuda_fft_multiply_repeateds   s.    )
ÿ
þþ
r8   c                 C   s4   |d | |d ƒ}||d 9 }|d ||d ƒ} | S )a¹  Do FFT multiplication by a filter function (possibly using CUDA).

    Parameters
    ----------
    h_fft : 1-d array or gpuarray
        The filtering array to apply.
    x : 1-d array
        The array to filter.
    n_fft : int
        The number of points in the FFT.
    cuda_dict : dict
        Dictionary constructed using setup_cuda_multiply_repeated().

    Returns
    -------
    x : 1-d array
        Filtered version of x.
    r&   r)   r*   r'   r   )Úxr6   Úx_fftr   r   r   Ú_fft_multiply_repeated¶   s    r;   c                 C   s  ddl m}m} td||d�}t|ƒd d }| ¡ }|d|… |ddd… d|d …  d	 |d|…< |d|… }t| tƒrôtd
| dƒ d} t	ƒ  t
rêz ddl}| |¡}t d¡ W n tk
rÖ   t d¡ Y qôX |jdttd� n
t d¡ ||d< | |fS )aO  Set up CUDA FFT resampling.

    Parameters
    ----------
    n_jobs : int | str
        If n_jobs == 'cuda', the function will attempt to set up for CUDA
        FFT resampling.
    W : array
        The filtering function to be used during resampling.
        If n_jobs='cuda', this function will be shortened (since CUDA
        assumes FFTs of real signals are half the length of the signal)
        and turned into a gpuarray.
    new_len : int
        The size of the array following resampling.

    Returns
    -------
    n_jobs : int
        Sets n_jobs = 1 if n_jobs == 'cuda' was passed in, otherwise
        original n_jobs is passed.
    cuda_dict : dict
        Dictionary with the following CUDA-related variables:
            use_cuda : bool
                Whether CUDA should be used.
            fft_plan : instance of FFTPlan
                FFT plan to use in calculating the FFT.
            ifft_plan : instance of FFTPlan
                FFT plan to use in calculating the IFFT.
            x_fft : instance of gpuarray
                Empty allocated GPU space for storing the result of the
                frequency-domain multiplication.
            x : instance of gpuarray
                Empty allocated GPU space for the data to resample.

    Notes
    -----
    This function is designed to be used with fft_resample().
    r   r%   F)Úuse_cudar&   r'   é   r   Néÿÿÿÿg       @r+   r,   zUsing CUDA for FFT resamplingzbCUDA not used, could not instantiate memory (arrays may be too large), falling back to n_jobs=NoneTr-   ÚW)r.   r&   r'   r   ÚlenÚcopyr/   r0   r
   r!   r   r   r1   r   r   r   r2   r3   r4   )r+   r?   Únew_lenr&   r'   r6   Z
rfft_len_xr   r   r   r   Ú_setup_cuda_fft_resampleÓ   s0    '2

þ
rC   r>   c                 C   s    ddl }|jj| | ¡||d�S )zUpload and compute rfft.r   N©r(   Úaxis)r   Úfftr&   r1   ©r9   r(   rE   r   r   r   r   r3     s    r3   c                 C   s   ddl }|jj| ||d� ¡ S )zCompute irfft and get.r   NrD   )r   rF   r'   ÚgetrG   r   r   r   r4      s    r4   Úreflect_limitedc                 C   sà   |dkrt dd�n|}| jtjkr.|  tj¡} t| ||ƒ} t| ƒ}||k }|rR|n|}|d | dƒ}	|d dkr˜|d }
|	|
|
d …  |r�dnd9  < |	|d	 9 }	|d
 |	|ƒ}|dk ¡ rÜ||d |jd |d  … }|S )aÝ  Do FFT resampling with a filter function (possibly using CUDA).

    Parameters
    ----------
    x : 1-d array
        The array to resample. Will be converted to float64 if necessary.
    new_len : int
        The size of the output array (before removing padding).
    npads : tuple of int
        Amount of padding to apply to the start and end of the
        signal before resampling.
    to_removes : tuple of int
        Number of samples to remove after resampling.
    cuda_dict : dict
        Dictionary constructed using setup_cuda_multiply_repeated().
    %(pad)s
        The default is ``'reflect_limited'``.

        .. versionadded:: 0.15

    Returns
    -------
    x : 1-d array
        Filtered version of x.
    NF)r<   r&   r=   r   r   g      à?r?   r'   )	r   ÚdtypeÚnpZfloat64ZastypeÚ
_smart_padr@   ÚanyÚshape)r9   rB   ZnpadsZ
to_removesr6   ÚpadZold_lenZshorterZuse_lenr:   ZnyqÚyr   r   r   Ú_fft_resample&  s      rQ   c              
   C   sö   t  |¡}|jdkst‚|dk ¡ r(| S |dk  ¡ r<tdƒ‚|dkrÞt jt|d t	| ƒ d dƒ| j
d�}t jt|d t	| ƒ d dƒ| j
d�}t  |d| d  | |d dd…  | d| d  | d	|d  d d…  |g¡S t  | t|ƒf|¡S d
S )zPad vector x.)r=   r   zn_pad must be non-negativerI   r   )rJ   r=   r>   éþÿÿÿN)rK   ZasarrayrN   ÚAssertionErrorÚallrM   ÚRuntimeErrorZzerosÚmaxr@   rJ   ZconcatenaterO   Útuple)r9   Zn_padrO   Zl_z_padZr_z_padr   r   r   rL   \  s    
&&$" ÿrL   )r   )FN)N)N)r$   )r>   )r>   )NrI   )rI   )ÚnumpyrK   Úutilsr   r   r   r   r   r   r	   r
   r   r   r!   r"   r   r8   r;   rC   r3   r4   rQ   rL   r   r   r   r   Ú<module>   s(   (
. ÿ
CG

  ÿ5