a
    ==ich                     @   sp  d Z ddlmZ ddlmZmZmZmZmZ 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 ddlZddlZddlZddlZdd Zdd Zd	d
 Zdd Zdd Zejdedejjgdddejjdd ejdeejjgdddejjdd ejdeejjgdddejjdd ej e r4dn
e!dd dKddZ"ej#dfdd Z$ej#dd!fd"d#Z%dd$ej#dd!fd%d&Z&dd'ej#dfd(d)Z'd*d+ Z(dLd,d-Z)dd$ej#dde(d!fd.d/Z*dMd0d1Z+dd$ej#ddd!e(ej,fd2d3Z-d4d5 Z.dd$ej#dfd6d7Z/dd'ej#dfd8d9Z0e1 Z2ej1ej3d:Z4ej1ej5d:Z6ej1ej7d:Z8ej9r\e4gng Z:ej;rne6gng Z<ej=re8gng Z>e2ge: Z?e?e< Z@e2gd;d< eAeB D  ZCd=d> ZDd?d@ ZEeFeE eD dAZGeFeHe2geIe2gdAZJeFeHe:eIe:dAZKeFeHe>eIe>dAZLeFeHe?eIe?dAZMe	jNdNdCdDZOdOdEdFZPdPdGdHZQG dIdJ dJejRZSdS )Qaq  
The Hypothesis library uses *property-based testing* to check
invariants about the code under test under a variety of random inputs.

 The key idea here is to express properties of the code under test
(e.g. that it passes a gradient check, that it implements a reference
function, etc), and then generate random instances and verify they
satisfy these properties.

The main functions of interest are exposed on `HypothesisTestCase`.
You can usually just add a short function in this to generate an
arbitrary number of test cases for your operator.

The key functions are:

- `assertDeviceChecks(devices, op, inputs, outputs)`. This asserts that the
  operator computes the same outputs, regardless of which device it is executed
  on.
- `assertGradientChecks(device, op, inputs, output_,
  outputs_with_grads)`. This implements a standard numerical gradient checker
  for the operator in question.
- `assertReferenceChecks(device, op, inputs, reference)`. This runs the
  reference function (effectively calling `reference(*inputs)`, and comparing
  that to the output of output.

`hypothesis_test_util.py` exposes some useful pre-built samplers.

- `hu.gcs` - a gradient checker device (`gc`) and device checker devices (`dc`)

- `hu.gcs_cpu_only` - a CPU-only gradient checker device (`gc`) and
  device checker devices (`dc`). Used for when your operator is only
  implemented on the CPU.
    )
caffe2_pb2)	workspacedevice_checkergradient_checker	test_utilcoreNc                   C   s   t ddkpt ddkS )NZ
SANDCASTLE1ZTW_JOB_USER
sandcastle)osgetenv r   r   s/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/hypothesis_test_util.pyis_sandcastle8   s    r   c                   C   s
   dt jv S )NZTRAVIS)r
   environr   r   r   r   	is_travis<   s    r   c                 C   s   t dt dt| d S )Nfr   )structunpackpackfloatxr   r   r   
to_float32@   s    r   c                  O   s   d|v rt jjdkr|d d|v r<t jjdk r<|d d|v rrt jjdkrrd|vrh|d d |d< |d t j| i |S )Nmin_satisfying_examples)   8   r   deadline)   ,   r   timeoutg     @@)
hypothesisversion__version_info__popsettings)argskwargsr   r   r   r$   F   s    


r$   c                  O   s   t jjdk}d|v r"|s"|d d|vrv|rvd|d< |dd d urVt|d |d< |dd d urvt|d |d< tj| i |S )N)r   C   r   width    	min_value	max_value)r    r!   r"   r#   getr   stfloats)r%   r&   Zwidth_supportedr   r   r   r.   V   s    
r.   r	   T2      i'  )Zderandomizesuppress_health_checkdatabasemax_examplesr   	verbosityr   dev
   )r1   r2   r3   r   r4   r   debugi  iP  ZCAFFE2_HYPOTHESIS_PROFILE   c                 C   s   t j| |dS )Nr*   r+   )r-   integersr9   r   r   r   dims   s    r;   c                 C   s   d }| t ju rtdddd}n| t ju r8tdddd}nj| t ju rRtdddd}nP| t ju rltjddd	}n6| t ju rtjdd
