+
    :i                        R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIHtHtHtHt ^ RIHtHtHtHtHtHt ^ RIt^ RIHt ^ RIH t  ]R,
          t! ^ RI"H#t# ]#! 4        ^ RI$H%t% R	t& ^ RI$H(t( R	t) ^ RI*t+R	t,]PZ                  ! ])R4      t.]PZ                  ! ]&R4      t/]);'       d    ](P`                  R8H  t1]PZ                  ! ]1R4      t2]Pf                  Pi                  R4      t5]Pf                  Pi                  R4      t6]Pn                  RF8*  t8]8t9]5'       * t:R t;],'       d   R t<MR t<R t=R t> ! R R]?4      t@ ! R R]@4      tA ! R R]?4      tB ! R R]@4      tC ! R R ]@4      tD ! R! R"]@4      tER# tFR$ tG]
P                  tI ! R% R&]?4      tJR' tK]G! ]I]P                  4      tM]G! ]K! R(4      !  tN]5'       g   ]G! ]K! R)4      !  tO]G! ]K! R*4      !  tP]G! ]K! R+4      !  tQ ! R, R-]4      tR] P                  RG9   tT]PZ                  ! ]TR.4       ! R/ R0]R4      4       tU]UP                  4         ! R1 R2]?4      tW ! R3 R4]W]R4      tX]XP                  4         ! R5 R6]4      tY] ! R7 R8]Y4      4       tZ]ZP                  4        ] ! R9 R:]Y4      4       t[] ! R; R<]Y4      4       t\]]2 ! R= R>]Y4      4       4       t]]]/ ! R? R@]Y4      4       4       t^] ! RA RB]4      4       t_]]. ! RC RD]4      4       4       t`]aRE8X  d   ]P                  ! 4        R# R#   ]' d    R
t& ELi ; i  ]' d    R
t) ELi ; i  ]' d    R
t, ELi ; i)Hz
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darwinc                 <    \         P                  ! V 4      V,           # N)nponesnvs   &&_/var/www/html/photoedit/myenv/lib/python3.14/site-packages/numba/tests/test_parallel_backend.pyfoor   H   s    771:>    c                     \         P                  ! \         P                  ! W 34      \         P                  ! W 34      4      pV\         P                  ! V 4      ,           V,           # r   )r   dotr   arange)r   r   xs   && r   linalgr"   M   s>    FF277A6?BGGQFO4299Q<!##r   c                 <    \         P                  ! V 4      V,           # r   )r   r    r   s   &&r   r"   r"   Q   s    yy|ar   c                     W,           # r    )abs   &&r   	ufunc_foor(   V   s	    5Lr   c                     W,           V^ &   R# )    Nr%   )r&   r'   outs   &&&r   
gufunc_foor,   Z   s    UCFr   c                   &   a  ] tR t^^t o R tRtV tR# )runnablec                    Wn         R # r   _options)selfoptionss   &,r   __init__runnable.__init___   s    r   r0   N)__name__
__module____qualname____firstlineno__r4   __static_attributes____classdictcell____classdict__s   @r   r.   r.   ^   s        r   r.   c                   &   a  ] tR t^ct o R tRtV tR# )
jit_runnerc                    \        R/ V P                  B ! \        4      p^p^
p\        W#4      pV! W#4      p\        P                  P                  WE4       R#    Nr%   )r   r1   r   r   testingassert_allcloser2   cfuncr&   r'   expectedgots   &     r   __call__jit_runner.__call__e   sF    $dmm$S)q9Ak


""81r   r%   Nr6   r7   r8   r9   rI   r:   r;   r<   s   @r   r?   r?   c        2 2r   r?   c                   ,   a  ] tR t^nt o R tR tRtV tR# )mask_runnerc                    Wn         W n        R # r   )runnermask)r2   rP   rQ   r3   s   &&&,r   r4   mask_runner.__init__o   s    	r   c                t    V P                   '       d   \        V P                   4       V P                  4        R # r   )rQ   r   rP   )r2   s   &r   rI   mask_runner.__call__s   s"    999 DII&r   )rQ   rP   Nr6   r7   r8   r9   r4   rI   r:   r;   r<   s   @r   rN   rN   n   s      r   rN   c                   &   a  ] tR t^{t o R tRtV tR# )linalg_runnerc                    \        R/ V P                  B ! \        4      p^p^
p\        W#4      pV! W#4      p\        P                  P                  WE4       R# rA   )r   r1   r"   r   rC   rD   rE   s   &     r   rI   linalg_runner.__call__}   sF    $dmm$V,!<Ak


""81r   r%   NrK   r<   s   @r   rW   rW   {   rL   r   rW   c                   &   a  ] tR t^t o R tRtV tR# )vectorize_runnerc                &   \        R .3/ V P                  B ! \        4      p\        P                  P	                  ^
4      P                  \        P                  4      ;r#\        W#4      pV! W#4      p\        P                  P                  WE4       R# )z(f4, f4)N)	r   r1   r(   r   randomastypefloat32rC   rD   rE   s   &     r   rI   vectorize_runner.__call__   sf    :,8$--8C		  $++BJJ77Q?Ak


""81r   r%   NrK   r<   s   @r   r[   r[      s     2 2r   r[   c                   &   a  ] tR t^t o R tRtV tR# )guvectorize_runnerc                ,   R .p\        VR3/ V P                  B ! \        4      p\        P                  P	                  ^
4      P                  \        P                  4      ;r4\        W44      pV! W44      p\        P                  P                  WV4       R# )z(f4, f4, f4[:])z	(),()->()N)
r   r1   r,   r   r]   r^   r_   r(   rC   rD   )r2   sigrF   r&   r'   rG   rH   s   &      r   rI   guvectorize_runner.__call__   sn     !C>>zJ		  $++BJJ77Q?Ak


""81r   r%   NrK   r<   s   @r   rb   rb      rL   r   rb   c                 8   VP                  R 4      p \        P                  ! 4        \        \	        \        V 4      R,          4      4       F   p\        P                  ! V 4      pV! 4        K"  	  R#   \         d   pTP                  T4        Rp?R# Rp?ii ; i)queueg      ?N)
getfaulthandlerenablerangeintlenr]   choice	Exceptionput)fnlistkwargsq_fnes   &,    r   chooserrw      sp    

7As3v;,-.Av&BD /  	as   AA2 2B=BBc                    a a V V3R  lpV# )c                   < S
! 4       pR V/p\        ^4       Uu. uF  pS	! \        V 3VR7      NK  	  ppV F  pVP                  4        K  	  V F  pVP                  4        K  	  VP	                  4       '       gw   . pVP	                  4       '       g#   VP                  VP                  R4      4       K8  Rp\        TRP                  V Uu. uF  p\        V4      NK  	  up4      ,          4      hR# u upi u upi )rg   )targetargsrr   Fz)Error(s) occurred in delegated runner:
%s
N)	rk   rw   startjoinemptyappendrh   RuntimeErrorrepr)rq   rs   kwsithstherrors_msgr!   parallel_class
queue_impls   &        r   run_compile$compile_factory.<locals>.run_compile   s    Lla" 1 WF9SI  	 "BHHJ BGGI wwyyFggiiaeeEl+?Dtdii&0I&Qa&0I&JJKK " 1Js   C5C:r%   )r   r   r   s   ff r   compile_factoryr      s    L r   c                   ,   a  ] tR t^t o R tR tRtV tR# )_proc_class_implc                    Wn         R # r   _method)r2   methods   &&r   r4   _proc_class_impl.__init__   s    r   c                f    \         P                  ! V P                  4      pVP                  ! V/ VB # r   )multiprocessingget_contextr   Process)r2   r{   rr   ctxs   &*, r   rI   _proc_class_impl.__call__   s*    ))$,,7{{D+F++r   r   NrU   r<   s   @r   r   r      s     , ,r   r   c                 t    V R 8X  d   Rp \         P                  ! V 4      p\        V 4      pVP                  pW#3# )defaultN)r   r   r   Queue)r   r   procrg   s   &   r   _get_mp_classesr      s:    

%
%f
-CF#DIIE;r   spawnfork
forkserverr   c                     a  ] tR t^t o Rt]! RR7      ]! RRR7      ]! RRR7      ]! RR7      ]! RRR7      ]! RR7      ]! RRR7      ]! RRRR7      ]! RR7      ]! RRR7      ]! RRRR7      .t	]
'       g:   ]! RRR	7      ]! RRRR
7      ]! RRR	7      ]! RRRR
7      .t]	P                  ]4       ]P                  ^8  d   . tM^^.t. t]	 F$  t] F  t]P'                  ]! ]]4      4       K  	  K&  	  RR.t]P'                  R4       ]'       d#   ]P'                  R4       ]P'                  R4       R]! R]
'       * R	7      .R]! RRR7      .R]! RRR7      .R]	R]/tRR0tRR ltRtV tR# )TestParallelBackendBasez.
Base class for testing the parallel backends
T)nopython)r   cache)r   nogilparallel)r   rz   )r   rz   r   )r   r   )r   r   r   	threadingr]   multiprocessing_spawnmultiprocessing_forkmultiprocessing_forkserverconcurrent_jitconcurrent_vectorizeconcurrent_guvectorizeconcurrent_mix_useconcurrent_mix_use_masksomptbbc                   \        V P                  P                  4      V n        \	        R V P                  4      ;_uu_ 4        VR8X  d   \        V4       MVR8X  d   \        V4       MVR8X  d   \        V4       MVR8X  d   \        V4       MVR8X  d   \        V4       MVR8X  dk   \
        \        .p\        '       d+   VP                  \        4       VP                  \        4       \        P                  ! V4       V F  pV! V4       K  	  M\        RV,          4      hRRR4       R#   + '       g   i     R# ; i)		CACHE_DIRr   r   r   r   multiprocessing_defaultr]   zUnknown parallelism supplied %sN)r   	__class__r6   
_cache_dirr   thread_implfork_proc_implforkserver_proc_implspawn_proc_impldefault_proc_impl_HAVE_OS_FORKr   r]   shuffle
ValueError)r2   rq   parallelismpsimpls   &&&  r   r   #TestParallelBackendBase.run_compile  s    ()@)@A[$//::k)F# 66v& <<$V, 77' 99!&)(!?3 =IIn-II23r"DL  !5CE E+ ;:::s   A>D0A$D00E	)r   N)r   )r6   r7   r8   r9   __doc__r?   rW   r[   rb   	all_impls_parfors_unsupportedparfor_implsextendr   NUMBA_NUM_THREADSmasks
mask_implsr   rQ   r   rN   r   r   runnerssafe_backendsr   r:   r;   r<   s   @r   r   r      s    
 	D!D-D-t$t40$'$z:$zFD)D<D4HI  t4t4@4$74$dC	
 	&!#AJDk$56   )K./1278 	4H0HJ
 	d:>!
 	!Z@#
 	i"JG ENME Er   r   zThreading layer not explicitc                   4   a  ] tR tRt o Rt]R 4       tRtV tR# )TestParallelBackendi6  a]  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                    V P                    FZ  pV P                  P                  4        F9  w  r#R V,           R,           V,           pR pV! W14      pWFn        \	        WV4       K;  	  K\  	  R# )test_rt   c                    a a V V3R  lpV# )c                    < \         P                  ! 4       pVP                  '       d   R pV P                  V4       R# V P	                  SSR7       R# )z)daemonized processes cannot have children)r   N)r   current_processdaemonskipTestr   )r2   selfprocr   r   ps   &  r   test_methodBTestParallelBackend.generate.<locals>.methgen.<locals>.test_methodJ  s>    #2#B#B#D#???#ND MM$/ ,,Tq,Ar   r%   )r   r   r   s   ff r   methgen-TestParallelBackend.generate.<locals>.methgenI  s    B '&r   N)r   r   itemsr6   setattr)clsr   namer   methnamer   ru   s   &      r   generateTestParallelBackend.generateC  s\    A!kk//1
"Q;,t3	' T%&r* 2 !r   r%   N)	r6   r7   r8   r9   r   classmethodr   r:   r;   r<   s   @r   r   r   6  s      + +r   r   c            	       ^   a  ] tR tRt o R]R]R]P                  ! RR4      /tR t	R t
R	tV tR
# )TestInSubprocessi[  r   r   	workqueueF c                   \         P                  ! V\         P                  \         P                  VR 7      p\        P                  ! \
        VP                  4      p VP                  4        VP                  4       w  rVVP                  ^ 8w  d-   \        RVP                  : RVP                  4       : R24      hVP                  4       VP                  4       3VP                  4        #   TP                  4        i ; i)stdoutstderrenvprocess failed with code : stderr follows
r|   
subprocessPopenPIPEr   Timer_TEST_TIMEOUTkillr}   communicate
returncodeAssertionErrordecodecancelr2   cmdliner   popentimeoutr+   errs   &&&    r   run_cmdTestInSubprocess.run_cmd`  s      (2(2%(*
 //-<		MMO((*HC1$$%%szz|56 6 ::<-NNGNNs   A>C, ,C>c                    \         P                  P                  4       p\        V4      VR &   \        P
                  RRV.pV P                  WC4      # )NUMBA_THREADING_LAYERz-mznumba.runtests)osenvironcopystrsys
executabler  )r2   testthreading_layerenv_copyr   s   &&&  r   run_test_in_separate_process-TestInSubprocess.run_test_in_separate_processs  sD    ::??$,/,@()>>4)94@||G..r   r%   N)r6   r7   r8   r9   skip_no_tbbskip_no_ompunittestskipIfbackendsr  r  r:   r;   r<   s   @r   r   r   [  s5     {{X__UB79H&/ /r   r   c                   H   a  ] tR tRt o RtRt]R 4       t]R 4       tRt	V t
R# )TestSpecificBackendiz  a  
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           	        aa
 V P                   p\        P                  pR V,           R,           V,           pV: RV: RV: 2o
