
    Pg/b             $          d dl Z d dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZ d dlmZ d dlZd dlZd dlmZmZ d dlmZ d dlmZ g dZ G d	 d
e      Zdej6                  fdZdej6                  fdZd Zdedeej6                  df   fdZ	 dzdedeej6                  df   fdZ 	 d{deej6                  eej6                     f   de!deej6                     fdZ"d Z#d Z$	 d|de	eej6                  df      fdZ% ede&      d}d       Z'd  Z(	 d{de	ej6                     fd!Z)d"ee*e	ej6                     f   deej6                  df   fd#Z+	 d{d$ej6                  d%e
ej6                     dej6                  fd&Z,d~dd'Z-	 ddeej6                  df   fd(Z.ddd)deeej6                  df   df   fd*Z/d+ Z0d{d,Z1d- Z2d. Z3d/ Z4	 d{de	ej6                     fd0Z5d1 Z6d2 Z7deeej6                  df   e!e!f   fd3Z8d4Z9	 ddeej6                  df   fd5Z:d6 Z; ed7e&      dd9       Z<d: Z=de	e	e
ej6                           fd;Z>de	e	e
ej6                           fd<Z?de!fd=Z@dd>ZAde!fd?ZBd@ ZCdAj                         ZEdBZF	 d{dCZGde!fdDZHde!fdEZIde!fdFZJdG ZKde!fdHZLdI ZMdJ ZN	 	 ddeOfdKZPdL ZQdM ZRdN ZSdO ZTdddddPdQZUdR ZVdS ZWdT ZXd{dUZYdV ZZdW Z[dXj                         Z\dY Z]dZ Z^d[ Z_dd\d]Z`dddddPd^Zad_d`ddad8dadddddadddbdcedee   f   ddedeebdfebdgebdhe!diebdje!dke!dle!dme!dne!doe!dpe!dqe
e!   de!f drZcds Zd	 d~d_d`dddad8daddddadddtdcedef   ddedue
e   deebdfebdgebdve!dhe!diebdje!dke!dle!dwe!dxe!dpe!dqe!de!f"dyZey)    N)product)CallableDictIterableListOptionalTupleUnion)
deprecated)_vmapvmap)is_tensor_like)_TensorOrTensors)	gradcheckgradgradcheckGradcheckErrorget_numerical_jacobianget_analytical_jacobian)get_numerical_jacobian_wrt_specific_inputc                       e Zd ZdZy)r   z<Error raised by :func:`gradcheck` and :func:`gradgradcheck`.N)__name__
__module____qualname____doc__     _/var/www/html/suriana-translation/venv/lib/python3.12/site-packages/torch/autograd/gradcheck.pyr   r      s    Gr   r   objc                     | j                   t        j                  t        j                  t        j                  t        j
                  hv S N)layouttorch
sparse_csr
sparse_csc
sparse_bsr
sparse_bscr   s    r   _is_sparse_compressed_tensorr(   !   s<    ::	  r   c                 T    t        |       xs | j                  t        j                  u S r    )r(   r!   r"   
sparse_coor'   s    r   _is_sparse_any_tensorr+   *   s!    ',N

e>N>N0NNr   c                 `    t        |       xr" | j                         xs | j                         S r    )r   is_floating_point
is_complexr'   s    r   _is_float_or_complex_tensorr/   .   s'    #PC$9$9$;$Os~~?OPr   input_tensorsreturn.c                     | D cg c]J  }t        |      r=|j                  r1|j                  |j                         |ft        j
                        L }}t        |      S c c}w )Nr!   )r/   requires_grad	new_zerosnumelr"   stridedtuple)r0   numel_outputtouts       r   _allocate_jacobians_with_inputsr<   2   s\     &q)aoo 	
QWWY-emmDC 
 :s   AA!output_tensorsc                     ||t         j                  d}| D cg c]0  }t        |      r# |j                  ||j	                         ffi |2 }}t        |      S c c}w )N)dtypedevicer!   )r"   r7   r/   r5   r6   r8   )r=   numel_inputr?   r@   optionsr:   r;   s          r    _allocate_jacobians_with_outputsrC   B   sg     5==IG  &q) 	[!''),88C 
 :s   5AFxonly_requiring_gradc              #      K   t        |       r| j                  s|s|  y y t        | t        j                  j
                        r-t        | t              s| D ]  }t        ||      E d {     y y y 7 	wr    )r   r4   
isinstancecollectionsabcr   str_iter_tensors)rD   rE   elems      r   rK   rK   R   so      a??"5G #6	A{//	0As9K 	@D$T+>???	@ :L	0?s   A(A6*A4+
A6c                    t        | t        t        f      r t        |       t	        t
        |             S t        |       r,| j                  t        j                  t        j                  hv r| S | j                  t        j                  u r| j                  }| j                         j                  }t        j                  | j                   d | j#                          t        j$                  |      }|j'                         j)                         j+                  |      }t        j,                  |j/                         g| j                   | j#                         d  | j                  |      }| j1                         j3                         }|j/                         dkD  rv|j5                         }|j7                         j9                  t        j:                  |||      j=                  d            j?                  d      }|jA                         ||<   t        jB                  ||| j                         jE                  d      jG                  | jH                        S tK        |       r| j                  t        jL                  t        jN                  hv r| jA                         j                   dd nd }	| j                  t        jP                  t        jL                  hv r| jS                         n| jU                         }
t        | j1                         jW                  t        j                              jW                  | j                  |	      }|jA                         j/                         tY        d|jA                         j                   d         z  }|
j/                         |
j                   d	   z  }|j/                         tY        d||z        z  }||j[                         k7  r+t]        | j                   d
| d|j[                                |jG                  | jH                        S t_        |       rta        | j                        | S )Nr?   r@   r?   r      T   r3   )r!   	blocksizez densify failed: expected nnz=z	 but got )1rG   listr8   typemap_densifyr   r!   r"   r7   _mkldnnr*   r@   _indicesr?   onesshape
sparse_dimint8nonzeror:   tozerosr6   detachcoalescestrideindicesmultensor	unsqueezesumvaluessparse_coo_tensor_coalesced_requires_grad_r4   r(   r%   r&   r#   crow_indicesccol_indices	to_sparsemax_nnzAssertionErrorr+   NotImplementedError)rD   r@   indices_dtypetmprd   ri   x_coalescedrc   flat_indicesrR   compressed_indicesrdense_numelbatch_numelsparse_numels                  r   rW   rW   ^   s]    !dE]#tAws8Q'((A!((u}}emm.L"L	
U%%	%

**jj!11<<>2%**VT++-//#&&]&;YY[51771<<>#345QWWV
 hhj))+"ZZ\F##%LL}VLVV
 Q  $/#5#5#7F< ##GVQWW=[^AOO,	

 
&a	( xxE,,e.>.>?? HHJQq! 	 xxE,,e.>.>?? NN! 	 QXXZ))1A1A)BCMM88y N 
 hhj&&(C188:3C3CA3F,GG(..04F4L4LR4PPwwyC;+D$EE1668# 88*:<.	RSRXRXRZQ[\  00	q	!!!((++Hr   c           
   #     K   t        |       rd }| j                         }t        | j                               }| j                  t
        j                  u r0| j                         j                         }| j                         }n| j                  t
        j                  u rRt        j                  | j                         | j                               j                         }| j                         }nJ| j                  t
        j                  u rTt        j                  | j!                         | j#                         d      j                         }| j                         }n| j                  t
        j$                  u rC| j                         }|j                         dd }t        j                  | j                         | j                               j'                  |d   |d   z  d      j)                  t        j*                  || j,                        j/                  dd            j1                  t        j2                  t        j4                  t        j6                  || j,                                    j9                  d|            j                         }|j;                  dd      }|j                  d      }nz| j                  t
        j<                  u rD| j                         }|j                         dd }t        j                  | j!                         | j#                         d      j'                  |d   |d   z  d      j)                  t        j*                  || j,                        j/                  dd            j1                  t        j2                  t        j4                  t        j6                  || j,                                    j9                  d|            j                         }|j;                  dd      }|j                  d      }nt?        d	| j                   d
       ||      |j@                  }tC        |      D ]  }||   }	tE        |j                         dd  D 
cg c]  }
tC        |
       c}
 D ]O  }||   jG                         t        |      z   tI        fdtC        tK        |            D              }|	||f Q  y | j                  t
        jL                  k(  rVtO        tE        | j                         D 
cg c]  }
tC        |
       c}
       D ]  \  }}| jQ                         }|||f  y | j@                  } tO        tE        | j                         D 
cg c]  }
tC        |
       c}
       D ]  \  }}| ||f  y c c}