d	}n| t j	u rt
 }ntd|d u r|S ||S )Ng      g      ?   )r*   r+   r(   r)   @   r   ir9   l    z*Unexpected dtype without elements provided)npfloat16r.   float32float64int32r-   r:   int64boolbooleans
ValueErrorfilter)dtypefilter_elemsr   r   r   elements_of_type   s    






rK   Fc                 C   s&   |d u rt |}tjjj|| ||dS )N)elementsunique)rK   r    extranumpyarrays)r;   rH   rL   rM   r   r   r   rP      s    rP   r   c                    s0   t jtf i || |d}| fddS )NZmin_sizemax_sizec                    s   t |  dS )N)rM   )rP   r;   rH   rL   rM   r   r   <lambda>       ztensor.<locals>.<lambda>r-   listsr;   flatmap)min_dimmax_dimrH   rL   rM   r&   dims_r   rT   r   tensor   s    r]   r=   c                 C   s   t dd||| |dS Nr0   r9   )r]   )min_lenmax_lenrH   rL   r   r   r   tensor1d   s    ra   c                 C   sh   | dkr t tjdgtjdS |rDt| gtjt  ddd S t| gtjt jdd|  ddS d S )Nr   shaperH   rH   rL   c                 S   s   t j| t jd| d  S )NrH   r   )r>   ZcumsumrB   r   r   r   r   rU      rV   zsegment_ids.<locals>.<lambda>   r9   )	r-   justr>   emptyrB   rP   rE   mapr:   )size	is_sortedr   r   r   segment_ids   s    rl   c                    s   |d u rd}|d u r }|dks$J ||ks0J  dkrX|dkrXt tjdgtjdS |dkshJ dt jt|d d|d d fdd fddt	tj
S )	Nr   rb   z(size is not 0, need at least one segmentr0   r9   c                    s    t jjjtj| tjd ddS )Nr   r9   )rL   )r    rN   rO   rP   r>   rB   r-   r:   )Znum_bordersrj   r   r   rU      s
    
zlengths.<locals>.<lambda>c                    s   t | t jd gt jdS )Nr   re   )r>   appendarrayrB   r   rm   r   r   rU      rV   )r-   rg   r>   rh   rB   r:   maxrY   ri   sorteddiff)rj   min_segmentsmax_segmentsr&   r   rm   r   lengths   s(    


ru   c           
         s^   |rt  nt d}t jtf i || |d}	t ||	dd }	|	 fddS )NFrQ   c                 S   s   | d rdgng | d  S )Nr   r0   r   pairr   r   r   rU      rV   z"segmented_tensor.<locals>.<lambda>c                    s    t t|  | d dS )Nr   rk   )r-   tuplesrP   )Z	data_dimsrH   rL   rk   segment_generatorr   r   rU      s   
)r-   rE   rg   rX   r;   ry   ri   rY   )
rZ   r[   rH   rk   rL   r{   allow_emptyr&   	gen_empty
data_dims_r   rz   r   segmented_tensor   s    
r   c                 O   s"   t jt| |d}t|d|i|S )N)rs   rt   r{   )	functoolspartialru   r   )rs   rt   r%   r&   genr   r   r   lengths_tensor   s    r   c                    s`   |rt  nt d}	t jtf i || |d}
t |	|
dd }| fddS )NFrQ   c                 S   s:   t t | d | d s.t jd| d d dnt dS )Nr0   r   r9   )r-   ry   rg   r:   rv   r   r   r   rU     s   z)sparse_segmented_tensor.<locals>.<lambda>c              
      sJ   t t| d  t| d t jd| d d d dd| d dS )Nr   r0   r9   rd   rx   )r-   ry   rP   r:   rS   rH   rL   rk   ityper{   r   r   rU     s   )r-   rE   rg   rX   r;   ry   rY   )rZ   r[   rH   rk   rL   r|   r{   r   r&   r}   r~   Z	all_dims_r   r   r   sparse_segmented_tensor  s    r   c                  K   s   t f dti| S )Nr{   )r   ru   )r&   r   r   r   sparse_lengths_tensor  s    r   c                    s0   t jtf i |||d}| fddS )NrQ   c                    s   t jt|  dS )NrQ   )r-   rX   rP   rS   rH   rL   nr   r   rU     s   
