§
    2@Äj‹©  ã                   óð  — d 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Zddl	Z	ddl
Z
ddlZddlZddlmZmZmZmZ ddlmZmZmZmZmZmZ ddlZddlmZ ddlm Z  edz
  Z!	 ddl"m#Z#  e#¦   «          dd	l$m%Z% d
Z&n# e'$ r dZ&Y nw xY w	 ddl$m(Z( d
Z)n# e'$ r dZ)Y nw xY w	 ddl*Z+d
Z,n# e'$ r dZ,Y nw xY w ej-        e)d¦  «        Z. ej-        e&d¦  «        Z/e)o
e(j0        dk    Z1 ej-        e1d¦  «        Z2ej3         4                    d¦  «        Z5ej3         4                    d¦  «        Z6ej7        dk    Z8e8Z9e5 Z:d„ Z;e,rd„ Z<nd„ Z<d„ Z=d„ Z> G d„ de?¦  «        Z@ G d„ de@¦  «        ZA G d„ de?¦  «        ZB G d„ d e@¦  «        ZC G d!„ d"e@¦  «        ZD G d#„ d$e@¦  «        ZEd%„ ZFd&„ ZGe
jH        ZI G d'„ d(e?¦  «        ZJd)„ ZK eGeIejL        ¦  «        ZM eG eKd*¦  «        Ž ZNe5s eG eKd+¦  «        Ž ZO eG eKd,¦  «        Ž ZP eG eKd-¦  «        Ž ZQ G d.„ d/e¦  «        ZRe jS        d0v ZT ej-        eTd1¦  «         G d2„ d3eR¦  «        ¦   «         ZUeU V                    ¦   «           G d4„ d5e?¦  «        ZW G d6„ d7eWeR¦  «        ZXeX V                    ¦   «           G d8„ d9e¦  «        ZYe G d:„ d;eY¦  «        ¦   «         ZZeZ V                    ¦   «          e G d<„ d=eY¦  «        ¦   «         Z[e G d>„ d?eY¦  «        ¦   «         Z\ee2 G d@„ dAeY¦  «        ¦   «         ¦   «         Z]ee/ G dB„ dCeY¦  «        ¦   «         ¦   «         Z^e G dD„ dEe¦  «        ¦   «         Z_ee. G dF„ dGe¦  «        ¦   «         ¦   «         Z`eadHk    r ejb        ¦   «          dS dS )Iz
Tests the parallel backend
é    N)ÚjitÚ	vectorizeÚguvectorizeÚset_num_threads)Útemp_directoryÚoverride_configÚTestCaseÚtagÚskip_parfors_unsupportedÚ
linux_only)Ú_TIMEOUT)Úconfigg      N@)Ú_check_tbb_version_compatible)ÚtbbpoolTF)ÚomppoolzOpenMP threadpool requiredzTBB threadpool requiredÚGNUzGNU OpenMP only testsÚwinÚdarwinl        c                 ó0   — t          j        | ¦  «        |z   S ©N)ÚnpÚones©ÚnÚvs     úRC:\Projects\Historical\venv\Lib\site-packages\numba/tests/test_parallel_backend.pyÚfoor   H   s   € ÝŒ7�1‰:Œ:˜‰>Ðó    c                 ó°   — t          j        t          j        | | f¦  «        t          j        | | f¦  «        ¦  «        }|t          j        | ¦  «        z   |z   S r   )r   Údotr   Úarange)r   r   Úxs      r   Úlinalgr#   M   sC   € ÝŒF•2”7˜A˜q˜6‘?”?¥B¤G¨Q°¨F¡O¤OÑ4Ô4ˆØ•2”9˜Q‘<”<Ñ !Ñ#Ð#r   c                 ó0   — t          j        | ¦  «        |z   S r   )r   r!   r   s     r   r#   r#   Q   s   € åŒy˜‰|Œ|˜aÑÐr   c                 ó   — | |z   S r   © )ÚaÚbs     r   Ú	ufunc_foor)   V   s   € Øˆq‰5€Lr   c                 ó   — | |z   |d<   d S )Nr   r&   )r'   r(   Úouts      r   Ú
gufunc_foor,   Z   s   € Ø�‰U€Cˆ�F€F€Fr   c                   ó   — e Zd Zd„ ZdS )Úrunnablec                 ó   — || _         d S r   )Ú_options)ÚselfÚoptionss     r   Ú__init__zrunnable.__init___   s   € ØˆŒˆˆr   N)Ú__name__Ú
__module__Ú__qualname__r3   r&   r   r   r.   r.   ^   s#   € € € € € ð ð  ð  ð  ð  r   r.   c                   ó   — e Zd Zd„ ZdS )Ú
jit_runnerc                 óÄ   —  t          di | j        ¤Žt          ¦  «        }d}d}t          ||¦  «        } |||¦  «        }t          j                             ||¦  «         d S ©Né   é
   r&   )r   r0   r   r   ÚtestingÚassert_allclose©r1   Úcfuncr'   r(   ÚexpectedÚgots         r   Ú__call__zjit_runner.__call__e   se   € Ø$•Ð$Ð$�d”mÐ$Ð$¥SÑ)Ô)ˆØˆØˆÝ�q˜!‘9”9ˆØˆe�A�q‰kŒkˆÝ
