
    3j+              
          S SK rS SKrS SKrS SKJrJrJr  S SKJ	r	J
r
JrJrJrJrJrJr  S SKrS SKJr  S SKJr  S SKJrJrJr  S SKJr  S\4S	 jrS
\R<                  S\4S jrS)S\ S\RB                  4S jjr"S\RB                  4S jr#S\RB                  4S jr$S\\\	      S\\RB                  \RJ                  4   4S jr&S\RJ                  S\RJ                  4S jr'S\R<                  S\R<                  4S jr(S\R<                  S\ S\\)\4   S\\)\4   S\R<                  4
S jr*S\R<                  S\\R<                  \R<                  \R<                  4   4S jr+S\R<                  S\R<                  4S jr,S\R<                  S\R<                  S\R<                  4S jr-S\R<                  S\R<                  S\\R<                  \R<                  \R<                  4   4S jr.S\R<                  S\\R<                  \R<                  4   4S  jr/S*S!\S\4S" jjr0S#\	S\	4S$ jr1\" S%5      r2S&\
\3\	4   S'\\2   S\24S( jr4g)+    N)asdictfieldsis_dataclass)AnyDictListOptionalTupleTypeTypeVarUnion)inv_ex)torch_version_ge)KORNIA_CHECKKORNIA_CHECK_IS_TENSORKORNIA_CHECK_TYPE)DeviceErrorreturnc                  F    [         R                  R                  S5      b  gg)z6Return whether `torch_xla` is available in the system.	torch_xlaTF)	importlibutil	find_spec     K/home/wildlama/miniconda3/lib/python3.13/site-packages/kornia/core/utils.pyxla_is_availabler   !   s    ~~,8r   xc                 2    S[        U R                  5      ;   $ )z'Return whether tensor is on MPS device.mps)strdevice)r   s    r   is_mps_tensor_safer#   (   s    CM!!r   indexc                     [         R                  R                  5       (       a  [         R                  " SU  35      $ [         R                  " S5      $ )zmTry to get cuda device, if fail, return cpu.

Args:
    index: cuda device index

Returns:
    torch.device

zcuda:cpu)torchcudais_availabler"   )r$   s    r   get_cuda_device_if_availabler*   -   s;     zz  ||eE7O,,<<r   c                      Sn [        [        R                  S5      (       a/  [        R                  R                  R	                  5       (       a  Sn [        R
                  " U 5      $ )zHTry to get mps device, if fail, return cpu.

Returns:
    torch.device

r&   r    )hasattrr'   backendsr    r)   r"   )devs    r   get_mps_device_if_availabler/   =   sG     Cu~~u%%>>**,,C<<r   c                      [         R                  S:X  a#  [        R                  " 5       S:X  a
  [        5       $ [	        5       $ )zwCheck OS and platform and run get_cuda_device_if_available or get_mps_device_if_available.

Returns:
    torch.device

darwinarm64)sysplatformmachiner/   r*   r   r   r   #get_cuda_or_mps_device_if_availabler6   K   s2     ||xH$4$4$6'$A*,,+--r   tensor_listc                 \   Su  pU  Hp  nUc  M  [        U[        R                  5      (       d  M)  UR                  nUR                  nUc	  Uc  UnUnMM  X:w  d  X%:w  d  MY  [        SU SU SU SU S3	X/US9e   Uc  [        R                  " 5       nUc  [        R                  " 5       nX4$ )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: (``torch.get_default_device()``, ``torch.get_default_dtype()``).

Returns:
    [torch.device, torch.dtype]

)NNz9Passed values are not in the same device and dtype. Got (z, z) and (z).)actual_devicesexpected_device)
isinstancer'   Tensorr"   dtyper   get_default_deviceget_default_dtype)r7   r"   r=   tensor_device_dtypes         r   _extract_device_dtyperC   X   s     MFfell33mmG\\F~%- "eo!"82eWGG9BvhbJ$*#4$*	    ~))+}'')?r   r=   c                 n    U [         R                  [         R                  4;   a  U $ [         R                  $ )zNormalize dtype to float32 or float64 for operations that require full precision.

Args:
    dtype: The input dtype to normalize.

Returns:
    torch.float32 if dtype is not float32 or float64, otherwise returns the original dtype.
)r'   float32float64)r=   s    r    _normalize_to_float32_or_float64rG   z   s'     emmU]];;5NNr   inputc                     [        U S5        [        U R                  5      n[        R                  R                  U R                  U5      5      R                  U R                  5      $ )a  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)r   rG   r=   r'   linalginvto)rH   r=   s     r   _torch_inverse_castrN      sI     5">?,U[[9E<<EHHUO,//<<r   binsminmaxc                     [        U S5        [        U R                  5      n[        R                  " U R                  U5      XU5      R                  U R                  5      $ )a  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.
rJ   )r   rG   r=   r'   histcrM   )rH   rO   rP   rQ   r=   s        r   _torch_histc_castrT      sG     5">?,U[[9E;;uxx37::5;;GGr   c                    [        U 5      (       a  [        R                  nODU R                  [        R                  :X  a  [        R                  nO[        U R                  5      n[        R                  R                  U R                  U5      5      u  p#nUR                  nUR                  U R                  5      UR                  U R                  5      UR                  U R                  5      4$ )a  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

For numerical stability, fp32 inputs are promoted to fp64 (except on MPS where fp64 is unsupported).
)
r#   r'   rE   r=   rF   rG   rK   svdrM   mH)rH   r=   out1out2out3Hout3s         r   _torch_svd_castr\      s     %  		%0=((%9D88DGGEKK $''%++"68LMMr   c                     [        U S5        [        U R                  5      n[        R                  R                  U R                  U5      5      nUR                  U R                  5      $ )a`  Make torch.linalg.svdvals 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
rJ   )r   rG   r=   r'   rK   svdvalsrM   )rH   r=   outs      r   _torch_linalg_svdvalsr`      sN     5">?,U[[9E ,,