ztensors.<locals>.<lambda>rW   )r   rZ   r[   rH   rL   r&   r\   r   r   r   tensors  s    r   c              	   C   s   t | dd||||dS r^   )r   )r   r_   r`   rH   rL   r   r   r   	tensors1d"  s    r   )device_typec                 C   s   g | ]}t jtj|d qS ))r   Z	device_id)r   DeviceOptionr   GpuDeviceType).0ir   r   r   
<listcomp>5  s   r   c                   C   s
   t tS N)r-   rg   device_optionsr   r   r   r   device_checker_device_options:  s    r   c                   C   s
   t tS r   )r-   sampled_fromr   r   r   r   r   gradient_checker_device_option>  s    r   )gcdc   temp_wsc                 c   s0   t  }t | d d V  t   t | d S )NT)r   ZCurrentWorkspaceZSwitchWorkspaceZResetWorkspace)nameZold_ws_namer   r   r   temp_workspaceM  s
    r   c           
   	   C   s   t |}|j|  t }|j|g |jr8|jnd|_t	 l |pVt
|d }t|j|D ] \}}tj||||| d qdt| t|jd|d}	W d    n1 s0    Y  |	S )Ntestr   device_optionr0   T)copydeepcopyr   CopyFromr   ZNetDefopextendr   r   r   InferOpBlobDevicesAsDictzipinputr   FeedBlobr,   Z	CreateNetZBenchmarkNet)
r   r   inputsinput_device_optionsZ
iterationsnet_input_device_optionsr   bretr   r   r   runOpBenchmarkV  s$    


0r   c              	   C   s   t |}|j|  t  t|jt|krBtd|j|f |pRt	|d }t
|j|D ] \}}tj||||| d q`t| ttt|j}g }|D ]"}	|j|	 }
t|
}|| q|W  d    S 1 s0    Y  d S )N7must supply an input for each input on the op: %s vs %sr   r   )r   r   r   r   r   lenr   rF   r   r   r   r   r   r,   RunOperatorOncelistrangeoutput	FetchBlobrn   )r   r   r   r   r   r   r   outputs_to_checkoutsoutput_indexoutput_blob_namer   r   r   r   runOpOnInputq  s4    




r   c                   @   s^   e Zd ZdZdddZdd	d
ZdddZdddZdddZdddZ	de
fdfddZdS )HypothesisTestCasez
    A unittest.TestCase subclass with some helper functions for
    utilizing the `hypothesis` (hypothesis.readthedocs.io) library.
    N{Gz?c                 C   s(   t j||d}| ||||| dS )al  
        Asserts that the operator computes the same outputs, regardless of
        which device it is executed on.

        Useful for checking the consistency of GPU and CPU
        implementations of operators.

        Usage example:

            @given(inputs=hu.tensors(n=2), in_place=st.booleans(), **hu.gcs)
            def test_sum(self, inputs, in_place, gc, dc):
                op = core.CreateOperator("Sum", ["X1", "X2"],
                                                ["Y" if not in_place else "X1"])
                X1, X2 = inputs
                self.assertDeviceChecks(dc, op, [X1, X2], [0])
        )r   N)r   ZDeviceChecker