VV
3R lpR V: RV: RS: 2p	\        W	\	        R4      ! V! V4      4      4       R# )r   rt   .c                 f  < V P                  SS4      w  rV P                  '       d   \        R V: RV: R24       \        P                  ! RV4      pVe!   V P                  VP                  ^4      4       V P                  RV4       V P                  RV9  4       V P                  RV9  4       R# )z
stdout:
 "z"
 stderr:
 ""z\.\.\. skipped '(.*?)'NOKFAILERROR)	r  _DEBUGprintresearchr   groupassertIn
assertTrue)r2   orv   mbackendinjected_methods   &   r   test_template2TestSpecificBackend._inject.<locals>.test_template  s    44_gNDA{{{1a@A 		3Q7A}aggaj)MM$"OOF!O,OOG1,-r   long_runningN)r7   r   r6   r   r	   )r   r   r   r(  backend_guardthemodtheclsr   r*  injected_testr)  s   &&&f&     @r   _injectTestSpecificBackend._inject  sf    $--Q;$t+(.A	. ,-dG<N#M-$@A	Cr   c           	     b   V P                   P                  4        F  w  rV P                   F{  pV P                  P	                  4        FZ  pVR9   d/   VR8X  d(   \
        P                  P                  R4      '       d   K8  VR9   d
   VR8X  d   KH  V P                  W4W4       K\  	  K}  	  K  	  R# )r   r   linuxr   N)r   r]   )r   r]   )	r  r   r   r   keysr
  platform
