U
    <c                    @   s  d dl Z d dlZ d dl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 d dlmZ d dlmZmZmZmZmZmZ d dlmZ d dlZd dlmZ d d	lmZmZmZ d d
lmZm Z m!Z!m"Z" d dl#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) dZ*dZ+dZ,dZ-e. Z/e/fddZ0G dd de.Z1G dd de.Z2e 3dddgZ4G dd de.Z5G dd de.Z6eG dd de.Z7d d! Z8d~d#d$Z9d%d& Z:G d'd( d(e7Z;d)d* Z<d+d, Z=d-d. Z>d/d/d0d1d2Z?d/d/d0d3d4Z@d/dd0d5d6ZAd/d7d8d9ZBd/d7d:d;ZCd/d/d0d<d=ZDd/d7d>d?ZEd/d7d@dAZFd/d/d0dBdCZGdDdE ZHG dFdG dGe7ZIddHdIZJdJdK ZKdLdM ZLdNdO ZMdPdQ ZNd/d7dRdSZOd/d7dTdUZPd/d7dVdWZQd/d7dXdYZRd/d7dZd[ZSd\d] ZTd^d_ ZUG d`da dae7ZVddbdcZWe	dddeZXG dfdg dge7ZYG dhdi die7ZZd/d/dddjdkdlZ[dmdn Z\G dodp dpe7Z]dqdr Z^d/d dsdtduZ_d/d dsdvdwZ`dxdy Zadzd{ Zbd|d} ZcdS )    N)asdict	dataclass)Enum)partial)product)AnyCallableIterableListOptionalTupledataclass_reprmake_tensor)skipCPUIfNoFFTtoltoleranceOverride)_dispatch_dtypesfloating_and_complex_typesfloating_and_complex_types_andfloating_types)is_iterable_of_tensorsnoncontiguous_likeTEST_WITH_ROCMtorch_to_numpy_dtype_dict)utils   
         c                 C   sL   z | dD ]}t| |} q| W S  tk
rF   |tk	r@| Y S  Y nX d S )N.)splitgetattrAttributeError_NOTHING)objnamedefaultpath r*   G/tmp/pip-unpacked-wheel-gikjz4vx/torch/testing/_internal/opinfo/core.py_getattr_qual/   s    r,   c                   @   s<   e Zd ZdZddddddgZdddd	d
ddZdd ZdS )DecorateInfozDescribes which test, or type of tests, should be wrapped in the given
    decorators when testing an operator. Any test that matches all provided
    arguments will be decorated. The decorators will only be applied if the
    active_if argument is True.
decoratorscls_name	test_namedevice_typedtypes	active_ifNT)r1   r2   r3   c                C   sf   t |tjjrt|n|g| _|| _|| _|| _|| _	|| _
| j	d k	rb| j	D ]}t |tjsLtqLd S N)
isinstancecollectionsabcSequencelistr.   r/   r0   r1   r2   r3   torchdtypeAssertionError)selfr.   r/   r0   r1   r2   r3   r;   r*   r*   r+   __init__J   s    


zDecorateInfo.__init__c                 C   sV   | j oT| jd ks| j|koT| jd ks.| j|koT| jd ksB| j|koT| jd kpT|| jkS r4   )r3   r/   r0   r1   r2   )r=   r/   r0   r1   r;   r*   r*   r+   	is_actived   s    zDecorateInfo.is_active)NN)__name__
__module____qualname____doc__	__slots__r>   r?   r*   r*   r*   r+   r-   ;   s      r-   c                   @   sx   e Zd ZdZddddddgZdddddd	d
dZddddddZdd Zdd Zdd Z	dd Z
dd Zdd ZdS )SampleInputz'Represents sample inputs to a function.inputargskwargsoutput_process_fn_gradbroadcasts_inputr'   NrG   rH   rI   rJ   r'   c          	      O   s   || _ |d k	s|d k	r(|s|rXtdn0t|s8t|rX|d krP|d krP|d ksXtd|d k	rd|n|| _t| jtszt|d k	r|n|| _t| jtst|d k	r|ndd | _|d k	r|nd| _	|d k	r|nd| _
d S )Nz
A SampleInput can be constructed "naturally" with *args and **kwargs or by
explicitly setting the "args" and "kwargs" paremeters, but the two
methods of construction cannot be mixed!zv
A SampleInput constructed "naturally" with *args and **kwargs
cannot specify additional metadata in keyword argumentsc                 S   s   | S r4   r*   xr*   r*   r+   <lambda>       z&SampleInput.__init__.<locals>.<lambda> F)rF   r<   lenrG   r5   tuplerH   dictrI   r'   rJ   )	r=   rF   rG   rH   rI   rJ   r'   Zvar_argsZ
var_kwargsr*   r*   r+   r>   ~   s8    zSampleInput.__init__rI   rJ   r'   c                C   s.   |d k	r|| _ |d k	r|| _|d k	r*|| _| S r4   rT   )r=   rI   rJ   r'   r*   r*   r+   with_metadata   s    zSampleInput.with_metadatac                 C   sl   d|| j  d|| j d|| j d| j d| j dt| j g}ddd	d
 |D  dS )Nzinput=zargs=zkwargs=zoutput_process_fn_grad=zbroadcasts_input=zname=zSampleInput(, c                 s   s   | ]}|d k	r|V  qd S r4   r*   .0ar*   r*   r+   	<genexpr>   s      z+SampleInput._repr_helper.<locals>.<genexpr>))rF   rG   rH   rI   rJ   reprr'   join)r=   	formatter	argumentsr*   r*   r+   _repr_helper   s    

	zSampleInput._repr_helperc                 C   s   |  dd S )Nc                 S   s   | S r4   r*   rL   r*   r*   r+   rN      rO   z&SampleInput.__repr__.<locals>.<lambda>r`   r=   r*   r*   r+   __repr__   s    zSampleInput.__repr__c                    s    fdd |   S )Nc                    s   t | tjr6tt| jdddd}d| dS t | trV fdd|  D S t	| rvdd	
t |  d S t | ttfrdd

t |  d S t| S )N(rP   r[   zTensor[]c                    s   i | ]\}}| |qS r*   r*   rX   kvr^   r*   r+   
<dictcomp>   s      z:SampleInput.summary.<locals>.formatter.<locals>.<dictcomp>zTensorList[rV   ,)r5   r:   TensorstrrR   shapereplacerS   itemsr   r]   mapr9   r\   )argrn   ri   r*   r+   r^      s    
z&SampleInput.summary.<locals>.formatterra   rb   r*   ri   r+   summary   s    zSampleInput.summaryc                    sN    fdd| j | j| j  }}}t|||| j| j| jd dS )Nc                    s    fdd}t | tjr || S t | tjr4|| S t | trLtt| S t | trdtt| S t | trfdd|  D S | S d S )Nc              
      s(   t    | W  5 Q R  S Q R X d S r4   )r:   no_gradt)fr*   r+   _tt   s    
z.SampleInput.transform.<locals>.tt.<locals>._ttc                    s   i | ]\}}| |qS r*   r*   rf   )ttr*   r+   rj      s      z5SampleInput.transform.<locals>.tt.<locals>.<dictcomp>)	r5   r:   rl   r;   r9   rq   rR   rS   rp   )rv   rx   rw   ry   r*   r+   ry      s    


z!SampleInput.transform.<locals>.ttZ_transformedrK   )rF   rG   rH   rE   rI   rJ   r'   )r=   rw   Zsample_tt_inputZtt_argsZ	tt_kwargsr*   rz   r+   	transform   s    
zSampleInput.transformc                 C   s   dd }|  |S )Nc                 S   s|   t | tjrd| jtjkr0|   tj	 S | jtj
krT|   tj	 S |   	 S t | tjrxt|  S | S r4   )r5   r:   rl   r;   bfloat16detachcputoZfloat32numpychalfZcfloatr   ru   r*   r*   r+   to_numpy  s    z#SampleInput.numpy.<locals>.to_numpyr{   )r=   r   r*   r*   r+   r     s    zSampleInput.numpyc                 C   s   dd }|  |S )Nc                 S   s(   t | tjrt| S t | tjr$| S | S r4   )r5   r:   rl   r   r;   ru   r*   r*   r+   to_noncontiguous$  s
    z3SampleInput.noncontiguous.<locals>.to_noncontiguousr   )r=   r   r*   r*   r+   noncontiguous#  s    zSampleInput.noncontiguous)r@   rA   rB   rC   rD   r>   rU   r`   rc   rs   r{   r   r   r*   r*   r*   r+   rE   r   s0   :  &rE   NumericsFilter	conditionZsafe_valc                   @   s(   e Zd ZdZdddgZedddZdS )	
ErrorInputzw
    A SampleInput that will cause the operation to throw an error plus information
    about the resulting error.
    sample_input
error_typeerror_regex)r   c                C   s   || _ || _|| _d S r4   )r   r   r   )r=   r   r   r   r*   r*   r+   r>   :  s    zErrorInput.__init__N)r@   rA   rB   rC   rD   RuntimeErrorr>   r*   r*   r*   r+   r   2  s   
r   c                   @   s    e Zd ZdZdd Zdd ZdS )	AliasInfozClass holds alias information. For example, torch.abs ->
    torch.absolute, torch.Tensor.absolute, torch.Tensor.absolute_
    c                 C   s:   || _ tt|| _ttj|d | _ttj|d d | _d S )N_)r'   r,   r:   opr#   rl   method_variantinplace_variant)r=   Z