w c c}
w c c}
w w)Nc                 x    t        |       }d}dg|z  }t        t        |            D ]  }|||<   || |   z  } |S )NrP   r   )lenreversedrange)sizedimru   rc   is        r   
get_stridez _iter_tensor.<locals>.get_stride   sP    d)CCS3YFeCj) q	tAw Mr   T)	transposerP   rQ   r   r@      z_iter_tensor for z inputc              3   4   K   | ]  }|   |   z    y wr    r   ).0krd   x_strides     r   	<genexpr>z_iter_tensor.<locals>.<genexpr>   s     QGAJ!4Qs   ))r+   rq   rT   r   r!   r"   r*   rY   r:   _valuesr#    _convert_indices_from_csr_to_coorm   col_indicesri   r$   rn   row_indicesr%   repeat_interleavemul_rf   r@   reshapeadd_stackwhererZ   repeatflattenr&   rs   datar   r   tolistrh   r   rX   	enumerateto_dense)x_tensorr   x_nnzx_size	x_indicesx_valuesx_block_valuesx_blocksizer   x_valuemx_idxd_idxx_tensor_denserd   r   s                 @@r   _iter_tensorr      s    " X&	 hmmo&??e... ))+--/I'')H__ 0 00>>%%')=)=)?ac   (H__ 0 00>>%%')=)=)?4ac   (H__ 0 00%__.N(--/!4K66))+X-A-A-C #";q>KN#BAFell;xGOOPQSTUVKKEJJ{8??$STfQ&
   &--a3HMM!$E__ 0 00%__.N(--/!4K66))+X-A-A-Ct #";q>KN#BAFell;xGOOPQSTUVKKEJJ{8??$STfQ&
   &--a3HMM!$E%(9(//9J&&QRRf%==u 	,AqkG X]]_QR5H"I58"IJ ,#A,--/$u+=QeCK>PQQue++,	, 
EMM	)%g(--//RQa/R&ST 	/LE5 &..0N %..		/ ==%g(--//RQa/R&ST 	)LE5E5((	) #J
 0S 0Ss,   Q>WV2
BW&V78AWV<'WMbP?c                 z   g }|t         | t        |             }|st        d |D              rt        d      ||}t        |      D cg c]   \  }}t	        |      s|j
                  s|" }	}}t        t        t        |d      |	            D ]  \  }\  }
}|t        | |||||
|      gz  }  |S c c}}w )a  Compute the numerical Jacobian of `fn(inputs)` with respect to `target`.

    If not specified, targets are the input. Returns M * N Jacobians where N is the
    number of tensors in target that require grad and M is the number of non-integral
    outputs.

    Args:
        fn: the function to compute the jacobian for
        inputs: inputs to `fn`
        outputs: provide precomputed outputs to avoid one extra invocation of fn
        target: the Tensors wrt whom Jacobians are calculated (default=`inputs`)
        eps: the magnitude of the perturbation during finite differencing
             (default=`1e-3`)
        is_forward_ad: if this numerical jacobian is computed to be checked wrt
                       forward AD gradients (this is used for error checking only)

    Returns:
        A list of M N-tuples of tensors

    Note that `target` may not even be part of `input` to `fn`, so please be
    **very careful** in this to not clone `target`.
    c              3   <   K   | ]  }|j                           y wr    r.   r   os     r   r   z*_get_numerical_jacobian.<locals>.<genexpr>  s      AA A   zsExpected output to be non-complex. get_numerical_jacobian no longer supports functions that return complex outputs.T)inputis_forward_ad)		_as_tupleany
ValueErrorr   r   r4   ziprK   r   )fninputsoutputstargetepsr   	jacobiansr   ainp_indicesinpinp_idxs               r   _get_numerical_jacobianr     s    2 13IB	& 123S A AAE
 	
 ~'a>!+<K  's=+F'TU 
>C5+

 
	
	
 s   B7!B7.B7aA  `get_numerical_jacobian` was part of PyTorch's private API and not meant to be exposed. We are deprecating it and it will be removed in a future version of PyTorch. If you have a specific use for this or feature request for this to be a stable API, please file us an issue at https://github.com/pytorch/pytorch/issues/new)categoryc                 p     |dk7  rt        d       fd}t        ||d||      }t        d |D              S )a  Compute the numerical Jacobian for a given fn and its inputs.

    This is a Deprecated API.

    Args:
        fn: the function to compute the Jacobian for (must take inputs as a tuple)
        inputs: input to `fn`
        target: the Tensors wrt whom Jacobians are calculated (default=`input`)
        eps: the magnitude of the perturbation during finite differencing
             (default=`1e-3`)
        grad_out: defaults to 1.0.

    Returns:
        A list of Jacobians of `fn` (restricted to its first output) with respect to
        each input or target, if provided.

    Note that `target` may not even be part of `input` to `fn`, so please be
    **very careful** in this to not clone `target`.
          ?zaExpected grad_out to be 1.0. get_numerical_jacobian no longer supports values of grad_out != 1.0.c                       |       S r    r   )inpsr   s    r   fn_pack_inpsz,get_numerical_jacobian.<locals>.fn_pack_inps\  s    $xr   Nc              3   &   K   | ]	  }|d      yw)r   Nr   )r   jacobian_for_each_outputs     r   r   z)get_numerical_jacobian.<locals>.<genexpr>a  s     W1I)!,Ws   )r   r   r8   )r   r   r   r   grad_outr   r   s   `      r   r   r   8  sH    : 	C2
 	

 (fdFCPIWYWWWr   c                    t        |      r|j                  |j                  k(  sJ |j                  |j                  f       |j                         |j                         k(  s0J |j                         |j                         |j                  f       |j	                         }|j	                         }|j                         }|j                         }|j                  ||z
          |        }|j                  ||z           |        }|j                  |       fdt        fdt        ||      D              S )Nc                 j     | |       || z
  dz  z  }|j                         j                  d      S )Nr   rS   )ra   r   )r   bretnbhd_checks_fnnorm_vs      r   computez,_compute_numerical_gradient.<locals>.compute{  s6    q!1uV$zz|##B''r   c              3   6   K   | ]  \  }} ||        y wr    r   )r   r   r   r   s      r   r   z._compute_numerical_gradient.<locals>.<genexpr>  s     =6AqA=   )
r(   r!   rq   r[   ri   ra   clonecopy_r8   r   )	r   entryvr   r   origoutaoutbr   s	      ``   @r   _compute_numerical_gradientr   d  s     $E* ||qxx'A%,,)AA'zz|qvvx'N%**,%++)NN'HHJ ;;=D	KKq4D	KKq4D	KK(
 =St_===r   c                 t   g } | t        |t              r|d   n|      }|rjt        |t              r | |d   dz        n
 | |dz        }t        ||      D ]0  \  }}|j                         rJ ||dz  z   }	|j	                  |	       2 |S |D ]'  }|s|j                         rJ |j	                  |       ) |S )Nr   rP                 ?)rG   r8   r   r.   append)
jvp_fndeltainput_is_complexr   jvps	ds_dx_tup	ds_dy_tupds_dxds_dyconj_w_ds
             r   *_compute_numerical_jvps_wrt_specific_inputr     s      "D:eU#;uQxGI%/u%=F58b=!6%RT*CU 	  	95 	"LE5'')))urz)HKK!		" K  	E (8(8(:::KK	 Kr   jacobians_colsc                     t        |||j                  j                  r|j                  nd       }t        |      D ]%  \  }}| j	                         D ]  \  }}||   ||<    ' |S NrO   )rC   r?   r.   r   items)	r   r   r   r6   r   r   jacobianr   r   s	            r   _combine_jacobian_colsr     sr    
 1U[[-C-CekkI !+ 8"((* 	DAqA$HQK	 r   r   maybe_perturbed_inputc                     | j                   t        j                  k(  r||j                         S | S t	        |       r|r||S | S | S r    )r!   r"   rX   	to_mkldnnr+   )r   r   	fast_modes      r   _prepare_inputr     sS    
 ||u}}$ ,(2244L	u	%.: )(L r   c           
         |dnd}| j                   |j                   k(  s(J d| d| d| j                    d|j                    d	       | j                  |j                  k(  s(J d| d| d	| j                   d|j                   d	       y )
Nzon index {idx}  zPExpected `func` to return outputs with the same shape when inputs are perturbed zby z, but got: shapes z and .zPExpected `func` to return outputs with the same dtype when inputs are perturbed z, but got: dtypes )r[   r?   )output1output2r   idxon_indexs        r   #_check_outputs_same_dtype_and_shaper     s     %(O H==GMM) &&.Zs3% 8==/w}}oQ	8)
 ==GMM) &&.Zs3% 8==/w}}oQ	8)r   c                 L   i }|||   n|}|j                   sJ t        |      D ]b  \  }}	}
t        | |||      }||	   }t        j                  t
        |	|      }t        ||||      }t        |||j                         |      ||
<   d t        ||||j                               S )N)r   r   )r4   r   _with_prepare_inputs	functoolspartialr   _get_numerical_jvp_fnr   r.   r   r6   )r   	input_idxr   r   r   r   r   jacobian_colsrD   r   r   
wrapped_fninput_to_perturbr   r   s                  r   r   r     s     46M!&F9EE%e, 
3)"fiC
S6"**/Sc
 '(#~
  JC 
e
 "-%OOr   )check_grad_dtypesall_uc                2   t         j                  j                  }t        d |D              }t	        d |D              rt        d      |rt        fd|D              }nt        fd|D              }|j                         5  g }g }	t        |      D ]  \  }
}t        |      r|j                  r~|j                  t         j                  k(  rt        d      |j                  |j                         t        j                  |            }|j                  |j!                  |      d          |	j                  |        |rt        t#        ||            D ]  \  }
\  }}|j%                  |j'                  |             t)         | |	       }t+        t,        |      }t        |      D ]  \  }}|j!                  |      \  }}|r.|,|j/                         |j/                         k7  rt1        d	      ||
   |   j3                  d
       |||
   |   j5                          z||
   |   j%                  |j7                  d              |j5                           nt        |      D ]  \  }
}t        t9        |j;                         D cg c]  }t=        |       c}       D ]  \  }}d||<   t)         | |	       }t+        t,        |      }t        |      D ]  \  }}|j!                  |      \  }}|r.|,|j/                         |j/                         k7  rt1        d	      |||
   |   |   j5                          f||
   |   |   j%                  |j7                  d              d||<     ddd       |S c c}w # 1 sw Y   |S xY w)a  Compute the analytical Jacobian using forward mode AD of `fn(inputs)` using forward mode AD with respect to `target`.

    Return N * M Jacobians where N is the number of tensors in target that require grad and
    M is the number of non-integral outputs.
    Contrary to other functions here, this function requires "inputs" to actually be used by the function.
    The computed value is expected to be wrong if the function captures the inputs by side effect instead of
    using the passed ones (many torch.nn tests do this).

    Args:
        fn: the function to compute the jacobian for
        inputs: inputs to `fn`
        outputs: provide precomputed outputs to avoid one extra invocation of fn
        check_grad_dtypes: if True, will check that the gradient dtype are valid
        all_u (optional): if provided, the Jacobian will be right multiplied with this vector

    Returns:
        A tuple of M N-tuples of tensors
    c              3   R   K   | ]  }t        |      s|j                  s| ! y wr    r   r4   r   r   s     r   r   z6_get_analytical_jacobian_forward_ad.<locals>.<genexpr>       U~a/@Q__!U   '''c              3   <   K   | ]  }|j                           y wr    r   r  s     r   r   z6_get_analytical_jacobian_forward_ad.<locals>.<genexpr>  s     
1a1<<>
1r   zJExpected inputs to be non-complex for _get_analytical_jacobian_forward_ad.c              3   6   K   | ]  }t        d         yw)rP   N)rC   r   r   r   s     r   r   z6_get_analytical_jacobian_forward_ad.<locals>.<genexpr>  s      
=>,Wa8
r   c              3   R   K   | ]  }t        |j                                  y wr    )rC   r6   r  s     r   r   z6_get_analytical_jacobian_forward_ad.<locals>.<genexpr>  s$      
EF,Waggi@
   $'7MKLDNN inputs are not support for forward AD gradcheck.rP   Nz'Forward AD gradient has dtype mismatch.r   rS   r           )r"   autograd
forward_adr8   r   r   
dual_levelr   r   r4   r!   rX   	make_dualra   
zeros_liker   unpack_dualr   r   view_asr   filterr/   r.   r   squeeze_zero_r   r   r   r   )r   r   r   r  r  fwADtensor_inputsr   fw_gradsdual_inputsr   r   fw_graduraw_outputsdual_outputsindex_od_ovalresr   lin_idxgrad_idxs     `                    r   #_get_analytical_jacobian_forward_adr-    s   , >>$$DUVUUM