Œ
×"Ò" 8¨SÑ1Ô1Ð1Ð1Ð1r   N©r4   r5   r6   rC   r&   r   r   r8   r8   c   ó#   € € € € € ð2ð 2ð 2ð 2ð 2r   r8   c                   ó   — e Zd Zd„ Zd„ ZdS )Úmask_runnerc                 ó"   — || _         || _        d S r   )ÚrunnerÚmask)r1   rI   rJ   r2   s       r   r3   zmask_runner.__init__o   s   € ØˆŒØˆŒ	ˆ	ˆ	r   c                 ód   — | j         rt          | j         ¦  «         |                      ¦   «          d S r   )rJ   r   rI   )r1   s    r   rC   zmask_runner.__call__s   s/   € ØŒ9ð 	'õ ˜DœIÑ&Ô&Ð&Ø�Š‰Œˆˆˆr   N©r4   r5   r6   r3   rC   r&   r   r   rG   rG   n   s2   € € € € € ðð ð ðð ð ð ð r   rG   c                   ó   — e Zd Zd„ ZdS )Úlinalg_runnerc                 óÄ   —  t          di | j        ¤Žt          ¦  «        }d}d}t          ||¦  «        } |||¦  «        }t          j                             ||¦  «         d S r:   )r   r0   r#   r   r=   r>   r?   s         r   rC   zlinalg_runner.__call__}   se   € Ø$•Ð$Ð$�d”mÐ$Ð$¥VÑ,Ô,ˆØˆØˆÝ˜!˜Q‘<”<ˆØˆe�A�q‰kŒkˆÝ
Œ
×"Ò" 8¨SÑ1Ô1Ð1Ð1Ð1r   NrD   r&   r   r   rN   rN   {   rE   r   rN   c                   ó   — e Zd Zd„ ZdS )Úvectorize_runnerc                 ó<  —  t          dgfi | j        ¤Žt          ¦  «        }t          j                             d¦  «                             t          j        ¦  «        x}}t          ||¦  «        } |||¦  «        }t          j                             ||¦  «         d S )Nz(f4, f4)r<   )	r   r0   r)   r   ÚrandomÚastypeÚfloat32r=   r>   r?   s         r   rC   zvectorize_runner.__call__ˆ   s‰   € Ø8•	˜:˜,Ð8Ð8¨$¬-Ð8Ð8½ÑCÔCˆÝ”	× Ò  Ñ$Ô$×+Ò+­B¬JÑ7Ô7Ð7ˆˆAÝ˜Q ‘?”?ˆØˆe�A�q‰kŒkˆÝ
Œ
×"Ò" 8¨SÑ1Ô1Ð1Ð1Ð1r   NrD   r&   r   r   rQ   rQ   †   s#   € € € € € ð2ð 2ð 2ð 2ð 2r   rQ   c                   ó   — e Zd Zd„ ZdS )Úguvectorize_runnerc                 óB  — dg} t          |dfi | j        ¤Žt          ¦  «        }t          j                             d¦  «                             t          j        ¦  «        x}}t          ||¦  «        } |||¦  «        }t          j         	                    ||¦  «         d S )Nz(f4, f4, f4[:])z	(),()->()r<   )
r   r0   r,   r   rS   rT   rU   r)   r=   r>   )r1   Úsigr@   r'   r(   rA   rB   s          r   rC   zguvectorize_runner.__call__’   s‘   € Ø Ð!ˆØ>•˜C Ð>Ð>°´Ð>Ð>½zÑJÔJˆÝ”	× Ò  Ñ$Ô$×+Ò+­B¬JÑ7Ô7Ð7ˆˆAÝ˜Q ‘?”?ˆØˆe�A�q‰kŒkˆÝ
Œ
×"Ò" 8¨SÑ1Ô1Ð1Ð1Ð1r   NrD   r&   r   r   rW   rW   �   rE   r   rW   c                 óL  — |                      d¦  «        }	 t          j        ¦   «          t          t	          t          | ¦  «        dz  ¦  «        ¦  «        D ] }t          j        | ¦  «        } |¦   «          Œ!d S # t          $ r }| 	                    |¦  «         Y d }~d S d }~ww xY w)NÚqueueg      ø?)
ÚgetÚfaulthandlerÚenableÚrangeÚintÚlenrS   ÚchoiceÚ	ExceptionÚput)ÚfnlistÚkwargsÚqÚ_ÚfnÚes         r   Úchooserrk   ›   s³   € Ø�
Š
�7ÑÔ€AðÝÔÑÔÐÝ•s�3˜v™;œ;¨Ñ,Ñ-Ô-Ñ.Ô.ð 	ð 	ˆAÝ”˜vÑ&Ô&ˆBØˆB‰DŒDˆDˆDð	ð 	øõ ð ð ð Ø	�Šˆa‰Œˆˆˆˆˆˆˆøøøøðøøøs   —A A9 Á9
B#ÂBÂB#c                 ó   ‡ ‡— ˆ ˆfd„}|S )Nc                 óô  •‡ ‡—  ‰¦   «         }d|iŠˆ ˆˆfd„t          d¦  «        D ¦   «         }|D ]}|                     ¦   «          Œ|D ]}|                     ¦   «          Œ|                     ¦   «         sƒg }|                     ¦   «         s<|                     |                     d¦  «        ¦  «         |                     ¦   «         ¯<d}t          |d                     d„ |D ¦   «         ¦  «        z  ¦  «        ‚d S )Nr[   c                 ó8   •— g | ]} ‰t           ‰f‰¬ ¦  «        ‘ŒS ))ÚtargetÚargsrf   )rk   )Ú.0Úire   ÚkwsÚparallel_classs     €€€r   ú
<listcomp>z8compile_factory.<locals>.run_compile.<locals>.<listcomp>ª   s<   ø€ ð "ð "ð "Øð ˆ~¥W°F°9ÀSÐIÑIÔIð "ð "ð "r   r;   Fz)Error(s) occurred in delegated runner:
%sú
c                 ó,   — g | ]}t          |¦  «        ‘ŒS r&   )Úrepr)rq   r"   s     r   ru   z8compile_factory.<locals>.run_compile.<locals>.<listcomp>µ   s   € Ð0IÐ0IÐ0I¸Qµ°a±´Ð0IÐ0IÐ0Ir   )r_   ÚstartÚjoinÚemptyÚappendr\   ÚRuntimeError)	re   rg   ÚthsÚthÚerrorsÚ_msgrs   rt   Ú
queue_impls	   `     @€€r   Úrun_compilez$compile_factory.<locals>.run_compile§   s   øøø€ ØˆJ‰LŒLˆØ˜ˆlˆð"ð "ð "ð "ð "ð "Ý˜a™œð"ñ "ô "ˆàð 	ð 	ˆBØ�HŠH‰JŒJˆJˆJØð 	ð 	ˆBØ�GŠG‰IŒIˆIˆIØ�wŠw‰yŒyð 	LØˆFØ—g’g‘i”ið ,Ø—’˜aŸeše E™lœlÑ+Ô+Ð+ð —g’g‘i”ið ,à?ˆDÝ˜t d§i¢iÐ0IÐ0IÀ&Ð0IÑ0IÔ0IÑ&JÔ&JÑJÑKÔKÐKð	Lð 	Lr   r&   )rt   r‚   rƒ   s   `` r   Úcompile_factoryr„   ¦   s0   øø€ ðLð Lð Lð Lð Lð Lð Ðr   c                   ó   — e Zd Zd„ Zd„ ZdS )Ú_proc_class_implc                 ó   — || _         d S r   )Ú_method)r1   Úmethods     r   r3   z_proc_class_impl.__init__¿   s   € ØˆŒˆˆr   c                 óN   — t          j        | j        ¦  «        } |j        |i |¤ŽS r   )ÚmultiprocessingÚget_contextrˆ   ÚProcess)r1   rp   rf   Úctxs       r   rC   z_proc_class_impl.__call__Â   s+   € ÝÔ)¨$¬,Ñ7Ô7ˆØˆsŒ{˜DÐ+ FÐ+Ð+Ð+r   NrL   r&   r   r   r†   r†   ½   s2   € € € € € ðð ð ð,ð ,ð ,ð ,ð ,r   r†   c                 ón   — | dk    rd } t          j        | ¦  «        }t          | ¦  «        }|j        }||fS )NÚdefault)r‹   rŒ   r†   ÚQueue)r‰   rŽ   Úprocr[   s       r   Ú_get_mp_classesr“   Ç   s@   € Ø�ÒÐØˆÝ
Ô
% fÑ
-Ô
-€CÝ˜FÑ#Ô#€DØŒI€EØ�ˆ;Ðr   ÚspawnÚforkÚ
forkserverr�   c                   ó  — e Zd ZdZ ed¬¦  «         edd¬¦  «         edd¬¦  «         ed¬¦  «         edd¬¦  «         ed¬¦  «         edd¬¦  «         eddd¬¦  «         ed¬¦  «         edd¬¦  «         eddd¬¦  «        gZe	sI edd¬	¦  «         eddd¬
¦  «         edd¬	¦  «         eddd¬
¦  «        gZ
e                     e
¦  «         ej        dk     rg ZnddgZg ZeD ]&ZeD ]!Ze                      eee¦  «        ¦  «         Œ"Œ'ddgZe                     d¦  «         er*e                     d¦  «         e                     d¦  «          ede	 ¬	¦  «        g edd¬¦  «        g edd¬¦  «        geedœZddhZdd„ZdS )ÚTestParallelBackendBasez6
    Base class for testing the parallel backends
    T)Únopython)r™   Úcache)r™   ÚnogilÚparallel)r™   ro   )r™   ro   rš   )r™   rœ   )r™   rœ   rš   é   é   Ú	threadingrS   Úmultiprocessing_spawnÚmultiprocessing_forkÚmultiprocessing_forkserver)Úconcurrent_jitÚconcurrent_vectorizeÚconcurrent_guvectorizeÚconcurrent_mix_useÚconcurrent_mix_use_masksÚompÚtbbc                 ó†  — t          | j        j        ¦  «        | _        t	          d| j        ¦  «        5  |dk    rt          |¦  «         nÞ|dk    rt          |¦  «         nÈ|dk    rt          |¦  «         n²|dk    rt          |¦  «         nœ|dk    rt          |¦  «         n†|dk    rnt
          t          g}t          r4|                     t          ¦  «         |                     t          ¦  «         t          j        |¦  «         |D ]} ||¦  «         Œnt          d|z  ¦  «        ‚d d d ¦  «         d S # 1 swxY w Y   d S )	NÚ	CACHE_DIRrŸ   r¡   r¢   r    Úmultiprocessing_defaultrS   zUnknown parallelism supplied %s)r   Ú	__class__r4   Ú
_cache_dirr   Úthread_implÚfork_proc_implÚforkserver_proc_implÚspawn_proc_implÚdefault_proc_implÚ_HAVE_OS_FORKr|   rS   ÚshuffleÚ
ValueError)r1   re   ÚparallelismÚpsÚimpls        r   rƒ   z#TestParallelBackendBase.run_compile  sÄ  € Ý(¨¬Ô)@ÑAÔAˆŒÝ˜[¨$¬/Ñ:Ô:ð 	Eð 	EØ˜kÒ)Ð)Ý˜FÑ#Ô#Ð#Ð#ØÐ 6Ò6Ð6Ý˜vÑ&Ô&Ð&Ð&ØÐ <Ò<Ð<Ý$ VÑ,Ô,Ð,Ð,ØÐ 7Ò7Ð7Ý Ñ'Ô'Ð'Ð'ØÐ 9Ò9Ð9Ý! &Ñ)Ô)Ð)Ð)Ø Ò(Ð(Ý!¥?Ð3�Ý ð 4Ø—I’I�nÑ-Ô-Ð-Ø—I’IÕ2Ñ3Ô3Ð3å”˜rÑ"Ô"Ð"Øð !ð !�DØ�D˜‘L”L�L�Lð!õ !Ø5¸ÑCñEô Eð Eð+	Eð 	Eð 	Eñ 	Eô 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eøøøð 	Eð 	Eð 	Eð 	Eð 	Eð 	Es   ´C5D6Ä6D:Ä=D:N)rŸ   )r4   r5   r6   Ú__doc__r8   rN   rQ   rW   Ú	all_implsÚ_parfors_unsupportedÚparfor_implsÚextendr   ÚNUMBA_NUM_THREADSÚmasksÚ
mask_implsr¹   rJ   r|   rG   r·   r´   ÚrunnersÚsafe_backendsrƒ   r&   r   r   r˜   r˜   Û   s¨  € € € € € ðð ð
 	ˆ
˜DÐ!Ñ!Ô!Øˆ
˜D¨Ð-Ñ-Ô-Øˆ
˜D¨Ð-Ñ-Ô-Øˆ˜tÐ$Ñ$Ô$Øˆ˜t¨4Ð0Ñ0Ô0ØÐ $Ð'Ñ'Ô'ØÐ $¨zÐ:Ñ:Ô:ØÐ $¨zÀÐFÑFÔFØÐ DÐ)Ñ)Ô)ØÐ D°Ð<Ñ<Ô<ØÐ D°À4ÐHÑHÔHð€Ið  ð 'àˆJ ¨tÐ4Ñ4Ô4ØˆJ ¨t¸4Ð@Ñ@Ô@ØˆM 4°$Ð7Ñ7Ô7ØˆM 4°$¸dÐCÑCÔCð	
ˆð 	×Ò˜Ñ&Ô&Ð&àÔ !Ò#Ð#àˆˆà�A�ˆà€JØð 7ð 7ˆØð 	7ð 	7ˆDØ×Ò˜k˜k¨$°Ñ5Ô5Ñ6Ô6Ð6Ð6ð	7ð  Ð)€KØ×ÒÐ.Ñ/Ô/Ð/Øð 9Ø×ÒÐ1Ñ2Ô2Ð2Ø×ÒÐ7Ñ8Ô8Ð8ð ˆJ Ð4HÐ0HÐJÑJÔJð
ð Ð d°:Ð>Ñ>Ô>ð!
ð Ð¨°ZÐ@Ñ@Ô@ð#
ð (Ø$.ðð €Gð ˜E�N€MðEð Eð Eð Eð Eð Er   r˜   )r¨   r©   Ú	workqueuezThreading layer not explicitc                   ó(   — e Zd ZdZed„ ¦   «         ZdS )ÚTestParallelBackendav   These are like the numba.tests.test_threadsafety tests but designed
    instead to torture the parallel backend.
    If a suitable backend is supplied via NUMBA_THREADING_LAYER these tests
    can be run directly. This test class cannot be run using the multiprocessing
    option to the test runner (i.e. `./runtests -m`) as daemon processes cannot
    have children.
    c                 ó¼   — | j         D ]S}| j                             ¦   «         D ]7\  }}d|z   dz   |z   }d„ } |||¦  «        }||_        t	          | ||¦  «         Œ8ŒTd S )NÚtest_rh   c                 ó   ‡ ‡— ˆ ˆfd„}|S )Nc                 óœ   •— t          j        ¦   «         }|j        rd}|                      |¦  «         d S |                      ‰‰¬¦  «         d S )Nz)daemonized processes cannot have children)r·   )r‹   Úcurrent_processÚdaemonÚskipTestrƒ   )r1   Úselfprocr�   r¹   Úps      €€r   Útest_methodzBTestParallelBackend.generate.<locals>.methgen.<locals>.test_methodJ  sX   ø€ Ý#2Ô#BÑ#DÔ#D˜à#œ?ð BØ#N˜DØ ŸMšM¨$Ñ/Ô/Ð/Ð/Ð/à ×,Ò,¨T¸qÐ,ÑAÔAÐAÐAÐAr   r&   )r¹   rÏ   rÐ   s   `` r   Úmethgenz-TestParallelBackend.generate.<locals>.methgenI  s0   øø€ ðBð Bð Bð Bð Bð Bð 'Ð&r   )r·   rÂ   Úitemsr4   Úsetattr)ÚclsrÏ   Únamer¹   ÚmethnamerÑ   ri   s          r   ÚgeneratezTestParallelBackend.generateC  s”   € à”ð 	+ð 	+ˆAØ!œk×/Ò/Ñ1Ô1ð +ð +‘
��dØ" Q™;¨Ñ,¨tÑ3�ð	'ð 	'ð 	'ð �W˜T 1Ñ%Ô%�Ø&�”Ý˜˜X rÑ*Ô*Ð*Ð*ð+ð	+ð 	+r   N)r4   r5   r6   rº   Úclassmethodr×   r&   r   r   rÆ   rÆ   6  s9   € € € € € ðð ð ð+ð +ñ „[ð+ð +ð +r   rÆ   c                   óD   — e Zd Zee ej        dd¦  «        dœZd„ Zd„ Z	dS )ÚTestInSubprocessFÚ ©r©   r¨   rÄ   c                 ó
  — t          j        |t           j        t           j        |¬¦  «        }t          j        t
          |j        ¦  «        }	 |                     ¦   «          |                     ¦   «         \  }}|j	        dk    r-t          d|j	        ›d|                     ¦   «         ›d�¦  «        ‚|                     ¦   «         |                     ¦   «         f|                     ¦   «          S # |                     ¦   «          w xY w)N©ÚstdoutÚstderrÚenvr   úprocess failed with code ú: stderr follows
rv   ©Ú
subprocessÚPopenÚPIPErŸ   ÚTimerÚ_TEST_TIMEOUTÚkillry   ÚcommunicateÚ
returncodeÚAssertionErrorÚdecodeÚcancel©r1   Úcmdlinerá   ÚpopenÚtimeoutr+   Úerrs          r   Úrun_cmdzTestInSubprocess.run_cmd`  sè   € ÝÔ  Ý(2¬Ý(2¬Ø%(ð*ñ *ô *ˆõ
 ”/¥-°´Ñ<Ô<ˆð		Ø�MŠM‰OŒOˆOØ×(Ò(Ñ*Ô*‰HˆC�ØÔ 1Ò$Ð$Ý$�nàÔ%Ð%Ð% s§z¢z¡|¤| | |ð5ñ6ô 6ð 6ð —:’:‘<”< §¢¡¤Ð-à�NŠNÑÔÐÐøˆG�NŠNÑÔÐÐøøøs   ÁB
C, Ã,Dc                 ó®   — t           j                             ¦   «         }t          |¦  «        |d<   t          j        dd|g}|                      ||¦  «        S )NÚNUMBA_THREADING_LAYERz-mznumba.runtests)ÚosÚenvironÚcopyÚstrÚsysÚ
executablerõ   )r1   ÚtestÚthreading_layerÚenv_copyrñ   s        r   Úrun_test_in_separate_processz-TestInSubprocess.run_test_in_separate_processs  sK   € Ý”:—?’?Ñ$Ô$ˆÝ,/°Ñ,@Ô,@ˆÐ(Ñ)Ý”> 4Ð)9¸4Ð@ˆØ�|Š|˜G XÑ.Ô.Ð.r   N)
r4   r5   r6   Úskip_no_tbbÚskip_no_ompÚunittestÚskipIfÚbackendsrõ   r  r&   r   r   rÚ   rÚ   [  sU   € € € € € Ø"Ø"Ø,˜Xœ_¨U°BÑ7Ô7ð9ð 9€Hðð ð ð&/ð /ð /ð /ð /r   rÚ   c                   óB   — e Zd ZdZdZed„ ¦   «         Zed„ ¦   «         ZdS )ÚTestSpecificBackenda¦  
    This is quite contrived, for each test in the TestParallelBackend tests it
    generates a test that will run the TestParallelBackend test in a new python
    process with an environment modified to ensure a specific threadsafe backend
    is used. This is with view of testing the backends independently and in an
    isolated manner such that if they hang/crash/have issues, it doesn't kill
    the test suite.
    Fc           	      óÜ   ‡‡