alias_namer*   r*   r+   r>   E  s    zAliasInfo.__init__c                 O   s   | j ||S r4   r   r=   rG   rH   r*   r*   r+   __call__K  s    zAliasInfo.__call__N)r@   rA   rB   rC   r>   r   r*   r*   r*   r+   r   @  s   r   c                   @   s  e Zd ZU dZeed< dZee ed< dZ	e
ed< dZeed< dZeed< eZeed	< eZeed
< eZeed< eZeed< e Zeed< e Zeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZeed< dZ eed< dZ!eed< dZ"eed< dZ#eed< dZ$eed< dZ%e&ed< dZ'e&ed< dZ(e&ed < d!Z)e&ed"< dZ*e&ed#< d!Z+e&ed$< d!Z,e&ed%< d&d' Z-eed(< dZ.e&ed)< dZ/e&ed*< dZ0e&ed+< dZ1e&ed,< d-Z2e3ed.< dZ4e&ed/< dZ5eed0< dZ6ee ed1< dZ7ee ed2< d!Z8e&ed3< dZ9e:e ed4< dZ;e:e ed5< d!Z<e&ed6< dZ=e&ed7< dZ>e&ed8< d!Z?e&ed9< d!Z@e&ed:< d!ZAe&ed;< d!ZBe&ed<< dZCe&ed=< dZDe&ed>< d!ZEe&ed?< d!ZFe&ed@< d!ZGe&edA< dBdC ZHdDdE ZIdFdG ZJdHdI ZKdJdK ZLdLdM ZMdNdO ZNdPdQ ZOdndRdSZPdodTdUZQdpdVdWZRdXdY ZSdqdZd[ZTdrd\d]ZUdsd^d_ZVdtd`daZWdudbdcZXddde ZYdfdg ZZdhdi Z[djdk Z\e]dldm Z^dS )vOpInfoz;Operator information and helper functions for acquiring it.r'   NrefaliasesrP   variant_test_namer   r   r   operator_variantinplace_operator_variantskipsr.   sample_inputs_funcreference_inputs_funcerror_inputs_funcsample_inputs_sparse_coo_funcsample_inputs_sparse_csr_funcsample_inputs_sparse_csc_funcsample_inputs_sparse_bsr_funcsample_inputs_sparse_bsc_funcr2   dtypesIfCUDAdtypesIfROCMbackward_dtypesbackward_dtypesIfCUDAbackward_dtypesIfROCMTsupports_outsupports_autogradsupports_gradgradFsupports_fwgrad_bwgradsupports_inplace_autogradsupports_forward_adsupports_varargsc                 O   s
   | ||S r4   r*   )r   rG   rH   r*   r*   r+   rN     rO   zOpInfo.<lambda>gradcheck_wrappercheck_batched_gradcheck_batched_gradgradcheck_batched_forward_grad"check_inplace_batched_forward_grad        gradcheck_nondet_tolgradcheck_fast_mode	aten_namedecomp_aten_nameaten_backward_nameassert_autodiffedautodiff_nonfusible_nodesautodiff_fusible_nodessupports_sparsesupports_scriptingsupports_tracingsupports_sparse_csrsupports_sparse_cscsupports_sparse_bsrsupports_sparse_bsctest_conjugated_samplestest_neg_viewassert_jit_shape_analysissupports_expanded_weightis_factory_functionc                 C   s  t |  | _| jd k	s(td| j| j| j| jf}|D ]}t	|t
