B
      ›\k<  ã               @   sÔ  d Z ddl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	m
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mZ dd	lmZmZmZ dd
lmZ e ej d¡Z!dd„ Z"dd„ Z#dd„ Z$dZ%dZ&dZ'dd„ Z(dZ)dd„ Z*e*eƒZ+e*eƒZ,dd„ Z-e-eƒZ.e-eƒZ/e 0e 1ej2¡e 1ej2¡ej3ej3¡Z4e 0e 1ej5¡e 1ej5¡ej3ej3¡Z6e 0ej7ej7ej3ej3¡Z8G dd„ deƒZ9G dd„ deƒZ:G d d!„ d!eƒZ;e!G d"d#„ d#eƒƒZ<e=d$krÐe >¡  dS )%z
Tests for @cfunc and friends.
é    )ÚdivisionÚprint_functionÚabsolute_importN)Ú
namedtuple)Úunittest_support)ÚcfuncÚcarrayÚfarrayÚtypesÚtypingÚutilsÚnjit)Úcffi_supportÚnumpy_supporté   )ÚTestCaseÚtagÚcaptured_stderr)ÚBaseCacheTestz4CFFI not supported -- please install the cffi modulec             C   s   | | S )N© )ÚaÚbr   r   ú5lib/python3.7/site-packages/numba/tests/test_cfunc.pyÚadd_usecase   s    r   c             C   s   | | }|S )Nr   )r   r   Úcr   r   r   Údiv_usecase   s    r   c             C   s   | d S )Né   r   )r   r   r   r   Úsquare_usecase"   s    r   zfloat64(float64, float64)zfloat64(int64, int64)zfloat64(float64)c             C   s   t ƒ  | | S )N)Úobject)r   r   r   r   r   Úobjmode_usecase+   s    r   é   c                s   ‡ fdd„}|S )Nc       	         s˜   ˆ | ||fƒ}ˆ |t ƒ}|j|d< |j|dd…< |j|dd…< |jj|d< |jj|d< d}x0t ||¡D ] \}}||||f ||  7 }qhW ||d< d S )Nr   r   é   é   é   é   )	ÚCARRAY_USECASE_OUT_LENÚndimÚshapeÚstridesÚflagsÚc_contiguousÚf_contiguousÚnpÚndindex)	Úin_ptrÚout_ptrÚmÚnÚin_ÚoutÚsÚiÚj)Úfuncr   r   Úcfarray_usecase5   s    

z-make_cfarray_usecase.<locals>.cfarray_usecaser   )r7   r8   r   )r7   r   Úmake_cfarray_usecase3   s    r9   c                s   ‡ fdd„}|S )Nc       	         s¢   ˆ | ||ft jd}ˆ |tt jƒ}|j|d< |j|dd…< |j|dd…< |jj|d< |jj|d< d}x0t  	||¡D ] \}}||||f ||  7 }qrW ||d< d S )N)Údtyper   r   r!   r"   r#   r$   )
r,   Úfloat32r%   r&   r'   r(   r)   r*   r+   r-   )	r.   r/   r0   r1   r2   r3   r4   r5   r6   )r7   r   r   r8   M   s    
z3make_cfarray_dtype_usecase.<locals>.cfarray_usecaser   )r7   r8   r   )r7   r   Úmake_cfarray_dtype_usecaseJ   s    r<   c               @   sX   e Zd Zedƒdd„ ƒZedƒedd„ ƒƒZdd„ Zedƒdd	„ ƒZd
d„ Z	dd„ Z
dS )Ú	TestCFuncÚ	importantc             C   sœ   t tƒtƒ}|  |jd¡ |  |jd¡ |  |jt¡ |j}|  	|t
¡ |  d|¡ |j}|  	|tj¡ |j}|  t |tj¡j|¡ |  |ddƒd¡ dS )z8
        Basic usage and properties of a cfunc.
        r   g       @g      @g      @N)r   Úadd_sigr   ÚassertEqualÚ__name__Ú__qualname__ZassertIsÚ__wrapped__Únative_nameÚassertIsInstanceÚstrÚassertInZaddressr   Z	INT_TYPESÚctypesÚcastÚc_void_pÚvalueÚassertPreciseEqual)ÚselfÚfZsymbolÚaddrZctr   r   r   Ú