1=
11X
 	
  
BO
 
	  
JW
 
	 
	 ?,' 	$FAsc"s'8'8::.$Q  nnSZZ\53C3CC3HI  0 0 5a 89s#	$  $-S5-A#B  <GQaii01'K(89%&A;O$-l$; ELGS#//4HC)ONN,0@@,-VWW aL)2215{!!W-335!!W-33CKKODE ' , (1 ,
7)2?1eAh?@* ,%GX ),GH%"+B,<"=K#)*E{#SL(1,(? R#'#3#3C#8S- # # 0CNN4D D"0 I#  ;%aL1':@@B%aL1':@@RQR ),GH%+,,S?,B - @W?,B s    HNN&CNNNc                     | j                   t        j                  k(  r| j                         }|S t	        |       r| j                         }|S | j                  }|S r    )r!   r"   rX   r   r+   r   r   )r   r  s     r   _get_input_to_perturbr/  Z  s[     ||u}}$ >>+  
u	% !;;=  !::r   c                 "      fd}|S )Nc                      t        fdt        t                    D              } t        d t         |        D              S )Nc              3   f   K   | ](  \  }}t        |      rt        ||k(  rnd       n| * y wr    )r   r   )r   r   r   r   r  r  s      r   r   z;_with_prepare_inputs.<locals>.wrapped_fn.<locals>.<genexpr>m  sC      
 1 a  1!y..dIV
s   .1c              3   <   K   | ]  }|j                           y wr    )r   )r   r   s     r   r   z;_with_prepare_inputs.<locals>.wrapped_fn.<locals>.<genexpr>s  s     <1QWWY<r   )r8   r   r   )r   r   r   r  r  r   s    r   r  z(_with_prepare_inputs.<locals>.wrapped_fnl  sB     
 ")F"34	
 
 <	"c((;<<<r   r   )r   r   r  r  r   r  s   ````` r   r   r   j  s    = = r   c                       fd}|S )Nc                 "    t        |       S r    )r   )r   r   r  r   r  s    r   r   z%_get_numerical_jvp_fn.<locals>.jvp_fnz  s    *(%n
 	
r   r   )r  r  r   r   r   s   ```` r   r  r  x  s    

 Mr   c                     t        | t              r8t        | d         s(| d   j                  |      | d   j                  |      fS | S t        |       s| j                  |      S | S Nr   rP   )rG   r8   r+   r   )r$  r[   s     r   _reshape_tensor_or_tupler8    sb    !U$QqT*aDLL'1e)<== H %Q'99U##Hr   c                 L    t        | t              r|| d   z  || d   z  fS || z  S r7  )rG   r8   )r$  r   s     r   _mul_tensor_or_tupler:    s0    !UAaD!ad(##1ur   c                    ||   }t        |      }t        | |||d      }t        j                  t        |      }	t        ||||	      }
t        ||j                        }t        ||      }t        |
||j                         |      S )NT)r   )r/  r   r   r   r   r  r8  r[   r:  r   r.   )r   r  r   r$  r   r   r   r  r  r   r   s              r   %_get_numerical_jvp_wrt_specific_inputr<    s     9E,U3%b&)=MtTJ&&'JPSTN":/?nUF $4$:$:;AQ$A55##%} r   c           	         g }t        t        ||            D ]  \  }	\  }
}t        | |
||||      }g }t        |      }t	        |      t	        |      k(  sJ t        ||      D ]"  \  }}t        |      r|j                  |       #$ |Cg }t        ||      D ]   \  }}|j                  t        ||             " |j                  |       |j                  |        |S r    )r   r   r<  r   r   r/   r   _dot_with_type_promotion)r   r   r   func_outr  all_vr   r   reduced_jacobiansr   r   r$  all_Jufiltered_JuJuoutputjacobian_scalarsr   s                     r   _get_numerical_vJurG    s    35$Se%<= 2<GQ6C
 X&6{c(m+++fh/ 	JB*62""2& 	 35UK0 I2 ''(@B(GHI$$%56$$[1)2* r   c                     t        | |      D ]?  \  }}|j                         dk7  s||z
  j                         j                         |kD  s? y y)Nr   FT)r   r6   absrp   )j1j2atolj1_xj2_xs        r   _check_jacobians_equalrO    sP     "bk 
d::<1$+!2!2!4!8!8!:T!A r   c                 R   t        ||      }t        t        |d            }d}d}t        |       D ]  \  }}||   }	||   }
t        |      D ]  \  }}|$|j	                         |	j	                         k7  rd}n||j
                  |	j
                  k7  rd}||
d d |f   j                          c|j                  t        j                  k(  s|j                         n|}|
d d |f   j                         |j                         k(  sJ |j                  d      |
d d |f<     |||fS )NTFrS   )r<   rT   rK   r   r   r?   r  r!   r"   r7   r   r6   r   )list_of_list_of_tensorsr   numel_outputsout_jacobiansdiff_input_listcorrect_grad_sizescorrect_grad_typesr   tensor_listr   out_jacobianjrf   denses                 r   _stack_and_check_tensorsr[    s9   
 4FMJM=67O#$;< 7;a $Q'";/ 	7IAv!fkkmsxxz&A%*"#		(A%*"~QT"((* .4]]emm-KFOO%QW  $AqD)//1U[[]BBB%*]]2%6QT"	77  ,.@@@r   a  

NOTE: If your op relies on non-deterministic operations i.e., it is listed here:
https://pytorch.org/docs/stable/generated/torch.use_deterministic_algorithms.html
this failure might be expected.

If you are adding a new operator, please file an issue and then use one of the
workarounds. The workaround depends on how your test invokes gradcheck/gradgradcheck.
If the test
- manually invokes gradcheck/gradgradcheck, then call gradcheck/gradgradcheck
  with `nondet_tol=<tol>` as a keyword argument.
- is OpInfo-based (e.g., in test_ops_gradients.py), then modify the OpInfo for the test
  to have `gradcheck_nondet_tol=<tol>`.
- is a Module test (e.g., in common_nn.py), then modify the corresponding
  module_test entry to have `gradcheck_nondet_tol=<tol>`
c                    t        t        | d            fd}|r7t        |j                         |      }t        |j                         |      }n4t	        |j                               }t	        |j                               }|sj                         nd}	t        || |	      \  }
}}t        || |	      \  }}}t        |
||      }|s|rt        d      |st        d      |st        d| dt        z         |
S )NTc                 L    t         j                  j                  | dd      S NTretain_graphallow_unusedr"   r  gradgrad_outputrT  rE  s    r   vjp_fnz5_check_analytical_jacobian_attributes.<locals>.vjp_fn   +    ~~""O[tRV # 
 	