— | j         }t          j        }d|z   dz   |z   }|›d|›d|›�Š
ˆˆ
fd„}d|›d|›d‰›�}	t          | |	 t	          d¦  «         ||¦  «        ¦  «        ¦  «         d S )NrÈ   rh   ú.c                 óz  •— |                       ‰‰¦  «        \  }}| j        rt          d|›d|›d�¦  «         t          j        d|¦  «        }|�(|                      |                     d¦  «        ¦  «         |                      d|¦  «         |                      d|v¦  «         |                      d|v¦  «         d S )	Nz
stdout:
 "z"
 stderr:
 "ú"z\.\.\. skipped '(.*?)'rž   ÚOKÚFAILÚERROR)	r  Ú_DEBUGÚprintÚreÚsearchrÍ   ÚgroupÚassertInÚ
assertTrue)r1   Úorj   ÚmÚbackendÚinjected_methods       €€r   Útest_templatez2TestSpecificBackend._inject.<locals>.test_templateŒ  sÀ   ø€ Ø×4Ò4°_ÀgÑNÔN‰DˆAˆqØŒ{ð BÝ�¸1¸1¸1¸a¸a¸aÐ@ÑAÔAÐAõ ”	Ð3°QÑ7Ô7ˆAØˆ}Ø—’˜aŸgšg a™jœjÑ)Ô)Ð)Ø�MŠM˜$ Ñ"Ô"Ð"Ø�OŠO˜F¨!˜OÑ,Ô,Ð,Ø�OŠO˜G¨1Ð,Ñ-Ô-Ð-Ð-Ð-r   Úlong_running)r5   rÆ   r4   rÓ   r
   )rÔ   rÏ   rÕ   r  Úbackend_guardÚthemodÚtheclsrÖ   r  Úinjected_testr  s      `      @r   Ú_injectzTestSpecificBackend._inject…  s»   øø€ à”ˆÝ$Ô-ˆØ˜Q‘; Ñ$ tÑ+ˆØ(.¨¨°°°¸¸ÐAˆð	.ð 	.ð 	.ð 	.ð 	.ð 	.ð 	.ð ,-¨1¨1¨d¨d¨d°G°GÐ<ˆå��]Ø#•�NÑ#Ô# M M°-Ñ$@Ô$@ÑAÔAñ	Cô 	Cð 	Cð 	Cð 	Cr   c           	      ó*  — | j                              ¦   «         D ]x\  }}| j        D ]k}| j                             ¦   «         D ]O}|dv r&|dk    r t
          j                             d¦  «        rŒ,|dv r|dk    rŒ7|                      ||||¦  «         ŒPŒlŒyd S )N)r¡   rS   r¨   Úlinux)rŸ   rS   rÄ   )	r  rÒ   r·   rÂ   Úkeysrü   ÚplatformÚ
startswithr!  )rÔ   r  r  rÏ   rÕ   s        r   r×   zTestSpecificBackend.generate�  sÛ   € à&)¤l×&8Ò&8Ñ&:Ô&:ð 	Að 	AÑ"ˆG�]Ø”_ð Að A�ØœK×,Ò,Ñ.Ô.ð Að A�Dð Ð?Ð?Ð?Ø 5Ò(Ð(ÝœL×3Ò3°GÑ<Ô<ð )à ð Ð4Ð4Ð4Ø# {Ò2Ð2Ø à—K’K  4¨°-Ñ@Ô@Ð@Ð@ðAðAð	Að 	Ar   N)r4   r5   r6   rº   r  rØ   r!  r×   r&   r   r   r  r  z  sa   € € € € € ðð ð €FàðCð Cñ „[ðCð. ðAð Añ „[ðAð Að Ar   r  c                   ób   — e Zd ZdZdej                             e¦  «        z  Zddeiz  Z	dd„Z
dS )ÚThreadLayerTestHelperzP
    Helper class for running an isolated piece of code based on a template
    z%raõ  if 1:
    import sys
    sys.path.insert(0, "%(here)r")
    import multiprocessing
    import numpy as np
    from numba import njit
    import numba
    try:
        import threading_backend_usecases
    except ImportError as e:
        print("DEBUG:", sys.path)
        raise e
    import os

    sigterm_handler = threading_backend_usecases.sigterm_handler
    busy_func = threading_backend_usecases.busy_func

    def the_test():
        %%s

    if __name__ == "__main__":
        the_test()
    ÚhereNc                 ór  — |€0t           j                             ¦   «         }t          d¦  «        |d<   t	          j        |t          j        t          j        |¬¦  «        }t          j        t          |j
        ¦  «        }	 |                     ¦   «          |                     ¦   «         \  }}|j        dk    r-t          d|j        ›d|                     ¦   «         ›d�¦  «        ‚	 |                     ¦   «          n# |                     ¦   «          w xY w|                     ¦   «         |                     ¦   «         fS )Nr¨   r÷   rÞ   r   râ   rã   rv   )rø   rù   rú   rû   rå   ræ   rç   rŸ   rè   ré   rê   ry   rë   rì   rí   rî   rï   rð   s          r   rõ   zThreadLayerTestHelper.run_cmdÕ  s  € Øˆ;Ý”*—/’/Ñ#Ô#ˆCÝ+.¨u©:¬:ˆCÐ'Ñ(ÝÔ  Ý(2¬Ý(2¬Ø%(ð*ñ *ô *ˆõ
 ”/¥-°´Ñ<Ô<ˆð	Ø�MŠM‰OŒOˆOØ×(Ò(Ñ*Ô*‰HˆC�ØÔ 1Ò$Ð$Ý$�nàÔ%Ð%Ð% s§z¢z¡|¤| | |ð5ñ6ô 6ð 6ð %ð
 �NŠNÑÔÐÐøˆG�NŠNÑÔÐÐøøøØ�zŠz‰|Œ|˜SŸZšZ™\œ\Ð)Ð)s   Á?A#C8 Ã8Dr   )r4   r5   r6   rº   rø   ÚpathÚdirnameÚ__file__Ú_hereÚtemplaterõ   r&   r   r   r(  r(  µ  sa   € € € € € ðð ð
 �2”7—?’? 8Ñ,Ô,Ñ,€Eðð, �5ˆ/ñ-€Hð0*ð *ð *ð *ð *ð *r   r(  c                   ól   — e Zd ZdZdZee ej        dd¦  «        dœZ	e
d„ ¦   «         Ze
d„ ¦   «         ZdS )ÚTestThreadingLayerSelectionz@
    Checks that numba.threading_layer() reports correctly.
    FrÛ   rÜ   c           	      ó|   ‡— ˆfd„}d‰z  }t          | | t          d¦  «         ||¦  «        ¦  «        ¦  «         d S )Nc                 ó
  •— d}| j         |‰z  z  }t          j        d|g}t          j                             ¦   «         }t          ‰¦  «        |d<   |                      ||¬¦  «        \  }}| j        rt          ||¦  «         d S d S )Nz½if 1:
                X = np.arange(1000000.)
                Y = np.arange(1000000.)
                Z = busy_func(X, Y)
                assert numba.threading_layer() == '%s'
            ú-cr÷   ©rá   )
r/  rü   rý   rø   rù   rú   rû   rõ   r  r  )r1   ÚbodyÚrunmerñ   rá   r+   rô   r  s          €r   r  z:TestThreadingLayerSelection._inject.<locals>.test_templateù  sŠ   ø€ ðˆDð ”M T¨G¡^Ñ4ˆEÝ”~ t¨UÐ3ˆGÝ”*—/’/Ñ#Ô#ˆCÝ+.¨w©<¬<ˆCÐ'Ñ(Ø—|’| G°�|Ñ5Ô5‰HˆC�ØŒ{ð  Ý�c˜3‘”���ð ð  r   z test_threading_layer_selector_%sÚ	important)rÓ   r
   )rÔ   r  r  r  r   s    `   r   r!  z#TestThreadingLayerSelection._injectö  sl   ø€ ð	 ð 	 ð 	 ð 	 ð 	 ð ;¸WÑDˆÝ��]Ø •�KÑ Ô   ¨}Ñ!=Ô!=Ñ>Ô>ñ	@ô 	@ð 	@ð 	@ð 	@r   c                 óp   — | j                              ¦   «         D ]\  }}|                      ||¦  «         Œd S r   )r  rÒ   r!  )rÔ   r  r  s      r   r×   z$TestThreadingLayerSelection.generate  sE   € à&)¤l×&8Ò&8Ñ&:Ô&:ð 	0ð 	0Ñ"ˆG�]Ø�KŠK˜ Ñ/Ô/Ð/Ð/ð	0ð 	0r   N)r4   r5   r6   rº   r  r  r  r  r  r  rØ   r!  r×   r&   r   r   r1  r1  ë  s�   € € € € € ðð ð €Fà"Ø"Ø,˜Xœ_¨U°BÑ7Ô7ð9ð 9€Hð ð@ð @ñ „[ð@ð( ð0ð 0ñ „[ð0ð 0ð 0r   r1  c                   ó˜   — e Zd Zdefd„Zeed„ ¦   «         ¦   «         Zeed„ ¦   «         ¦   «         Zed„ ¦   «         Z	ed„ ¦   «         Z