startswithr1  )r   r(  r-  r   r   s   &    r   r   TestSpecificBackend.generate  s    &)ll&8&8&:"G__KK,,.D ??5(LL33G<<  44#{2 KK@ / % ';r   r%   N)r6   r7   r8   r9   r   r  r   r1  r   r:   r;   r<   s   @r   r  r  z  s;      FC C. A Ar   r  c                      a  ] tR tRt o RtR]P                  P                  ]4      ,          t	RR]	/,          t
R	R ltRtV tR# )
ThreadLayerTestHelperi  zH
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                d   Vf-   \         P                  P                  4       p\        R4      VR&   \        P
                  ! V\        P                  \        P                  VR7      p\        P                  ! \        VP                  4      p VP                  4        VP                  4       w  rVVP                  ^ 8w  d-   \        RVP                  : RVP                  4       : R24      h VP!                  4        VP                  4       VP                  4       3#   TP!                  4        i ; i)Nr   r  r   r   r   r|   )r  r  r  r	  r   r   r   r   r   r   r   r}   r   r   r   r   r   r   s   &&&    r   r  ThreadLayerTestHelper.run_cmd  s    ;**//#C+.u:C'(  (2(2%(*
 //-<	MMO((*HC1$$%%szz|56 6 %
 NNzz|SZZ\)) NNs   AD D/r%   r   )r6   r7   r8   r9   r   r  pathdirname__file___heretemplater  r:   r;   r<   s   @r   r:  r:    sB     
 277??8,,E, 5/-H0* *r   r:  c            	       z   a  ] tR tRt o RtRtR]R]R]P                  ! RR4      /t
]R 4       t]R	 4       tR
tV tR# )TestThreadingLayerSelectioni  z8
Checks that numba.threading_layer() reports correctly.
Fr   r   r   r   c           	     h   a V3R  lpRS,          p\        W\        R4      ! V! V4      4      4       R# )c                 $  < R pV P                   VS,          ,          p\        P                  RV.p\        P                  P                  4       p\        S4      VR&   V P                  W4R7      w  rVV P                  '       d   \        WV4       R# R# )zif 1:
                X = np.arange(1000000.)
                Y = np.arange(1000000.)
                Z = busy_func(X, Y)
                assert numba.threading_layer() == '%s'
            -cr  r   N)
