U
    iâËd  ã                   @   s$  d dl Z d dlZ d dl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
mZ d dlmZ d dlmZ d dlmZmZ e jjZe je_g e_ejdkr¸e jjjZe jge_de_dZn*e  e j  !d¡¡j"Ze jge_e j#e_d	Zd
d„ Z$dZ%dd„ Z&dd„ Z'G dd„ deƒZ(e)dk�r e *¡  dS )é    N)Úcompile_isolatedÚFlags)Újit)Úerrors)ÚTestCaseÚtagÚnté   Úciè  c                 C   s$   |D ]}t dt ƒ tƒ | |< qd S )Né
   )ÚsleepÚsleep_factorÚPyThread_get_thread_ident©ÚaÚindicesÚidx© r   úM/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/numba/tests/test_gil.pyÚf#   s    r   zvoid(int64[:], intp[:])c                 C   s*   t ƒ  |D ]}tdt ƒ tƒ | |< q
dS )z/
    Same as f(), but inside a lifted loop
    r   N)Úobjectr   r   r   r   r   r   r   Úlifted_f/   s    r   c                 C   s*   |D ] }t dt ƒ tƒ  tƒ | |< qdS )z)
    Same as f(), but in object mode
    r   N)r   r   r   r   r   r   r   r   Úobject_f9   s    r   c                   @   sd   e Z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S )ÚTestGILReleasec                 C   s   t j|t jd�S )N©Zdtype)ÚnpÚarangeZint64)ÚselfZ	n_membersr   r   r   Úmake_test_arrayF   s    zTestGILRelease.make_test_arrayc                 C   sš   g }||   d¡tjdtjd�ƒ |   d¡}t|ƒD ]>}tj|jtjd�}tj |¡ tj	|||fd�}| 
|¡ q2|D ]}| ¡  qv|D ]}| ¡  qˆ|S )Nr	   r   é2   )ÚtargetÚargs)r   r   r   ZintpÚrangeÚsizeÚrandomÚshuffleÚ	threadingÚThreadÚappendÚstartÚjoin)r   ÚfuncÚ	n_threadsÚthreadsÚarrÚir   Útr   r   r   Úrun_in_threadsI   s    


zTestGILRelease.run_in_threadsc                 C   s,   | j |dd�}t|ƒ}|  t|ƒd|¡ d S )Né   )r,   r	   )r1   ÚsetÚassertEqualÚlen)r   r+   r.   Údistinctr   r   r   Úcheck_gil_held]   s    zTestGILRelease.check_gil_heldc                 C   sj   dD ]\}|   ||¡}t|ƒ}z|  t|ƒd|¡ W n& tk
rX } z|}W 5 d }~X Y qX  d S q|‚d S )N)r2   é   é    r	   )r1   r3   ZassertGreaterr5   ÚAssertionError)r   r+   r,   r.   r6   ÚeZfailurer   r   r   Úcheck_gil_releasedb   s    z!TestGILRelease.check_gil_releasedc                 C   s   t tdd�tƒ}|  |¡ dS )zu
        Test the GIL is held by default, by checking serialized runs
        produce deterministic results.
        T©ÚnopythonN©r   Úf_sigr   r7   ©r   Úcfuncr   r   r   Útest_gil_heldp   s    zTestGILRelease.test_gil_heldc                 C   s    t tddd�tƒ}|  |¡ dS )zj
        Test releasing the GIL, by checking parallel runs produce
        unpredictable results.
        T©r>   ÚnogilN©r   r@   r   r<   rA   r   r   r   Útest_gil_releasedx   s    z TestGILRelease.test_gil_releasedc                 C   s   t tdd�tƒ}|  |¡ dS )zz
        Test the GIL can by released by a lifted loop even though the
        surrounding code uses object mode.
        T©rE   N)r   r@   r   r<   rA   r   r   r   Ú$test_gil_released_inside_lifted_loop€   s    z3TestGILRelease.test_gil_released_inside_lifted_loopc                    s8   t tdd�tƒ‰ t tddd�‡ fdd„ƒ}|  |¡ dS )zh
        Releasing the GIL in the caller is sufficient to have it
        released in a callee.
        Tr=   rD   c                    s   ˆ | |ƒ d S ©Nr   ©r   r/   ©Z
compiled_fr   r   ÚcallerŽ   s    z:TestGILRelease.test_gil_released_by_caller.<locals>.callerNrF   ©r   rM   r   rL   r   Útest_gil_released_by_callerˆ   s    z*TestGILRelease.test_gil_released_by_callerc                    s:   t tddd�tƒ‰ t tddd�‡ fdd„ƒ}|  |¡ dS )zR
        Same, but with both caller and callee asking to release the GIL.
        TrD   c                    s   ˆ | |ƒ d S rJ   r   rK   rL   r   r   rM   ˜   s    zETestGILRelease.test_gil_released_by_caller_and_callee.<locals>.callerNrF   rN   r   rL   r   Ú&test_gil_released_by_caller_and_callee“   s    z5TestGILRelease.test_gil_released_by_caller_and_calleec                    s8   t tddd�tƒ‰ t tdd�‡ fdd„ƒ}|  |¡ dS )zP
        When only the callee asks to release the GIL, it gets ignored.
        TrD   r=   c                    s   ˆ | |ƒ d S rJ   r   rK   rL   r   r   rM   ¢   s    z9TestGILRelease.test_gil_ignored_by_callee.<locals>.callerNr?   rN   r   rL   r   Útest_gil_ignored_by_callee�   s    
z)TestGILRelease.test_gil_ignored_by_calleec              	   C   s`   t jdd��$}t  dtj¡ ttdd�tƒ}W 5 Q R X |  t	dd„ |D ƒƒ|¡ |  
|d¡ dS )	za
        When the function is compiled in object mode, a warning is
        printed out.
        T)ÚrecordÚalwaysrH   c                 s   s(   | ] }|j tjkod t|jƒkV  qdS )z:Code running in object mode won't allow parallel executionN)Úcategoryr   ÚNumbaWarningÚstrÚmessage)Ú.0Úwr   r   r   Ú	<genexpr>¯   s   þz2TestGILRelease.test_object_mode.<locals>.<genexpr>é   N)ÚwarningsÚcatch_warningsÚsimplefilterr   rU   r   r@   r   Ú
assertTrueÚanyr1   )r   ZwlistrB   r   r   r   Útest_object_mode§   s    þþzTestGILRelease.test_object_modeN)Ú__name__Ú
__module__Ú__qualname__r   r1   r7   r<   rC   rG   rI   rO   rP   rQ   ra   r   r   r   r   r   D   s   

r   Ú__main__)+ÚctypesÚctypes.utilÚosÚsysr&   r\   Únumpyr   ZunittestZnumba.core.compilerr   r   Znumbar   Z
numba.corer   Znumba.tests.supportr   r   Z	pythonapir   Zc_longÚrestypeZargtypesÚnameÚwindllÚkernel32ZSleepr   Zc_uintr   ÚCDLLÚutilÚfind_libraryZusleepÚc_intr   r@   r   r   r   rb   Úmainr   r   r   r   Ú<module>   s<   





r