d„ ZdS )	ÚTestThreadingLayerPriorityÚenv_varc                 óÒ   — t           j                             ¦   «         }d|d<   ||d<   d|› d�}t          j        dt          j        |¦  «        g}|                      ||¬¦  «         dS )	zJTest setting priority via env var NUMBA_THREADING_LAYER_PRIORITY.
        r�   r÷   ÚNUMBA_THREADING_LAYER_PRIORITYa²  
                import numba

                # trigger threading layer decision
                # hence catching invalid THREADING_LAYER_PRIORITY
                @numba.jit(
                    'float64[::1](float64[::1], float64[::1])',
                    nopython=True,
                    parallel=True,
                )
                def plus(x, y):
                    return x + y

                captured_envvar = list("a	  ".split())
                assert numba.config.THREADING_LAYER_PRIORITY ==                     captured_envvar, "priority mismatch"
                assert numba.threading_layer() == captured_envvar[0],                    "selected backend mismatch"
                r4  r5  N)rø   rù   rú   rü   rý   ÚtextwrapÚdedentrõ   )r1   r<  rá   ÚcodeÚcmds        r   Úeach_env_varz'TestThreadingLayerPriority.each_env_var  s‚   € õ Œj�oŠoÑÔˆØ'0ˆÐ#Ñ$Ø07ˆÐ,Ñ-ðð *1ðð ð ˆõ( ŒNØÝŒO˜DÑ!Ô!ð