r   rP   zGradient has dtype mismatchz&Analytical gradient has incorrect sizezBackward is not reentrant, i.e., running backward with same input and grad_output multiple times gives different values, although analytical gradient matches numerical gradient.The tolerance for nondeterminism was r   )
rT   rK   (_get_analytical_vjps_wrt_specific_outputr   !_compute_analytical_jacobian_rowsr6   r[  rO  r   FAILED_NONDET_MSG)r   rE  
nondet_tolr  r   r   rf  vjps1vjps2output_numel
jacobians1types_oksizes_ok
jacobians2_	reentrantrT  s    `              @r   %_check_analytical_jacobian_attributesru    s    =67O
 8QRS8QRS1&&,,.I1&&,,.I)26<<>L%=v|&"J( 0v|LJ1&z:zJI):;;EFF4 5?<qB EVV
 	
 r   c           
      B   g }t        ||      D ]  \  }}t        | |||d|      }	g }
t        |	|      D ]  \  }}|j                  j                  d      }|j	                         rt        j                  |j                               }|j                  dd      }|j                  dd      }|
j                  |j                  |d         d|j                  |d         z  z          |
j                  |j                  |              |j                  |
        |S )NT)r   r   r   rS   rP   r   )r   ru  Tsqueezer.   r"   view_as_realresolve_conjselectr   dot)r   r   rk  r  r@  r  rA  rE  r   all_vJrF  vJr$  tvtrtis                   r   !_get_analytical_vJu_backward_moder  "  s    35%( 3	6FJ(9TQ
 02' 
	3EB aB}}''(9:YYr1%YYr1% ''qtrBFF1Q4L7H(HI ''q	2
	3 	  !12!3" r   aB  `get_analytical_jacobian` was part of PyTorch's private API and not meant to be exposed. We are deprecating it and it will be removed in a future version of PyTorch. If you have a specific use for this or feature request for this to be a stable API, please file us an issue at https://github.com/pytorch/pytorch/issues/newr  c                    |dk7  rt        d      j                         rt        d      t        t        | d            fd}t	        |j                               }t	        |j                               }j                         }t        || |      \  }}	}
t        || |      \  }}}t        |||      }|||
|	fS )Nr   zbExpected grad_out to be 1.0. get_analytical_jacobian no longer supports values of grad_out != 1.0.ztExpected output to be non-complex. get_analytical_jacobian no longer supports functions that return complex outputs.Tc                 L    t         j                  j                  | dd      S r^  rb  rd  s    r   rf  z'get_analytical_jacobian.<locals>.vjp_fnS  rg  r   )	r   r.   rT   rK   ri  r   r6   r[  rO  )r   rE  rk  r   rf  rl  rm  rn  ro  rp  rq  rr  rs  rt  rT  s    `            @r   r   r   :  s     	C2
 	
 E
 	
 =67O
 .ffllnEE-ffllnEE<<>L%=v|&"J( 0v|LJ1&z:zJIy(H44r   c                 B    t        | ||   t        d      d      }||   S )NinfF)rk  r  )ru  float)r   r   r  
output_idxr   s        r   _get_analytical_jacobianr  f  s.     6
#ePUI Yr   c           	         t        j                  |t         j                        }|j                  d      }g }t	        |j                               D ]  }|j                          d||<    | |      }t        |      D ]S  \  }}|dk(  r|j                  g        ||xx   t        |t         j                        r|j                         nd gz  cc<   U  |S )Nmemory_formatrS   r   r   )r"   r  legacy_contiguous_formatviewr   r6   r  r   r   rG   Tensorr   )	rf  sample_outputgrad_out_baseflat_grad_outjacobians_rowsrY  grad_inputsr   d_xs	            r   ri  ri  o  s     $$U%C%CM "&&r*M9;N=&&() 	a]+, 	FAsAv%%b)1)#u||<		$" 			 r   c                      | |j                  |j                              }|D cg c]/  }t        |t        j                        r|j                         nd g1 }}|S c c}w r    )r   r[   rG   r"   r  r   )rf  r  r   r  vjpvjpss         r   rh  rh    s[     =#6#678KLW0EH
354@0D 0 K0s   4Ac           	      d   d}t        |       D ]  \  }}t        |      s|j                  s |j                  t        j
                  k(  s6|j                  t        j                  k(  st        j                  d| d       |j                  r|j                         }nt        |      r|j                         }n|}|j                  t        j                  urGt        d t!        |j#                         |j%                               D              st'        d| d      d} |st)        d      y)	NFzInput #z requires gradient and is not a double precision floating point or complex. This check will likely fail if all the inputs are not of double precision floating point or complex. c              3   :   K   | ]  \  }}|d kD  xs |dk    yw)r   rP   Nr   )r   stszs      r   r   z _check_inputs.<locals>.<genexpr>  s,      B F%bAg%s   zThe zth input has a dimension with stride 0. gradcheck only supports inputs that are non-overlapping to be able to compute the numerical gradients correctly. You should call .contiguous on the input before passing it to gradcheck.Tzngradcheck expects at least one input tensor to require gradient, but none of the them have requires_grad=True.)r   r   r4   r?   r"   float64
complex128warningswarn	is_sparser   r(   ri   r!   rX   allr   rc   r   RuntimeErrorr   )tupled_inputsany_input_requiring_gradr   r   contents        r   _check_inputsr    s   $m, ,S#3#4#4II.#))u?O?O2OcU #J J }}++--c2**, ~~U]]2 "%gnn&6"G  'se $S S  (,$9,< $<
 	
 r   c                 x    t        d | D              rt        d      t        d | D              rt        d      y )Nc              3   h   K   | ]*  }t        |t        j                        st        |       , y wr    )rG   r"   r  r+   r   r:   s     r   r   z!_check_outputs.<locals>.<genexpr>  s#     
T
1ell8S #
Ts   22zySparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) on the output of fn for gradcheck.c              3      K   | ]<  }t        |t        j                        s|j                  t        j                  k(   > y wr    )rG   r"   r  r!   rX   r  s     r   r   z!_check_outputs.<locals>.<genexpr>  s*     
UAu||9T188u}}$
Us
   A"AzyMKLDNN output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) on the output of fn for gradcheck.)r   r   )r   s    r   _check_outputsr    sN    

TW
TT W
 	
 
Ug
UUW
 	
 Vr   c                    t        | ||||      }|D ];  }|D ]4  }t        j                  |d      j                         dkD  s+t	        d       = y)Nr   r   r   3Numerical gradient for function expected to be zeroT)r   r"   nerh   r   )funcr   r?  r   r   jacobians_all_inputs_outputs%jacobians_all_outputs_and_fixed_inputr   s           r    _check_no_differentiable_outputsr    sm    
 $;fhC}$  2N -= 	Hxx!$((*Q.$I 	 r   c                    t        ||      D ]q  \  }}t        | ||||      }	|	D ]X  }
|
j                         dk(  r|
t        j                  |
      z
  j                         j                         |kD  sOt        d       s y)Nr   r  T)r   r<  r6   r"   r  rI  rp   r   )r  r?  
all_inputsinputs_indicesr  r   rk  r   r$  r   jvps              r   %_check_no_differentiable_outputs_fastr    s     .%0 
4T7JPQSVW 	Cyy{ae&&s++002668:E$I 		 r   a  
gradcheck or gradgradcheck failed while testing batched gradient computation.
This could have been invoked in a number of ways (via a test that calls
gradcheck/gradgradcheck directly or via an autogenerated test).

If you are adding a new operator, please file an issue and then use one of the
workarounds. The workaround depends on how your test invokes gradcheck/gradgradcheck.
If the test
- manually invokes gradcheck/gradgradcheck, then call gradcheck/gradgradcheck
  with `check_batched_grad=False` as a keyword argument.
- is OpInfo-based (e.g., in test_ops_gradients.py), then modify the OpInfo for the test
  to have `check_batched_grad=False` and/or `check_batched_gradgrad=False`.

If you're modifying an existing operator that supports batched grad computation,
or wish to make a new operator work with batched grad computation, please read
the following.

To compute batched grads (e.g., jacobians, hessians), we vmap over the backward
computation. The most common failure case is if there is a 'vmap-incompatible
operation' in the backward pass. Please see
NOTE: [How to write vmap-compatible backward formulas]
in the codebase for an explanation of how to fix this.
a  
gradcheck failed while testing batched gradient computation with forward-mode AD.
This test is enabled automatically when both `check_batched_grad=True`
and `check_forward_ad=True`, but can be disabled in the following ways
dependong on how the test was invoked (via a test that calls gradcheck
directly or via an autogenerated test).

If you are adding a new operator, please file an issue and then use one of the
workarounds. The workaround depends on how your test invokes gradcheck/gradgradcheck.
If the test
- manually invokes gradcheck/gradgradcheck, then call gradcheck/gradgradcheck
  with `check_batched_forward_grad=False` as a keyword argument.
- is OpInfo-based (e.g., in test_ops_gradients.py), then modify the OpInfo for the test
  to have `check_batched_forward_grad=False`
c                 Z    d|  d| d|rt         nt         d| d| dj                         S )Nz
For output z and input z:

z

Got:
z

Expected:

)FAILED_BATCHED_GRAD_MSG_FWD_ADFAILED_BATCHED_GRAD_MSGstrip)r  r  r*  expr   s        r   !_get_failed_batched_grad_test_msgr    sT    <{9+ .#06M N O    
 
EG
r   c                 0    t         j                  j                  t        t              sJ t              D ]   \  t              rj                  sdt         j                  f fd}t              sEt        d      D cg c]  }t        j                         }}|D cg c]
  } ||       }}t        | D cg c]  }t        j                  |       }}	  t        |      t        j                  |            }t        t        ||            D ]7  \  \  }
}t        j$                  |
|      r t!        t'        |
|d             # yc c}w c c}w c c}w # t        $ r}	t!        d|	 dt"               |	d }	~	ww xY w)Ntangentc           	         
j                         5  
j                  j                         |       t        fdt	              D              }t         	|       }g }|D ]  }|
j                  |      \  }}||j                  |       .|j                  t        j                  g |j                  |j                        j                  |j                                t        |      cd d d        S # 1 sw Y   y xY w)Nc              3   l   K   | ]+  \  }}|k(  rnt        |      r|j                         n| - y wr    )r   ra   )r   r   r   dualr  s      r   r   z=_test_batched_grad_forward_ad.<locals>.jvp.<locals>.<genexpr>0  sA      ) !S i' *8*=#**,3H)s   14rN   )r  r  ra   r8   r   r   r  r   r"   r`   r?   r@   expandr[   )r  inputs_with_dualr&  r   dual_output
primal_outtangent_outr  current_inputr  r  r  r   s          @r   r  z*_test_batched_grad_forward_ad.<locals>.jvp-  s    " "~~m&:&:&<gF#( ) %.f$5	) $   )/?)@A#/ K"* .2.>.>{.K+J".

;/

!KK "**:*::CTCT$fZ%5%56 Sz-" " "s   CC<<Dr   (While computing batched gradients, got: 

Tr   )r"   r  r  rG   r8   r   r   r4   r  r/   r   
randn_liker   r   r   r  r   r  allcloser  )r  r   r  rs  tangentsr:   expectedshardsresultexr*  r  r  r  r  s   ``          @@@r   _test_batched_grad_forward_adr  %  s   >>$$Dfe$$$$-f$5 3 	=}--2M2M	" 	" 	"2 +=9=B1XFE$$]3FF$,-qCF--698nEFEKK'EE	U3ZH 56F &/s68/D%E 	!IzS~~c3' 1y#s$ 	Y3h ) G-E  	 :2$dCaBbc	s*   E"1E'E,+$E11	F:FFc           	      r   t        t        | d            t        j                  t        j
                  j                  |dd      fd}t        d      D cg c]  }t	        j                  |       }}|D cg c]
  } ||       }}t        | D cg c]  }t	        j                  |       }}t        j                         5  t        j                  dd       t        j                  dd       	  t        |      t	        j                  |            }		 d d d        t%        t        	|            D ]5  \  }\  }}t	        j&                  ||      r t!        t)        ||||             yc c}w c c}w c c}w # t        $ r}
t!        d	|
 d
t"               |
d }
~
ww xY w# 1 sw Y   xY w)NTr_  c                 P     |       }t        d t        |      D              }|S )Nc              3      K   | ]P  \  }}||nDt        j                  g |j                  |j                        j	                  |j
                         R y w)NrN   )r"   r`   r?   r@   r  r[   )r   rc  r   s      r   r   z2_test_batched_grad.<locals>.vjp.<locals>.<genexpr>q  sS      
 c  RsyyDKKCIIVW
s   AA)r8   r   )r   resultsrT  rc  s     r   r  z_test_batched_grad.<locals>.vjpo  s3    q' 
 !/:	
 
 r   r   ignorezThere is a performance drop)messagezPlease use torch.vmapr  r  )rT   rK   r   r   r"   r  rc  r   r  r   r   r  catch_warningsfilterwarningsr   r  r   r  r   r  r  )r   rE  r  r  rs  grad_outputsgOr  r  r  r  r  r*  r  rT  rc  s                 @@r   _test_batched_gradr  `  s    =56OD 7<Ah?E$$V,?L?"./BB/H/25x.AF#AHA 
	 	 	" 2OP2IJ		T#Yu{{<89F	 "+3vx+@!A 
	:C>>#s#-j)S#N
 	

 7 @/A  	
 !:2$dCZB[\	 s<   E7?E<F/F-<$F	F*F%%F**F--F6c                    t        t        |d            }|st        d      t        j                  j                  | || D cg c]'  }t        j                  |t        j                        ) c}d      }t        ||      D ]n  \  }}|
t        |t        j                        rv|j                  t        j                  k7  rX|j                  |j                  k7  r=t        dt        |j                        z   dz   t        |j                        z   dz         t        |      rt        |j                        j                  dd	      j                  d
d	      }|j!                         |j!                         k7  r0t        d| d|j!                          d|j!                                |j#                         |j#                         k7  r0t        d| d|j#                          d|j#                                |j%                         }|j%                         }|r4t        j&                  |t        j                  |            s5t        d      |j)                  d      j+                         st        d      |j,                  |j,                  k7  rt        d      |j.                  |j.                  k7  rt        d      |j1                         |j1                         k7  sft        d       yc c}w )NT(no Tensors requiring grad found in inputr  ra  zgrad is incorrect layout (z is not )ztorch.r   _coozgrad is z& tensor, but has incorrect sparse_dim z, expected z% tensor, but has incorrect dense_dim z&backward not multiplied by grad_outputr   zgrad is incorrect typezgrad is incorrect devicezgrad is incorrect size)rT   rK   r   r"   r  rc  r  r  r   rG   r  r!   r7   rJ   r+   replacer\   	dense_dimr   r  eqr  r?   r@   r   )	r   r   maskedrT  r   grads_inputgidisparse_kinds	            r   !_test_backward_mul_by_grad_outputr    s   *.}VT/J*KOGHH..%% 	
 Qe.L.LM	
  & K k?3 $;B:b%,,'BII,FyyBII%$0"))n% ! "))n% 	  %R(!"))n44XrBJJ6SUV==?bmmo5(";- 0MMO,K7HJ  <<>R\\^3(";- 0LLN+;r||~6FH  BB>>"e&6&6r&:;$%MNNq !IJJ88rxx !9::99		! !;<<779	! !9::I$;J W	
s   ,K6c                 X   t         j                  j                  }t        |      \  }}t	        ||d      \  }}}t        d |D              }	|j                         5  g }
g }t               }t        |      D ]  \  }}t        |      r|j                  r|j                  t         j                  k(  rt        d      |j                  |j                         t        j                   |            }|
j#                  |j%                  |      d          |j'                  |       |j#                  |        t        t)        |
|            D ](  \  }\  }}|j+                  |j-                  |             * t        |      D ]  \  }}||vr||   }|j                  |j                         t        j                   |            ||<   t/         | |       }t1        t2        |      }|j                         ||<   t/         | |       }t1        t2        |      }|||<   t        t)        ||            D ]_  \  }\  }}|j%                  |      \  }}|j%                  |      \  }}|4|7t        j4                  ||      rNt7        d|d|dd	|d
|	        	 d d d        y# 1 sw Y   yxY w)NTuse_forward_adc              3   R   K   | ]  }t        |      s|j                  s| ! y wr    r
  r  s     r   r   z/_test_undefined_forward_mode.<locals>.<genexpr>  r  r  r  rP   z2Mismatch in tangent values for output with index: z when input: z! has an undefined tangent value. z Got: z but expected: )r"   r  r  _get_inp_tensors_make_vectorsr8   r  setr   r   r4   r!   rX   r   r  ra   r  r   r  addr   r   r  r   r  r/   r  r   )r  r   r   r  inp_tensors_idxinp_tensorsr@  r  all_u_denser   r!  r"  tensor_indicesr   r   r#  r$  r   dual_inp_objr%  dual_outputs1dual_outputs2r'  d_o1d_o2val1res1val2res2s                                r   _test_undefined_forward_moder    s   >>$$D#3F#; O[ -k7SW XE5+UVUUM		 7' 	$FAsc"s'8'8::.$Q  nnSZZ\53C3CC3HI  0 0 5a 89""1%s#	$  )Xu)=> 	.OA|MM!))G,-	. "&) "	HC.(&s+L  $~~cjjlE<L<LS<QRK#D+$67K"#>LM  #zz|K#D+$67K"#>LM  ,K)23}m3T)U %$!--d3
d!--d3
d >>$5,P#+?$ - 
 
%"	+7p q7p s   HJ %J (J ?J  J)c           
        	
 t        t        |d            		st        d      d 
	
fdt         | |       D cg c]I  }t	        |t
        j                        r-t        j                  j                  j                         |      K c}g}t        |d         dkD  rt        t        |            D ]o  }t         | |       }|j                  t        |      D cg c]9  \  }}||k(  r-t        j                  j                  j                         |      n|; c}}       q t        fd|D              S c c}w c c}}w )NTr  c                  .    t        j                  d       y )Na   Backwards compatibility: New undefined gradient support checking feature is enabled by default, but it may break existing callers of this function. If this is true for you, you can call this function with "check_undefined_grad=False" to disable the feature)r  r  r   r   r   warn_bc_breakingz7_test_undefined_backward_mode.<locals>.warn_bc_breaking  s    P	