rB  r
  r  r  r  r  r	  r  r  r   )r2   bodyrunmer   r   r+   r  r(  s   &      r   r*  :TestThreadingLayerSelection._inject.<locals>.test_template  st    D MMTG^4E~~tU3G**//#C+.w<C'(||G|5HC{{{c r   z test_threading_layer_selector_%s	importantN)r   r	   )r   r(  r-  r*  r0  s   &f&  r   r1  #TestThreadingLayerSelection._inject  s1    	  ;WDK }!=>	@r   c                n    V P                   P                  4        F  w  rV P                  W4       K  	  R # r   )r  r   r1  )r   r(  r-  s   &  r   r   $TestThreadingLayerSelection.generate  s(    &)ll&8&8&:"GKK/ ';r   r%   N)r6   r7   r8   r9   r   r  r  r  r  r  r  r   r1  r   r:   r;   r<   s   @r   rD  rD    s\      F{{X__UB79H @ @( 0 0r   rD  c                      a  ] tR tRt o V 3R lR lt]]R 4       4       t]]R 4       4       t]R 4       t	]R 4       t
R tR	tV tR
# )TestThreadingLayerPriorityi  c                    < V ^8  d   QhRS[ /# )   env_var)r	  )formatr=   s   "r   __annotate__'TestThreadingLayerPriority.__annotate__  s     # #C #r   c                    \         P                  P                  4       pRVR&   WR&   RV R2p\        P                  R\
        P                  ! V4      .pV P                  WBR7       R# )	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"
                rG  rH  N)r  r  r  r
  r  textwrapdedentr  )r2   rT  r   codecmds   &&   r   each_env_var'TestThreadingLayerPriority.each_env_var  so     jjoo'0#$07,-) *1	 2( NNOOD!

 	S"r   c                    . ROp\         P                  ! V4       F%  pRP                  V4      pV P                  V4       K'  	  R# )r    N)r   r   r   )	itertoolspermutationsr~   r^  )r2   r   r   rT  s   &   r   test_valid_env_var-TestThreadingLayerPriority.test_valid_env_var8  s9     .''0AhhqkGg& 1r   c                    R pV P                  \        4      ;_uu_ 4       pV P                  V4       RRR4       R F)  pV P                  V \	        XP
                  4      4       K+  	  R#   + '       g   i     LA; i)ztbb omp workqueue notvalidhereN)z!THREADING_LAYER_PRIORITY invalid:zIt must be a permutation of)assertRaisesr   r^  r$  r	  	exception)r2   rT  raisesmsgs   &   r   test_invalid_env_var/TestThreadingLayerPriority.test_invalid_env_var@  sa     3~..&g& /