uxx
/C66%++r   ABc                    [        U 5      (       a  [        R                  nO[        R                  n[        R                  R                  U R                  U5      UR                  U5      5      nUR                  U R                  5      $ )al  Make torch.solve work with other than fp32/64.

For stable operation, the input matrices should be cast to fp64, and the output will
be cast back to the input dtype. However, fp64 is not yet supported on MPS.

This function is actively used in:
- kornia.geometry.transform.imgwarp
- kornia.geometry.transform.thin_plate_spline
- kornia.geometry.epipolar.essential
)r#   r'   rE   rF   rK   solverM   r=   )ra   rb   r=   r_   s       r   _torch_solve_castre      s[     !
,,

QTT%[!$$u+
6C 66!''?r   c                 X   [        U S5        U R                  nU[        R                  [        R                  4;  a  [        R                  n[        R
                  R                  UR                  U5      5      u  p4nUS:H  n[        U R                  5      n[        UR                  5      nX-
  S:X  a  U R                  S5      n [        R
                  R                  X4U R                  U5      5      n	U	R                  U R                  5      UR                  UR                  5      U4$ )zzSolves the system of equations.

Avoids crashing because of singular matrix input and outputs the mask of valid solution.
zB must be torch.Tensorr      )r   r=   r'   rE   rF   rK   lu_factor_exrM   lenshape	unsqueezelu_solve)
rb   ra   r=   A_LUpivotsinfo
valid_maskn_dim_Bn_dim_AXs
             r   safe_solve_with_maskru      s     167EU]]EMM22 22144;?D$#qyJ!''lG!''lGAKKOdADDK8A44=$''!''*J66r   c                     [        U S5        U R                  n[        U5      n[        U R	                  U5      5      u  p4US:H  nUR	                  U5      U4$ )zqPerform inverse.

Avoids crashing because of non-invertable matrix input and outputs the mask of valid solution.
zA must be torch.Tensorr   )r   r=   rG   r   rM   )ra   dtype_originalr=   inverserp   masks         r   safe_inverse_with_maskrz      sS    
 167WWN,^<E144;'MG19D::n%t++r   bothc                 "   U (       at  [        SS5      (       a2  [        R                  " 5       =(       d    [        R                  " S5      $ [        R                  " 5       =(       d    [        R                  " 5       $ [        R                  " 5       $ )a|  Check if torch autocast is enabled.

Args:
    both: if True will consider autocast region for both types of devices

Returns:
    Return a Bool,
    will always return False for a torch without support, otherwise will be: if both is True
    `torch.is_autocast_enabled() or torch.is_autocast_enabled('cpu')`. If both is False will return just
    `torch.is_autocast_enabled()`.

      r&   )r   r'   is_autocast_enabledis_autocast_cpu_enabled)r{   s    r   r   r     s_     Aq!!,,.R%2K2KE2RR,,.Q%2O2O2QQ$$&&r   objc                    [        U 5      (       aM  [        U [        5      (       d8  [        U 5      R	                  5        VVs0 s H  u  pU[        U5      _M     snn$ [        U [        [        -  5      (       a  [        U 5      " S U  5       5      $ [        U [        5      (       a/  U R	                  5        VVs0 s H  u  pU[        U5      _M     snn$ U $ s  snnf s  snnf )z8Recursively convert dataclass instances to dictionaries.c              3   8   #    U  H  n[        U5      v   M     g 7f)N)dataclass_to_dict).0items     r   	<genexpr>$dataclass_to_dict.<locals>.<genexpr>  s     AST*400Ss   )	r   r;   typer   itemsr   listtupledict)r   keyvalues      r   r   r     s    CC!6!6@Fs@Q@Q@ST@S*#&u--@STT	C	&	&CyASAAA	C		@C		L*#&u--LL
 U Ms   C:CTdict_objdataclass_typec                 V   [        U [        S5        [        [        U5      S5        [	        U5       Vs0 s H  o"R
                  UR                  _M     nn0 nU R                  5        H2  u  pVXS;   a$  [        X5   5      (       a  [        XcU   5      XE'   M.  XdU'   M4     U" S0 UD6$ s  snf )z8Recursively convert dictionaries to dataclass instances.zInput conf must be dictz"dataclass_type must be a dataclassr   )	r   r   r   r   r   namer   r   dict_to_dataclass)r   r   ffield_typesconstructor_argsr   r   s          r   r   r   )  s    h&?@n-/ST;A.;Q"R;Qa66166>;QK"Rnn&
,{/?"@"@$5e=M$N!$)S!	 ' -,-- #Ss    B&)r   )T)5importlib.utilr   r4   r3   dataclassesr   r   r   typingr   r   r   r	   r
   r   r   r   r'   torch.linalgr   kornia.core._compatr   kornia.core.checkr   r   r   kornia.core.exceptionsr   boolr   r<   r#   intr"   r*   r/   r6   r=   rC   rG   rN   floatrT   r\   r`   re   ru   rz   r   r   r   r!   r   r   r   r   <module>r      sx  &   
 4 4 I I I   0 U U .$ "%,, "4 "
 ELL  U\\ 
.U\\ 
.tHSM': uU\\SXS^S^E^?_ D	OEKK 	OEKK 	O=u|| = =HU\\ H H5;M HTYZ_aeZeTf Hkpkwkw HN5<< NE%,,ell2Z,[ N0 %,, " %,, 5<< ,7ELL 7U\\ 7eELLRWR^R^`e`l`lDl>m 72,ell ,uU\\5<<5O/P ,'d 'd '.	3 	3 	 CL.S#X .Q .A .r   