U
    hdk                     @   s  d dl Zd dlmZmZmZmZm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Zdd Zdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Z d!d" Z!d#d$ Z"d%d& Z#d'd( Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(d1d2 Z)d3d4 Z*d5d6 Z+d7d8 Z,d9d: Z-d;d< Z.d=d> Z/d?d@ Z0dAdB Z1dCdD Z2dEdF Z3dGdH Z4dIdJ Z5dKdL Z6dMdN Z7dOdP Z8dQdR Z9dSdT Z:dUdV Z;G dWdX dXeZ<e=dYkre>  dS )Z    N)skip_unless_cc_53skip_unless_cuda_pythonunittestCUDATestCaseskip_on_cudasim)numpy_support)cudafloat32float64int32	vectorizevoidint64c                 C   s    t d}t| | ||< d S N   )r   gridmathacosABi r   Z/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/numba/cuda/tests/cudapy/test_math.py	math_acos   s    
r   c                 C   s    t d}t| | ||< d S r   )r   r   r   asinr   r   r   r   	math_asin   s    
r   c                 C   s    t d}t| | ||< d S r   )r   r   r   atanr   r   r   r   	math_atan   s    
r   c                 C   s    t d}t| | ||< d S r   )r   r   r   acoshr   r   r   r   
math_acosh   s    
r    c                 C   s    t d}t| | ||< d S r   )r   r   r   asinhr   r   r   r   
math_asinh    s    
r"   c                 C   s    t d}t| | ||< d S r   )r   r   r   atanhr   r   r   r   
math_atanh%   s    
r$   c                 C   s    t d}t| | ||< d S r   )r   r   r   cosr   r   r   r   math_cos*   s    
r&   c                 C   s    t d}t| | ||< d S r   )r   r   r   sinr   r   r   r   math_sin/   s    
r(   c                 C   s    t d}t| | ||< d S r   )r   r   r   tanr   r   r   r   math_tan4   s    
r*   c                 C   s    t d}t| | ||< d S r   )r   r   r   coshr   r   r   r   	math_cosh9   s    
r,   c                 C   s    t d}t| | ||< d S r   )r   r   r   sinhr   r   r   r   	math_sinh>   s    
r.   c                 C   s    t d}t| | ||< d S r   )r   r   r   tanhr   r   r   r   	math_tanhC   s    
r0   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   atan2r   r   Cr   r   r   r   
math_atan2H   s    
r4   c                 C   s    t d}t| | ||< d S r   )r   r   r   expr   r   r   r   math_expM   s    
r6   c                 C   s    t d}t| | ||< d S r   )r   r   r   erfr   r   r   r   math_erfR   s    
r8   c                 C   s    t d}t| | ||< d S r   )r   r   r   erfcr   r   r   r   	math_erfcW   s    
r:   c                 C   s    t d}t| | ||< d S r   )r   r   r   expm1r   r   r   r   
math_expm1\   s    
r<   c                 C   s    t d}t| | ||< d S r   )r   r   r   fabsr   r   r   r   	math_fabsa   s    
r>   c                 C   s    t d}t| | ||< d S r   )r   r   r   gammar   r   r   r   
math_gammaf   s    
r@   c                 C   s    t d}t| | ||< d S r   )r   r   r   lgammar   r   r   r   math_lgammak   s    
rB   c                 C   s    t d}t| | ||< d S r   )r   r   r   logr   r   r   r   math_logp   s    
rD   c                 C   s    t d}t| | ||< d S r   )r   r   r   log2r   r   r   r   	math_log2u   s    
rF   c                 C   s    t d}t| | ||< d S r   )r   r   r   log10r   r   r   r   
math_log10z   s    
rH   c                 C   s    t d}t| | ||< d S r   )r   r   r   log1pr   r   r   r   
math_log1p   s    
rJ   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   	remainderr2   r   r   r   math_remainder   s    
rL   c                 C   s    t d}t| | ||< d S r   )r   r   r   sqrtr   r   r   r   	math_sqrt   s    
rN   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   hypotr2   r   r   r   
math_hypot   s    
rP   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   powr2   r   r   r   math_pow   s    
rR   c                 C   s    t d}t| | ||< d S r   )r   r   r   ceilr   r   r   r   	math_ceil   s    
rT   c                 C   s    t d}t| | ||< d S r   )r   r   r   floorr   r   r   r   
math_floor   s    
rV   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   copysignr2   r   r   r   math_copysign   s    
rX   c                 C   s&   t d}t| | || ||< d S r   )r   r   r   fmodr2   r   r   r   	math_fmod   s    
rZ   c                 C   s(   t d}t| | \||< ||< d S r   )r   r   r   modfr2   r   r   r   	math_modf   s    
r\   c                 C   s    t d}t| | ||< d S r   )r   r   r   isnanr   r   r   r   
math_isnan   s    
r^   c                 C   s    t d}t| | ||< d S r   )r   r   r   isinfr   r   r   r   
math_isinf   s    
r`   c                 C   s    t d}t| | ||< d S r   )r   r   r   isfiniter   r   r   r   math_isfinite   s    
rb   c                 C   s    t d}t| | ||< d S r   )r   r   r   degreesr   r   r   r   math_degrees   s    
rd   c                 C   s    t d}t| | ||< d S r   )r   r   r   radiansr   r   r   r   math_radians   s    
rf   c                 C   s    t d}t| | ||< d S r   )r   r   r   truncr   r   r   r   
math_trunc   s    
rh   c                 C   s"   t d}| | ||  ||< d S r   r   r   r2   r   r   r   math_pow_binop   s    
rj   c                 C   s"   t d}| | ||  ||< d S r   ri   r2   r   r   r   math_mod_binop   s    
rk   c                   @   sB  e Zd ZdddZdddZdddZdd
dZdddZdd Zdd Z	dd Z
dd ZdddZdddZdddZdddZdd  Zdd!d"Zdd#d$Zdd%d&Zdd'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zeed9d:d; Zd<d= Z d>d? Z!d@dA Z"dBdC Z#dDdE Z$dFdG Z%dHdI Z&dJdK Z'dLdM Z(dNdO Z)dPdQ Z*dRdS Z+dTdU Z,dVdW Z-dXdY Z.dZd[ Z/d\d] Z0d^d_ Z1e2d`dadb Z3dcdd Z4dedf Z5dgdh Z6didj Z7dkdl Z8dmdn Z9dodp Z:dqdr Z;e2dsdtdu Z<dvdw Z=dxdy Z>dzd{ Z?d|d} Z@d~d ZAdd ZBdd ZCdd ZDdd ZEdS )TestCudaMathr   r   c                 C   s   |  ||tjtj|| d S N)unary_templatenpZfloat16selffuncnpfuncstartstopr   r   r   unary_template_float16   s    z#TestCudaMath.unary_template_float16c                 C   s   |  ||tjtj|| d S rm   rn   ro   r	   rp   r   r   r   unary_template_float32   s    z#TestCudaMath.unary_template_float32c                 C   s   |  ||tjtj|| d S rm   rn   ro   r
   rp   r   r   r   unary_template_float64   s    z#TestCudaMath.unary_template_float642   c                 C   s   |  ||tjtj|| d S rm   )rn   ro   r   r
   rp   r   r   r   unary_template_int64   s    z!TestCudaMath.unary_template_int64c                 C   s   |  ||tjtj|| d S rm   )rn   ro   uint64r
   rp   r   r   r   unary_template_uint64   s    z"TestCudaMath.unary_template_uint64c                 C   s   d}t ||||}t ||}	t|d d d }