C MMSEC(8(8$9:	
 /.s   A++A;	c                :    R F  pV P                  V4       K  	  R# )omp tbb workqueueN)rn  zomp workqueue tbbr^  r2   rT  s   & r   test_omp#TestThreadingLayerPriority.test_ompL      AGg& Br   c                :    R F  pV P                  V4       K  	  R# )tbb omp workqueueN)ru  ztbb workqueue ompro  rp  s   & r   test_tbb#TestThreadingLayerPriority.test_tbbQ  rs  r   c                :    R F  pV P                  V4       K  	  R# )workqueue tbb ompN)ry  zworkqueue omp tbbro  rp  s   & r   test_workqueue)TestThreadingLayerPriority.test_workqueueV  s    AGg& Br   r%   N)r6   r7   r8   r9   r^  r  r  rd  rk  rq  rv  rz  r:   r;   r<   s   @r   rQ  rQ    sz     # #B '  ' ;  ; ' ' ' '' 'r   rQ  c                      a  ] tR tRt o RtRt]R 4       t]R 4       t	R t
]P                  ! ]R4      R 4       tR	tV tR
# )TestMiscBackendIssuesi[  zD
Checks fixes for the issues with threading backends implementation
Fc                    Rp\         P                  RV.p\        P                  P	                  4       pRVR&   RVR&   V P                  W#R7       R# )	z(
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"
        rG  r   r  100KOMP_STACKSIZErH  Nr
  r  r  r  r  r  r2   rJ  r   r   s   &   r   test_omp_stack_overflow-TestMiscBackendIssues.test_omp_stack_overflowb  sN    
 >>4/jjoo',#$%OW&r   c                    Rp\         P                  RV.p\        P                  P	                  4       pRVR&   RVR&   V P                  W#R7       R# )	zY
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"
        rG  r   r  1r   rH  Nr  r  s   &   r   test_single_thread_tbb,TestMiscBackendIssues.test_single_thread_tbby  sO     >>4/jjoo',#$#& W&r   c                x   Rp\         P                  RV.p\        P                  P	                  4       pRVR&   RVR&    V P                  W#R7      w  rER
