§
    ƒÛg³£  ã                   óè  — 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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'j/        dk    Z0 e
j,        e0d¦  «        Z1ej2         3                    d¦  «        Z4ej2         3                    d¦  «        Z5ej6        dk    Z7e7Z8e4 Z9d„ Z:e+rd„ Z;nd„ Z;d„ Z<d„ Z= G d„ de>¦  «        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?¦  «        ZDd%„ ZEd&„ ZFe	jG        ZH G d'„ d(e>¦  «        ZId)„ ZJ eFeHejK        ¦  «        ZL eF eJd*¦  «        Ž ZMe4s eF eJd+¦  «        Ž ZN eF eJd,¦  «        Ž ZO eF eJd-¦  «        Ž ZP G d.„ d/e¦  «        ZQejR        d0v ZS e
j,        eSd1¦  «         G d2„ d3eQ¦  «        ¦   «         ZTeT U                    ¦   «           G d4„ d5e>¦  «        ZV G d6„ d7eVeQ¦  «        ZWeW U                    ¦   «           G d8„ d9e¦  «        ZXe G d:„ d;eX¦  «        ¦   «         ZYeY U                    ¦   «          e G d<„ d=eX¦  «        ¦   «         ZZe G d>„ d?eX¦  «        ¦   «         Z[ee1 G d@„ dAeX¦  «        ¦   «         ¦   «         Z\ee. G dB„ dCeX¦  «        ¦   «         ¦   «         Z]e G dD„ dEe¦  «        ¦   «         Z^ee- G dF„ dGe¦  «        ¦   «         ¦   «         Z_e`dHk    r e
ja        ¦   «          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     úW/granary/edev/quantum/lib/python3.11/site-packages/numba/tests/test_parallel_backend.pyÚfoor   G   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#   L   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#   P   s   € åŒy˜‰|Œ|˜aÑÐr   c                 ó   — | |z   S r   © )ÚaÚbs     r   Ú	ufunc_foor)   U   s   € Øˆq‰5€Lr   c                 ó   — | |z   |d<   d S )Nr   r&   )r'   r(   Úouts      r   Ú
gufunc_foor,   Y   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__d   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   b   ó#   € € € € € ð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__n   s   € ØˆŒØˆŒ	ˆ	ˆ	r   c                 ód   — | j         rt          | j         ¦  «         |                      ¦   «          d S r   )rJ   r   rI   )r1   s    r   rC   zmask_runner.__call__r   s/   € ØŒ9ð 	'õ ˜DœIÑ&Ô&Ð&Ø�Š‰Œˆˆˆr   N©r4   r5   r6   r3   rC   r&   r   r   rG   rG   m   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   z   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_methodI  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>.methgenH  s0   øø€ ðBð Bð Bð Bð Bð Bð 'Ð&r   )r·   rÂ   Úitemsr4   Úsetattr)ÚclsrÏ   Únamer¹   ÚmethnamerÑ   ri   s          r   ÚgeneratezTestParallelBackend.generateB  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Æ   5  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_processr  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Ú   Z  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                 óü   •— |                       ‰‰¦  «        \  }}| j        rt          d|›d|›d�¦  «         |                      d|¦  «         |                      d|v¦  «         |                      d|v¦  «         d S )Nz
stdout:
 "z"
 stderr:
 "ú"ÚOKÚFAILÚERROR)r  Ú_DEBUGÚprintÚassertInÚ
assertTrue)r1   Úorj   Ú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Ø�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  y  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   r-  r-  å  s�   € € € € € ðð ð €Fà"Ø"Ø,˜Xœ_¨U°BÑ7Ô7ð9ð 9€Hð ð@ð @ñ „[ð@ð( ð0ð 0ñ „[ð0ð 0ð 0r   r-  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"
                r0  r1  N)rø   rù   rú   rü   rý   ÚtextwrapÚdedentrõ   )r1   r8  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   r?  )r1   r�   rÏ   r8  s       r   Útest_valid_env_varz-TestThreadingLayerPriority.test_valid_env_var2  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í   r?  r  rû   Ú	exception)r1   r8  Ú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©r?  ©r1   r8  s     r   Útest_ompz#TestThreadingLayerPriority.test_ompF  ó2   € àAð 	'ð 	'ˆGØ×Ò˜gÑ&Ô&Ð&Ð&ð	'ð 	'r   c                 ó:   — dD ]}|                       |¦  «         Œd S )N)ztbb omp workqueueztbb workqueue omprL  rM  s     r   Útest_tbbz#TestThreadingLayerPriority.test_tbbK  rO  r   c                 ó:   — dD ]}|                       |¦  «         Œd S )N)zworkqueue tbb ompzworkqueue omp tbbrL  rM  s     r   Útest_workqueuez)TestThreadingLayerPriority.test_workqueueP  s2   € ØAð 	'ð 	'ˆGØ×Ò˜gÑ&Ô&Ð&Ð&ð	'ð 	'r   N)r4   r5   r6   rû   r?  r  r  rD  rJ  rN  rQ  rS  r&   r   r   r7  r7    s¿   € € € € € ð# Cð #ð #ð #ð #ðB Øð'ð 'ñ „[ñ „[ð'ð Øð;ð ;ñ „[ñ „[ð;ð ð'ð 'ñ „[ð'ð ð'ð 'ñ „[ð'ð'ð 'ð 'ð 'ð 'r   r7  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"
        r0  r¨   r÷   Ú100KÚOMP_STACKSIZEr1  N©rü   rý   rø   rù   rú   rõ   ©r1   r3  rñ   rá   s       r   Útest_omp_stack_overflowz-TestMiscBackendIssues.test_omp_stack_overflow\  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"
        r0  r©   r÷   Ú1r¿   r1  NrY  rZ  s       r   Útest_single_thread_tbbz,TestMiscBackendIssues.test_single_thread_tbbs  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()
        r0  rÄ   r÷   Ú4r¿   r1  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   r3  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"
        r0  rÄ   r÷   r`  r¿   r1  rY  rZ  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  r^  rb  r  Ú