test_basico   s    zTestCFunc.test_basicc             C   s@   ddl m} | ¡ \}}ttƒtƒ}| |j¡}|  |d¡ d S )Nr   )Úcffi_usecasesg      @)	Ú rQ   Zload_inline_moduler   Ú
square_sigr   Z_numba_test_funcptrÚcffirL   )rM   rQ   ÚffiÚlibrN   Úresr   r   r   Ú	test_cffi†   s
    zTestCFunc.test_cffic             C   s.   t tdtjidtƒ}|  | dd¡d¡ d S )Nr   )Úlocalsr    r!   g       @)r   Údiv_sigr
   Zint64r   rL   rH   )rM   rN   r   r   r   Útest_locals‘   s    zTestCFunc.test_localsc          	   C   s¨   t tƒtƒ}tƒ }|  | dd¡d¡ W d Q R X |  | ¡ d¡ tƒ }| dd¡}|  |d¡ W d Q R X | ¡ }|  d|¡ t	j
dkr˜|  d	|¡ n|  d
|¡ d S )Nr"   r   g      @rR   r   g        z(ZeroDivisionError: ('division by zero',))r!   zException ignoredz ignored)r   rZ   r   r   rL   rH   r@   ÚgetvaluerG   ÚsysÚversion_info)rM   rN   ÚerrrW   r   r   r   Útest_errors—   s    
zTestCFunc.test_errorsc             C   s2   t tƒtƒ}| ¡ }|  |j|¡ |  d|¡ d S )Nzfadd double)r   r?   r   Zinspect_llvmrG   rD   )rM   rN   Zirr   r   r   Útest_llvm_ir«   s    zTestCFunc.test_llvm_irc          	   C   s\   |   t¡ ttddtƒ W dQ R X |  ¡ }ttƒtƒ W dQ R X |  dt|j	ƒ¡ dS )z7
        Object mode is currently unsupported.
        T)ZforceobjNzUntyped global name 'object')
ÚassertRaisesÚNotImplementedErrorr   r?   r   ÚassertTypingErrorr   rG   rF   Ú	exception)rM   Úraisesr   r   r   Útest_object_mode±   s
    
zTestCFunc.test_object_modeN)rA   Ú
__module__rB   r   rP   Úskip_cffi_unsupportedrX   r[   r`   ra   rg   r   r   r   r   r=   m   s   
r=   c               @   sJ   e Zd Zej e¡Zej ed¡Z	dZ
dd„ Zdd„ Zedƒdd	„ ƒZd
S )ÚTestCFuncCachezcfunc_cache_usecases.pyZcfunc_caching_test_fodderc             C   s`   dt | j| jd }tjtjd|gtjtjd}| ¡ \}}|j	dkr\t
d|j	| ¡ f ƒ‚d S )Naf  if 1:
            import sys

            sys.path.insert(0, %(tempdir)r)
            mod = __import__(%(modname)r)
            mod.self_test()

            f = mod.add_usecase
            assert f.cache_hits == 1
            f = mod.outer
            assert f.cache_hits == 1
            f = mod.div_usecase
            assert f.cache_hits == 1
            )ÚtempdirÚmodnamez-c)ÚstdoutÚstderrr   z/process failed with code %s: stderr follows
%s
)Údictrk   rl   Ú
subprocessÚPopenr]   Ú
executableÚPIPEZcommunicateÚ
returncodeÚAssertionErrorÚdecode)rM   ÚcodeÚpopenr3   r_   r   r   r   Úrun_in_separate_processÂ   s    
z&TestCFuncCache.run_in_separate_processc             C   s   |  ¡  d S )N)Z	self_test)rM   Úmodr   r   r   Úcheck_moduleÚ   s    zTestCFuncCache.check_moduler>   c             C   sÎ   |   d¡ |  ¡ }|   d¡ |  |jjd¡ |  |jjd¡ |  |jjd¡ |  |jjd¡ |  |¡ |  ¡ }|   d¡ |  |jjd¡ |  |jjd¡ |  |jjd¡ |  |jjd¡ |  |¡ |  	¡  d S )Nr   r#   r   )
Zcheck_pycacheÚimport_moduler@   r   Z
cache_hitsZouterZadd_nocache_usecaser   r{   ry   )rM   rz   r   r   r   Útest_cachingÝ   s     




