a
    d                     @   s\  d dl Z d dlmZmZ d dlmZmZ d dlmZm	Z	m
Z
mZmZ d dlZd dlmZ d dlmZ d!eejddd	Zd"e	ee d
ddZe
ee  eejejf dddZejejdddZejeeeejdddZejeejejejf dddZeeedddZejejeejejejf dddZejeejejf ddd ZdS )#    N)partialwraps)isclass
isfunction)AnyCallableListOptionalTuple)Tensor)torch_version_geq)indexreturnc              
   C   s^   z*t j rt d|  }n
t d}W n. tyX } zt d}W Y d}~n
d}~0 0 |S )zTries to get cuda device, if fail, returns cpu.

    Args:
        index: cuda device index

    Returns:
        torch.device
    zcuda:cpuN)torchZcudaZis_availabledeviceBaseException)r   deve r   ]/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/utils/helpers.pyget_cuda_device_if_available   s    	
 r   funcreplace_withc                    s.    d u rt tdS t  fdd}|S )N)r   c                     sl   d}t  r jj}t r" j}d urHtjd| d dtd ntjd| dtd  | i |S )N `z` is deprecated in favor of `z`.)categoryz;` is deprecated and will be removed in the future versions.)r   	__class____name__r   warningswarnDeprecationWarning)argskwargsnamer   r   r   wrapper#   s    z_deprecated.<locals>.wrapper)r   _deprecatedr   )r   r   r&   r   r   r   r'      s
    r'   )tensor_listr   c                 C   s   d\}}| D ]t}|durt |tjfs(q|j}|j}|du rN|du rN|}|}q||ks^||krtd| d| d| d| d	q|du rtd}|du rt }||fS )zCheck if all the input are in the same device (only if when they are torch.Tensor).

    If so, it would return a tuple of (device, dtype). Default: (cpu, ``get_default_dtype()``).

    Returns:
        [torch.device, torch.dtype]
    )NNNz8Passed values are not in the same device and dtype.Got (z, z) and (z).r   )
isinstancer   r   r   dtype
ValueErrorZget_default_dtype)r(   r   r*   ZtensorZ_deviceZ_dtyper   r   r   _extract_device_dtype5   s6    
r,   )inputr   c                 C   sT   t | tjs tdt|  d| j}|tjtjfvr<tj}t| 	|	| jS )a2  Helper function to make torch.inverse work with other than fp32/64.

    The function torch.inverse is only implemented for fp32/64 which makes impossible to be used by fp16 or others. What
    this function does, is cast input data type to fp32, apply torch.inverse, and cast back to the input dtype.
    !Input must be torch.Tensor. Got: .)
r)   r   r   AssertionErrortyper*   float32float64inverseto)r-   r*   r   r   r   _torch_inverse_castT   s    r6   )r-   binsminmaxr   c                 C   sZ   t | tjs tdt|  d| j}|tjtjfvr<tj}t| 	||||	| jS )a.  Helper function to make torch.histc work with other than fp32/64.

    The function torch.histc is only implemented for fp32/64 which makes impossible to be used by fp16 or others. What
    this function does, is cast input data type to fp32, apply torch.inverse, and cast back to the input dtype.
    r.   r/   )
r)   r   r   r0   r1   r*   r2   r3   Zhistcr5   )r-   r7   r8   r9   r*   r   r   r   _torch_histc_castb   s    r:   c                 C   st   t | tjs tdt|  d| j}|tjtjfvr<tj}t| 	|\}}}|	| j|	| j|	| jfS )a|  Helper function to make torch.svd work with other than fp32/64.

    The function torch.svd is only implemented for fp32/64 which makes
    impossible to be used by fp16 or others. What this function does, is cast
    input data type to fp32, apply torch.svd, and cast back to the input dtype.

    NOTE: in torch 1.8.1 this function is recommended to use as torch.linalg.svd
    r.   r/   )
r)   r   r   r0   r1   r*   r2   r3   Zsvdr5   )r-   r*   Zout1Zout2Zout3r   r   r   _torch_svd_castp   s    	r;   )ABr   c                 C   sB   | j }|tjtjfvrtj}tj| |||}|| j S )a*  Helper function to make torch.solve work with other than fp32/64.

    The function torch.solve is only implemented for fp32/64 which makes impossible to be used by fp16 or others. What
    this function does, is cast input data type to fp32, apply torch.svd, and cast back to the input dtype.
    )r*   r   r2   r3   ZlinalgZsolver5   )r<   r=   r*   outr   r   r   _torch_solve_cast   s
    r?   )r=   r<   r   c           	      C   s   t dds>t|| }tdt ||tjt|tj|j	dfS t
| tjs^tdt|  d| j}|tjtjfvrztj}tj||dd\}}}|d	k}t| |||}|| j||j|fS )
zsHelper function, which avoids crashing because of singular matrix input and outputs the mask of valid
    solution.   
   z>PyTorch version < 1.10, solve validness mask maybe not correctr*   r   zB must be torch.Tensor. Got: r/   T)Z	get_infosr   )r   r?   r    r!   RuntimeWarningr   oneslenboolr   r)   r   r0   r1   r*   r2   r3   Zlur5   Zlu_solve)	r=   r<   Zsolr*   ZA_LUZpivotsinfoZ
valid_maskXr   r   r   safe_solve_with_mask   s    

rI   )r<   r   c                 C   s   t dds:t| }tdt |tjt| tj| j	dfS t
| tjsZtdt|  d| j}|tjtjfvrxtj}n|}ddlm} || |\}}|dk}|||fS )	zyHelper function, which avoids crashing because of non-invertable matrix input and outputs the mask of valid
    solution.r@   	   z?PyTorch version < 1.9, inverse validness mask maybe not correctrB   zA must be torch.Tensor. Got: r/   r   )inv_ex)r   r6   r    r!   rC   r   rD   rE   rF   r   r)   r   r0   r1   r*   r2   r3   Ztorch.linalgrK   r5   )r<   invZdtype_originalr*   rK   r4   rG   maskr   r   r   safe_inverse_with_mask   s    
rN   )r   )NN)r    	functoolsr   r   inspectr   r   typingr   r   r   r	   r
   r   Zkornia.corer   Zkornia.utils._compatr   intr   r   strr'   r*   r,   r6   r:   r;   r?   rI   rN   r   r   r   r   <module>   s   $"&