ˆð
 	�Š�S˜cˆÑ"Ô"Ð"Ð"Ð"r   c                 ó�   — g d¢}t          j        |¦  «        D ],}d                     |¦  «        }|                      |¦  «         Œ-d S )NrÜ   ú )Ú	itertoolsÚpermutationsrz   rC  )r1   r�   rÏ   r<  s       r   Útest_valid_env_varz-TestThreadingLayerPriority.test_valid_env_var8  sY   € ð .Ð-Ð-ˆÝÔ'¨Ñ0Ô0ð 	'ð 	'ˆAØ—h’h˜q‘k”kˆGØ×Ò˜gÑ&Ô&Ð&Ð&ð	'ð 	'r   c                 óô   — d}|                       t          ¦  «        5 }|                      |¦  «         d d d ¦  «         n# 1 swxY w Y   dD ]+}|                      |› t	          |j        ¦  «        ¦  «         Œ,d S )Nztbb omp workqueue notvalidhere)z!THREADING_LAYER_PRIORITY invalid:zIt must be a permutation of)ÚassertRaisesrí   rC  r  rû   Ú	exception)r1   r<  ÚraisesÚmsgs       r   Útest_invalid_env_varz/TestThreadingLayerPriority.test_invalid_env_var@  sÄ   € ð 3ˆØ×Ò�~Ñ.Ô.ð 	'°&Ø×Ò˜gÑ&Ô&Ð&ð	'ð 	'ð 	'ñ 	'ô 	'ð 	'ð 	'ð 	'ð 	'ð 	'ð 	'øøøð 	'ð 	'ð 	'ð 	'ð
ð 	;ð 	;ˆCð �MŠM˜S˜(¥C¨Ô(8Ñ$9Ô$9Ñ:Ô:Ð:Ð:ð		;ð 	;s   �?¿AÁAc                 ó:   — dD ]}|                       |¦  «         Œd S )N)zomp tbb workqueuezomp workqueue tbb©rC  ©r1   r<  s     r   Útest_ompz#TestThreadingLayerPriority.test_ompL  ó2   € àAð 	'ð 	'ˆGØ×Ò˜gÑ&Ô&Ð&Ð&ð	'ð 	'r   c                 ó:   — dD ]}|                       |¦  «         Œd S )N)ztbb omp workqueueztbb workqueue omprP  rQ  s     r   Útest_tbbz#TestThreadingLayerPriority.test_tbbQ  rS  r   c                 ó:   — dD ]}|                       |¦  «         Œd S )N)zworkqueue tbb ompzworkqueue omp tbbrP  rQ  s     r   Útest_workqueuez)TestThreadingLayerPriority.test_workqueueV  s2   € ØAð 	'ð 	'ˆGØ×Ò˜gÑ&Ô&Ð&Ð&ð	'ð 	'r   N)r4   r5   r6   rû   rC  r  r  rH  rN  rR  rU  rW  r&   r   r   r;  r;    s¿   € € € € € ð# Cð #ð #ð #ð #ðB Øð'ð 'ñ „[ñ „[ð'ð Øð;ð ;ñ „[ñ „[ð;ð ð'ð 'ñ „[ð'ð ð'ð 'ñ „[ð'ð'ð 'ð 'ð 'ð 'r   r;  c                   ó|   — e Zd ZdZdZed„ ¦   «         Zed„ ¦   «         Zd„ Z	 e
j        ed¦  «        d„ ¦   «         ZdS )	ÚTestMiscBackendIssueszL
    Checks fixes for the issues with threading backends implementation
    Fc                 ó¦   — d}t           j        d|g}t          j                             ¦   «         }d|d<   d|d<   |                      ||¬¦  «         dS )	z8
        Tests that OMP does not overflow stack
        a‹  if 1:
            from numba import vectorize, threading_layer
            import numpy as np

            @vectorize(['f4(f4,f4,f4,f4,f4,f4,f4,f4)'], target='parallel')
            def foo(a, b, c, d, e, f, g, h):
                return a+b+c+d+e+f+g+h

            x = np.ones(2**20, np.float32)
            foo(*([x]*8))
            assert threading_layer() == "omp", "omp not found"
        r4  r¨   r÷   Ú100KÚOMP_STACKSIZEr5  N©rü   rý   rø   rù   rú   rõ   ©r1   r7  rñ   rá   s       r   Útest_omp_stack_overflowz-TestMiscBackendIssues.test_omp_stack_overflowb  s[   € ð
ˆõ ”> 4¨Ð/ˆÝŒj�oŠoÑÔˆØ',ˆÐ#Ñ$Ø%ˆˆOÑØ�Š�W #ˆÑ&Ô&Ð&Ð&Ð&r   c                 ó¦   — d}t           j        d|g}t          j                             ¦   «         }d|d<   d|d<   |                      ||¬¦  «         dS )	zq
        Tests that TBB works well with single thread
        https://github.com/numba/numba/issues/3440
        aM  if 1:
            from numba import njit, prange, threading_layer

            @njit(parallel=True)
            def foo(n):
                acc = 0
                for i in prange(n):
                    acc += i
                return acc

            foo(100)
            assert threading_layer() == "tbb", "tbb not found"
        r4  r©   r÷   Ú1r¿   r5  Nr]  r^  s       r   Útest_single_thread_tbbz,TestMiscBackendIssues.test_single_thread_tbby  s\   € ðˆõ ”> 4¨Ð/ˆÝŒj�oŠoÑÔˆØ',ˆÐ#Ñ$Ø#&ˆÐÑ Ø�Š�W #ˆÑ&Ô&Ð&Ð&Ð&r   c                 ó†  — d}t           j        d|g}t          j                             ¦   «         }d|d<   d|d<   	 |                      ||¬¦  «        \  }}d
S # t          $ r_}| j        rt          ||¦  «         t          |¦  «        }|  
                    d|¦  «         d	}|  
                    ||¦  «         Y d
}~d
S d
}~ww xY w)zW
        Tests workqueue raises sigabrt if a nested parallel call is performed
        a¸  if 1:
            from numba import njit, prange
            import numpy as np

            @njit(parallel=True)
            def nested(x):
                for i in prange(len(x)):
                    x[i] += 1


            @njit(parallel=True)
            def main():
                Z = np.zeros((5, 10))
                for i in prange(Z.shape[0]):
                    nested(Z[i])
                return Z

            main()
        r4  rÄ   r÷   Ú4r¿   r5  zfailed with codezTNumba workqueue threading layer is terminating: Concurrent access has been detected.N)rü   rý   rø   rù   rú   rõ   rí   r  r  rû   r  )	r1   r7  rñ   rá   r+   rô   rj   Úe_msgrA   s	            r   Ú+test_workqueue_aborts_on_nested_parallelismzATestMiscBackendIssues.test_workqueue_aborts_on_nested_parallelism’  så   € ðˆõ& ”> 4¨Ð/ˆÝŒj�oŠoÑÔˆØ'2ˆÐ#Ñ$Ø#&ˆÐÑ ð	+Ø—|’| G°�|Ñ5Ô5‰HˆC���øÝð 		+ð 		+ð 		+ØŒ{ð  Ý�c˜3‘”�Ý˜‘F”FˆEØ�MŠMÐ,¨eÑ4Ô4Ð4ð?ˆHà�MŠM˜( EÑ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*øøøøð		+øøøs   »A Á