zTestCFuncCache.test_cachingN)rA   rh   rB   ÚosÚpathÚdirnameÚ__file__ÚhereÚjoinZusecases_filerl   ry   r{   r   r}   r   r   r   r   rj   ¼   s   rj   c               @   s€   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	e
dƒdd„ ƒZdd„ Zdd„ Zdd„ Ze
dƒdd„ ƒZdd„ ZdS )Ú
TestCArrayz*
    Tests for carray() and farray().
    c             C   sH   t  dd¡ d¡ t j¡}t jtt jd}|||ƒ||ƒf|jžŽ  |S )Né
   é   )r   r!   )r:   )r,   ÚarangeÚreshapeÚastyper;   Úemptyr%   r'   )rM   Úpointer_factoryr7   r   r3   r   r   r   Úrun_carray_usecaseû   s    zTestCArray.run_carray_usecasec             C   s(   |   ||¡}|   ||¡}|  ||¡ d S )N)rŒ   rL   )rM   r‹   Úpyfuncr   ÚexpectedÚgotr   r   r   Úcheck_carray_usecase  s    zTestCArray.check_carray_usecasec             C   s   |j  t j¡S )N)rH   Údata_asrJ   )rM   Úarrr   r   r   Úmake_voidptr  s    zTestCArray.make_voidptrc             C   s   |j  t  t j¡¡S )N)rH   r‘   ÚPOINTERZc_float)rM   r’   r   r   r   Úmake_float32_pointer	  s    zTestCArray.make_float32_pointerc             C   s   |j  t  t j¡¡S )N)rH   r‘   r”   Zc_double)rM   r’   r   r   r   Úmake_float64_pointer  s    zTestCArray.make_float64_pointerc          	      s‚  ‡ fdd„}t  d¡ d¡ t j¡j|d}|ˆ  |¡|jƒ}|||ƒ |ˆ  |¡|jƒ}||| 	d¡ƒ |ˆ  |¡|j|j
ƒ}|||ƒ |ˆ  |¡|jt jƒ}|||ƒ |ˆ  |¡|j|j
ƒ}|||ƒ |ˆ  |¡|jt jƒ}||| t j¡ƒ ˆ  t¡ |ˆ  |¡|jƒ W d Q R X ˆ  t¡ ||jj|jƒ W d Q R X ˆ  t¡}|ˆ  |¡|jt jƒ W d Q R X ˆ  dt|jƒ¡ d S )Nc                s$   ˆ   | |¡ ˆ  | jj|jj¡ d S )N)rL   r@   rH   Údata)r   rŽ   )rM   r   r   Úeq  s    z*TestCArray.check_carray_farray.<locals>.eqr#   )r   r!   )ÚorderÚKz%mismatching dtype 'int32' for pointer)r,   r‡   rˆ   r‰   r;   Úcopyr•   r'   ÚsizeZravelr:   r“   Úint32Zviewrb   Ú	TypeErrorrH   r—   rG   rF   re   )rM   r7   r™   r˜   Úbaser   rf   r   )rM   r   Úcheck_carray_farray  s,     



 zTestCArray.check_carray_farrayr>   c             C   s   |   td¡ dS )z,
        Test pure Python carray().
        ÚCN)r    r   )rM   r   r   r   Útest_carray7  s    zTestCArray.test_carrayc             C   s   |   td¡ dS )z,
        Test pure Python farray().
        ÚFN)r    r	   )rM   r   r   r   Útest_farray>  s    zTestCArray.test_farrayc             #   sN   xHt jt jt jt jt jt jfD ](‰ t‡ fdd„|jD ƒƒ}|j	|Ž V  qW dS )zŠ
        Generate a bunch of concrete signatures by varying the width
        and signedness of size arguments (see issue #1923).
        c             3   s    | ]}|t jkrˆ n|V  qd S )N)r
   Úintp)Ú.0r   )Úactual_sizer   r   ú	<genexpr>K  s   z.TestCArray.make_carray_sigs.<locals>.<genexpr>N)
r
   r¥   r   ZintcÚuintpZuint32ZuintcÚtupleÚargsÚreturn_type)rM   Z
formal_sigr«   r   )r§   r   Úmake_carray_sigsD  s
    zTestCArray.make_carray_sigsc          	   C   sØ   |}x0|   t¡D ]"}t|ƒ|ƒ}|  | j||j¡ qW |}x0|   t¡D ]"}t|ƒ|ƒ}|  | j||j¡ qFW |  ¡ }ttƒ|ƒ}W d Q R X |  dt	|j
ƒ¡ |}x0|   t¡D ]"}t|ƒ|ƒ}|  | j||j¡ q®W d S )Nz7mismatching dtype 'float32' for pointer type 'float64*')r­   Úcarray_float32_usecase_sigr   r   r•   rH   rd   Úcarray_float64_usecase_sigrG   rF   re   Úcarray_voidptr_usecase_sig)rM   ZusecaseZdtype_usecaser   ÚsigrN   rf   r   r   r   Úcheck_numba_carray_farrayO  s     
z$TestCArray.check_numba_carray_farrayc             C   s   |   tt¡ dS )zK
        Test Numba-compiled carray() against pure Python carray()
        N)r²   Úcarray_usecaseÚcarray_dtype_usecase)rM   r   r   r   Útest_numba_carrayg  s    zTestCArray.test_numba_carrayc             C   s   |   tt¡ dS )zK
        Test Numba-compiled farray() against pure Python farray()
        N)r²   Úfarray_usecaseÚfarray_dtype_usecase)rM   r   r   r   Útest_numba_farrayn  s    zTestCArray.test_numba_farrayN)rA   rh   rB   Ú__doc__rŒ   r   r“   r•   r–   r    r   r¢   r¤   r­   r²   rµ   r¸   r   r   r   r   r„   ö   s   (r„   c               @   s4   e Zd ZdZefdd„Zdd„ Zdd„ Zdd	„ Zd
S )ÚTestCffiStructzÎ
typedef struct _big_struct {
    int    i1;
    float  f2;
    double d3;
    float  af4[9];
} big_struct;