t|d d d }t|
|f|}|d|f ||	 |t jkrd}n|t j	krd}nd}t j
j|||	|d d S )Nr{   r   gvIh%<=ư>gMbP?rtol)ro   linspaceastype
empty_liker   
from_dtyper   jitr
   r	   testingassert_allclose)rq   rr   rs   npdtype	nprestypert   ru   nelemr   r   arytyperestypecfuncr   r   r   r   rn      s    

zTestCudaMath.unary_templatec           
   	   C   s   t |}|jd }t jd||jdd|jt jt jg|d}t j|t jd}t	
|d d d td d d f|}	|	d|jf || t j||| |	d|jf | | t j|||  d S )N   g        g      ?g      ?dtyper   )ro   ZfinfoZtinyarraymaxinfnanr   r   r   r   sizer   Zassert_array_equal)
rq   rr   rs   r   npmtypefiZdenormr   r   r   r   r   r   unary_bool_special_values   s    

&z&TestCudaMath.unary_bool_special_valuesc                 C   s   |  ||tjt d S rm   )r   ro   r	   rq   rr   rs   r   r   r   !unary_bool_special_values_float32  s    z.TestCudaMath.unary_bool_special_values_float32c                 C   s   |  ||tjt d S rm   )r   ro   r
   r   r   r   r   !unary_bool_special_values_float64  s    z.TestCudaMath.unary_bool_special_values_float64c                 C   s   |  ||tjtj|| d S rm   rw   rp   r   r   r   unary_bool_template_float32  s    z(TestCudaMath.unary_bool_template_float32c                 C   s   |  ||tjtj|| d S rm   ry   rp   r   r   r   unary_bool_template_float64  s    z(TestCudaMath.unary_bool_template_float641   c                 C   s   |  ||tjtj|| d S rm   )rn   ro   r   rp   r   r   r   unary_bool_template_int32  s    z&TestCudaMath.unary_bool_template_int32c                 C   s   |  ||tjtj|| d S rm   )rn   ro   r   rp   r   r   r   unary_bool_template_int64  s    z&TestCudaMath.unary_bool_template_int64c                 C   s   d}t ||||}t j|jt jd}	|d d d }