assertTrueCheckSimple)selfr   r   r   r   r   	thresholdr   r   r   r   assertDeviceChecks  s    z%HypothesisTestCase.assertDeviceChecks{Gzt?皙?Fc              	   C   sd   t j|||t||	d}|j||||||	|
d\}}}| |j|j | |dt|j|   dS )aj  
        Implements a standard numerical gradient checker for the operator
        in question.

        Useful for checking the consistency of the forward and
        backward implementations of operators.

        Usage example:

            @given(inputs=hu.tensors(n=2), in_place=st.booleans(), **hu.gcs)
            def test_sum(self, inputs, in_place, gc, dc):
                op = core.CreateOperator("Sum", ["X1", "X2"],
                                                ["Y" if not in_place else "X1"])
                X1, X2 = inputs
                self.assertGradientChecks(gc, op, [X1, X2], 0, [0])
        )stepsizer   r   Zworkspace_namer   )grad_opsr   ensure_outputs_are_inferredz Gradient check failed for input N)r   ZGradientCheckerstrr   assertEqualrc   r   r   )r   r   r   r   r   Zoutputs_with_gradsr   r   r   r   r   r   resZgradZgrad_estimatedr   r   r   assertGradientChecks  s$    z'HypothesisTestCase.assertGradientChecks-C6?c              	   C   s  |d }t j|g||i\}}	t|}
||
||}t|t| t| | t|t| t	|j
|D ]\}}|	|}|s| | qrt|t jr|}d }|}n|\}}|j}tt|}tjj||||d|d |d urrtt|j}tjj||ddd qrd S )NZ_gradz2Gradient {0} (x) is not matching the reference (y)atolrtolerr_msgr   )r   r   )r   ZGradientRegistryZGetBackwardPassr   r   r   ZRunOperatorsOncer   r   r   r   r,   ZassertIsNone
isinstanceZBlobReferencevaluesr   r>   testingassert_allcloseformatindices)r   r   r   Zref_outputsoutput_to_gradgrad_referencer   Zgrad_blob_namer   Zgrad_mapZoutput_gradZgrad_ref_outputsr   refZ
grad_namesZref_valsZref_indicesval_namevalsr   r   r   r   _assertGradReferenceChecks  sD    	




z-HypothesisTestCase._assertGradReferenceChecksc              
   C   s  |  | p||v d| ||vr(d S t|}t|tju r|jtdkrZtj	j
}q|jtdkrttj	j}q|jtdkrtj	j}q|jtdkrtj	j}qdtj}ntt|}ztjjt|| tjt|jtjd||| |jd |tj	jkrW d S tjj|| |d	||| |d W nN ty } z4tt| td
dksx|r||W Y d }~n
d }~0 0 d S )NzShape for {0} was not inferredrA   r@   rB   rC   z
unknown {}zShape {} mismatch: {} vs. {})r   zType {} mismatch: {} vs. {}CAFFE2_ASSERT_SHAPEINFERENCEr   )r   r   r   r   typer>   ZndarrayrH   r   ZTensorProtoDOUBLEFLOATZINT32ZINT64r   r   assert_array_equalro   ZastyperB   rc   Zassert_equalAssertionErrorloggingwarningr
   r   )r   r   shapestypesr   ensure_output_is_inferredZcorrect_typeer   r   r   _assertInferTensorChecks  sR    






z+HypothesisTestCase._assertInferTensorChecksc                 C   s  t |}|j| t T t|jt|krDtd|j|f |pTt	|d }t
|j|D ] \}}tj|||||d qbtd}| j|g d}zt|g\}}d}W nJ ty } z0tt| tddks|r|W Y d	}~n
d	}~0 0 t| || }t|ts:t|ts:td
|
sh| t|t|j ttt|j}
g }t
|
|D ]\}}|j| }t |}|j!j"dv rt#j$%|| n*|	d	u r|}	t#j$j&|||	|d'|d |r| j(|||||d |)| qv|d	ur`|d	usJ dt*|& | j+||||||d W d	   n1 sV0    Y  |W  d	   S 1 sz0    Y  d	S )a  
        This runs the reference Python function implementation
        (effectively calling `reference(*inputs)`, and compares that
        to the output of output, with an absolute/relative tolerance
        given by the `threshold` parameter.

        Useful for checking the implementation matches the Python
        (typically NumPy) implementation of the same functionality.

        Usage example:

            @given(X=hu.tensor(), inplace=st.booleans(), **hu.gcs)
            def test_softsign(self, X, inplace, gc, dc):
                op = core.CreateOperator(
                    "Softsign", ["X"], ["X" if inplace else "Y"])

                def softsign(X):
                    return (X / (1 + np.abs(X)),)

                self.assertReferenceChecks(gc, op, [X], softsign)
        r   r   r   ZopnetFTr   r   NzlYou are providing a wrong reference implementation. A proper one should return a tuple/list of numpy arrays.)SOz(Output {0} is not matching the referencer   )r   z=If grad_reference is set,output_to_grad has to be set as well)r   ),r   r   r   r   r   r   r   rF   r   r   r   r   r   r,   ZNetZProtor   r   ZInferShapesAndTypesRuntimeErrorr   r   r   r
   r   