C Á!AB;Â;C zTest needs fork(2)c                 ó¦   — d}t           j        d|g}t          j                             ¦   «         }d|d<   d|d<   |                      ||¬¦  «         d S )NaÛ  if 1:
            from numba import njit, prange, threading_layer
            import numpy as np
            import multiprocessing

            if __name__ == "__main__":
                # Need for force fork context (OSX default is "spawn")
                multiprocessing.set_start_method('fork')

                @njit(parallel=True)
                def func(x):
                    return 10. * x

                arr = np.arange(2.)

                # run in single process to start Numba's thread pool
                np.testing.assert_allclose(func(arr), func.py_func(arr))

                # now run in a multiprocessing pool to get a fork from a
                # non-main thread
                with multiprocessing.Pool(10) as p:
                    result = p.map(func, [arr])
                np.testing.assert_allclose(result,
                                           func.py_func(np.expand_dims(arr, 0)))

                assert threading_layer() == "workqueue"
        r4  rÄ   r÷   rd  r¿   r5  r]  r^  s       r   Ú0test_workqueue_handles_fork_from_non_main_threadzFTestMiscBackendIssues.test_workqueue_handles_fork_from_non_main_thread»  s\   € ðˆõ6 ”> 4¨Ð/ˆÝŒj�oŠoÑÔˆØ'2ˆÐ#Ñ$Ø#&ˆÐÑ à�Š�W #ˆÑ&Ô&Ð&Ð&Ð&r   N)r4   r5   r6   rº   r  r  r_  r  rb  rf  r  Ú