td fs<tq<| jd krj| j| _ttdd || _| jrt	| jtjstd| j dt| j| _| jd k	rt| jnF| jd k	r| jn6| jd k	r| jn&| jd k	r| jn| jd k	r| jn| j| _| jd k	r$t| jn(| jd k	r6| jn| jd k	rH| jn| j| _| jd k	rft| jn| j| _| jd k	rt| jn| j| _| jd k	rt| jn| j| _| jstt| j| _| jtkrttj| jd | _t| jsd | _| jtkr| jd }ttj|d | _| jtkr2tt | jd | _| j!tkrj| jd k	rdd| j }tt |d | _!nd | _!| j"| j#| _"t$ | j%| _%t$ | j&| _&t$ | j'| _'t$ | j(| _(t$ | j)| _)t$ | j*| _*| j+d k	rt$ | j+| _+| j,sg | _,| j-d krd| j g| _-| j.d kr2| j/| _.n| j.rJ| j/sJtd	| j0d krh| j/pb| j1| _0n | j0r| j/s| j1std
| j2d kr| j.| _2n| j2r| j.std| j3d kr| j1| _3n| j3r| j1std| j4d kr| j3| _4n| j4r| j3std| j5r0| j/s0td| jf| j6d krN| j/pH| j1| _6n | j6rn| j/sn| j1sntd| j7d k	rt8dd | j7D | _7nd| _7d S )NzOpInfo for {0} has no dtypes!c                 S   s   t | tjS r4   )r5   r   _dynamic_dispatch_dtypes)r2   r*   r*   r+   rN   b  rO   z&OpInfo.__post_init__.<locals>.<lambda>z"To use dynamic dypes for operator z, acquire the dtypes dynamically for argument `dtypesIfCUDA`.This is to ensure that CUDA dtypes are acquired correctly as theydiffer from CPU dtypes occasionallyr   izaten::zrsupports_gradgrad refines the part of autograd is supported, so it should not be set if supports_autograd is Falsezcheck_batched_grad refines the part of autograd that will be checked (by gradcheck), so it should not be set if supports_autograd is Falsezcheck_batched_gradgrad refines the part of autograd that will be checked (by gradgradcheck), so it should not be set if either supports_gradgrad or supports_autograd is False.zcheck_batched_forward_grad should only be used when supports_forward_ad is True. It is used to disable the test in the specific cases where the op supports forward ad but fails to compute batched forward grad.a  check_batched_forward_grad should only be used when check_batched_forward_grad is True. It is used to disable the test in the specific cases where the op supports batched forward grad but fails to compute batched forward grad for the inplace variant of the op.zsupports_fwgrad_bwgrad enables forward-over-backward gradgrad checks and should only be True if backward ad is also checked, i.e., supports_forward_ad should be True.zsupports_inplace_autograd refines the part of autograd that is supported, so it should not be set if both supports_autograd and supports_forward_ad are Falsec                 s   s   | ]}t |V  qd S r4   )r   rW   r*   r*   r+   rZ   &  s     z'OpInfo.__post_init__.<locals>.<genexpr>r*   )9r   copyZ_original_opinfo_argsr2   r<   formatr'   r   r   r5   r   typer   anyrq   Zdynamic_dtypesr   r   setr   r   r   r   r,   r:   r   r%   r#   rl   callabler   r   operatorr   r.   r   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rR   )r=   Zdtypes_argsZ
dtype_listZinplace_nameZinplace_operator_namer*   r*   r+   __post_init__O  s&   





  


	

	zOpInfo.__post_init__c                 O   s   | j ||S )z+Calls the function variant of the operator.r   r   r*   r*   r+   r   *  s    zOpInfo.__call__c                 C   s   t | S r4   r   rb   r*   r*   r+   __str__.  s    zOpInfo.__str__c                 C   s   | j S )z>Returns the function variant of the operator, torch.<op_name>.r   rb   r*   r*   r+   get_op1  s    zOpInfo.get_opc                 C   s   | j S )zReturns the method variant of the operator, torch.Tensor.<op_name>.
        Returns None if the operator has no method variant.
        )r   rb   r*   r*   r+   
get_method5  s    zOpInfo.get_methodc                 C   s   | j S )zReturns the inplace variant of the operator, torch.Tensor.<op_name>_.
        Returns None if the operator has no inplace variant.
        )r   rb   r*   r*   r+   get_inplace;  s    zOpInfo.get_inplacec                 C   s   | j S )zReturns operator variant of the operator, e.g. operator.neg
        Returns None if the operator has no operator variant.
        )r   rb   r*   r*   r+   get_operatorA  s    zOpInfo.get_operatorc                 C   s   | j S )zReturns the inplace operator variant of the operator, e.g operator.iadd
        Returns None if the operator has no inplace operator variant)r   rb   r*   r*   r+   get_inplace_operatorG  s    zOpInfo.get_inplace_operatorc           
      K   sv   | j | |||f|}t|}dd }t|D ]@\}}	|| }	t|	jtjrX||	j|	_q,||	jd |	jd< q,t|S )z~Returns an iterable of SampleInputs but with the tensor input or first
        tensor in a sequence input conjugated.
        c                 S   s   | j }|  } | |S r4   )requires_gradZconjrequires_grad_)tensorZ_requires_gradr*   r*   r+   	conjugateT  s    z1OpInfo.conjugate_sample_inputs.<locals>.conjugater   )r   r9   	enumerater5   rF   r:   rl   rR   )
r=   devicer;   r   rH   samplesconj_samplesr   r   sampler*   r*   r+   conjugate_sample_inputsL  s    zOpInfo.conjugate_sample_inputsc                 K   sP   | j | |||f|}|ddrL| j|||f|}t|}|| t|}|S )z
        Returns an iterable of SampleInputs.

        These samples should be sufficient to test the function works correctly
        with autograd, TorchScript, etc.
        include_conjugated_inputsF)r   getr   r9   extendrR   )r=   r   r;   r   rH   r   r   Zsamples_listr*   r*   r+   sample_inputsc  s      
zOpInfo.sample_inputsc                 K   sB   | j dkr| j| |||f|S |ddr.t| j | |||f|S )z
        Returns an iterable of SampleInputs.

        Distinct from sample_inputs() above because this returns an expanded set
        of inputs when reference_inputs_func is defined. If undefined this returns
        the sample inputs.
        Nr   F)r   r   r   NotImplementedErrorr=   r   r;   r   rH   r*   r*   r+   reference_inputsv  s
    