#   \         dZ   pT P                  '       d   \        XX4       \        T4      pT P                  RT4       R	pT P                  Y4        R
p?R
# R
p?ii ; i)zG
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()
        rG  r   r  4r   rH  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$  )	r2   rJ  r   r   r+   r  rv   e_msgrG   s	   &        r   +test_workqueue_aborts_on_nested_parallelismATestMiscBackendIssues.test_workqueue_aborts_on_nested_parallelism  s    & >>4/jjoo'2#$#& 	+||G|5HC 		+{{{c3FEMM,e4?HMM(**		+s   A B9 AB44B9zTest needs fork(2)c                    R p\         P                  RV.p\        P                  P	                  4       pRVR&   RVR&   V P                  W#R7       R# )a  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"
        rG  r   r  r  r   rH  Nr  r  s   &   r   0test_workqueue_handles_fork_from_non_main_threadFTestMiscBackendIssues.test_workqueue_handles_fork_from_non_main_thread  sO    6 >>4/jjoo'2#$#& W&r   r%   N)r6   r7   r8   r9   r   r  r  r  r  r  r  r  
skipUnlessr   r  r:   r;   r<   s   @r   r}  r}  [  s_      F' ', ' '0'+R (<=&' >&'r   r}  c                   f   a  ] tR tRt o RtRtR tR tR t]	R 4       t
R tR	 t]	R
 4       tRtV tR# )TestForkSafetyIssuesi  zN
Checks Numba's behaviour in various situations involving GNU OpenMP and fork
Fc                V    R p\         P                  RV.pV P                  V4      w  r4R# )zsif 1:
            from numba.np.ufunc import omppool
            assert omppool.openmp_vendor == 'GNU'
            rG  N)r
  r  r  )r2   rJ  r   r+   r  s   &    r   !test_check_threading_layer_is_gnu6TestForkSafetyIssues.test_check_threading_layer_is_gnu  s-     >>4/<<(Sr   c                    RpV P                   V,          p\        P                  RV.p V P                  V4      w  rER#   \         d'   pT P                  R\        T4      4        Rp?R# Rp?ii ; i)zf
Whilst normally valid, this actually isn't for Numba invariant of OpenMP
Checks SIGABRT is received.
zif 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()
        rG  zfailed with code -6N)rB  r
  r  r  r   r$  r	  )r2   rI  rJ  r   r+   r  rv   s   &      r   !test_par_parent_os_fork_par_child6TestForkSafetyIssues.test_par_parent_os_fork_par_child  sf    
	 $>>4/	9||G,HC 	9MM/Q88	9s   ? A0