skipUnlessr´   rh  r&   r   r   rY  rY  [  s•   € € € € € ðð ð €Fàð'ð 'ñ „[ð'ð, ð'ð 'ñ „[ð'ð0'+ð '+ð '+ðR €XÔ˜Ð(<Ñ=Ô=ð&'ð &'ñ >Ô=ð&'ð &'ð &'r   rY  c                   ó`   — e Zd ZdZdZd„ Zd„ Zd„ Zed„ ¦   «         Z	d„ Z
d„ Zed	„ ¦   «         Zd
S )ÚTestForkSafetyIssueszV
    Checks Numba's behaviour in various situations involving GNU OpenMP and fork
    Fc                 óX   — d}t           j        d|g}|                      |¦  «        \  }}d S )Nzsif 1:
            from numba.np.ufunc import omppool
            assert omppool.openmp_vendor == 'GNU'
            r4  )rü   rý   rõ   )r1   r7  rñ   r+   rô   s        r   Ú!test_check_threading_layer_is_gnuz6TestForkSafetyIssues.test_check_threading_layer_is_gnuî  s2   € ðˆõ ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSˆSˆSr   c                 óä   — d}| j         |z  }t          j        d|g}	 |                      |¦  «        \  }}dS # t          $ r.}|                      dt          |¦  «        ¦  «         Y d}~dS d}~ww xY w)z~
        Whilst normally valid, this actually isn't for Numba invariant of OpenMP
        Checks SIGABRT is received.
        züif 1:
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            Z = busy_func(X, Y)
            pid = os.fork()
            if pid  == 0:
                Z = busy_func(X, Y)
            else:
                os.wait()
        r4  zfailed with code -6N)r/  rü   rý   rõ   rí   r  rû   )r1   r6  r7  rñ   r+   rô   rj   s          r   Ú!test_par_parent_os_fork_par_childz6TestForkSafetyIssues.test_par_parent_os_fork_par_childö  s�   € ð
	ˆð ” Ñ$ˆÝ”> 4¨Ð/ˆð	9Ø—|’| GÑ,Ô,‰HˆC���øÝð 	9ð 	9ð 	9Ø�MŠMÐ/µ°Q±´Ñ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8øøøøð	9øøøs   �7 ·
A/Á#A*Á*A/c                 óž   — d}| j         |z  }t          j        d|g}|                      |¦  «        \  }}| j        rt          ||¦  «         dS dS )au  
        Implicit use of multiprocessing fork context.
        Does this:
        1. Start with OpenMP
        2. Fork to processes using OpenMP (this is invalid)
        3. Joins fork
        4. Check the exception pushed onto the queue that is a result of
           catching SIGTERM coming from the C++ aborting on illegal fork
           pattern for GNU OpenMP
        aí  if 1:
            mp = multiprocessing.get_context('fork')
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            q = mp.Queue()

            # Start OpenMP runtime on parent via parallel function
            Z = busy_func(X, Y, q)

            # fork() underneath with no exec, will abort
            proc = mp.Process(target = busy_func, args=(X, Y, q))
            proc.start()

            err = q.get()
            assert "Caught SIGTERM" in str(err)
        r4  N©r/  rü   rý   rõ   r  r  ©r1   r6  r7  rñ   r+   rô   s         r   Ú*test_par_parent_implicit_mp_fork_par_childz?TestForkSafetyIssues.test_par_parent_implicit_mp_fork_par_child  s_   € ðˆð  ” Ñ$ˆÝ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSØŒ;ð 	Ý�#�s‰OŒOˆOˆOˆOð	ð 	r   c                 óž   — d}| j         |z  }t          j        d|g}|                      |¦  «        \  }}| j        rt          ||¦  «         dS dS )au  
        Explicit use of multiprocessing fork context.
        Does this:
        1. Start with OpenMP
        2. Fork to processes using OpenMP (this is invalid)
        3. Joins fork
        4. Check the exception pushed onto the queue that is a result of
           catching SIGTERM coming from the C++ aborting on illegal fork
           pattern for GNU OpenMP
        a  if 1:
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            ctx = multiprocessing.get_context('fork')
            q = ctx.Queue()

            # Start OpenMP runtime on parent via parallel function
            Z = busy_func(X, Y, q)

            # fork() underneath with no exec, will abort
            proc = ctx.Process(target = busy_func, args=(X, Y, q))
            proc.start()
            proc.join()

            err = q.get()
            assert "Caught SIGTERM" in str(err)
        r4  Nrq  rr  s         r   Ú*test_par_parent_explicit_mp_fork_par_childz?TestForkSafetyIssues.test_par_parent_explicit_mp_fork_par_child-  s_   € ðˆð" ” Ñ$ˆÝ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSØŒ;ð 	Ý�#�s‰OŒOˆOˆOˆOð	ð 	r   c                 óž   — d}| j         |z  }t          j        d|g}|                      |¦  «        \  }}| j        rt          ||¦  «         dS dS )zØ
        Explicit use of multiprocessing spawn, this is safe.
        Does this:
        1. Start with OpenMP
        2. Spawn to processes using OpenMP
        3. Join spawns
        4. Run some more OpenMP
        a¼  if 1:
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            ctx = multiprocessing.get_context('spawn')
            q = ctx.Queue()

            # Start OpenMP runtime and run on parent via parallel function
            Z = busy_func(X, Y, q)
            procs = []
            for x in range(20): # start a lot to try and get overlap
                ## fork() + exec() to run some OpenMP on children
                proc = ctx.Process(target = busy_func, args=(X, Y, q))
                procs.append(proc)
                sys.stdout.flush()
                sys.stderr.flush()
                proc.start()

            [p.join() for p in procs]

            try:
                q.get(False)
            except multiprocessing.queues.Empty:
                pass
            else:
                raise RuntimeError("Queue was not empty")

            # Run some more OpenMP on parent
            Z = busy_func(X, Y, q)
        r4  Nrq  rr  s         r   Ú-test_par_parent_mp_spawn_par_child_par_parentzBTestForkSafetyIssues.test_par_parent_mp_spawn_par_child_par_parentP  s_   € ðˆð: ” Ñ$ˆÝ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSØŒ;ð 	Ý�#�s‰OŒOˆOˆOˆOð	ð 	r   c                 óž   — d}| j         |z  }t          j        d|g}|                      |¦  «        \  }}| j        rt          ||¦  «         dS dS )a  
        Implicit use of multiprocessing (will be fork, but cannot declare that
        in Py2.7 as there's no process launch context).
        Does this:
        1. Start with no OpenMP
        2. Fork to processes using OpenMP
        3. Join forks
        4. Run some OpenMP
        a,  if 1:
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            q = multiprocessing.Queue()

            # this is ok
            procs = []
            for x in range(10):
                # fork() underneath with but no OpenMP in parent, this is ok
                proc = multiprocessing.Process(target = busy_func,
                                               args=(X, Y, q))
                procs.append(proc)
                proc.start()

            [p.join() for p in procs]

            # and this is still ok as the OpenMP happened in forks
            Z = busy_func(X, Y, q)
            try:
                q.get(False)
            except multiprocessing.queues.Empty:
                pass
            else:
                raise RuntimeError("Queue was not empty")
        r4  Nrq  rr  s         r   Ú=test_serial_parent_implicit_mp_fork_par_child_then_par_parentzRTestForkSafetyIssues.test_serial_parent_implicit_mp_fork_par_child_then_par_parent|  ó_   € ðˆð2 ” Ñ$ˆÝ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSØŒ;ð 	Ý�#�s‰OŒOˆOˆOˆOð	ð 	r   c                 óž   — d}| j         |z  }t          j        d|g}|                      |¦  «        \  }}| j        rt          ||¦  «         dS dS )zÇ
        Explicit use of multiprocessing 'fork'.
        Does this:
        1. Start with no OpenMP
        2. Fork to processes using OpenMP
        3. Join forks
        4. Run some OpenMP
        a  if 1:
            X = np.arange(1000000.)
            Y = np.arange(1000000.)
            ctx = multiprocessing.get_context('fork')
            q = ctx.Queue()

            # this is ok
            procs = []
            for x in range(10):
                # fork() underneath with but no OpenMP in parent, this is ok
                proc = ctx.Process(target = busy_func, args=(X, Y, q))
                procs.append(proc)
                proc.start()

            [p.join() for p in procs]

            # and this is still ok as the OpenMP happened in forks
            Z = busy_func(X, Y, q)
            try:
                q.get(False)
            except multiprocessing.queues.Empty:
                pass
            else:
                raise RuntimeError("Queue was not empty")
        r4  Nrq  rr  s         r   Ú=test_serial_parent_explicit_mp_fork_par_child_then_par_parentzRTestForkSafetyIssues.test_serial_parent_explicit_mp_fork_par_child_then_par_parent¥  rz  r   N)r4   r5   r6   rº   r  rm  ro  rs  r   ru  rw  ry  r|  r&   r   r   rk  rk  æ  sª   € € € € € ðð ð €Fð)ð )ð )ð9ð 9ð 9ð,ð ð ðB ð ð  ñ „Zð ðD*ð *ð *ðX'ð 'ð 'ðR ð&ð &ñ „Zð&ð &ð &r   rk  c                   ó>   — e Zd ZdZed„ ¦   «         Zed„ ¦   «         ZdS )ÚTestTBBSpecificIssuesFc                 óÚ   — d}t           j        d|g}|                      |¦  «        \  }}d}|                      ||¦  «         | j        r"t          d|¦  «         t          d|¦  «         d S d S )Na%  if 1:
            import threading
            import numba
            numba.config.THREADING_LAYER='tbb'
            from numba import njit, prange, objmode
            from numba.core.serialize import PickleCallableByPath
            import os

            e_running = threading.Event()
            e_proceed = threading.Event()

            def indirect_core():
                e_running.set()
                # wait for forker() to have forked
                while not e_proceed.isSet():
                    pass

            indirect = PickleCallableByPath(indirect_core)

            @njit
            def obj_mode_func():
                with objmode():
                    indirect()

            @njit(parallel=True, nogil=True)
            def work():
                acc = 0
                for x in prange(10):
                    acc += x
                obj_mode_func()
                return acc

            def runner():
                work()

            def forker():
                # wait for the jit function to say it's running
                while not e_running.isSet():
                    pass
                # then fork
                os.fork()
                # now fork is done signal the runner to proceed to exit
                e_proceed.set()

            numba_runner = threading.Thread(target=runner,)
            fork_runner =  threading.Thread(target=forker,)

            threads = (numba_runner, fork_runner)
            for t in threads:
                t.start()
            for t in threads:
                t.join()
        r4  z9Attempted to fork from a non-main thread, the TBB libraryúOUT:úERR:)rü   rý   rõ   r  r  r  )r1   r7  rñ   r+   rô   Úmsg_heads         r   Útest_fork_from_non_main_threadz4TestTBBSpecificIssues.test_fork_from_non_main_threadÕ  s‚   € ð64ˆõl ”> 4¨Ð/ˆØ—<’< Ñ(Ô(‰ˆˆSàNˆØ�Š�h Ñ$Ô$Ð$àŒ;ð 	Ý�&˜#ÑÔÐÝ�&˜#ÑÔÐÐÐð	ð 	r   c                 ó¨  — |                       ¦   «          d}d                     d|¦  «        }t          j        d|g}t          j                             ¦   «         }d|d<   |                      ||¬¦  «        \  }}||v r|                      d¦  «         n|  	                    d	|¦  «         | j
        r"t          d
|¦  «         t          d|¦  «         d S d S )NzSKIP: COMPILATION FAILEDax  if 1:
            import ctypes
            import sys
            import multiprocessing as mp
            from tempfile import TemporaryDirectory, NamedTemporaryFile
            from numba.pycc.platform import Toolchain, external_compiler_works
            from numba import njit, prange, threading_layer
            import faulthandler
            faulthandler.enable()
            if not external_compiler_works():
                raise AssertionError('External compilers are not found.')
            with TemporaryDirectory() as tmpdir:
                with NamedTemporaryFile(dir=tmpdir) as tmpfile:
                    try:
                        src = """
                        #define TBB_PREVIEW_WAITING_FOR_WORKERS 1
                        #include <tbb/tbb.h>
                        static tbb::task_scheduler_handle tsh;
                        extern "C"
                        {
                        void launch(void)
                        {
                            tsh = tbb::task_scheduler_handle::get();
                        }
                        }
                        """
                        cxxfile = f"{tmpfile.name}.cxx"
                        with open(cxxfile, 'wt') as f:
                            f.write(src)
                        tc = Toolchain()
                        object_files = tc.compile_objects([cxxfile,],
                                                           output_dir=tmpdir)
                        dso_name = f"{tmpfile.name}.so"
                        tc.link_shared(dso_name, object_files,
                                       libraries=['tbb',],
                                       export_symbols=['launch'])
                        # Load into the process, it doesn't matter whether the
                        # DSO exists on disk once it's loaded in.
                        DLL = ctypes.CDLL(dso_name)
                    except Exception as e:
                        # Something is broken in compilation, could be one of
                        # many things including, but not limited to: missing tbb
                        # headers, incorrect permissions, compilers that don't
                        # work for the above
                        print(e)
                        print('BROKEN_COMPILERS')
                        sys.exit(0)

                    # Do the test, launch this library and also execute a
                    # function with the TBB threading layer.

                    DLL.launch()

                    @njit(parallel=True)
                    def foo(n):
                        acc = 0
                        for i in prange(n):
                            acc += i
                        return acc

                    foo(1)

            # Check the threading layer used was TBB
            assert threading_layer() == 'tbb'

            # Use mp context for a controlled version of fork, this triggers the
            # reported bug.

            ctx = mp.get_context('fork')
            def nowork():
                pass
            p = ctx.Process(target=nowork)
            p.start()
            p.join(10)
            print("SUCCESS")
            ÚBROKEN_COMPILERSr4  r©   r÷   r5  z3Compilation of DSO failed. Check output for detailsÚSUCCESSr€  r�  )Úskip_if_no_external_compilerÚreplacerü   rý   rø   rù   rú   rõ   rÍ   r  r  r  )r1   r…  r7  rñ   rá   r+   rô   s          r   Ú&test_lifetime_of_task_scheduler_handlez<TestTBBSpecificIssues.test_lifetime_of_task_scheduler_handle0  só   € ð 	×)Ò)Ñ+Ô+Ð+ð 6ÐðK÷V ’Ð*Ð,<Ñ=Ô=ðW 	õZ ”> 4¨Ð/ˆÝŒj�oŠoÑÔˆØ',ˆÐ#Ñ$Ø—<’< ¨S�<Ñ1Ô1‰ˆˆSà˜sÐ"Ð"Ø�MŠMÐOÑPÔPÐPÐPà�MŠM˜) SÑ)Ô)Ð)àŒ;ð 	Ý�&˜#ÑÔÐÝ�&˜#ÑÔÐÐÐð	ð 	r   N)r4   r5   r6   r  r   rƒ  r‰  r&   r   r   r~  r~  Ï  sX   € € € € € ð €FàðXð Xñ „ZðXðt ð_ð _ñ „Zð_ð _ð _r   r~  c                   ó4   — e Zd ZdZd„ Zed„ ¦   «         Zd„ ZdS )ÚTestInitSafetyIssuesFc                 ó  — t          j        |t           j        t           j        ¬¦  «        }t          j        t
          |j        ¦  «        }	 |                     ¦   «          |                     ¦   «         \  }}|j	        dk    r-t          d|j	        ›d|                     ¦   «         ›d�¦  «        ‚	 |                     ¦   «          n# |                     ¦   «          w xY w|                     ¦   «         |                     ¦   «         fS )N)rß   rà   r   râ   rã   rv   rä   )r1   rñ   rò   ró   r+   rô   s         r   rõ   zTestInitSafetyIssues.run_cmd˜  sí   € ÝÔ  Ý(2¬Ý(2¬ð:ñ :ô :ˆõ ”/¥-°´Ñ<Ô<ˆð	Ø�MŠM‰OŒOˆOØ×(Ò(Ñ*Ô*‰HˆC�ØÔ 1Ò$Ð$Ý$�nàÔ%Ð%Ð% s§z¢z¡|¤| | |ð5ñ6ô 6ð 6ð %ð
 �NŠNÑÔÐÐøˆG�NŠNÑÔÐÐøøøØ�zŠz‰|Œ|˜SŸZšZ™\œ\Ð)Ð)s   ÁA#C ÃCc                 óT  — t           j                             t           j                             t          ¦  «        d¦  «        }t
          j        |g}|                      |¦  «        \  }}|                      d|¦  «         | j	        r"t          d|¦  «         t          d|¦  «         d S d S )Nzorphaned_semaphore_usecase.pyzleaked semaphorer€  r�  )rø   r+  rz   r,  r-  rü   rý   rõ   ÚassertNotInr  r  )r1   Ú	test_filerñ   r+   rô   s        r   Útest_orphaned_semaphorez,TestInitSafetyIssues.test_orphaned_semaphore©  s¢   € õ
 ”G—L’L¥¤§¢µÑ!:Ô!:Ø!@ñBô Bˆ	å”> 9Ð-ˆØ—<’< Ñ(Ô(‰ˆˆSð 	×ÒÐ+¨SÑ1Ô1Ð1àŒ;ð 	Ý�&˜#ÑÔÐÝ�&˜#ÑÔÐÐÐð	ð 	r   c                 óN  — dD ]¡}	 t          j        |¦  «         n# t          $ r Y Œ$w xY wd}t          j        d|                     |¦  «        g}|                      |¦  «        \  }}| j        r t          d|¦  «         t          d|¦  «         |  	                    ||¦  «         Œ¢d S )N)r•   r”   r–   zƒimport numba; import multiprocessing;multiprocessing.set_start_method('{}');print(multiprocessing.get_context().get_start_method())r4  r€  r�  )
r‹   rŒ   r¶   rü   rý   Úformatrõ   r  r  r  )r1   ÚmethrB  rñ   r+   rô   s         r   Útest_lazy_lock_initz(TestInitSafetyIssues.test_lazy_lock_initº  sÐ   € ð 4ð 	%ð 	%ˆDðÝÔ+¨DÑ1Ô1Ð1Ð1øÝð ð ð Ø�ðøøøðMˆCõ ”~ t¨S¯ZªZ¸Ñ-=Ô-=Ð>ˆGØ—|’| GÑ,Ô,‰HˆC�ØŒ{ð #Ý�f˜cÑ"Ô"Ð"Ý�f˜cÑ"Ô"Ð"Ø�MŠM˜$ Ñ$Ô$Ð$Ð$ð	%ð 	%s   †›
(§(N)r4   r5   r6   r  rõ   r   r�  r”  r&   r   r   r‹  r‹  “  sT   € € € € € ð €Fð*ð *ð *ð" ðð ñ „Zðð %ð %ð %ð %ð %r   r‹  c                   ó   — e Zd Zd„ ZdS )ÚTestOpenMPVendorsc                 óø   — t          ¦   «         }d|d<   d|d<   d|d<   |                     ¦   «         D ]G}t          j                             |¦  «        r&|                      ||         t          j        ¦  «         ŒHdS )z>
        Checks the OpenMP vendor strings are correct
        ÚMSÚwin32ÚIntelr   r   r#  N)Údictr$  rü   r%  r&  ÚassertEqualr   Úopenmp_vendor)r1   rA   Úks      r   Útest_vendorszTestOpenMPVendors.test_vendorsÔ  s‰   € õ ‘6”6ˆØ ˆ�ÑØ$ˆ�ÑØ!ˆ�Ñð —’‘”ð 	Eð 	EˆAÝŒ|×&Ò& qÑ)Ô)ð EØ× Ò  ¨!¤­gÔ.CÑDÔDÐDøð	Eð 	Er   N)r4   r5   r6   rŸ  r&   r   r   r–  r–  Ð  s(   € € € € € ðEð Eð Eð Eð Er   r–  Ú__main__)crº   r]   rF  r‹   rø   rS   r  rå   rü   r?  rŸ   r  Únumpyr   Únumbar   r   r   r   Únumba.tests.supportr   r   r	   r
   r   r   r[   Út_queueÚnumba.testing.mainr   Ú_RUNNER_TIMEOUTÚ
numba.corer   ré   Únumba.np.ufunc.parallelr   Únumba.np.ufuncr   Ú_HAVE_TBB_POOLÚImportErrorr   Ú_HAVE_OMP_POOLÚscipy.linalg.cython_lapackÚscipyÚ_HAVE_LAPACKri  r  r  r�  Ú_gnuompÚskip_unless_gnu_ompr%  r&  Ú_windowsÚ_osxÚmaxsizeÚ_32bitr¼   r´   r   r#   r)   r,   Úobjectr.   r8   rG   rN   rQ   rW   rk   r„   ÚThreadÚ_thread_classr†   r“   r‘   r¯   r²   r°   r±   r³   r˜   ÚTHREADING_LAYERÚ_specific_backendsrÆ   r×   rÚ   r  r(  r1  r;  rY  rk  r~  r‹  r–  r4   Úmainr&   r   r   ú<module>r¼     sR  ððð ð Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø 	€	€	€	Ø €€€Ø 	€	€	€	Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ø €€€à Ð Ð Ð à >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >ðGð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Gð Ð Ð Ð Ø :Ð :Ð :Ð :Ð :Ð :Ø Ð Ð Ð Ð Ð ð   #Ñ%€ð
àEÐEÐEÐEÐEÐEØ!Ð!Ñ#Ô#Ð#Ø&Ð&Ð&Ð&Ð&Ð&Ø€N€NøØð ð ð Ø€N€N€NðøøøðØ&Ð&Ð&Ð&Ð&Ð&Ø€N€NøØð ð ð Ø€N€N€NðøøøðØ%Ð%Ð%Ð%Ø€L€LøØð ð ð Ø€L€L€Lðøøøð "ˆhÔ! .Ð2NÑOÔO€Ø!ˆhÔ! .Ð2KÑLÔL€à
Ð
;˜WÔ2°eÒ;€Ø)�hÔ)¨'Ð3JÑKÔKÐ àŒ<×"Ò" 5Ñ)Ô)€Ø
„|×Ò˜xÑ(Ô(€Ø	Œ˜Ò	€ØÐ à�€ð
ð ð ð ð  ð$ð $ð $ð $ð ð  ð  ð
ð ð ðð ð ð ð  ð  ð  ð  ˆvñ  ô  ð  ð
2ð 2ð 2ð 2ð 2�ñ 2ô 2ð 2ð
ð 
ð 
ð 
ð 
�&ñ 
ô 
ð 
ð2ð 2ð 2ð 2ð 2�Hñ 2ô 2ð 2ð2ð 2ð 2ð 2ð 2�xñ 2ô 2ð 2ð2ð 2ð 2ð 2ð 2˜ñ 2ô 2ð 2ðð ð ðð ð ð( Ô €ð,ð ,ð ,ð ,ð ,�vñ ,ô ,ð ,ðð ð ð ˆo˜m¨W¬]Ñ;Ô;€Ø!�/ ? ?°7Ñ#;Ô#;Ð<€Øð KØ$�_ o o°fÑ&=Ô&=Ð>€NØ*˜?¨O¨O¸LÑ,IÔ,IÐJÐð $�O _ _°YÑ%?Ô%?Ð@Ð ðUEð UEð UEð UEð UE˜hñ UEô UEð UEðp Ô+Ð/JÐJÐ ð €ÔÐ'Ð)GÑHÔHð+ð +ð +ð +ð +Ð1ñ +ô +ñ IÔHð+ðB × Ò Ñ Ô Ð ð/ð /ð /ð /ð /�vñ /ô /ð /ð>5Að 5Að 5Að 5Að 5AÐ*Ð,Cñ 5Aô 5Að 5Aðp × Ò Ñ Ô Ð ð3*ð 3*ð 3*ð 3*ð 3*˜Hñ 3*ô 3*ð 3*ðl ð"0ð "0ð "0ð "0ð "0Ð"7ñ "0ô "0ñ Ôð"0ðJ × $Ò $Ñ &Ô &Ð &ð ðC'ð C'ð C'ð C'ð C'Ð!6ñ C'ô C'ñ ÔðC'ðL ðF'ð F'ð F'ð F'ð F'Ð1ñ F'ô F'ñ ÔðF'ðT Øðdð dð dð dð dÐ0ñ dô dñ Ôñ ÔðdðN Øðð ð ð ð Ð1ñ ô ñ „ñ ÔððD ð9%ð 9%ð 9%ð 9%ð 9%˜8ñ 9%ô 9%ñ Ôð9%ðx ØðEð Eð Eð Eð E˜ñ Eô Eñ „ñ ÔðEð$ ˆzÒÐØ€H„M�O„O€O€O€Oð Ðs6   Á%A> Á>BÂBÂB ÂBÂBÂ#B* Â*B4Â3B4