zOpInfo.reference_inputsc                 K   s   | j | |f|S )z5
        Returns an iterable of ErrorInputs.
        r   )r=   r   rH   r*   r*   r+   error_inputs  s    zOpInfo.error_inputsc                 K   s   | j | |||f|S )z`Returns an iterable of SampleInputs that contain inputs with sparse
        coo layout.
        )r   r   r*   r*   r+   sample_inputs_sparse_coo  s       zOpInfo.sample_inputs_sparse_cooc                 K   s   | j | |||f|S )z`Returns an iterable of SampleInputs that contain inputs with sparse
        csr layout.
        )r   r   r*   r*   r+   sample_inputs_sparse_csr  s       zOpInfo.sample_inputs_sparse_csrc                 K   s   | j | |||f|S )z`Returns an iterable of SampleInputs that contain inputs with sparse
        csc layout.
        )r   r   r*   r*   r+   sample_inputs_sparse_csc  s       zOpInfo.sample_inputs_sparse_cscc                 K   s   | j | |||f|S )z`Returns an iterable of SampleInputs that contain inputs with sparse
        bsr layout.
        )r   r   r*   r*   r+   sample_inputs_sparse_bsr  s       zOpInfo.sample_inputs_sparse_bsrc                 K   s   | j | |||f|S )z`Returns an iterable of SampleInputs that contain inputs with sparse
        bsc layout.
        )r   r   r*   r*   r+   sample_inputs_sparse_bsc  s       zOpInfo.sample_inputs_sparse_bscc                 C   sF   g }| j D ]6}t|tr6|||||r@||j  q
|| q
|S )z0Returns the decorators targeting the given test.)r.   r5   r-   r?   r   append)r=   Z
test_classr0   r   r;   result	decoratorr*   r*   r+   get_decorators  s    

zOpInfo.get_decoratorsc                 C   s0   |dkr| j S |dkr&tr | jS | jS | j S d S Nr~   Zcuda)r2   r   r   r   )r=   r1   r*   r*   r+   supported_dtypes  s
    zOpInfo.supported_dtypesc                 C   s`   | j st S d }|dkr | j}n |dkr:tr2| jn| j}n| j}ttjtj	tj
}t||S r   )r   r   r   r   r   r   r   r:   r|   float16	complex32intersection)r=   r1   r   Zallowed_backward_dtypesr*   r*   r+   supported_backward_dtypes  s"      z OpInfo.supported_backward_dtypesc                 C   s   ||  |kS r4   )r   )r=   r;   r1   r*   r*   r+   supports_dtype  s    zOpInfo.supports_dtypec                 C   s2   | j rd| j dd nd}d| jdd|S )zMReturns a formatted full name for this OpInfo that can be used in test names.r   r!   rP   z{}{})r   ro   r   r'   )r=   variantr*   r*   r+   formatted_name  s
    zOpInfo.formatted_name)F)F)F)F)F)F)F)F)_r@   rA   rB   rC   rm   __annotations__r   r   r   r   r	   r   r   r%   r   r   r   r   rR   r   r   r.   r   r   r   r   r   r   r   r   r2   r   r   r   r   r   r   r   boolr   r   r   r   r   r   r   r   r   r   r   r   floatr   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr   r*   r*   r*   r+   r   e  s   
 \







r   c                 k   sZ   t g || |dV  t dg|| |dV  t ddg|| |dV  t ddddg|| |dV  dS )z7Generates input tensors for testing reduction operators)r;   r   r      r    r      Nr   )r   r;   r   rH   r*   r*   r+   _generate_reduction_inputs  s    
   r  Tc                 c   s   i V  dddV  dddV  | dkr6| d ddV  |rt t| ddV  | dkrbdddV  | d	krt td| dddV  d
S )zGenerates a subset of all valid dim and keepdim kwargs given ndim that
    is appropriate for testing reduction operators.
    r   T)dimkeepdimFr  r  r   r  r    N)rR   range)ndimsupports_multiple_dimsr*   r*   r+   _generate_reduction_kwargs  s    r  c           
      k   s~   | dd}| ddd }t|||D ]P}t|j|D ]>}||f|D ],\}	}|| t| ||	|dV  qHq8q(dS )z&Sample inputs for reduction operators.r  Tgenerate_args_kwargsc                     s   t  i fV S r4   rR   rG   rH   r*   r*   r+   rN     rO   z)sample_inputs_reduction.<locals>.<lambda>r  N)r   r  r  r  updaterE   r}   r   )
op_infor   r;   r   rH   r  r  rv   Zreduction_kwargsrG   r*   r*   r+   sample_inputs_reduction  s"      
  r  c                
       s\   e Zd ZdZdddddddd
dddee ee eeeeej	 ee
d fdd	Z  ZS )ReductionOpInfoa  Reduction operator information.

    An operator is a reduction operator if it reduces one or more dimensions of
    the input tensor to a single value. Reduction operators must implement the
    following signature:

    - `op(input, *args, *, dim=None, keepdim=False, **kwargs) -> Tensor`

    ReductionOpInfo tests that reduction operators implement a consistent API.
    Optional features such as reducing over multiple dimensions are captured in
    the optional keyword parameters of the ReductionOpInfo constructor.

    If a reduction operator does not yet implement the full required API of
    reduction operators, this should be documented by xfailing the failing
    tests rather than adding optional parameters to ReductionOpInfo.

    NOTE
    The API for reduction operators has not yet been finalized and some
    requirements may change.

    See tests in test/test_reductions.py
    NTFc                 c   s   t  i fV S r4   r  )rv   r  r  r*   r*   r+   rN   j  s    zReductionOpInfo.<lambda>)identity
nan_policyr  promotes_int_to_floatpromotes_int_to_int64result_dtypecomplex_to_realr  c                   s   t   | _|dkst|r$|r$t|r0|r0t|r<|r<t|rH|rHt fdd}|
dd  |
d| t j|f|
 || _|| _| _	|| _