typedef struct _error {
    int bits:4;
} error;

typedef double (*myfunc)(big_struct*, size_t);
c             C   s    ddl m} |ƒ }| |¡ |S )Nr   )ÚFFI)rT   r»   Zcdef)rM   Úsrcr»   rU   r   r   r   Úget_ffi†  s    
zTestCffiStruct.get_ffic             C   sþ   |   ¡ }| d¡}tj|dd}|  |tj¡ |  t|ƒd¡ |  | d¡tj	¡ |  | d¡tj
¡ |  | d¡tj¡ |  | d¡tjtj
d	d
¡ | d¡}tj|dd}|  |tj¡ |  |jd t |¡¡ |  |jd tj¡ |  |jtj¡ d S )NÚ
big_structT)Úuse_record_dtypeé   Úi1Úf2Úd3Úaf4)é	   )r:   r'   Úmyfuncr   r   )r½   Útypeofr   Úmap_typerE   r
   ZRecordr@   Úlenr   r;   Úfloat64ZNestedArrayr   Z	Signaturer«   ÚCPointerr©   r¬   )rM   rU   r¾   ZnbtyperÆ   r±   r   r   r   Útest_type_parsing  s"    

z TestCffiStruct.test_type_parsingc                s"  |   ¡ }| d¡}tj|dd}tj| d¡dd}tdd„ ƒ‰ t|ƒ‡ fdd„ƒ}| d	¡}| d
|¡}xftdƒD ]Z}|d || _	|d || _
d| d || _x&tdƒD ]}	|d |	 || j|	< q°W qtW t| d|¡ƒ}
| |
d¡}tj| |¡t |¡dd}ˆ |ƒ}|  ||¡ d S )Nr¾   T)r¿   rÆ   c             S   sL   d}xBt | jƒD ]4}| | }||j|j |j 7 }|| | j ¡ 7 }qW |S )Nr   )Úrangerœ   rÁ   rÂ   rÃ   rÄ   Úsum)rŸ   Ztmpr5   Úelemr   r   r   Úcalcª  s    z0TestCffiStruct.test_cfunc_callback.<locals>.calcc                s   t | |ƒ}ˆ |ƒS )N)r   )Úptrr1   rŸ   )rÐ   r   r   Úfoo³  s    
z/TestCffiStruct.test_cfunc_callback.<locals>.foozbig_struct[3]zbig_struct*r!   é{   éÕ   r   rÅ   r…   Zsize_t)Úbufferr:   r'   )r½   rÇ   r   rÈ   r   r   ÚnewrI   rÍ   rÁ   rÂ   rÃ   rÄ   ÚintrH   r,   ZndarrayrÕ   r   Zas_dtyper@   )rM   rU   r¾   Znb_big_structr±   rÒ   ZmydatarÑ   r5   r6   rO   r   ZarrayZexpectr   )rÐ   r   Útest_cfunc_callback¤  s,    
	
z"TestCffiStruct.test_cfunc_callbackc          	   C   sH   |   ¡ }|  t¡}tj| d¡dd W d Q R X |  dt|jƒ¡ d S )NÚerrorT)r¿   z0field 'bits' has bitshift, this is not supported)	r½   rb   Ú
ValueErrorr   rÈ   rÇ   r@   rF   re   )rM   rU   rf   r   r   r   Útest_unsupport_bitsizeÏ  s    z%TestCffiStruct.test_unsupport_bitsizeN)rA   rh   rB   Zc_sourcer½   rÌ   rØ   rÛ   r   r   r   r   rº   u  s
   +rº   Ú__main__)?r¹   Z
__future__r   r   r   rH   r~   rp   r]   Úcollectionsr   Znumpyr,   Znumbar   Zunittestr   r   r	   r
   r   r   r   r   r   Zsupportr   r   r   Ztest_dispatcherr   Z
skipUnlessZ	SUPPORTEDri   r   r   r   r?   rZ   rS   r   r%   r9   r³   r¶   r<   r´   r·   ZvoidrË   r;   r¥   r®   rÊ   r¯   Zvoidptrr°   r=   rj   r„   rº   rA   Úmainr   r   r   r   Ú<module>   sX   $

O:g