A++A0c                    RpV P                   V,          p\        P                  RV.pV P                  V4      w  rEV P                  '       d   \        WE4       R# R# )a-  
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)
        rG  NrB  r
  r  r  r  r   r2   rI  rJ  r   r+   r  s   &     r   *test_par_parent_implicit_mp_fork_par_child?TestForkSafetyIssues.test_par_parent_implicit_mp_fork_par_child  sN      $>>4/<<(;;;#O r   c                    RpV P                   V,          p\        P                  RV.pV P                  V4      w  rEV P                  '       d   \        WE4       R# R# )a-  
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)
        rG  Nr  r  s   &     r   *test_par_parent_explicit_mp_fork_par_child?TestForkSafetyIssues.test_par_parent_explicit_mp_fork_par_child-  sN    " $>>4/<<(;;;#O r   c                    RpV P                   V,          p\        P                  RV.pV P                  V4      w  rEV P                  '       d   \        WE4       R# R# )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)
        rG  Nr  r  s   &     r   -test_par_parent_mp_spawn_par_child_par_parentBTestForkSafetyIssues.test_par_parent_mp_spawn_par_child_par_parentP  sN    : $>>4/<<(;;;#O r   c                    RpV P                   V,          p\        P                  RV.pV P                  V4      w  rEV P                  '       d   \        WE4       R# R# )z
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")
        rG  Nr  r  s   &     r   =test_serial_parent_implicit_mp_fork_par_child_then_par_parentRTestForkSafetyIssues.test_serial_parent_implicit_mp_fork_par_child_then_par_parent|  N    2 $>>4/<<(;;;#O r   c                    RpV P                   V,          p\        P                  RV.pV P                  V4      w  rEV P                  '       d   \        WE4       R# R# )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")
        rG  Nr  r  s   &     r   =test_serial_parent_explicit_mp_fork_par_child_then_par_parentRTestForkSafetyIssues.test_serial_parent_explicit_mp_fork_par_child_then_par_parent  r  r   r%   N)r6   r7   r8   r9   r   r  r  r  r  r   r  r  r  r  r:   r;   r<   s   @r   r  r    sV      F)9,B    D*X'R & &r   r  c                   D   a  ] tR tRt o Rt]R 4       t]R 4       tRtV t	R# )TestTBBSpecificIssuesi  Fc                    R p\         P                  RV.pV P                  V4      w  r4RpV P                  WT4       V P                  '       d   \        RV4       \        RV4       R# R# )a%  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()
        rG  z9Attempted to fork from a non-main thread, the TBB libraryOUT:ERR:N)r
  r  r  r$  r  r   )r2   rJ  r   r+   r  msg_heads   &     r   test_fork_from_non_main_thread4TestTBBSpecificIssues.test_fork_from_non_main_thread  s_    64l >>4/<<(Nh$;;;&#&# r   c                   V P                  4        R pRP                  RV4      p\        P                  RV.p\        P
                  P                  4       pRVR&   V P                  W4R7      w  rVW9   d   V P                  R4       MV P                  RV4       V P                  '       d   \        R	V4       \        R
V4       R# R# )z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_COMPILERSrG  r   r  rH  z3Compilation of DSO failed. Check output for detailsSUCCESSr  r  N)skip_if_no_external_compilerreplacer
  r  r  r  r  r  r   r$  r  r   )r2   r  rJ  r   r   r+   r  s   &      r   &test_lifetime_of_task_scheduler_handle<TestTBBSpecificIssues.test_lifetime_of_task_scheduler_handle0  s     	))+ 6KV *,<=W 	Z >>4/jjoo',#$<<<1"MMOPMM)S);;;&#&# r   r%   N)