|| _|| _|| _ | _d S )N)N	propagateZomitc                  ?   s$   |d<  |d< t | |E d H  d S )Nr  r  )r  r  r  r  r*   r+   r   }  s    z4ReductionOpInfo.__init__.<locals>.sample_inputs_funcr   r   )localsr   Z_original_reduction_argsr<   
setdefaultsuperr>   r  r  r  r  r  r  r  r  )r=   r'   r  r  r  r  r  r  r  r  rH   r   	__class__r  r+   r>   P  s$    !zReductionOpInfo.__init__)NF)r@   rA   rB   rC   r   r   rm   r   r:   r;   r   r>   __classcell__r*   r*   r   r+   r  8  s&   r  c                 k   s   | j | |||f|E d H  t| ||||dE d H  |tjk	rRt| |||dE d H  |tjtjtjfkr|t| |||dE d H  t| ||||dE d H  t	| |||dE d H  t
| |||dE d H  |js|jrt| |||dE d H  d S )Nr   r;   r   exclude_zeror   r;   r   )r   #generate_elementwise_binary_tensorsr:   r   /generate_elementwise_binary_small_value_tensorsuint8int8/generate_elementwise_binary_large_value_tensors0generate_elementwise_binary_broadcasting_tensors/generate_elementwise_binary_with_scalar_samplesBgenerate_elementwise_binary_with_scalar_and_type_promotion_samplesis_floating_point
is_complex2generate_elementwise_binary_extremal_value_tensors)r   r   r;   r   r$  rH   r*   r*   r+   $_reference_inputs_elementwise_binary  s`    
               r1  c                 k   s   t | dr| jdd}tt| ||||f|}| E d H  | D ]}| V  q@t| ||||dE d H  t| ||||dE d H  d S )Nrhs_make_tensor_kwargsr$  Fr#  )hasattrr2  r   r   r1  r   1generate_elementwise_binary_noncontiguous_tensors7generate_elementwise_binary_arbitrarily_strided_tensors)r   r   r;   r   rH   r$  genr   r*   r*   r+   #reference_inputs_elementwise_binary  s:    

r7  c                    s    fdd}|S )Nc                 ;   s    d k	r | |f|E d H  | j sHttjd|ddd}t|tddV  | jsvtdtjd|dfd}t|tddV  |dd	s| jstdd
d}t|tddV  d S )N)r  r  r    r   r  rG   rP   )r   r   r  Zskip_two_python_scalarsFr    )	supports_rhs_python_scalarrE   r:   r   r   	Exceptionsupports_one_python_scalarr   supports_two_python_scalars)r   r   rH   sir   r*   r+   error_inputs_func_wrapper  s    
zGmake_error_inputs_elementwise_binary.<locals>.error_inputs_func_wrapperr*   )r   rA  r*   r   r+   $make_error_inputs_elementwise_binary  s    rB  F)r   r$  c          
      c   sP   d}t t||||d}|D ]0}||f| j}||f| j}	t||	fdV  qd S )N)r   r  r   r    r*   )r   i,  i  i  r#  r:  )r   r   lhs_make_tensor_kwargsr2  rE   )
r   r   r;   r   r$  shapesmake_argrn   lhsrhsr*   r*   r+   r&    s    r&  c                c   sT   d}t t||||d}|D ]4\}}}	|d|||	}
||}t|
|fdV  qd S )N))r      r  r  r     r  ))r   r      rN  r  )r   r   r  )rP  r   rO  r    )rQ  )r   r   rO  r    )rQ  )r   r   r   r    ))	   r   r  )r   r  rO  r    r#    r:  )r   r   
as_stridedrE   )r   r   r;   r   r$  strided_casesrI  rn   stridesoffsetrY   br*   r*   r+   r5  %  s$    	  r5  c                c   s~  |d kr t | dr | jdd}d}d}dddd	d
dddtj d tjd tj d tjd tj tjtj d tjd f}g }g }	|jrt||}
np|jrt||}tt	dd |}t||}
nB|t
jt
jt
jt
jfkrt||}
n|t
jkrt||}
ntd|
D ]:\}}|| |dkr8|r8|	d n
|	| q
t
j||||d}t
j|	|||d}t||fdV  d S )Nr2  r$  F)	r   r  7                     )r   r  r  irY  irZ  ir   g       gMbPgMbP?g      пg      ?            ?r  h㈵>c                 S   s   t |  S r4   complexrL   r*   r*   r+   rN   k  rO   zAgenerate_elementwise_binary_small_value_tensors.<locals>.<lambda>Unsupported dtype!r   r  r%  r:  )r3  r2  r   mathpir.  r   r/  r9   rq   r:   r)  int16int32int64r(  
ValueErrorr   r   rE   )r   r   r;   r   r$  Z_unsigned_int_valsZ	_int_valsZ_float_valsl_valsr_valsprodcomplex_valslrrJ  rK  r*   r*   r+   r'  E  sV    






r'  )r   c                c   s   d}d}|d }g }g }|t jkr.t||}	nh|jr@t||}	nV|jrnt||}
ttdd |
}
t|
|
}	n(|t jt jt j	fkrt||}	nt
d|	D ]\}}|| || qt j||||d}t j||||d}t||fdV  d S )	N)iiY  i3i)  )ii  gIgI@g>g>@)gLSgLSAg@xg@xDc                 S   s   t |  S r4   rc  rL   r*   r*   r+   rN     rO   zAgenerate_elementwise_binary_large_value_tensors.<locals>.<lambda>re  r%  r:  )r:   r   r   r.  r/  r9   rq   rh  ri  rj  rk  r   r   rE   )r   r   r;   r   Z_large_int_valsZ_large_float16_valsZ_large_float_valsrl  rm  rn  ro  rp  rq  rJ  rK  r*   r*   r+   r*    s,    


r*  c                c   s4  t dt dt df}g }g }|jr0t||}n6|jr^t||}ttdd |}t||}ntd|D ]\}	}
||	 ||
 qjtj	||||d}tj	||||d}t
||fdV  |jrt dntt dt d}td	|||d}|| d d d
< td	|||d}|| d d d
< t
||fdV  d S )Ninfz-infnanc                 S   s   t |  S r4   rc  rL   r*   r*   r+   rN     rO   zDgenerate_elementwise_binary_extremal_value_tensors.<locals>.<lambda>re  r%  r:  )r[  r[  r    )r  r.  r   r/  r9   rq   rk  r   r:   r   rE   rd  r   flatten)r   r   r;   r   Z_float_extremalsrl  rm  rn  ro  rp  rq  rJ  rK  rs  r*   r*   r+   r0    sB    

      r0  c                c   sx   d}t t||||d}t|ddgD ]N\}}|\}	}
||	fd|i| j}||
fd|i| j}t||fddV  q$d S )N))r  r*   )r9  r*   )ru  r9  ))r  r  r9  )r  r  r9  )r    r  r9  )r  r    r  r9  )rx  rw  )r    r  r  rw  ))r  r    r  r*   )ry  rx  r#  TFr   )rG   rJ   )r   r   r   rG  r2  rE   )r   r   r;   r   r$  rH  rI  rn   r   	shape_lhs	shape_rhsrJ  rK  r*   r*   r+   r+    s2    r+  c                c   s   t t|||d}d}| jr|D ]P}||f| j}||f| j}|d| j }	|d| j }
t||
fdV  q| jrt|	|fdV  | jr|d| j }	|d| j }
t|	|
fdV  d S )	Nr%  )r*   r;  )r   r    )r   r  r    )r  r   r*   r:  )r*   )r*   )r*   )r*   )	r   r   r<  rG  r2  itemrE   r>  r?  )r   r   r;   r   rI  rH  rn   rJ  rK  Z
lhs_scalarZ
rhs_scalarr*   r*   r+   r,    s(       r,  c                c   s   | j dkrtt|||d}d}tdtdtd f}tdd |D }| jr||f| j}||f| j}	|| D ]*}
t||
fdV  | j	rrt|
|	fdV  qrd S )	N)	eqnegtgeltlelogical_and
logical_orlogical_xorr%  )   rs  rr  c                 s   s   | ]}t |V  qd S r4   )r:   r   )rX   valr*   r*   r+   rZ   *  s     zUgenerate_elementwise_binary_with_scalar_and_type_promotion_samples.<locals>.<genexpr>r:  )
r'   r   r   r  rR   r<  rG  r2  rE   r>  )r   r   r;   r   rI  rn   valuesZscalar_tensorsrJ  rK  Zscalarr*   r*   r+   r-    s"    
   r-  c                c   s  t t||||d}|dddi| j}|dddi| j}t| | fdV  t| |fdV  |d| j}|d| j}t|j|jfdV  d}|D ]}	||	f| j}||	f| j}tj	|	d ||d	d
 }
|

| tj	|	d ||d	d
 }|
| t|
 | fdV  t|
 |fdV  qd}	||	f| j}||	f| j}|d d ddf }
|d d ddf }t|
 | fdV  t|
 |fdV  d}|D ]N}	||	f| j}||	f| j}|ddd}
|ddd}t|
|fdV  qd S )Nr#  i  r   Tr:  i  ie  )r   rO  )   r9  r   r;   ).r   )r  r  r  r  r  .)r  r    )r  rO  r  r    r  )r  )r  )r  )r  )r   r   rG  r2  rE   clone
contiguousTr:   emptyZcopy_expand)r   r   r;   r   r$  rI  rJ  rK  rH  rn   Zlhs_non_contigZrhs_non_contigr*   r*   r+   r4  6  sL    	

r4  c                 k   s*  | ddrtnt}| ddr$tnt}t| dr@| j dd}tt||||d}d|fdf|df|ff||fdf|||f||ff|||f|||ff|d|f||ff|d|fd||ffd	dtfd	|tfff	}	| d
i }
|	D ]H\}}||f| j}||f| j}|t	
||k}t||f|
|dV  qd S )Nsmall_inputs_onlyFr2  r$  r#  )r*   r*   r*   r  r   sample_kwargs)rG   rH   rJ   )r   SMXSr3  r2  r   r   rG  r:   Zbroadcast_shapesrE   )r   r   r;   r   rH   Z_MZ_Sr$  rI  rH  r  rz  r{  rJ  rK  rJ   r*   r*   r+    sample_inputs_elementwise_binaryw  s@    
	
   r  c                       s8   e Zd ZdZeeddddddddd
 fdd
Z  ZS )BinaryUfuncInfoa'  Operator information for 'universal binary functions (binary ufuncs).'
    These are functions of two tensors with common properties like:
      - they are elementwise functions
      - the output shape is determined by the input shape
      - they typically have method and inplace variants
      - they typically support the out kwarg
      - they typically have NumPy or SciPy references
    See NumPy's universal function documentation
    (https://numpy.org/doc/stable/reference/ufuncs.html) for more details
    about the concept of ufuncs.
    NFT)
r   r   r   rG  r2  r  always_returns_boolr<  r>  r?  c       
            s   t   | _ttdddf}|dt | |d< tt	| j
|f||t|d| |d krfi }|| _|d krxi }|| _|| _|| _|	| _|
| _|| _| jrd| _| jr|	stdd S )NzSkipping redundant test.
TestCommonZtest_numpy_refsr   )r   r   r   Tz=Can't support lhs and rhs Python scalars but not rhs scalars!)r  r   Z_original_binary_ufunc_argsr-   unittestskipr   rR   r  r  r>   rB  rG  r2  r  r  r<  r>  r?  r<   )r=   r'   r   r   r   rG  r2  r  r  r<  r>  r?  rH   Zcommon_skipsr   r*   r+   r>     sF    
	zBinaryUfuncInfo.__init__)r@   rA   rB   rC   r  r7  r>   r"  r*   r*   r   r+   r    s   r  c           
   
   k   s   |si }| ddrtnt}| j\}}|d kr2|n|| j }|d krH|n|| j }| jsj| jsj| jsj| jrt	t
||f|||||d|dV  n0|fddfD ]"}	t	t
|	|||||d|dV  qd S )Nr  F)r   r;   lowhighr   rH   rD  r*   )r   r  Ldomain_domain_epsr   r   r   r   rE   r   )
r  r   r;   r   Z	op_kwargsrH   _Lr  r  rn   r*   r*   r+   sample_inputs_elementwise_unary  sJ    

r  c                 C   s   || }|  || d S r4   )Zmasked_fill_)r   r   
safe_valuemaskr*   r*   r+   _replace_values_in_tensor  s    r  c          	      K   s|   |j \}}|d kr|n||j }|d kr,|n||j }t| f|||d|}|jd k	rx|tjk	rx|j\}}t||| |S )N)r  r  r;   )r  r  r   reference_numerics_filterr:   r   r  )	rn   r   r;   rH   r  r  rY   r   r  r*   r*   r+   _make_unary_elementwise_tensor!  s    

r  c                C   s
  | j tjkr| S |j\}}|d kr&|n||j }|d kr<|n||j }| j tjkrd|d k	rdt|d}| j js| j js|d k	rt	
|nd }|d k	rt	|nd }|jd k	r|j\}}t| || |d k	s|d k	r| j jr| j|| | j|| n| j||d | S )Nr   )minmax)r;   r:   r   r  r  r(  r  r.  r/  rf  ceilfloorr  r  realZclamp_imag)rY   r   r  r  r   r  r*   r*   r+    _filter_unary_elementwise_tensor1  s&    



r  c          
   
   k   s   |t jkrt jd|t jdt jd|dt jd|dt jd|dtd||dtd||df}|D ] }t|| |||d d	V  q^d
}tt| |||d}|D ](}	||	}t|| |||d d	V  qd S )Nr   r  Tr8  F)TFrE  rF  r  )rF  rE  rC  )r   r    r    )r  r   r   )rM  r   r   r   )r    r   r  r   r   r   r;   r   )	r:   r   r  r   r   rE   r  r   r  )
r   r   r;   r   rH   ZtensorsrY   rH  rI  rn   r*   r*   r+   "generate_elementwise_unary_tensorsO  s*    
r  c                c   sD   t | |||dD ].}t|j| d}t|| |||d dV  qd S Nr%  r   r   r  )r'  r  rF   rE   r  r   r   r;   r   r   rY   r*   r*   r+   .generate_elementwise_unary_small_value_tensorsu  s       
r  c                c   sF   t | |||dD ]0}t|j| d}t|j| |||d dV  qd S r  )r*  r  rF   rE   r  r  r*   r*   r+   .generate_elementwise_unary_large_value_tensors  s       
r  c                c   s:   t | |||dD ]$}t|j| |||jd dV  qd S )Nr%  r   r  )r0  rE   rF   r  )r   r   r;   r   r   r*   r*   r+   1generate_elementwise_unary_extremal_value_tensors  s       
 r  c                c   s   | j \}}|d kr|n|| j }|d kr,|n|| j }tt| |||d}|ddd}t|| |||d dV  |dj}t|| |||d dV  d}|D ]6}	||	}|d	d
d
}
t|
| |||
d dV  qd S )Nr  r  T)r   r   r  )r  r  r  r    r  )r  r  r   r  rE   r  r  r  )r   r   r;   r   r  r  rI  rv   rH  rn   Zt_non_contigr*   r*   r+   0generate_elementwise_unary_noncontiguous_tensors  s,    
	
 r  c          
      c   sV   d}t t|||d}|D ]8\}}}|d|||}	t|	| |||	d dV  qd S )NrL  r%  rS  r   r  )r   r   rT  rE   r  )
r   r   r;   r   rU  rI  rn   rV  rW  rY   r*   r*   r+   6generate_elementwise_unary_arbitrarily_strided_tensors  s     	     r  c                 k   s   | j | |||f|E d H  t| f|||d|E d H  |tjk	r`t| f|||d|E d H  |tjtjtjfkr| js|js|j	st
| f|||d|E d H  |js| jr|j	rt| f|||d|E d H  d S Nr%  )r   r  r:   r   r  r(  r)  handles_large_floatsr.  r/  r  handles_complex_extremal_valuesr  )r   r   r;   r   rH   r*   r*   r+   #_reference_inputs_elementwise_unary  sd      
      r  c                 k   sv   t t| |||f|}| E d H  | D ]}| V  q&t| f|||d|E d H  t| f|||d|E d H  d S r  )r   r  r   r  r  )r   r   r;   r   rH   r6  r   r*   r*   r+   "reference_inputs_elementwise_unary  s<        
    r  c                
       s<   e Zd ZdZe ddddeedd dd	 fd	d