r   c                    | D cg c]'  }t        j                  |t         j                        ) }}	 t         j                  j	                  | |d      }t        |      D ]9  \  }}|	|j                  d      j                         r)         t        d       yc c}w # t
        $ r}         t        d      |d }~ww xY w)Nr  Tr  zExpected backward function to handle undefined output grads. Please look at "Notes about undefined output gradients" in "tools/autograd/derivatives.yaml"r   zExpected all input grads to be undefined or zero when all output grads are undefined or zero. Please look at "Notes about undefined output gradients" in "tools/autograd/derivatives.yaml")
r"   r  r  r  rc  r  r   r   r  r  )	output_to_checkr   grads_outputr  er  r   rT  r  s	          r   check_undefined_grad_supportzC_test_undefined_backward_mode.<locals>.check_undefined_grad_support  s     %
 Qe.L.LM
 

	..--,T . K o6 	EBq "$8 	 1
  	 4 		s   ,B!#B& &	C/CCr   rP   c              3   .   K   | ]  } |        y wr    r   )r   rE  r  s     r   r   z0_test_undefined_backward_mode.<locals>.<genexpr>O  s     S+F3Ss   )rT   rK   r   _differentiable_outputsrG   r"   r  _C
_functionsUndefinedGradr   r   r   r   r  )r  r   r   r   outputs_to_checkundef_grad_idxr
  r   r  rT  r  s           @@@r   _test_undefined_backward_moder    s0   *.}VT/J*KOGHH
> -T6];	
!U\\* HH--/2	
 A!##CL1 		N5dFmDO##
 #,O"<	 Q n, HH''557:		 SBRSSS+	
s   AD< >Ec                 b    t        | t              r| S t        | t              rt        |       S | fS r    )rG   r8   rT   rD   s    r   r   r   R  s+    !U	At	Qxtr   c                 8    t        d t        |       D              S )Nc              3   :   K   | ]  }|j                   s|  y wr    )r4   r   s     r   r   z*_differentiable_outputs.<locals>.<genexpr>\  s     <qAOO<s   )r8   r   r  s    r   r  r  [  s    <IaL<<<r   c                     | xr |xr ||v }|xr |xr ||v }|rdnd}	|rdnd}
|s|sdnd|	 d|
 d}|rd	nd}|d
||||| fz  z   S )N	imaginaryrealr   r   r   zWhile considering the z part of complex z only, zcomputed with forward mode zWJacobian %smismatch for output %d with respect to input %d,
numerical:%s
analytical:%s
r   )
analytical	numericalr  r  complex_indices	test_imagr   out_is_complexinp_is_complexpartelementprefixmodes                r   _get_notallclose_msgr'  _  s     	QQJ/4Q  #WW9;WN#;D'hYG . 	%dV+<WIWM 
 -:(rD (Y	:
>? 	?r   c                 $    t        t        |        S r    )rT   r   )matrix_of_tensorss    r   
_transposer*  {  s    &'((r   c                 d    d } || t         j                         || t         j                        fS )Nc                       fd}|S )Nc                  H    t         |        }t        fd|D              S )Nc              3   R   K   | ]  }|j                         r |      n|   y wr    r   )r   r   fn_to_applys     r   r   zU_real_and_imag_output.<locals>.apply_to_c_outs.<locals>.wrapped_fn.<locals>.<genexpr>  s"     OQ1<<>Qq@Or  )r   r8   )r   outsr   r/  s     r   r  zB_real_and_imag_output.<locals>.apply_to_c_outs.<locals>.wrapped_fn  s"    R[)DO$OOOr   r   )r   r/  r  s   `` r   apply_to_c_outsz._real_and_imag_output.<locals>.apply_to_c_outs  s    	P r   )r"   r  imag)r   r1  s     r   _real_and_imag_outputr3    s*     2uzz*OB

,KKKr   c                 B    fd} || d       } || d       }||fS )Nc                       fd}|S )Nc                  h    t        |       }D ]  } ||   |         ||<    t         |       S r    rT   r   )r   
new_inputsshould_be_complexcomplex_inp_indicesr   r/  r  s      r   r  zA_real_and_imag_input.<locals>.apply_to_c_inps.<locals>.wrapped_fn  sN    fJ%8 !0;01=AR3S1
,- R_--r   r   )r   r/  r  r:  r  s   `` r   apply_to_c_inpsz-_real_and_imag_input.<locals>.apply_to_c_inps  s    	. r   c                 &    | |j                   dz  z   S Nr   )r2  r   r   s     r   <lambda>z&_real_and_imag_input.<locals>.<lambda>  s    C$))b.4H r   c                 &    |j                   | dz  z   S r=  )r  r>  s     r   r?  z&_real_and_imag_input.<locals>.<lambda>  s    DIIb4H r   r   )r   r:  r  r;  real_fnimag_fns    ``   r   _real_and_imag_inputrC    s/    
	 b"HIGb"HIGGr   c                    t        |      D cg c]  \  }}|j                         s| }}}t        d t        |      D              }|
rf|rTt	        |      \  }} || }t        |      } | ||||||||||d        || }t        |      } | ||||||||||
       n | |||||||||	       |	r>t        |      D cg c]"  \  }}t        |      r|j                         r|$ }}}|rt        |||      \  }}|D cg c]+  }t        |      r|j                         r|j                  n|- }} || }t        |      } | ||||||||||dd       |D cg c]+  }t        |      r|j                         r|j                  n|- }} || }t        |      } | ||||||||||d       |rt        |||       t        |||       y y  | |||||||||d
       |rt        |||       y y y c c}}w c c}}w c c}w c c}w )Nc              3   <   K   | ]  }|j                           y wr    r   r   s     r   r   z'_gradcheck_real_imag.<locals>.<genexpr>  s      MA Mr   T)r  r   )r  )r  r   r  )r  r  r  )r   r.   r   r   r3  r  r   rC  r2  r  r  )gradcheck_fnr  r?  r  r   r   rtolrL  r  check_forward_adcheck_backward_adrk  check_undefined_gradr   r   complex_out_indiceshas_any_complex_outputrA  rB  imag_func_outimag_outputsreal_func_outreal_outputsr   r:  imag_inputsdiff_imag_func_outreal_inputsdiff_real_func_outs                                r   _gradcheck_real_imagrU    s    *37);NAq||~1NN  M89L MM!4T:GW#]3M2=AL! 3 $]3M2=AL! 3 !
  $M2
3c"s~~'7 
 

 3)= GW ) +3/CNN4D#MK  $[1M!8!G"! 3#" ) +3/CNN4D#MK  $[1M!8!G"! 3# $,Wm[Q,Wm[Q $ !# $,T7MJ $G c Od
*s   G4G4'G:0H 0H)r  r  r   r  c	                   t        |      }|st        | ||||	      S |r|n
t        |      }t        t	        | ||||	            }t        ||      D cg c]  \  }}|j                  s| }}}|	rt        | |||      }t        |      D ]b  \  }}t        |      D ]O  \  }}||   |   }t        ||j                  |j                        ||      r6t        t        |||||
|d             d yt        |      D ]v  \  }}t        ||||      }t        t        |||               D ]H  \  }\  }}t        ||j                  |j                        ||      r1t        t        |||||
|             x yc c}}w )Nr  )r  Tr  )r   r  rW   r*  r   r   r4   r-  r   _allclose_with_type_promotionr_   r@   r   r'  ru  )r  r?  r  r   r   rG  rL  r  rk  r  r  r   r  tupled_inputs_numericalr  r   njanalytical_forwardr   	n_per_outrY  nr   r  s                           r   _slow_gradcheckr]  )  s     "H/-s.
 	
 06m8M;R#(	
I "%Xy!9M2Q__MIM@-=N
 &i0 	LAy!), 1&q)!,4QQXXdS(,q!QRV 	*  g& 		DAq>q*.?J 's:y|'DE 	6Aq4QQXXdS(,Q1a)T 		 7 Ns   E8*E8c                 x    | j                         dk(  r|j                         dk(  sJ | |z  j                         S )NrP   )r   rh   )r$  r   s     r   r>  r>  j  s1    557a<AEEGqL((E;;=r   c                     t        j                  | j                  |j                        }| j                  |      } |j                  |      }t        j                  | |||      S r   )r"   promote_typesr?   r_   r  )r   r   rG  rL  promoted_types        r   rW  rW  o  sQ    ''9M	=!A	=!A>>!Qd++r   c                     | t         j                  k(  rt         j                  S | t         j                  k(  rt         j                  S | S r    )r"   r  r  	complex64float32rO   s    r   _to_real_dtypere  v  s5       }}	%//	!}}r   c                    | j                   t        j                  k(  r| j                         }|rt	        | j
                        n| j
                  }t        j                  |j                         |      j                  || j                        j                  |j                        }||j                         z  }t        j                  | j                         || j                         | j                        }|S t!        |       rK| j                   t        j"                  t        j$                  hv r!| j'                         | j)                         }}n | j+                         | j-                         }}| j/                         }|rt	        | j
                        n| j
                  }t        j                  |j                         |      j                  || j                        j                  |j                        }||j                         z  }t        j0                  |||| j                         | j                   | j                        }|S |rt	        | j
                        n| j
                  }t        j                  | j                         |      j                  || j                        }||j                         z  }|S )N)	generatorrN   r   )r!   r@   )r!   r"   r*   r   re  r?   randr6   r_   r@   r  r[   normrj   rY   r   r(   r#   r%   rm   r   rn   r   ri   sparse_compressed_tensor)	rD   rg  downcast_complexr   r?   ri   vecrx   plain_indicess	            r   _vec_from_tensorrn    s	    	xx5### 99;+;qww'JJx~~'9=ReAHHR-T(..! 	
 	&++-%%ajjlFAFFHQXXV8 J7 