r6   r7   r8   r9   r  r   r  r  r:   r;   r<   s   @r   r  r    s7      FX Xt _ _r   r  c                   @   a  ] tR tRt o RtR t]R 4       tR tRt	V t
R# )TestInitSafetyIssuesi  Fc                   \         P                  ! V\         P                  \         P                  R 7      p\        P                  ! \
        VP                  4      p VP                  4        VP                  4       w  rEVP                  ^ 8w  d-   \        RVP                  : RVP                  4       : R24      h VP                  4        VP                  4       VP                  4       3#   TP                  4        i ; i))r   r   r   r   r|   r   )r2   r   r   r   r+   r  s   &&    r   r  TestInitSafetyIssues.run_cmd  s      (2(2: //-<	MMO((*HC1$$%%szz|56 6 %
 NNzz|SZZ\)) NNs   AC, ,C>c                N   \         P                  P                  \         P                  P                  \        4      R 4      p\
        P                  V.pV P                  V4      w  r4V P                  RV4       V P                  '       d   \        RV4       \        RV4       R# R# )zorphaned_semaphore_usecase.pyzleaked semaphorer  r  N)r  r>  r~   r?  r@  r
  r  r  assertNotInr  r   )r2   	test_filer   r+   r  s   &    r   test_orphaned_semaphore,TestInitSafetyIssues.test_orphaned_semaphore  s|    
 GGLL!:!@B	>>9-<<( 	+S1;;;&#&# r   c                N   R F  p \         P                  ! V4       Rp\        P                  RTP                  T4      .pT P                  T4      w  rET P                  '       d   \        RT4       \        RT4       T P                  Y4       K  	  R#   \         d     K  i ; i)r   zimport numba; import multiprocessing;multiprocessing.set_start_method('{}');print(multiprocessing.get_context().get_start_method())rG  r  r  N)r   r   r   )
r   r   r   r
  r  rU  r  r  r   r$  )r2   methr]  r   r+   r  s   &     r   test_lazy_lock_init(TestInitSafetyIssues.test_lazy_lock_init  s     4D++D1MC ~~tSZZ-=>G||G,HC{{{fc"fc"MM$$ 4
  s   BB$#B$r%   N)r6   r7   r8   r9   r  r  r   r  r  r:   r;   r<   s   @r   r  r    s/      F*"   % %r   r  c                   &   a  ] tR tRt o R tRtV tR# )TestOpenMPVendorsi  c                    \        4       pRVR&   RVR&   RVR&   VP                  4        FP  p\        P                  P	                  V4      '       g   K*  V P                  W,          \        P                  4       KR  	  R# )z.
Checks the OpenMP vendor strings are correct
MSwin32Intelr   r   r4  N)dictr5  r
  r6  r7  assertEqualr   openmp_vendor)r2   rG   ks   &  r   test_vendorsTestOpenMPVendors.test_vendors  sh     6 $! A||&&q))  g.C.CD !r   r%   N)r6   r7   r8   r9   r  r:   r;   r<   s   @r   r  r    s     E Er   r  __main__l        )r   r   r   )cr   ri   rb  r   r  r]   r!  r   r
  rZ  r   r  numpyr   numbar   r   r   r   numba.tests.supportr   r   r   r	   r
   r   rg   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_LAPACKr  r  r  r  _gnuompskip_unless_gnu_ompr6  r7  _windows_osxmaxsize_32bitr   r   r   r"   r(   r,   objectr.   r?   rN   rW   r[   rb   rw   r   Thread_thread_classr   r   r   r   r   r   r   r   r   THREADING_LAYER_specific_backendsr   r   r   r  r:  rD  rQ  r}  r  r  r  r  r6   mainr%   r   r   <module>r     s      	  	  
     > >G G  :   #%
E!#&N&N%L
 !!.2NO!!.2KL

;
;W22e;))'3JK <<""5)
||x(		 
 $ 
 v  
2 2
& 
2H 22x 22 2(   ,v , mW]];!?7#;<$of&=>N*OL,IJ $_Y%?@ UEh UEp ++/JJ  
')GH+1 + I+B    /v />5A*,C 5Ap    3*H 3*l "0"7 "0 "0J  $ $ & C'!6 C' C'L F'1 F' F'T d0 d  dN 1   D 9%8 9% 9%x E E  E$ zMMO y%  N  N  Ls6   )L ?L+ L; 	L('L(+	L87L8;	MM