Z  ZS )UnaryUfuncInfoa  Operator information for 'universal unary functions (unary ufuncs).'
    These are functions of a single tensor with common properties like:
      - they are elementwise functions
      - the input shape is the output shape
      - they typically have method and inplace variants
      - they typically support the out kwarg
      - they typically have NumPy or SciPy references
    See NumPy's universal function documentation
    (https://numpy.org/doc/1.18/reference/ufuncs.html) for more details
    about the concept of ufuncs.
    )NNTFc                 C   s   i i fS r4   r*   )r   r;   rF   r*   r*   r+   rN   	  rO   zUnaryUfuncInfo.<lambda>N)	r2   r  r  r  supports_complex_to_floatr   r   r  r  c       	            sV   t   | _t j|f|||d| || _|| _|| _|| _|
| _	|	| _
d| _d S )N)r2   r   r   rb  )r  r   Z_original_unary_ufunc_argsr  r>   r  r  r  r  r  r  r  )r=   r'   r2   r  r  r  r  r   r   r  r  rH   r   r*   r+   r>   	  s"    zUnaryUfuncInfo.__init__)	r@   rA   rB   rC   r   r  r  r>   r"  r*   r*   r   r+   r  	  s   r  c           
   
      s8  |t jkp|t jk}|sLttttd td f|||d ttd|||d}nxd }d }| jdkrdd}	n,| jdkrtd}	n| jd	krd
}	d}d}nd}	tt|	d |||||d tt|	d |||||d}| jtj	kr2t
  t|sdndddddt
  tdddt
  tdddt