&a	(88((%*:*:;;010@!--/010@!--/88:+;qww'JJx~~'9=ReAHHR-T(..! 	
 	&++-,,FFH8888
 J ,<qww'jji8;; < 
 	sxxzJr   c                     t        |       D cg c]   \  }}t        |      r|j                  r||f" }}}|D cg c]  }|d   	 c}|D cg c]  }|d   	 c}fS c c}}w c c}w c c}w r7  )r   r   r4   )r  r   r:   inp_idx_tuptups        r   r  r    st     m,Aq! 
AK 
 **sCF*{,KSV,KKK
 +,Ks   %AA#A(c                     t        |t              r|d   n|}|j                         }|dn|j                         }| t        |      z  t        |      z  S )Nr   r   )rG   r8   rh   r  )rL  r$  r   sum_usum_vs        r   _adjusted_atolru    sL     1e$!!AEEGE9C!%%'E%,u--r   a  
Fast gradcheck failed but element-wise differences are small. This means that the
test might've passed in slow_mode!

If you are adding a new operator, please file an issue and then use one of the
workarounds. The workaround depends on how your test invokes gradcheck/gradgradcheck:

If the test
- manually invokes gradcheck/gradgradcheck, then call gradcheck/gradgradcheck
  with `fast_mode=False` as a keyword argument.
- is OpInfo-based (e.g., in test_ops_gradients.py), then modify the OpInfo for the test
  to have `gradcheck_fast_mode=False`
- is a Module test (e.g., in common_nn.py), then modify the corresponding
  module_test entry to have `gradcheck_fast_mode=False`
c	                 B    t         |||            }	|r$ fd}
t        |
   f|   f      d   d   }nt        |      }|	|z
  j                         j	                         }t        j                  ||	||      }d|	 d| d| d}|r	|t        z  }|S )Nr  c                 F    t              }| |<   t         |          S r    r7  )r   r8  r  r  r  r  s     r   new_fnz,_run_slow_mode_and_get_error.<locals>.new_fn  s,    m,J$'Jy!T:./
;;r   r   a  
The above quantities relating the numerical and analytical jacobians are computed 
in fast mode. See: https://github.com/pytorch/pytorch/issues/53876 for more background 
about fast mode. Below, we recompute numerical and analytical jacobians in slow mode:

Numerical:
 z
Analytical:
z1

The max per-element difference (slow mode) is: z.
)r   r-  r  rI  rp   r"   r  FAST_FAIL_SLOW_OK_MSG)r  r  r   r  r  rG  rL  r   r   slow_numericalrx  slow_analyticalslow_max_diffslow_allclosemsgs   `` ``          r   _run_slow_mode_and_get_errorr    s     -mW#]N 	<
 >]9-/'*2E1G

 37Iz

 $o5::<@@BMNN?ND$OM	 '' ('( )::G	M  $$Jr   c                 Z    t        |       r| j                         j                  d      S | S )NrS   )r+   r   r   )rf   s    r   _to_flat_dense_if_sparser    s'    V$ ((,,r   c                   t        j                         }d }g }g }| D ]  } |||d      }t        |      }	|j                         r< |||d      }
|j	                  ||
f       t        |
      }|j	                  |	|f       d|j	                  |       |j	                  |	        |rd n|D cg c]  } |||       c}}|||fS c c}w )Nc                  h    t        j                  d      5  t        |  cd d d        S # 1 sw Y   y xY w)Ncpu)r"   r@   rn  )argss    r   _vec_from_tensor_cpuz+_make_vectors.<locals>._vec_from_tensor_cpu	  s-     \\%  	+#T*	+ 	+ 	+s   (1T)r"   	Generatorr  r.   r   )r  r   r  g_cpur  r  r  r   urur_denseuiui_denser;   r@  s                 r   r  r    s    OOE+ EK 
)!#ud3+B/>>%c5$7BLL"b"/3H(34LLx(
)  	:AB3"3.B 

 %$$ Cs   .Cr  c                   t        |      D ]  \  }}t        |      D ]  \  }}|r	| |   |   }n| |   |   }|j                  |j                        }t        |	||   |r||   nd       }t	        ||j                  |j                        ||      rtt        |||||||	|
|	      }t        t        |||||||      |z           y )Nr   )r   r_   r@   ru  rW  r  r   r'  )all_analyticalall_numericalr  r  r   r  r@  r  rG  rL  r   r   r   r   all_numerical_for_input_irY  r\  r   updated_atoljacobians_strs                       r   !_check_analytical_numerical_equalr  $  s      )2-(@ $$78 	DAq"1%a("1%a(AHH%A)$ae%(QUVL0ADDND,W <-!QdC! %(1aOY $$ 	r   c	                R   t        |      \  }}t        |||	      \  }}}|r|||fnt        |||f      \  }}}t        | |||||||	      }|	r|J t	        | |t        |      ||      }n#|st        | ||||||       t        ||||||      }t        |||
||| |||||||	       y)Nr  r  )r  r  T)	r  r  rW   rG  r-  r   r  r  r  )r  r?  r   r   r   rG  rL  r  rk  r  r  r   r  r  r  r@  r  r  inputs_numericalall_u_numericalall_v_numericalnumerical_vJuanalytical_vJus                          r   _fast_gradcheckr  I  s   " $4F#; O[ !.W^!E5+
 #)hu7M.N 7o '$	M }}<h/
 1hZ ;GZ):E;
 &$  r   gư>gh㈵>T)r   rL  rG  raise_exceptionrk  rJ  r  check_batched_gradcheck_batched_forward_gradrH  rI  r   r  r  r   r   rL  rG  r  rk  rJ  r  r  r  rH  rI  r   r  c                    |s	|sJ d       |	r	|sJ d       |
r	|sJ d       t               j                         }|j                  d       |s	 t        di |S t        di |S # t        $ r
}Y d}~yd}~ww xY w)a  Check gradients computed via small finite differences against analytical
    gradients wrt tensors in :attr:`inputs` that are of floating point or complex type
    and with ``requires_grad=True``.

    The check between numerical and analytical gradients uses :func:`~torch.allclose`.

    For most of the complex functions we consider for optimization purposes, no notion of
    Jacobian exists. Instead, gradcheck verifies if the numerical and analytical values of
    the Wirtinger and Conjugate Wirtinger derivatives are consistent. Because the gradient
    computation is done under the assumption that the overall function has a real-valued
    output, we treat functions with complex output in a special way. For these functions,
    gradcheck is applied to two real-valued functions corresponding to taking the real
    components of the complex outputs for the first, and taking the imaginary components
    of the complex outputs for the second. For more details, check out
    :ref:`complex_autograd-doc`.

    .. note::
        The default values are designed for :attr:`input` of double precision.
        This check will likely fail if :attr:`input` is of less precision, e.g.,
        ``FloatTensor``.

    .. note::
        Gradcheck may fail when evaluated on non-differentiable points
        because the numerically computed gradients via finite differencing may differ
        those computed analytically (not necessarily because either is incorrect).
        For more context, see :ref:`non-differentiable-func-grad`.

    .. warning::
       If any checked tensor in :attr:`input` has overlapping memory, i.e.,
       different indices pointing to the same memory address (e.g., from
       :func:`torch.Tensor.expand`), this check will likely fail because the numerical
       gradients computed by point perturbation at such indices will change
       values at all other indices that share the same memory address.

    Args:
        func (function): a Python function that takes Tensor inputs and returns
            a Tensor or a tuple of Tensors
        inputs (tuple of Tensor or Tensor): inputs to the function
        eps (float, optional): perturbation for finite differences
        atol (float, optional): absolute tolerance
        rtol (float, optional): relative tolerance
        raise_exception (bool, optional): indicating whether to raise an exception if
            the check fails. The exception gives more information about the
            exact nature of the failure. This is helpful when debugging gradchecks.
        nondet_tol (float, optional): tolerance for non-determinism. When running
            identical inputs through the differentiation, the results must either match
            exactly (default, 0.0) or be within this tolerance.
        check_undefined_grad (bool, optional): if ``True``, check if undefined output grads
            are supported and treated as zeros, for ``Tensor`` outputs.
        check_batched_grad (bool, optional): if ``True``, check if we can compute
            batched gradients using prototype vmap support. Defaults to False.
        check_batched_forward_grad (bool, optional): if ``True``, checks if we can compute
            batched forward gradients using forward ad and prototype vmap support. Defaults to ``False``.
        check_forward_ad (bool, optional): if ``True``, check that the gradients computed with forward
            mode AD match the numerical ones. Defaults to ``False``.
        check_backward_ad (bool, optional): if ``False``, do not perform any checks that rely on
            backward mode AD to be implemented. Defaults to ``True``.
        fast_mode (bool, optional): Fast mode for gradcheck and gradgradcheck is currently only
            implemented for R to R functions. If none of the inputs and outputs are complex
            a faster implementation of gradcheck that no longer computes the entire jacobian
            is run; otherwise, we fall back to the slow implementation.
        masked (bool, optional): if ``True``, the gradients of unspecified elements of
            sparse tensors are ignored. Defaults to ``False``.
    Returns:
        ``True`` if all differences satisfy allclose condition

    zIExpected at least one of check_forward_ad or check_backward_ad to be TruezESetting check_batched_grad=True requires check_backward_ad to be TruezLSetting check_batched_forward_grad=True requires check_forward_ad to be Truer  NFr   )localscopypop_gradcheck_helperr   )r  r   r   rL  rG  r  rk  rJ  r  r  r  rH  rI  r   r  r  r  s                    r   r   r     s    l 	-SRS- 	#4ONO  	#+;VUV  8==?DHH	$,t,, !(4((  		s   