skipUnlessr´   rd  r&   r   r   rU  rU  U  s•   € € € € € ðð ð €Fàð'ð 'ñ „[ð'ð, ð'ð 'ñ „[ð'ð0'+ð '+ð '+ðR €XÔ˜Ð(<Ñ=Ô=ð&'ð &'ñ >Ô=ð&'ð &'ð &'r   rU  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'
            r0  )rü   rý   rõ   )r1   r3  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()
        r0  zfailed with code -6N)r+  rü   rý   rõ   rí   r  rû   )r1   r2  r3  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)
        r0  N©r+  rü   rý   rõ   r  r  ©r1   r2  r3  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)
        r0  Nrm  rn  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)
        r0  Nrm  rn  s         r   Ú-test_par_parent_mp_spawn_par_child_par_parentzBTestForkSafetyIssues.test_par_parent_mp_spawn_par_child_par_parentJ  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")
        r0  Nrm  rn  s         r   Ú=test_serial_parent_implicit_mp_fork_par_child_then_par_parentzRTestForkSafetyIssues.test_serial_parent_implicit_mp_fork_par_child_then_par_parentv  ó_   € ðˆð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")
        r0  Nrm  rn  s         r   Ú=test_serial_parent_explicit_mp_fork_par_child_then_par_parentzRTestForkSafetyIssues.test_serial_parent_explicit_mp_fork_par_child_then_par_parentŸ  rv  r   N)r4   r5   r6   rº   r  ri  rk  ro  r   rq  rs  ru  rx  r&   r   r   rg  rg  à  sª   € € € € € ðð ð €Fð)ð )ð )ð9ð 9ð 9ð,ð ð ðB ð ð  ñ „Zð ðD*ð *ð *ðX'ð 'ð 'ðR ð&ð &ñ „Zð&ð &ð &r   rg  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()
        r0  z9Attempted to fork from a non-main thread, the TBB libraryúOUT:úERR:)rü   rý   rõ   r  r  r  )r1   r3  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_COMPILERSr0  r©   r÷   r1  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�  r3  rñ   rá   r+   rô   s          r   Ú&test_lifetime_of_task_scheduler_handlez<TestTBBSpecificIssues.test_lifetime_of_task_scheduler_handle*  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   rz  rz  É  sX   € € € € € ð €FàðXð Xñ „ZðXðt ð_ð _ñ „Zð_ð _ð _r   rz  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())r0  r|  r}  )
r‹   rŒ   r¶   rü   rý   Úformatrõ   r  r  r  )r1   Úmethr>  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__)brº   r]   rB  r‹   rø   rS   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_LAPACKre  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$  r-  r7  rU  rg  rz  r‡  r’  r4   Úmainr&   r   r   ú<module>r¸     sI  ððð ð Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ø €€€à Ð Ð Ð à >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >Ð >ð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ñ /ô /ð /ð>0Að 0Að 0Að 0Að 0AÐ*Ð,Cñ 0Aô 0Að 0Aðf × Ò Ñ Ô Ð ð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& Â&B0Â/B0