| f fdddD S | jtjkrt
  t|sRdndddddt
  tdddt
  t|sdndddt
  tdddt
  tdddt
  tdddgS t
  t|sd nd!ddd"dt
  tdddt
  t|sd#nd!d$dt
| f fd%dd&D S d S )'Nr  r  r%  )   )zfft.hfftz	fft.irfftz_refs.fft.hfftz_refs.fft.irfft))r  rR  rR  !   )z	fft.hfft2z
fft.irfft2z_refs.fft.hfft2z_refs.fft.irfft2))r     rR  r  )z	fft.hfftnz
fft.irfftnz_refs.fft.hfftnz_refs.fft.irfftn))r  r  r  r  r`  ra  ))r  r     )    r   )r   r  r  r;   r   )r    r   )rP  r  rv  Zortho)sr  normr  )r  )r  )r  c                 3   s"   | ]}t   t|d dV  qdS r  r  NrE   rS   rX   r  Z	nd_tensorr*   r+   rZ   	  s   z-sample_inputs_spectral_ops.<locals>.<genexpr>)r  r	  )rM  r  r  r	  )r  r  r  r   r  )nr  r  rO  )r  c                 3   s"   | ]}t   t|d dV  qdS r  r  r  r  r*   r+   rZ   	  s     )r  r  r  )r:   r   halfr   r   r  r'   ndimensionalSpectralFuncTypeNDrE   rS   TwoD)
r=   r   r;   r   rH   Zis_fp16_or_chalfZoned_tensorr  r  rH  r*   r  r+   sample_inputs_spectral_ops9	  s        


	


 r  r  )ZOneDr  r  c                       s4   e Zd ZdZde edded fddZ  ZS )SpectralFuncInfoz.Operator information for torch.fft transforms.N)r   r2   r   r.   )r  c                   s   t t  | _| j| |d k	r,t|ng }|tttt	j
tddiddg7 }t jf ||||d| || _|| _d S )Ng{Gz?r  Z#test_complex_half_reference_testing)r'   r2   r.   r   )rS   r  r   Z_original_spectral_func_argsr  r9   r   r-   r   r:   r   r   r  r>   r   r  )r=   r'   r   r2   r  r   r.   rH   r   r*   r+   r>   	  s*    	zSpectralFuncInfo.__init__)	r@   rA   rB   rC   r   r  r  r>   r"  r*   r*   r   r+   r  	  s   r  c                       s.   e Zd ZdZe dddd fdd
Z  ZS )ShapeFuncInfozZEarly version of a specialized OpInfo for Shape manipulating operations like tile and rollNr2   r   r   r   c                   s,   t t| j|f||||d| || _d S )Nr  )r  r  r>   r   )r=   r'   r   r2   r   r   r   rH   r   r*   r+   r>   	  s    
zShapeFuncInfo.__init__)r@   rA   rB   rC   r   r>   r"  r*   r*   r   r+   r  	  s   r  )r   	same_sizer  r  c                   s@   |r  fddt  D S  fddt  D S d S )Nc                    s    g | ]}t   fd qS )r;   r   r   r   )rX   r   Nr   r;   r   r*   r+   
<listcomp>	  s   z)sample_inputs_foreach.<locals>.<listcomp>c                    s(   g | ] }t  |  | fd qS r  r   )rX   r   r  r*   r+   r  	  s      )r
  )r=   r   r;   r  r   r  r  r  r*   r  r+   sample_inputs_foreach	  s    r  c                 C   sR   d|  }|d }t t|d }t t|d }t t| d }t tj| d d }||||fS )N	_foreach_r   )r#   r:   rl   )r'   Zop_nameZinplace_op_namer   Z
inplace_opr   ref_inplacer*   r*   r+   get_foreach_method_names	  s    r  c                       s4   e Zd ZdZe eejddef fdd	Z	  Z
S )ForeachFuncInfoz;Early version of a specialized OpInfo for foreach functionsNFc                    sf   t  jd| f||||d| t|\}}	}
}|| _|	| _|
| _|| _|| _|dkrbtj	j
| _d S )Nr  r  r  )r  r>   r  r   r   r   r  supports_alpha_paramr:   ZlinalgZvector_norm)r=   r'   r2   r   r   r  r   rH   Zforeach_methodZforeach_method_inplaceZtorch_ref_methodZtorch_ref_inplacer   r*   r+   r>   
  s.    
zForeachFuncInfo.__init__)r@   rA   rB   rC   r   r   r:   r  r  r>   r"  r*   r*   r   r+   r  
  s   r  c                 O   s   | ||j  f||S )zGradcheck wrapper for functions that take Hermitian matrices as input.

    They require a modified function because the finite-difference algorithm
    for calculating derivatives does not preserve the Hermitian property of the input.
    )ZmH)r   rF   rG   rH   r*   r*   r+   !gradcheck_wrapper_hermitian_input.
  s    r  upperidxc                O   sF   |r||   n
||  }| |d| |f||d d |f|S )aJ  Gradcheck wrapper for functions that take lower or upper triangular matrices as input.

    They require a modified function because the finite-difference algorithm
    for calculating derivatives does not preserve the triangular property of the input.
    `idx` is used to specific which `args[idx]` is to be triangularized.
    Nr  )ZtriuZtril)r   r  r  rG   rH   Ztriangular_argr*   r*   r+   "gradcheck_wrapper_triangular_input7
  s    r  c                O   st   || }| ddd}t|}t|}t|}	|| |	 }
t| f|d| |
f||d d ||d|S )zGradcheck wrapper for functions that take lower/upper triangular matrices
    with real and positive diagonals, for example, cholesky-like operations.
    r   r  r  Nr  r  )Zdiagonalr:   Z
diag_embedZ	ones_liker  )r   r  r  rG   rH   rr   Zarg_diagZarg_diag_embedZid_diag_tensorZ	id_tensorZnew_argr*   r*   r+   9gradcheck_wrapper_triangular_input_real_positive_diagonalB
  s&    



  r  c                 O   sP   | |f||}| d}|dk	rLtjj| |f||}t|||g }|S )zGradcheck wrapper for masked operations.

    When mask is specified, replaces masked-out elements with zeros.

    Use for operations that produce non-finite masked-out elements,
    for instance, for minimum and maximum reductions.
    r  N)r   r:   maskedZ_output_maskwhere	new_zeros)r   rF   rG   rH   outputr  output_maskr*   r*   r+   "gradcheck_wrapper_masked_operationT
  s    
r  c           
      O   s~   | |f||}| d}| d}|dk	rz|dk	rzt||}tf d|i|}tjj|f||}	t|	||g }|S )aS  Gradcheck wrapper for masked pointwise operations. Assumes that the result
    will be masked iff both tensors are masked at a specific index

    When mask is specified, replaces masked-out elements with zeros.

    Use for operations that produce non-finite masked-out elements,
    for instance, for minimum and maximum reductions.
    
input_mask
other_maskNr  )r   r:   r  rS   r  Z_input_maskr  r  )
r   rF   rG   rH   r  r  r  Zcombined_maskZ
new_kwargsr  r*   r*   r+   ,gradcheck_wrapper_masked_pointwise_operationd
  s    	

r  c                    sL   dd  |r|n| j }t | jtt | jt fdd| D dS )z
    Given a SampleInput, this function analyzes its input, args and kwargs,
    and produces a copy with each non-Tensor entry being copied by reference,
    and with each Tensor entry cloned with `t.clone().requires_grad_(t.requires_grad)`
    c                 S   s(   t | tjr |   | jS | S d S r4   )r5   r:   rl   r}   r  r   r   ru   r*   r*   r+   clone_tensor
  s    z"clone_sample.<locals>.clone_tensorc                 3   s   | ]\}}| |fV  qd S r4   r*   rf   r  r*   r+   rZ   
  s     zclone_sample.<locals>.<genexpr>r  )rH   rE   rF   rR   rq   rG   rS   rp   )r   rH   r  r*   r  r+   clone_samplex
  s    r  )T)N)F)dr6   collections.abcrf  r   r  Zdataclassesr   r   enumr   	functoolsr   	itertoolsr   typingr   r   r	   r
   r   r   Ztorchgen.utilsr   r:   Ztorch.testingr   Z*torch.testing._internal.common_device_typer   r   r   Z$torch.testing._internal.common_dtyper   r   r   r   Z$torch.testing._internal.common_utilsr   r   r   r   Ztorch.testing._internal.opinfor   r  r  r  r  objectr%   r,   r-   rE   
namedtupler   r   r   r   r  r  r  r  r1  r7  rB  r&  r5  r'  r*  r0  r+  r,  r-  r4  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r*   r*   r*   r+   <module>   s    7 >  '     	

'Z*($  ! =$/ &# A)M 
/'#8
m
'   &	 