A$ $	A72A7c                    t        |      }t        |        | | }t        |      }t        |       t	        j
                  |rt        nt        |      }t        || ||||||||
|||       |	rt        | |       |syt        |      D ]  \  }}|s	t        |||        t        |||       |r|rt        | ||       y)N)r  )rH  rI  rk  rJ  T)r   r  r  r  r   r   r  r]  rU  r  r   r  r  r  )r  r   r   rL  rG  rk  rJ  r  r  r  rH  rI  r   r  r  r?  r   rF  r   r   s                       r   r  r  
  s      f%M- ]#H%h/G7$$$/&L )+1  "%dM: '" 41}a34 &g}fE 1%dG]Cr   )r   rL  rG  gen_non_contig_grad_outputsr  rk  rJ  r  r  check_fwd_over_revcheck_rev_over_revr   r  r  r  r  r  c                    |s	|sJ d       |	r	|sJ d       |r	|sJ d       t        |      }|#t          |       }t        fd|D              }nt        |      }t        |      t	        |      D ch c]   \  }}t        |      s|j                  s|" c}}t	        |      D ch c]  \  }}|j                  s| c}} fd}t        |||z   ||||||	|
|||||      S c c}}w c c}}w )a+  Check gradients of gradients computed via small finite differences
    against analytical gradients wrt tensors in :attr:`inputs` and
    :attr:`grad_outputs` that are of floating point or complex type and with
    ``requires_grad=True``.

    This function checks that backpropagating through the gradients computed
    to the given :attr:`grad_outputs` are correct.

    The check between numerical and analytical gradients uses :func:`~torch.allclose`.

    .. note::
        The default values are designed for :attr:`input` and
        :attr:`grad_outputs` of double precision. This check will likely fail if
        they are of less precision, e.g., ``FloatTensor``.

    .. warning::
       If any checked tensor in :attr:`input` and :attr:`grad_outputs` has
       overlapping memory, i.e., different indices pointing to the same memory
       address (e.g., from :func:`torch.Tensor.expand`), this check will likely fail
       because the numerical gradients computed by point perturbation at such
       indices will change values at all other indices that share the same
       memory address.

    Args:
        func (function): a Python function that takes Tensor inputs and returns
            a Tensor or a tuple of Tensors
        inputs (tuple of Tensor or Tensor): inputs to the function
        grad_outputs (tuple of Tensor or Tensor, optional): The gradients with
            respect to the function's outputs.
        eps (float, optional): perturbation for finite differences
        atol (float, optional): absolute tolerance
        rtol (float, optional): relative tolerance
        gen_non_contig_grad_outputs (bool, optional): if :attr:`grad_outputs` is
            ``None`` and :attr:`gen_non_contig_grad_outputs` is ``True``, the
            randomly generated gradient outputs are made to be noncontiguous
        raise_exception (bool, optional): indicating whether to raise an exception if
            the check fails. The exception gives more information about the
            exact nature of the failure. This is helpful when debugging gradchecks.
        nondet_tol (float, optional): tolerance for non-determinism. When running
            identical inputs through the differentiation, the results must either match
            exactly (default, 0.0) or be within this tolerance. Note that a small amount
            of nondeterminism in the gradient will lead to larger inaccuracies in
            the second derivative.
        check_undefined_grad (bool, optional): if True, check if undefined output grads
            are supported and treated as zeros
        check_batched_grad (bool, optional): if True, check if we can compute
            batched gradients using prototype vmap support. Defaults to False.
        fast_mode (bool, optional): if True, run a faster implementation of gradgradcheck that
            no longer computes the entire jacobian.
        masked (bool, optional): if True, the gradients of unspecified elements of
            sparse tensors are ignored (default, False).
    Returns:
        True if all differences satisfy allclose condition
    zLExpected at least one of check_fwd_over_rev or check_rev_over_rev to be TruezHSetting check_undefined_grad=True requires check_rev_over_rev to be TruezFSetting check_batched_grad=True requires check_rev_over_rev to be Truec           
   3     K   | ]x  }t         j                  j                  |j                  |j	                         s|j                         r|j                  nt         j                  |j                  d dd       z yw)rS   rP   T)r?   r@   lowhighr4   noncontiguousN)	r"   testingmake_tensorr[   r-   r.   r?   doubler@   )r   rD   r  s     r   r   z gradgradcheck.<locals>.<genexpr>  sm      $
  MM%%&&(ALLN gg\\xx"9 & 
$
s   A>Bc                  N   t        fdt        | d 	        D              }t         |       }t        fdt        | 	 d        D              }t        fdt        |      D              }t        j                  j                  |||dd      }t        d |D              }|S )Nc              3   P   K   | ]  \  }}|v r|j                         n|  y wr    rl   r   r   rD   diff_input_args_indicess      r   r   z2gradgradcheck.<locals>.new_func.<locals>.<genexpr>  s3      
1 #$'>">AAE
   #&c              3   P   K   | ]  \  }}|v r|j                         n|  y wr    r  )r   r   rD   diff_grad_output_indicess      r   r   z2gradgradcheck.<locals>.new_func.<locals>.<genexpr>  s3      
1 #$'?"?AQF
r  c              3   2   K   | ]  \  }}|v s|  y wr    r   r  s      r   r   z2gradgradcheck.<locals>.new_func.<locals>.<genexpr>  s"       
!Q18O3OA 
s   T)create_graphra  c              3   &   K   | ]	  }||  y wr    r   )r   gs     r   r   z2gradgradcheck.<locals>.new_func.<locals>.<genexpr>  s     D!amADs   )r8   r   r  r"   r  rc  )
r  
input_argsr   r  diff_input_argsr  r  r  r  num_outputss
         r   new_funczgradgradcheck.<locals>.new_func  s     
!$}"56
 

 *$
*;< 
!$|}"56
 
    
#J/ 
 
 nn))_lTX * 
 D{DDr   )r   rL  rG  r  rk  rJ  r  r  r   rH  rI  r  )r   r  r8   r   r   r   r4   r   )r  r   r  r   rL  rG  r  r  rk  rJ  r  r  r  r  r   r  r  r   tupled_grad_outputsr   rD   r  r  r  r  s   `     `               @@@r   r   r   F  sO   T 	0VUV0 	%7RQR  	#5POP  f%M *$*>?# $
 $
 
 (5)*K
  .a.2C   34 a ( ++'1+-+, 7 s   ;C3C3C32C9C9)NN)F)NNr   F)Nr   r   r    )r1   N)NF)FN)r  r   )FF)frH   r   r  	itertoolsr   typingr   r   r   r   r   r	   r
   typing_extensionsr   r"   torch.testingtorch._vmap_internalsr   r   torch.overridesr   torch.typesr   __all__r  r   r  r(   r+   r/   r<   rC   boolrK   rW   r   r   FutureWarningr   r   r   intr   r   r   r   r-  r/  r   r  r8  r:  r<  rG  rO  r[  rj  ru  r  r   r  ri  rh  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  rJ   r'  r*  r3  rC  rU  r]  r>  rW  re  rn  r  ru  ry  r  r  r  r  r  r  r   r  r   r   r   r   <module>r     sm       I I I (   - * (H\ Hell Ou|| OQ
5<<" <@
5<<" QV	@U\\8ELL112	@IM	@ell	@;|d)P DI2	%c!
"#2j C
 !X!XH>@ 49	%,,6d5<<001
5<< SX<<080F
\\0" DIP
5<<P6 /44i
5s"#S()iX  27	%,,:A
5s"#T4/0A8 $ GK)
5<<)X0 C
 !5!5H 	$x%
&'6	$x%
&'&D &R
	", 
EG- 0" $ 49 84 8v4T 4n3$ 3l@F?TD ?TD=  	8)

L*DKd >B
,+\L. 
EG "%P%Z "` Ox  !%#$',""!!f)
3.//
0f)f) 
	f)
 f) f) f) f) f) f) f) !%f) f) f) f)  TN!f)" 
#f)R9~ 04Z
 (- !%#$$##Z
3((
)ZZ +,Z
 
Z Z Z "&Z Z Z Z Z Z Z Z  !Z" #Z$ 
%Zr   