td d d }t|
|f|}|d|f ||	 t j	|||	 d S )Nr{   r   r   )
ro   r   r   emptyshaper   r   r   r   r   )rq   rr   rs   r   r   rt   ru   r   r   r   ZiarytypeZoarytyper   r   r   r   unary_bool_template  s    z TestCudaMath.unary_bool_templatec                 C   s   |  ||tjtj|| d S rm   )binary_templatero   r	   rp   r   r   r   binary_template_float32(  s    z$TestCudaMath.binary_template_float32c                 C   s   |  ||tjtj|| d S rm   )r   ro   r
   rp   r   r   r   binary_template_float64+  s    z$TestCudaMath.binary_template_float64c                 C   s   |  ||tjtj|| d S rm   )r   ro   r   r
   rp   r   r   r   binary_template_int64.  s    z"TestCudaMath.binary_template_int64c                 C   s   |  ||tjtj|| d S rm   )r   ro   r}   r
   rp   r   r   r   binary_template_uint641  s    z#TestCudaMath.binary_template_uint64c                 C   s   d}t ||||}t ||}	t|d d d }
t|d d d }t|
|
|f|}|d|f |||	 t j	||||	 d S )Nr{   r   )
ro   r   r   r   r   r   r   r   r   r   )rq   rr   rs   r   r   rt   ru   r   r   r   r   r   r   r   r   r   r   4  s    zTestCudaMath.binary_templatec                 C   sH   |  ttj | ttj | jttjddd | jttjddd d S Nr   rt   ru   )rx   r   ro   Zarccosrz   r|   r~   rq   r   r   r   test_math_acosA  s    zTestCudaMath.test_math_acosc                 C   sH   |  ttj | ttj | jttjddd | jttjddd d S r   )rx   r   ro   Zarcsinrz   r|   r~   r   r   r   r   test_math_asinL  s    zTestCudaMath.test_math_asinc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r   ro   Zarctanrz   r|   r~   r   r   r   r   test_math_atanW  s    zTestCudaMath.test_math_atanc                 C   sT   | j ttjddd | jttjddd | jttjddd | jttjddd d S )Nr      r   )rx   r    ro   Zarccoshrz   r|   r~   r   r   r   r   test_math_acosh`  s    zTestCudaMath.test_math_acoshc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r"   ro   Zarcsinhrz   r|   r~   r   r   r   r   test_math_asinhi  s    zTestCudaMath.test_math_asinhc                 C   sT   | j ttjddd | jttjddd | jttjddd | jttjddd d S )Nr   g?r   )rx   r$   ro   Zarctanhrz   r|   r~   r   r   r   r   test_math_atanhr  s    zTestCudaMath.test_math_atanhc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r&   ro   r%   rz   r|   r~   r   r   r   r   test_math_cos{  s    zTestCudaMath.test_math_coszNVIDIA Binding needed for NVRTCc                 C   s   |  ttj |  ttj |  ttj | j ttj	dd | j t
tjdd | j ttjdd | j ttjdd |  ttj |  ttj |  ttj |  ttj d S )Nr   rt   )rv   r(   ro   r'   r&   r%   r6   r5   rD   rC   rF   rE   rH   rG   r>   r=   rN   rM   rT   rS   rV   rU   rh   rg   r   r   r   r   test_math_fp16  s    zTestCudaMath.test_math_fp16c                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r(   ro   r'   rz   r|   r~   r   r   r   r   test_math_sin  s    zTestCudaMath.test_math_sinc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r*   ro   r)   rz   r|   r~   r   r   r   r   test_math_tan  s    zTestCudaMath.test_math_tanc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r,   ro   r+   rz   r|   r~   r   r   r   r   test_math_cosh  s    zTestCudaMath.test_math_coshc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r.   ro   r-   rz   r|   r~   r   r   r   r   test_math_sinh  s    zTestCudaMath.test_math_sinhc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r0   ro   r/   rz   r|   r~   r   r   r   r   test_math_tanh  s    zTestCudaMath.test_math_tanhc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )r   r4   ro   Zarctan2r   r   r   r   r   r   r   test_math_atan2  s    zTestCudaMath.test_math_atan2c                 C   s@   t dd }| t| | t| | t| | t| d S )Nc                 S   s
   t | S rm   )r   r7   xr   r   r   ufunc  s    z)TestCudaMath.test_math_erf.<locals>.ufunc)r   rx   r8   rz   r|   r~   rq   r   r   r   r   test_math_erf  s    
zTestCudaMath.test_math_erfc                 C   s@   t dd }| t| | t| | t| | t| d S )Nc                 S   s
   t | S rm   )r   r9   r   r   r   r   r     s    z*TestCudaMath.test_math_erfc.<locals>.ufunc)r   rx   r:   rz   r|   r~   r   r   r   r   test_math_erfc  s    
zTestCudaMath.test_math_erfcc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r6   ro   r5   rz   r|   r~   r   r   r   r   test_math_exp  s    zTestCudaMath.test_math_expc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   r<   ro   r;   rz   r|   r~   r   r   r   r   test_math_expm1  s    zTestCudaMath.test_math_expm1c                 C   sL   | j ttjdd | jttjdd | jttjdd | jttjdd d S Nr   r   )rx   r>   ro   r=   rz   r|   r~   r   r   r   r   test_math_fabs  s    zTestCudaMath.test_math_fabsc                 C   sP   t dd }| jt|dd | jt|dd | jt|dd | jt|dd d S )Nc                 S   s
   t | S rm   )r   r?   r   r   r   r   r     s    z+TestCudaMath.test_math_gamma.<locals>.ufunc皙?r   r   )r   rx   r@   rz   r|   r~   r   r   r   r   test_math_gamma  s    
zTestCudaMath.test_math_gammac                 C   sP   t dd }| jt|dd | jt|dd | jt|dd | jt|dd d S )Nc                 S   s
   t | S rm   )r   rA   r   r   r   r   r   	  s    z,TestCudaMath.test_math_lgamma.<locals>.ufuncr   r   r   )r   rx   rB   rz   r|   r~   r   r   r   r   test_math_lgamma  s    
zTestCudaMath.test_math_lgammac                 C   sL   | j ttjdd | jttjdd | jttjdd | jttjdd d S Nr   r   )rx   rD   ro   rC   rz   r|   r~   r   r   r   r   test_math_log  s    zTestCudaMath.test_math_logc                 C   sL   | j ttjdd | jttjdd | jttjdd | jttjdd d S r   )rx   rF   ro   rE   rz   r|   r~   r   r   r   r   test_math_log2  s    zTestCudaMath.test_math_log2c                 C   sL   | j ttjdd | jttjdd | jttjdd | jttjdd d S r   )rx   rH   ro   rG   rz   r|   r~   r   r   r   r   test_math_log10&  s    zTestCudaMath.test_math_log10c                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   rJ   ro   rI   rz   r|   r~   r   r   r   r   test_math_log1p/  s    zTestCudaMath.test_math_log1pc                 C   sL   | j ttjdd | jttjdd | jttjdd | jttjdd d S )Ngdy=r   r   )r   rL   ro   rK   r   r   r   r   r   r   r   test_math_remainder8  s    z TestCudaMath.test_math_remainderz3math.remainder(0, 0) raises a ValueError on CUDASimc                 C   sZ   t ttd d d ttdd }tdtj}|d |dd | t|d  d S )Nr   c                 S   s   t ||| d< d S )Nr   )r   rK   )rr   yr   r   r   test_0_0@  s    z6TestCudaMath.test_math_remainder_0_0.<locals>.test_0_0)r   r   r   )	r   r   r   r
   r   ro   Zzeros
assertTruer]   )rq   r   r   r   r   r   test_math_remainder_0_0>  s
    
z$TestCudaMath.test_math_remainder_0_0c                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   rN   ro   rM   rz   r|   r~   r   r   r   r   test_math_sqrtJ  s    zTestCudaMath.test_math_sqrtc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )r   rP   ro   rO   r   r   r   r   r   r   r   test_math_hypotS  s    zTestCudaMath.test_math_hypotc           
      C   s   d}t dd||}t j|t jd}t |}t|d d d }t	|td d d |ft
}|d|f ||| t |}tt|D ]}	t||	 ||	 ||	< qt jjt ||||dd d S )Nr{   r      r   r   r   r   )ro   r   r   Zaranger   r   r   r   r   r   rR   rangelenr   rQ   r   r   power)
rq   r   r   r   r   r3   r   r   ZCrefr   r   r   r   pow_template_int32\  s    

zTestCudaMath.pow_template_int32c                 C   s8   |  ttj | ttj | tj | tj d S rm   )r   rR   ro   r   r   r   r	   r
   r   r   r   r   test_math_powm  s    zTestCudaMath.test_math_powc                 C   s    |  ttj | ttj d S rm   )r   rj   ro   r   r   r   r   r   r   test_math_pow_binopv  s    z TestCudaMath.test_math_pow_binopc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   rT   ro   rS   rz   r|   r~   r   r   r   r   test_math_ceil}  s    zTestCudaMath.test_math_ceilc                 C   s<   |  ttj | ttj | ttj | ttj d S rm   )rx   rV   ro   rU   rz   r|   r~   r   r   r   r   test_math_floor  s    zTestCudaMath.test_math_floorc                 C   s   |  ttj d S rm   )rz   rh   ro   rg   r   r   r   r   test_math_trunc  s    zTestCudaMath.test_math_truncz%trunc only supported on NumPy float64c                 C   s.   |  ttj | ttj | ttj d S rm   )rx   rh   ro   rg   r|   r~   r   r   r   r   test_math_trunc_non_float64  s    z(TestCudaMath.test_math_trunc_non_float64c                 C   s(   | j ttjdd | jttjdd d S r   )r   rX   ro   rW   r   r   r   r   r   test_math_copysign  s    zTestCudaMath.test_math_copysignc              	      sd   fdd} fdd}d}  d( |tdd|tjtd d  d	 W 5 Q R X   d
. |ttjtj gtjtd d  d	 W 5 Q R X   d |tjtd d  d	 W 5 Q R X   d( |tdd|tjtd d  d	 W 5 Q R X   d. |ttjtj gtjtd d  d	 W 5 Q R X   d |tjtd d  d	 W 5 Q R X d S )Nc                    sv   t jt jg| d}t |}t |}t|||ft}|dt|f |||  t 	|  t 	| d S )Nr   r   )
ro   r   r   
zeros_liker   r   r\   r   r   r]   )r   r   r   r   r3   r   r   r   r   modf_template_nan  s    

z6TestCudaMath.test_math_modf.<locals>.modf_template_nanc                    s   |  |} t| }t| }t|||ft}|dt| f | || t| \}} t	||  t	|| d S r   )
r   ro   r   r   r   r\   r   r[   r   Zarray_equal)r   r   r   r   r3   r   DEr   r   r   modf_template_compare  s    


z:TestCudaMath.test_math_modf.<locals>.modf_template_comparer{   zfloat32 modf on simple floatr   
   )r   r   zfloat32 modf on +- infinityzfloat32 modf on nanzfloat64 modf on simple floatzfloat64 modf on +- infinityzfloat64 modf on nan)ZsubTestro   r   r	   r   r   r
   )rq   r   r   r   r   r   r   test_math_modf  s.    	


 

zTestCudaMath.test_math_modfc                 C   s(   | j ttjdd | jttjdd d S r   )r   rZ   ro   rY   r   r   r   r   r   test_math_fmod  s    zTestCudaMath.test_math_fmodc                 C   s(   | j ttjdd | jttjdd d S r   )r   rk   ro   rY   r   r   r   r   r   test_math_mod_binop  s    z TestCudaMath.test_math_mod_binopc                 C   sX   |  ttj | ttj | ttj | ttj | ttj | ttj d S rm   )	r   r^   ro   r]   r   r   r   r   r   r   r   r   r   test_math_isnan  s    zTestCudaMath.test_math_isnanc                 C   sX   |  ttj | ttj | ttj | ttj | ttj | ttj d S rm   )	r   r`   ro   r_   r   r   r   r   r   r   r   r   r   test_math_isinf  s    zTestCudaMath.test_math_isinfc                 C   sX   |  ttj | ttj | ttj | ttj | ttj | ttj d S rm   )	r   rb   ro   ra   r   r   r   r   r   r   r   r   r   test_math_isfinite  s    zTestCudaMath.test_math_isfinitec                 C   s    |  ttj | ttj d S rm   )r   rd   ro   rc   r   r   r   r   r   test_math_degrees  s    zTestCudaMath.test_math_degreesc                 C   s    |  ttj | ttj d S rm   )r   rf   ro   re   r   r   r   r   r   test_math_radians
  s    zTestCudaMath.test_math_radiansN)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{   )F__name__
__module____qualname__rv   rx   rz   r|   r~   rn   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   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   rl      s   













																	
				
,rl   __main__)?numpyro   Znumba.cuda.testingr   r   r   r   r   Znumba.npr   Znumbar   r	   r
   r   r   r   r   r   r   r   r   r    r"   r$   r&   r(   r*   r,   r.   r0   r4   r6   r8   r:   r<   r>   r@   rB   rD   rF   rH   rJ   rL   rN   rP   rR   rT   rV   rX   rZ   r\   r^   r`   rb   rd   rf   rh   rj   rk   rl   r   mainr   r   r   r   <module>   sh   $    :