RunNetOncer   tupler   r   r   r   r   rH   kindr>   r   r   r   r   r   rn   ZDeviceScoper   )r   r   r   r   	referencer   r   r   r   r   r   r   r   r   r   r   Ztest_shape_inferencer   r   r   Zreference_outputsr   r   r   r   r   r   r   r   assertReferenceChecksG  s    #








&z(HypothesisTestCase.assertReferenceChecksTc              	   C   s$  |r<t tt|jt|j t |jt |j ks<J dt|}|j| t	  |pjt
|d }t|j|D ] \}	}
tj|	|
||	|d qx|rt| t| dd |jD }|r|f i ttt|jt|j ||  n|||d W d    n1 s0    Y  d S )Nz0in-place ops are not supported in as_kwargs moder   r   c                 S   s   g | ]}t |qS r   )r   r   )r   r   r   r   r   r     rV   z=HypothesisTestCase.assertValidationChecks.<locals>.<listcomp>)r   outputs)r   setr   r   r   r   r   r   r   r   r   r   r   r   r   r,   r   r   dict)r   r   r   r   	validatorr   Z	as_kwargsZinit_netr   r   r   r   r   r   r   assertValidationChecks  s6    





z)HypothesisTestCase.assertValidationChecksc           
   	   C   s   t |}|j| t | |p.t|d }t|j|D ] \}}	t	j
||	|||d q<|d u rx| |t	j| n| ||t	j| W d    n1 s0    Y  d S )Nr   r   )r   r   r   r   r   r   r   r   r   r   r   r,   assertRaisesr   assertRaisesRegex)
r   r   r   r   r   	exceptionregexpr   r   r   r   r   r   assertRunOpRaises  s"    	


z$HypothesisTestCase.assertRunOpRaises)Nr   )Nr   r   NF)r   )F)Nr   NNNNF)NTN)__name__
__module____qualname____doc__r   r   r   r   r   r   	Exceptionr   r   r   r   r   r     s<     
(     
7 
0 
6       
q   
)r   )r0   r8   )NN)NN)r   )Nr6   )N)Tr   Zcaffe2.protor   Zcaffe2.pythonr   r   r   r   r   
contextlibr   r   r    Zhypothesis.extra.numpyZhypothesis.strategies
strategiesr-   r   rO   r>   r
   r   r   r   r   r$   r.   Zregister_profileZHealthCheckZtoo_slowZ	VerbosityverboseZload_profiler   r;   r@   rK   rP   r]   ra   rl   ru   r   r   rC   r   r   r   r   r   Zcpu_doCUDAZcuda_doZHIPZhip_dor   Zgpu_doZhas_cuda_supportZ_cuda_do_listZhas_hip_supportZ_hip_do_listZhas_gpu_supportZ_gpu_do_listZ_device_options_no_hipr   r   ZNumGpuDevicesZexpanded_device_optionsr   r   r   Zgcsr   rg   Zgcs_cpu_onlyZgcs_cuda_onlyZgcs_gpu_onlyZ
gcs_no_hipcontextmanagerr   r   r   ZTestCaser   r   r   r   r   <module>   s   &
	






	


  
 
 