
    J/Phgp                    	   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
mZ ddlmZmZmZ ddlmZ ddlZddlmZ ddlZddlmZ ddlmZ ddlZdd	lmZmZmZm Z mZm!Z!m"Z"m#Z#m$Z$m%Z%m&Z& dd
lm'Z'm(Z( ddl)m*Z*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZb ddlcmdZdmeZemfZfmgZg ddlhmiZi ddljmkZkmlZl ddlmmnZn ddlompZpmqZqmrZrmsZsmtZtmuZu ddl4mvZv ddlZddlwZwddlwZxddlymzZz ddl{Zddl|m}Z} dZ~ ej        e~d          Zd ZdZd Z eve          d             Z G d d e          Zd! Zd" Zd# Zd$ Zd% Zd& Zd' Zd( Zd) Zd* Zd+ Zd, Zd- Zdd.d/Zd0 Zd1 d2 eeeeeeeeeeeed3Zd4 Zd5eiZe5d6             Ze5d7             Ze5d8             Ze5d9             Z ed:d;d<g          Z ed=e           ed>e           ed?e           ed@e           ed?e           ed@e          dAZ G dB dCe          Z G dD dEej        ej                  ZdF Zeezj        e<    G dG dHe          Z G dI dJe          ZdK Z G dL dM          Z G dN dO          ZdP Z G dQ dR          ZddSZdT Z G dU dV          Z G dW dX          Z G dY dZ          Zd[ Z G d\ d]e          Z G d^ d_e          Z G d` dae          Zdb Zdc Zdd Zde Zdf Zdg Zdh Zdi Zdj Zdk Zdl Zdm Zdn Zdo Zdp Zdq Zdr Z edsg dtduv          Z	 	 	 ddwZdx Zdy Zdz Zd{ Zd| Zd} Zd~ Zee&j        e<   ddZee!j        e<   d Zee!j        e<   d Zee"j        e<   ddZ	 ddZd Zd Zd Zd Z edg d          Zd Zd Zd Z	 	 	 ddZd Zd Zd Zd Zee&j        e<   d Zd Zd Zee&j        e<   d ZddZddZd Zee&j        e<   d Zee&j        e<   ddZd Zd Zd ZddZee&j        e<   ddZee&j        e<   ddZee&j        e<   d Zee&j        e<   d Zee&j        e<   d Zee$j         e<   ddZee&j        e<   ed             Z e0e           G d de1                      Zd ZdS )a  
This module transforms data-parallel operations such as Numpy calls into
'Parfor' nodes, which are nested loops that can be parallelized.
It also implements optimizations such as loop fusion, and extends the rest of
compiler analysis and optimizations to support Parfors.
This is similar to ParallelAccelerator package in Julia:
https://github.com/IntelLabs/ParallelAccelerator.jl
'Parallelizing Julia with a Non-invasive DSL', T. Anderson et al., ECOOP'17.
    N)reduce)defaultdictOrderedDict
namedtuple)contextmanager)make_dataclass)ir)impl_ret_untracked)typestypingutilserrorsr	   analysispostprocrewrites	typeinferconfigir_utils)prangepndindex)datetime_minimumdatetime_maximum)as_dtypenumpy_version)infer_globalAbstractTemplate)StencilPass)register_jitablelower_builtin)+mk_unique_var
next_labelmk_allocget_np_ufunc_typmk_range_blockmk_loop_headerget_name_var_tablereplace_varsreplace_vars_inner
visit_varsvisit_vars_innerremove_deadcopy_propagateget_block_copiesapply_copy_propagatedprint_func_irfind_topo_orderget_stmt_writesrename_labelsget_call_tablesimplifysimplify_CFGhas_no_side_effectcanonicalize_array_mathadd_offset_to_labelsfind_callnamefind_build_sequenceguardrequireGuardExceptioncompile_to_numba_irget_definitionbuild_definitionsreplace_arg_nodesreplace_returns
is_getitem
is_setitemis_get_setitemindex_var_of_get_setitemset_index_var_of_get_setitemfind_potential_aliasesreplace_var_namestransfer_scope)compute_use_defscompute_live_mapcompute_dead_mapscompute_cfg_from_blocks)CFGraph)npydecl	signature)Function)random_int_argsrandom_1arg_sizerandom_2arg_sizelastrandom_3arg_sizelastrandom_callsassert_equiv)overload)array_analysis)stencilparforP   F)widthdrop_whitespacec                 |    |                                  D ]&}d t                              |          D              'd S )Nc                 ,    g | ]}t          |          S  print.0ys     T/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/numba/parfors/parfor.py
<listcomp>z!print_wrapped.<locals>.<listcomp>l   s    ///aq///    )
splitlines_txtwrapperwrap)xls     rg   print_wrappedro   j   sH    \\^^ 0 0//;++A../////0 0ri   c                      d S Nra   ra   ri   rg   init_prangerr   s   s    
Fri   c                      d } | S )Nc                      d S rq   ra   ra   ri   rg   no_opz#init_prange_overload.<locals>.no_opx   s    ri   ra   )ru   s    rg   init_prange_overloadrv   v   s      Lri   c                       e Zd Zd ZdS )internal_prangec                     t          | S rq   )range)clsargss     rg   __new__zinternal_prange.__new__~   s    d|ri   N)__name__
__module____qualname__r}   ra   ri   rg   rx   rx   |   s#            ri   rx   c                     |j         dk    rd }nA|j         dk    r3t          |j        t          j        t          j        f          rd }nd }nd }|S )Nr   c                     | d         S Nra   ra   in_arrs    rg   min_1z min_parallel_impl.<locals>.min_1       ":ri      c                 j   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t           j        j        
                    t          |                     D ]}t          || |                   }|S rq   )numbaparforsparforrr   min_checkerlencpythonbuiltinsget_type_max_valuedtyperx   r   r   valis      rg   r   z min_parallel_impl.<locals>.min_1       $00222CKK(((m,??MM-==c&kkJJ ; ;A*3q	::CC
ri   c                 j   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t           j        j        
                    t          |                     D ]}t          || |                   }|S rq   )r   r   r   rr   r   r   r   r   r   r   rx   minr   s      rg   r   z min_parallel_impl.<locals>.min_1       $00222CKK(((m,??MM-==c&kkJJ . .Ac6!9--CC
ri   c                 :   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t          j
        | j                  D ]}t          || |                   }|S rq   )r   r   r   rr   r   r   r   r   r   r   r   shaper   r   s      rg   r   z min_parallel_impl.<locals>.min_1   |    M ,,...F$$$-(;;FLIIC^FL11 * *#vay))Jri   ndim
isinstancer   r   
NPDatetimeNPTimedelta)return_typeargr   s      rg   min_parallel_implr      s     x1}}	 	 	 		Qci%"2E4E!FGG 	      	 	 	 Lri   c                     |j         dk    rd }nA|j         dk    r3t          |j        t          j        t          j        f          rd }nd }nd }|S )Nr   c                     | d         S r   ra   r   s    rg   max_1z max_parallel_impl.<locals>.max_1   r   ri   r   c                 j   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t           j        j        
                    t          |                     D ]}t          || |                   }|S rq   )r   r   r   rr   max_checkerr   r   r   get_type_min_valuer   rx   r   r   s      rg   r   z max_parallel_impl.<locals>.max_1   r   ri   c                 j   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t           j        j        
                    t          |                     D ]}t          || |                   }|S rq   )r   r   r   rr   r   r   r   r   r   r   rx   maxr   s      rg   r   z max_parallel_impl.<locals>.max_1   r   ri   c                 :   t           j        j                                         t	          t          |                      t           j        j                            | j	                  }t          j
        | j                  D ]}t          || |                   }|S rq   )r   r   r   rr   r   r   r   r   r   r   r   r   r   r   s      rg   r   z max_parallel_impl.<locals>.max_1   r   ri   r   )r   r   r   s      rg   max_parallel_implr      s    
x1}}	 	 	 		Qci%"2E4E!FGG 	      	 	 	 Lri   c                    t           j        j                                         t	          t          |                      |                                 }t           j        j        	                    |j
                  }t          j                            d|          }t           j        j                            t          |                    D ]8}t          j                            |||                   }t          ||          }9|j        S Nr   )r   r   r   rr   argmin_checkerr   ravelr   r   r   r   r   
IndexValuerx   r   indexr   Ainit_valivalr   	curr_ivals         rg   argmin_parallel_implr          	M$$&&&3v;;A}%88AAH?%%a22D]!11#a&&99 $ $O..q!A$77	4##:ri   c                    t           j        j                                         t	          t          |                      |                                 }t           j        j        	                    |j
                  }t          j                            d|          }t           j        j                            t          |                    D ]8}t          j                            |||                   }t          ||          }9|j        S r   )r   r   r   rr   argmax_checkerr   r   r   r   r   r   r   r   rx   r   r   r   s         rg   argmax_parallel_implr      r   ri   c                     t           j        j                                         | j        d         }|j        d         }d}t           j        j                            |          D ]}|| |         ||         z  z  }|S r   )r   r   r   rr   r   rx   )abrn   msr   s         rg   dotvv_parallel_implr      su    	M$$&&&	
A	
A 	
A]!11!44  	QqTAaD[Hri   c                     t           j        j                                         | j        }|j        \  }}t          j        || j                  }t           j        j                            |          D ]}|| |         ||d d f         z  z  }|S rq   )	r   r   r   rr   r   npzerosr   rx   )r   r   rn   r   ncr   s          rg   dotvm_parallel_implr      s    	M$$&&&	A7DAq 	AGA ]!11!44  	QqTAadG^Hri   c                 N   t           j        j                                         | j        \  }}|j        }t          j        || j                  }t           j        j                            |          D ]1}d}t          |          D ]}|| ||f         ||         z  z  }|||<   2|S r   )
r   r   r   rr   r   r   emptyr   rx   rz   )	r   r   r   r   rn   r   r   r   js	            rg   dotmv_parallel_implr      s    	M$$&&&7DAq	A 	AGA]!11!44  q 	  	 A1a41Q4AA!Hri   c                 
   t          |t          j        j                  r]t          |t          j        j                  r@|j        |j        cxk    rdk    r
n nt
          S |j        dk    r|j        dk    rt          S d S d S d S d S )Nr      )r   r   npytypesArrayr   r   r   )r   atypbtyps      rg   dot_parallel_implr     s    4-.. '4-..'9	&&&&Q&&&&&&& Y!^^	Q&&' ' ' ' ^ri   c                 h     | d          |j         dk    rd }n|j         dk    rfd}nfd}|S )Nr   c                     | d         S r   ra   r   s    rg   sum_1z sum_parallel_impl.<locals>.sum_1  r   ri   r   c                     t           j        j                                         }t           j        j                            t          |                     D ]}|| |         z  }|S rq   r   r   r   rr   rx   r   r   r   r   zeros      rg   r   z sum_parallel_impl.<locals>.sum_1  s\    M ,,...C])99#f++FF ! !vay Jri   c                     t           j        j                                         }t          j        | j                  D ]}|| |         z  }|S rq   r   r   r   rr   r   r   r   s      rg   r   z sum_parallel_impl.<locals>.sum_1  sO    M ,,...C^FL11 ! !vay Jri   r   )r   r   r   r   s      @rg   sum_parallel_implr     sx    ;q>>D
x1}}	 	 	 		Q	 	 	 	 	 		 	 	 	 	 Lri   c                 h     | d          |j         dk    rd }n|j         dk    rfd}nfd}|S )Nr   r   c                     | d         S r   ra   r   s    rg   prod_1z"prod_parallel_impl.<locals>.prod_1*  r   ri   c                     t           j        j                                         }t           j        j                            t          |                     D ]}|| |         z  }|S rq   r   r   r   r   ones      rg   r   z"prod_parallel_impl.<locals>.prod_1-  s\    M ,,...C])99#f++FF ! !vay Jri   c                     t           j        j                                         }t          j        | j                  D ]}|| |         z  }|S rq   r   r   s      rg   r   z"prod_parallel_impl.<locals>.prod_14  sO    M ,,...C^FL11 ! !vay Jri   r   )r   r   r   r   s      @rg   prod_parallel_implr   &  sx    
+a..C
x1}}	 	 	 		Q	 	 	 	 	 		 	 	 	 	 Mri   c                 h     | d          |j         dk    rd }n|j         dk    rfd}nfd}|S )Nr   c                     | d         S r   ra   r   s    rg   mean_1z"mean_parallel_impl.<locals>.mean_1B  r   ri   r   c                     t           j        j                                         }t           j        j                            t          |                     D ]}|| |         z  }|t          |           z  S rq   r   r   s      rg   r   z"mean_parallel_impl.<locals>.mean_1E  sg    M ,,...C])99#f++FF ! !vay s6{{?"ri   c                     t           j        j                                         }t          j        | j                  D ]}|| |         z  }|| j        z  S rq   )r   r   r   rr   r   r   sizer   s      rg   r   z"mean_parallel_impl.<locals>.mean_1L  sV    M ,,...C^FL11 ! !vay v{?"ri   r   )r   r   r   r   s      @rg   mean_parallel_implr   =  sx    ;q>>D
x1}}	 	 	 		Q	# 	# 	# 	# 	# 	#	# 	# 	# 	# 	# Mri   c                 H    |j         dk    rd }n|j         dk    rd }nd }|S )Nr   c                     dS r   ra   r   s    rg   var_1z var_parallel_impl.<locals>.var_1V  s    1ri   r   c                 n   |                                  }t          j        j                                         d}t          j        j                            t          |                     D ]9}| |         |z
  }|t          j        |t          j	        |          z            z  }:|t          |           z  S r   )
meanr   r   r   rr   rx   r   r   realconjr   r   ssdr   r   s        rg   r   z var_parallel_impl.<locals>.var_1Y  s    AM ,,...C])99#f++FF 3 3Qi!mrwsRWS\\1222V$$ri   c                 .   |                                  }t          j        j                                         d}t          j        | j                  D ]9}| |         |z
  }|t          j        |t          j	        |          z            z  }:|| j
        z  S r   )r   r   r   r   rr   r   r   r   r   r   r   r   s        rg   r   z var_parallel_impl.<locals>.var_1d  s    AM ,,...C^FL11 3 3Qi!mrwsRWS\\1222$$ri   r   )r   r   r   s      rg   var_parallel_implr   T  sV    
x1}}	 	 	 		Q		% 		% 		% 		%		% 		% 		% Lri   c                     d }|S )Nc                 0    |                                  dz  S )Ng      ?)varr   s    rg   std_1z std_parallel_impl.<locals>.std_1q  s    zz||s""ri   ra   )r   r   r   s      rg   std_parallel_implr   p  s    # # #Lri   )r   c                  
 t          | j                  

fd}d }
fd}d }
fd}d }t          d |D                       rd }	nd	 }	t          |          d
k    r||n|S t          |          dk    r||n|S t          |          dk    r||n|S t          |          dk    r|	S t	          d                    |                    )Nc                 2    t          j        d| d          S Nr   r   r   arange)stopinferred_dtypes    rg   arange_1z&arange_parallel_impl.<locals>.arange_1x  s    yD!^444ri   c                 0    t          j        d| d|          S r  r  )r  r   s     rg   arange_1_dtypez,arange_parallel_impl.<locals>.arange_1_dtype{  s    yD!U+++ri   c                 2    t          j        | |d          S Nr   r  )startr  r  s     rg   arange_2z&arange_parallel_impl.<locals>.arange_2~  s    ya888ri   c                 0    t          j        | |d|          S r  r  )r  r  r   s      rg   arange_2_dtypez,arange_parallel_impl.<locals>.arange_2_dtype  s    ya///ri   c                 2    t          j        | ||          S rq   r  )r  r  stepr  s      rg   arange_3z&arange_parallel_impl.<locals>.arange_3  s    ydN;;;ri   c                 0    t          j        | |||          S rq   r  )r  r  r  r   s       rg   arange_3_dtypez,arange_parallel_impl.<locals>.arange_3_dtype  s    ydE222ri   c              3   J   K   | ]}t          |t          j                  V  d S rq   )r   r   Complex)re   r   s     rg   	<genexpr>z'arange_parallel_impl.<locals>.<genexpr>  s.      
6
6A:a''
6
6
6
6
6
6ri   c                    t           j        j                                         || z
  |z  }t	          j        |j                  }t	          j        |j                  }t          t          t          ||          d                    }t          j        ||          }t           j        j                            |          D ]}	| |	|z  z   ||	<   |S r   )r   r   r   rr   mathceilr   imagintr   r   r   r   rx   )
r  r  r  r   nitems_cnitems_rnitems_initemsarrr   s
             rg   arange_4z&arange_parallel_impl.<locals>.arange_4  s    M ,,...u,Hy//Hy//HS844a8899F(65))C])99&AA * *T)AJri   c                 L   t           j        j                                         t	          j        || z
  |z            }t          t          |d                    }t          j	        ||          }| }t           j        j        
                    |          D ]}| ||z  z   ||<   |S r   )r   r   r   rr   r  r  r  r   r   r   rx   )	r  r  r  r   r  r   r!  r   r   s	            rg   r"  z&arange_parallel_impl.<locals>.arange_4  s    M ,,...y$,$!677HXq))**F(65))CC])99&AA * *T)AJri   r   r         zparallel arange with types {})r   r   anyr   
ValueErrorformat)r   r   r|   r  r	  r  r  r  r  r"  r  s             @rg   arange_parallel_implr)  u  sY   k/00N5 5 5 5 5, , ,9 9 9 9 90 0 0< < < < <3 3 3 
6
6
6
6
666 		 		 		 			 	 	 4yyA~~ =xxn<	Ta!Mxx~=	Ta!Mxx~=	Ta8??EEFFFri   c                     t          | j                  d }fd}t          |          dk    r|S t          |          dk    r|S t          d                    |                    )Nc                 .    t          j        | |d          S )N2   )r   linspace)r  r  s     rg   
linspace_2z*linspace_parallel_impl.<locals>.linspace_2  s    {5$+++ri   c                     t           j        j                                         t	          j        |          }|dz
  }|| z
  }| |d<   t           j        j                            |          D ]}| |||z  z  z   ||<   |S )Nr   r   )r   r   r   rr   r   r   rx   )r  r  numr!  divdeltar   r   s          rg   
linspace_3z*linspace_parallel_impl.<locals>.linspace_3  s    ((***hsE""AguA%55c:: 	/ 	/AUa#g..CFF
ri   r   r$  zparallel linspace with types {})r   r   r   r'  r(  )r   r|   r.  r3  r   s       @rg   linspace_parallel_implr4    s    [&''E, , ,     4yyA~~	Ta:AA$GGHHHri   c                     t           S rq   )r   rr   s     rg   <lambda>r8        %9 ri   c                     t           S rq   )r   r6  s     rg   r8  r8    r9  ri   )argminnumpyargmaxr=  r   r=  r   r=  aminr=  amaxr=  )sumr=  )prodr=  )r   r=  )r   r=  )stdr=  )dotr=  )r  r=  )r-  r=  c                 *    |j         dk    rd }nd }|S )zParallel implementation of ndarray.fill.  The array on
       which to operate is retrieved from get_call_name and
       is passed along with the value to fill.
    r   c                     t           j        j                                         t           j        j                            t          |                     D ]}|| |<   d S rq   r   r   s      rg   fill_1z"fill_parallel_impl.<locals>.fill_1  sQ    M ,,...])99#f++FF    q		4ri   c                     t           j        j                                         t          j        | j                  D ]}|| |<   d S rq   r   r   s      rg   rL  z"fill_parallel_impl.<locals>.fill_1  sD    M ,,...^FL11    q		4ri   r   )r   r!  r   rL  s       rg   fill_parallel_implrN    s9    
 x1}}	 	 	 		 	 	
 Mri   fillc                 0    | dk    rt          d          d S )Nr   zDzero-size array to reduction operation maximum which has no identityr'  arr_sizes    rg   r   r     )    1}} < > > 	> }ri   c                 0    | dk    rt          d          d S )Nr   zDzero-size array to reduction operation minimum which has no identityrQ  rR  s    rg   r   r     rT  ri   c                 0    | dk    rt          d          d S )Nr   z*attempt to get argmin of an empty sequencerQ  rR  s    rg   r   r     !    1}}EFFF }ri   c                 0    | dk    rt          d          d S )Nr   z*attempt to get argmax of an empty sequencerQ  rR  s    rg   r   r     rW  ri   checker_implnamefuncr   r   r   r   )r;  r>  r@  rA  rB  rD  c                   $    e Zd ZdZd Zd Zd ZdS )LoopNestzThe LoopNest class holds information of a single loop including
    the index variable (of a non-negative integer value), and the
    range variable, e.g. range(r) is 0 to r-1 with step size 1.
    c                 >    || _         || _        || _        || _        d S rq   )index_variabler  r  r  )selfr_  r  r  r  s        rg   __init__zLoopNest.__init__  s#    ,
				ri   c                 Z    d                     | j        | j        | j        | j                  S )Nz3LoopNest(index_variable = {}, range = ({}, {}, {})))r(  r_  r  r  r  r`  s    rg   __repr__zLoopNest.__repr__  s'    Et*DJ	49MM	Ori   c                    g }|                     | j                   t          | j        t          j                  r|                     | j                   t          | j        t          j                  r|                     | j                   t          | j        t          j                  r|                     | j                   |S rq   )appendr_  r   r  r	   Varr  r  )r`  all_usess     rg   	list_varszLoopNest.list_vars  s    xt*+++
TZ
(
( '??4:&&&
TY
'
' &??49%%%
TY
'
' &??49%%%ri   N)r~   r   r   __doc__ra  rd  ri  ra   ri   rg   r]  r]    sN         
  O O O	 	 	 	 	ri   r]  c                   b     e Zd ZdZd e            d fd
Zd Zd Zd Zdd	Z	dd
Z
d Z xZS )Parforr   F)no_sequential_loweringracesc	                   t          t          |                               d|           t          |           j        | _        t          |           xj        dz  c_        || _        || _        || _        || _	        d | _
        || _        t          |          dk    sJ |g| _        || _        |	| _        |
| _        g | _        i | _        d | _        t(          j        r-d}t-          |                    | j        ||                     d S d S )Nr   )oplocr   z9Parallel for-loop #{} is produced from pattern '{}' at {})superrl  ra  type
id_counterid
loop_nests
init_block	loop_body	index_varparams	equiv_setr   patternsflagsrm  rn  redvarsreddictlowererr   DEBUG_ARRAY_OPT_STATSrc   r(  )r`  rv  rw  rx  rq  ry  r{  patternr}  rm  rn  fmt	__class__s               rg   ra  zParfor.__init__-  s*    	fd$$ 	% 	
 	
 	

 t**'T

" %$""" 7||a 	
 '=#

 ' 	*OC#**'7C) ) * * * * *	* 	*ri   c                     dt          | j                  z   t          | j                  z   t          | j                  z   t          | j                  z   S )Nzid=)strru  reprrv  rx  ry  rc  s    rg   rd  zParfor.__repr___  sJ    s47||#d4?&;&;;  !#'#7#78 	8ri   c                 $    d | j         D             S )Nc                     g | ]	}|j         
S ra   r_  re   rm   s     rg   rh   z-Parfor.get_loop_nest_vars.<locals>.<listcomp>d  s    :::Q :::ri   )rv  rc  s    rg   get_loop_nest_varszParfor.get_loop_nest_varsc  s    ::$/::::ri   c                    g }| j                                         D ]&\  }}|j        D ]}||                                z  }'| j        D ]}||                                z  }| j        j        D ]}||                                z  }|S )zslist variables used (read/written) in this parfor by
        traversing the body and combining block uses.
        )rx  itemsbodyri  rv  rw  )r`  rh  rn   r   stmtloops         rg   ri  zParfor.list_varsf  s     N((** 	- 	-DAq - -DNN,,,- O 	) 	)D(((HHO( 	) 	)D(((HHri   Nc                     || j         j        }|| j         _        | j                             |          }||| j         _        |S )zvget the shape classes for a given variable.
        If a typemap is specified then use it for type resolution
        )r{  typemapget_shape_classes)r`  r   r  save_typemapress        rg   r  zParfor.get_shape_classesw  sH     >1L%,DN"n..s33%1DN"
ri   c                    |pt           j        }t          d                    | j                                      dd          |           t          d| j        |           t          d| j        |           t          d| j        |           | j	        D ]}t          ||           t          d|           | j
                            |           t          | j                                                  D ]/\  }}t          d	|d
|           |                    |           0t          d                    | j                                      dd          |           d S )Nzbegin parfor {}   -)filezindex_var = z	params = zraces = zinit block:zlabel :zend parfor {})sysstdoutrc   r(  ru  centerry  rz  rn  rv  rw  dumpsortedrx  r  )r`  r  loopnestoffsetblocks        rg   r  zParfor.dump  sj   !sz ''0088SAAMMMMndn48888k4;T2222j$*40000 	' 	'H(&&&&&m$''''T"""#DN$8$8$:$:;; 	 	MFEE)5555JJt%%dg..66r3??dKKKKKKri   c                 Z   | j         d}t          |          | j         D ]}|                    |          }|d}t          |          t          |t          j                  rF|j        t          j        k    r1d}t          j
        |||j        t          j        fz  | j                  dS )z?
        Check that Parfors params are of valid types.
        Nz?Cannot run parameter validation on a Parfor with params not setzDCannot validate parameter %s, there is no type information availablea  Use of a tuple (%s) of length %d in a parallel region exceeds the maximum supported tuple size.  Since Generalized Universal Functions back parallel regions and those do not support tuples, tuples passed to parallel regions are unpacked if their size is below a certain threshold, currently configured to be %d. This threshold can be modified using the Numba environment variable NUMBA_PARFOR_MAX_TUPLE_SIZE.)rz  r'  getr   r   	BaseTuplecountr   PARFOR_MAX_TUPLE_SIZEr   UnsupportedParforsErrorrq  )r`  r  msgptys        rg   validate_paramszParfor.validate_params  s     ;CS//! 	( 	(AQBz/ oo%"eo.. (8f:::OC !8 "(F,HI:J"h( ( (!	( 	(ri   rq   )r~   r   r   rt  setra  rd  r  ri  r  r  r  __classcell__)r  s   @rg   rl  rl  )  s        J $)#%%0* 0* 0* 0* 0* 0* 0*d8 8 8; ; ;  "   $L L L L( ( ( ( ( ( (ri   rl  c                     |j         }t          |           }|j                            dd          } |j        ||           t          | |           |j        d         | _        |r
||j        d<   g g fS )z/Recursive array analysis for parfor nodes.
    r   N)func_irwrap_parfor_blocks
equiv_setsr  rununwrap_parfor_blocksr{  )r   r{  r  rZ   r  parfor_blocksbackup_equivsets          rg   _analyze_parforr    s     $G&v..M %/33At<<ON}i000///%03F 7'6!!$r6Mri   c                       e Zd ZdZd Zd Zed             Zej        d             ZddZ	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZd Zd ZdS )ParforDiagnosticszHolds parfor diagnostic info, this is accumulated throughout the
    PreParforPass and ParforPass, also in the closure inlining!
    c                     d | _         t                      | _        d| _        t	          t
                    | _        t	          t
                    | _        g | _        i | _	        d| _
        d S )N__numba_parfor_gufuncF)r[  dictreplaced_fnsinternal_namer   listfusion_infonested_fusion_infofusion_reports
hoist_info	has_setuprc  s    rg   ra  zParforDiagnostics.__init__  sW    	 FF4&t,,"-d"3"3 ri   c                 
   || _         | j         j        j        | _        | j         j        | _        || _        | j        | j        v rd| _        nd| j        d| j        | _        | 	                                | _
        d| _        d S )NzInternal parallel functionz	Function , T)r  func_idfunc_qualnamerZ  rq  linefusion_enabledr  purposeget_parforsinitial_parforsr  )r`  r  r  s      rg   setupzParforDiagnostics.setup  s    L(6	L$	,**7DLL + 15			499EDL  $//11ri   c                     | j         S rq   
_has_setuprc  s    rg   r  zParforDiagnostics.has_setup  s
    ri   c                     || _         d S rq   r  )r`  states     rg   r  zParforDiagnostics.has_setup  s    ri   Nc                 D    t          |                                           S rq   )r   r  r`  blockss     rg   count_parforszParforDiagnostics.count_parfors  s    4##%%&&&ri   c                 n    t          |          }|                     ||           t          |           d S rq   )r  _get_parforsr  )r`  r   parfors_listr  s       rg   _get_nested_parforsz%ParforDiagnostics._get_nested_parfors  s9    #F++&,///V$$$$$ri   c                     |                                 D ]O\  }}|j        D ]B}t          |t                    r+|                    |           |                     ||           CPd S rq   )r  r  r   rl  rf  r  )r`  r  r  labelblkr  s         rg   r  zParforDiagnostics._get_parfors  s     ,,.. 	A 	AJE3 A AdF++ A ''---,,T<@@@A	A 	Ari   c                 J    g }|                      | j        j        |           |S rq   )r  r  r  )r`  r  s     rg   r  zParforDiagnostics.get_parfors  s(    $,-|<<<ri   c                 V   g }| j                                         D ]\  }}|                    dg           }|D ]n}t          |j        t
          j                  rM|j        j        dk    r=t          t          | j
        |j                  }||dk    r|                    |           o|S )Nhoistedcall)r   r=  )r  r  r  r   valuer	   Exprrp  r;   r9   r  rf  )r`  allocspf_iddatar  instr  s          rg   hoisted_allocationsz%ParforDiagnostics.hoisted_allocations  s    ?0022 	0 	0KE488Ir**D 0 0dj"'22 0z}..$]DL$*MM+8J0J0J"MM$///0 ri   c                 
   t          j        |          }|i k    rg t                      fS t                      }|                                D ]}|D ]}|                    |           t          |                                          }||z
  }|t                      }t                      }t          t          t          |                                                              |                    dz             D ]@}|	                    |          }	|	|	||<   |	g k    r|                    |           ;g ||<   Ag }
t          |                                          D ]}|
                    ||                    |
|fS )zf
        compute adjacency list of the fused loops
        and find the roots in of the lists
        Nr   )copydeepcopyr  valuesaddkeysrz   r   unionr  r  rf  )r`  _ar   vtxvrm   potential_rootsroots	not_rootsr   rn   s              rg   compute_graph_infoz$ParforDiagnostics.compute_graph_info  ss   
 M"77suu9ee 	 	A  



 affhh--#%=EEE EE	s3qvvxx==..s3344q899 	 	A%%((C!a    !
 !! 	 	AHHQqTNNNN%xri   c                 :    fd |||dd          \  }}||fS )z
        Computes the number of fused and serialized loops
        based on a fusion adjacency list `fadj` and a nested
        parfors adjacency list `nadj` for the root, `root`
        c                     ||         D ]E}|dz  }||         g k    r|t          | |                   z  }, | ||||          \  }}||z  }|}F||fS r  r   )	fadjnadjrootnfusednserialknfns
count_roots	           rg   r  z/ParforDiagnostics.get_stats.<locals>.count_root=  sw    $Z ! !17b==c$q'll*FF'ZdAvwGGFBbLF GG7?"ri   r   ra   )r`  r  r  r  r  r   r  s         @rg   	get_statszParforDiagnostics.get_stats7  sC    		# 		# 		# 		# 		# %*T4q!<<wri   c                     g }|                     ||                    ||         D ]7}||         g k    r)|                     |                     ||                     8|S )zf
        returns a list of nodes reachable in an adjacency list from a
        specified root
        )extendreachable_nodes)r`  adjr  fusersr  s        rg   r  z!ParforDiagnostics.reachable_nodesJ  sg    
 c$i   T 	< 	<A1v||d223::;;;ri   c                 t   ||         d         }|j         d         }t          d|j        j        dz
            }| j        j        j        }|                     | j                  \  }}|                     | j                  \  }	}
||	g}t          |t                    r|d         dk    r|d         d         }|j        |k    rt          d|j        dz
            S g }|D ]\}|rX||         D ]+}|                    |                     ||                     ,|r"t          dt          |          dz
            c S ]|j                                        D ]=}|j        D ]3}|j        j        |k    r!t          d|j        j        dz
            c c S 4>| j        j                                        D ]}	 |j                            |          }t'          |dz
  dd          D ]C}|j        |         }t          |t(                    st          d|j        j        dz
            } nDv# t*          $ r Y w xY w|S )zX
        pd_id - the parfors id
        parfors_simple - the simple parfors map
        r   r   internalr   )r|  r   rq  r  r  filenamer  r  r  r   tuplerf  sort_pf_by_liner   rx  r  r  r  r   rz   rl  r'  )r`  r  parfors_simplepfr  r  r  r  nrootsr  frootsgraphsreported_loctmpr	  r  r  r  idxr   s                       rg   r  z!ParforDiagnostics.sort_pf_by_lineV  s    E"1%+a.1bfkAo&&<#,..t/FGGf..t/?@@f gu%% !	!qzZ''&qz!}(H44q,"3a"7888 C% < < <%(Z T T #

4+?+?>+R+R S S S S" <'*1c#hhl';'; ; ; ;  "|2244 A A$'H A AD#x0H<<'*1dhma.?'@'@ @ @ @ @ @  =A  $|299;; 	! 	!!"%(.."4"4C%*37Ar%:%: * *'*x{'1$'?'? !*+.q$(-!2C+D+DD$)E!*  * ! ! ! D!s   5A2H((
H54H5c           	      *   t                      }t          | j        d           D ]}|j        d         }|j        d         }|j        }t          |t                    r|d         dk    r}|d         dk    rQd                    t          t          |d         d                                       }|d         d         }|d	d
}n |d         dk    rd}n|d         dk    rd}nJ d}|rt          ||j        ||fz             |||f||j        <   |S )Nc                     | j         j        S rq   )rq  r  rm   s    rg   r8  z6ParforDiagnostics.get_parfors_simple.<locals>.<lambda>  s
    QUZ ri   keyr   r   r   r  .r    z(internal parallel version)userzuser defined pranger   zinternal pndindexz5Parallel for-loop #%s: is produced from %s:
    %s
 
)r  r  r  r|  rq  r   r  joinreversedr  ro   ru  )	r`  print_loop_searchr  r  	r_patternr  rq  replfnr  s	            rg   get_parfors_simplez$ParforDiagnostics.get_parfors_simple  s?    -3G3GHHH 	9 	9B AIk!nG&C'5)) !1:))qzZ//!$(4
13F3F*G*G!H!H%ajm/5vv7T7T$U		 v--$9		 z11$7		 LC  =cRUC$;;<<<%'i$8N25!!ri   c                    |                      | j                  \  }}|                      | j                  \  }}t          |          t          |          k    rt          |          }|}nt          |          }|}t	          t          |          |          D ]}|                    g            t                      }	|r&|D ]#}
||
         g k    r|	                    |
           $||	z  }i }|D ] }|                     ||          }d||f||<   !i }|	D ] }|                     ||          }d||f||<   !|	                                }|
                    |           |S )Nfusenest)r  r  r  r   rz   rf  r  r  r  r  update)r`  r  r  r  r  _nrootslimr  rm   r  r7  	all_rootsfroots_linesr  nroots_lines	all_liness                   rg   get_all_lineszParforDiagnostics.get_all_lines  s    ..t/?@@f//0GHHgt99s4yy  d))CCCd))CCs3xx%% 	 	AJJrNNNN  	" " "7b==JJqMMMVO	  	1 	1A''>::D!'DL 	1 	1A''>::D!'DL %%''	&&&ri   c                    | j         j        j        }|                                 }| j         j        j        }	 t          j        |                                          }n# t          $ r d }Y nw xY w|rL|rIt          d |D                       }t          t                    }|                                D ]Z\  }	}
||	         d         j        |k    r>|                     |	|          }||                             t!          |	                     [t          dgd |                                D             z             }|d|t%          t!          |                    dz   z  z   z   }g }|                    d           |                    d|z             |                    |dz  dz              d	}t          d
| j         j        j        dz
            }t)          ||          D ]\  }}|                    |d           }|dd                    |          z   }nd}|                    d          }t%          |          }|r|                    |dz  ||          }n|                    |dz  ||          }|                    |||d          z              t3          d                    |                     d S t3          d           d S )Nc                 ,    g | ]}t          |          S ra   r  r  s     rg   rh   z4ParforDiagnostics.source_listing.<locals>.<listcomp>  s    333SVV333ri   r   c                 ,    g | ]}t          |          S ra   r  r  s     rg   rh   z4ParforDiagnostics.source_listing.<locals>.<listcomp>  s    (Q(Q(QAQ(Q(Q(Qri   r   
zParallel loop listing for %sr  z	|loop #IDz{0:{1}}| {2}r   #r   r  zNo source available)r  rq  r  r  r  r[  inspect	getsourcerj   OSErrorr   r   r  r  r  rf  r  r  r   r  	enumerater  r!  stripr(  rc   )r`  r  purpose_strr  r  	func_namelines	src_widthmap_line_to_pfr  r  
match_linemax_pf_per_liner]   newlinesr  lstartnor  pf_idspfstrstrippedsrclenrn   s                           rg   source_listingz ParforDiagnostics.source_listing  s   <#,""$$L(-		%i00;;==EE 	 	 	EEE	 "	)^ "	)33U33344I(..N&,,.. > >1 "!$Q'0H<<!%!5!5a!H!HJ":.55c!ff===!1#(Q(Q9N9N9P9P(Q(Q(Q"QRRO_CJJ!8K%L!LMEHOOD!!!OO:[HIIIOOECK+5666 CDL,1A566F%eV44 7 7D'++B55%$))F"3"33EEE::d++X >

53;u==AA

53;u==A1VWW: 56666$))H%%&&&&&'(((((s   &A A.-A.c                 r    dt                                          j                  \  }}                      j                  \  }}t          |          t          |          k    rt          |          }|}nt          |          }|}t	          t          |          |          D ]}|                    g             fd}	 fd}
d}g }t          |                                          D ]<\  }}|\  }}}|dk    r||vr |
d||d|          }%|dk    r |	|||||          };J d S )N+--c                     fd||         g k    r4t          d|z              | ||d           t          d           |dz   }|S )Nc           	          t          |z  dz  |ddz              ||         D ]}||         g k    rg }|                    |dz   z  dz  |ddz              | |         g k    rG|
vrC                    | |          }|D ]*}|                    |dz   z  dz  |ddz              +
                    |           t          d                    |                      	| |||dz              d S )Nr  
(parallel)r   r5  )ro   rf  r  r!  )fadj_nadj_nrootdepthr  r  fusedr   facprint_greportedr`  swords           rg   rW  zHParforDiagnostics.print_unoptimised.<locals>.print_nest.<locals>.print_g  s[   cEkC/uueee\\2ZZ[[[u < <AQx2~~ 

3%!)#4s#:%%QRQRQRT`T`=a#abbb 8r>>ax.?.?$($8$8$B$BE%* k k #

3%!)+<s+BRWRWYZYZYZ\h\hEi+i j j j j ***%diinn5555ua;;;;< <ri   Parallel region %s:r   r5  r   ro   rc   )	rQ  rR  therootrX  	region_idrW  rV  r`  rY  s	      ` @rg   
print_nestz7ParforDiagnostics.print_unoptimised.<locals>.print_nest  s    < < < < < < < < < W~##3i?@@@ugq111d%M	ri   c                    g }t          d|z             |                    |z  dz  
|ddz              ||         g k    rMt          	                    ||                    }|D ]'}|                    |z  dz  
|ddz              (|dz   }t          d                    |                     t          d           |S )NrZ  r  rP  r   r5  )ro   rf  r  r  r!  rc   )r  r  r	  rT  r]  r  rU  r  rV  r`  rY  s           rg   
print_fusez7ParforDiagnostics.print_unoptimised.<locals>.print_fuse,  s    C/);<<<JJsU{S(uuull+SSTTT5zRt33C??@@ Y YAJJsU{S0qqq,,3WWXXXX!AI$))C..)))$KKKri   r   r(  fr)  )r   r  r  r  rz   rf  r  r  )r`  r?  r  r  r  r+  r,  r  rm   r^  r`  r]  rX  r  infoopt_tyr  r	  rV  rY  s   `                 @@rg   print_unoptimisedz#ParforDiagnostics.print_unoptimised  s   %jj..t/?@@f//0GHHgt99s4yy  d))CCCd))CCs3xx%% 	 	AJJrNNNN	 	 	 	 	 	 	.	 	 	 	 	 	 	 	 // 	 	JD$!%FE3(( *
3sAy I II6!!&JtT5(INN			 	ri   c           	          dt                                          j                  \  }}                      j                  \  }}t          |          t          |          k    rt          |          }|}nt          |          }|}t	          t          |          |          D ]}|                    g            t                       fd}	 fd}
d}g }t          |                                          D ]<\  }}|\  }}}|dk    r||vr |
d||d|          }%|dk    r |	|||||          };J rt                                                    D ]\\  }}d}|d	         }|d
         }|d         }|dk    r|dz  }t          ||||||fz             B|dz  }t          ||||fz             ]d S t          d           d S )NrM  c                     	fd||         g k    rSt          dz             t          	|dd           |ddd<    | ||d           t          d           dz   S )	Nc                 "   ||         D ]}|z  dz  |ddz   }||         g k    rg }| |         g k    rN|
vrJt                              | |                    }|dz  }|d                    d |D                       z  }|dz  }
                    |           t	          |           	         dxx         t          |          z  cc<   n#t	          |dz               | |||dz              	         d	xx         dz  cc<   d S )
Nr  z(serial, fused with loop(s): r  c                 ,    g | ]}t          |          S ra   r  r  s     rg   rh   zZParforDiagnostics.print_optimised.<locals>.print_nest.<locals>.print_g.<locals>.<listcomp>c  s    -D-D-Dc!ff-D-D-Dri   )rU  r   
serialized)r  r  r!  rf  ro   r   )rQ  rR  rS  rT  r  r  rU  rV  rW  r]  rX  r`  summaryrY  s          rg   rW  zFParforDiagnostics.print_optimised.<locals>.print_nest.<locals>.print_g[  s[   u : :A++55!!!YY.OOCQx2~~ " 8r>>ax.?.?$*4+?+?q+I+I$J$JE#;;C499-D-De-D-D-D#E#EECs
 ***%c***	*7333s5zzA3333%cCi000ua;;;I&|44494444: :ri   rZ  r  rP  r   r  rU  rl  r   r5  r[  )
rQ  rR  r\  rX  r]  rW  rV  r`  rm  rY  s
      ``@rg   r^  z5ParforDiagnostics.print_optimised.<locals>.print_nestZ  s    : : : : : : : : : : :$ W~##3i?@@@55'''<<HIII.5QR%S%S	"ugq111d%M	ri   c                 |   t          d|z             |z  dz  
|ddz   }g }||         g k    rJt                              ||                    }|dz  }|d                    d |D                       z  }|t	          |          dd	|<   |d	z  }t          |           t          d
           |dz   }|S )NrZ  r  z	(parallelrh  r  c                 ,    g | ]}t          |          S ra   rj  r  s     rg   rh   zIParforDiagnostics.print_optimised.<locals>.print_fuse.<locals>.<listcomp>}  s    !8!8!8Q#a&&!8!8!8ri   r   rn  rk  r5  r   )ro   r  r  r!  r   rc   )r  r  r	  rT  r]  r  rU  rV  r`  rm  rY  s          rg   r`  z5ParforDiagnostics.print_optimised.<locals>.print_fusev  s    /);<<<+#55%%%&MMCE5zRt33C??@@//tyy!8!8%!8!8!8999*/#e**TU!V!VGI3JC#$KKK!AIri   r   r(  ra  r)  z5
 
Parallel region %s (loop #%s) had %s loop(s) fusedr  rU  rl  zE and %s loop(s) serialized as part of the larger parallel loop (#%s).r  z&Parallel structure is already optimal.)
r   r  r  r  rz   rf  r  r  r  ro   )r`  r?  r  r  r  r+  r,  r  rm   r^  r`  r]  rX  r  rb  rc  r  r	  r  r  r  r  rU  rl  rV  rm  rY  s   `                       @@@rg   print_optimisedz!ParforDiagnostics.print_optimisedF  sr    %jj..t/?@@f//0GHHgt99s4yy  d))CCCd))CCs3xx%% 	 	AJJrNNNN&&	 	 	 	 	 	 	 	8	 	 	 	 	 	 	 	" 	 // 	 	JD$!%FE3(( *
3sAy I II6!!&JtT5(INN		  	Dw}}// : :1$y'
|_
?? + ,C "#D%T(J"JKKKK3JC!#D%(8"89999: : BCCCCCri   c                 ,   d}t          d           | j                                        D ]T\  }}|                    dg           }|D ]4}t	          |j        t          j                  r	 |j        j        }|dk    rd}|j	        }t          |||fz             	 t          j                            |j                  }	n4# t          $ r' t          j                            |j                  }	Y nw xY wt#          j        |	          }
|
rF|j        r?t          d|
|j        dk     rdn	|j        d	z
                                           z              t          d
           d}# t*          t,          f$ r Y 0w xY w6V|st          d           d S d S )NFzAllocation hoisting:r  r   zThe memory allocation derived from the instruction at %s is hoisted out of the parallel loop labelled #%s (it will be performed before the loop is executed and reused inside the loop):z   Allocation:: r   r   r   z0    - numpy.empty() is used for the allocation.
TzNo allocation hoisting found)rc   r  r  r  r   r  r	   r  attrrq  ro   ospathrelpathr  r'  abspath	linecachegetlinesr  r<  KeyErrorAttributeError)r`  foundr  r  r  r  rs  r  rq  ru  r?  s              rg   allocation_hoistz"ParforDiagnostics.allocation_hoist  s   $%%%?0022 	 	KE488Ir**D  dj"'22 #z7??$;C
 #'(C)#e*<===E')ws|'D'D#- E E E')ws|'D'DE$-$6t$<$<E$ w w -.@5chYZll`c`hkl`lCmCsCsCuCu.u v v v)*]^^^$(E$n5   ).  	:899999	: 	:s7   -/E%$CE%.C30E%2C33A0E%%E:9E:c                    t          d           t          d           d}| j        r| j                                        D ]\  }}|                    dd           }|                    dd           }|s|st          d|z             Ht          d|z             |rt          d           d	 |D              d
}|rt          d           d |D              d
}|st	          d           t	          d           d S )Nr7  zInstruction hoisting:Fr  not_hoistedzloop #%s has nothing to hoist.z	loop #%s:z  Has the following hoisted:c                 2    g | ]}t          d |z            S )    %srb   rd   s     rg   rh   z7ParforDiagnostics.instruction_hoist.<locals>.<listcomp>  s$    :::QU8a<((:::ri   Tz   Failed to hoist the following:c                 >    g | ]\  }}t          d |d|          S )z    z: rb   re   rm   rf   s      rg   rh   z7ParforDiagnostics.instruction_hoist.<locals>.<listcomp>  s1    JJJdaUU111aa011JJJri   zNo instruction hoisting foundzP--------------------------------------------------------------------------------)rc   r  r  r  ro   )r`  hoist_info_printedr  r  r  r  s         rg   instruction_hoistz#ParforDiagnostics.instruction_hoist  s:   b			%&&&"? 	.#4466 . .t((9d33"hh}d;; { :UBCCCkE)*** .8999::'::::)-& .<===JJkJJJJ)-&! 	;9:::hri   r   c           
            j         st          d           j        j        j        } j        j        } j        |v rd}d}nd|d|d}d}d}d}d}d}	d}
d}d}d}d}d}|d	v rd
}d
}nt          d          |dv rd
}|dv rd
}|dk    rd
}	d
}
|dk    rd
}d
}d
}|dk    r|sd S t          d           t          t          dz             t          d|z  
                    t          d                     t          t          dz             t          d           |r(t          d
                    t          d                                          |          }                                 }|r)t          d|z             t          dt          z              j        j        j        }	 t          j                            |          }n/# t          $ r" t          j                            |          }Y nw xY w|r                     ||           d                                  }d |D             }t)          |          }|s|	rit*          s:t          d
                    t          d                     d}t          |           n(d}t          |           t          t          dz             |dk    r  fd}|r8 j        D ]0}|\  }}}t          d|d|d            t          d!|z             1 j        i k    r#|	r!t          d"            | j        d#d$           |	rs j        rd%}nd&}t          d'                    ||d                    d( |D                                            t          t          dz             t          d           |
r~ j        i k    rst          d)
                    t          d                     t          d*           d+}d,} | j        ||           t          t          dz             t          d                                |          }|rTt;          d-
                    t          d                                          |           t;          t          dz             |rTt;          d.
                    t          d                                          |           t;          t          dz             t          d           t          t          dz             t          d           |s|r#t          d/
                    d0d                     |r                                   |r !                                 d S d S t          d1                    ||                     d S )2Nzself.setup has not been calledzInternal parallel functions r  z
 Function r  r  r   F)r   r   r$  r%  Tz1Report level unknown, should be one of 1, 2, 3, 4)r   r$  r%  )r$  r%  r$  r%  z
 =z% Parallel Accelerator Optimizing: %s r7  zLooking for parallel loopsr  z
Found %s parallel loops.rM  c                     g | ]	}|j         
S ra   )ru  r  s     rg   rh   z*ParforDiagnostics.dump.<locals>.<listcomp>0  s    ,,,qad,,,ri   z Fusing loops zPAttempting fusion of parallel loops (combines loops with similar properties)...
z+Performing sequential lowering of loops...
r  c                     t                    fd}                    |           \  } ||           d S )Nc                     fd|D ]4}t          |d            |d           t          d           5d S )Nc                     | |         D ]=}t          |z  dz  |dz              | |         g k    r | ||dz              >d S )Nr  r   ro   )r	  r  rT  r  rV  node_msgrW  rY  s       rg   rW  zYParforDiagnostics.dump.<locals>.dump_graph_indented.<locals>.print_graph.<locals>.print_gC  sv    !$T ; ;A)#+*;55RSRSRSU]U]>^*^___"1v|| 'Q	 : : :; ;ri   r  r   r7  r  )	r	  r  r7  rW  rV  rn   r  root_msgrY  s	      @rg   print_graphzHParforDiagnostics.dump.<locals>.dump_graph_indented.<locals>.print_graphB  s    ; ; ; ; ; ; ; ;
 # * *%55!!!XX&FGGG1a(((%b))))* *ri   )r   r  )	r   r  r  r  r  rV  rn   r`  rY  s	    ``  @@rg   dump_graph_indentedz3ParforDiagnostics.dump.<locals>.dump_graph_indented@  sp    %jj	* 	* 	* 	* 	* 	* 	* 	* 	*  221555Au%%%%%ri   z  Trying to fuse loops #z and #r  r  z
 
Fused loop summary:
z&has the following loops fused into it:z(fused)z4Following the attempted fusion of parallel for-loopsWith fusion disabledzL
{} there are {} parallel for-loop(s) (originating from loops labelled: {}).c                     g | ]}d |z  S )z#%sra   r  s     rg   rh   z*ParforDiagnostics.dump.<locals>.<listcomp>b  s    ;Z;Z;Z!EAI;Z;Z;Zri   z Optimising loop nests zNAttempting loop nest rewrites (optimising for the largest parallel loops)...
 zis a parallel loopz--> rewritten as a serial loopz Before Optimisation z After Optimisation zLoop invariant code motionr\   z+Function %s, %s, has no parallel for-loops.)"r  RuntimeErrorr  r  r  rq  r  r'  ro   
_termwidthr  r&  r  r  rt  ru  rv  rw  rK  r  r   sequential_parfor_loweringr  r  r  r(  r!  r  r1  rc   rd  rq  r}  r  )!r`  levelrZ  r  r=  r  r#  print_source_listingprint_fusion_searchprint_fusion_summaryprint_loopnest_rewriteprint_pre_optimisedprint_post_optimisedprint_allocation_hoistprint_instruction_hoistprint_internalr  r  r  ru  r   
parfor_ids	n_parforsr  r  reportl1l2after_fusionr  r  r0  rY  s!   `                               @rg   r  zParforDiagnostics.dump  s   ~ 	A?@@@|#1|%%8K GG & 26ttt<KG!$#$!&#$!&"' L  #' #'  PQQQI"&F??%)"A::#' %)"A::"&&*#!Nj   Fej3&'''>LTTU_adeefffj3&'''b  	P6==j#NNOOO001BCC""$$ 	,6>???#
*+++ <#,	- 7??8,,DD 	- 	- 	- 7??8,,DDD		-   	=<<< ""$$,,G,,,

OO	  		0"6 		0- 0.55j#FFGGG8c""""Dc"""j3.///r>>& & & & & & # 2"1 2 2F"(KBC!M222rrr"RSSS!(S.11112%%' o!">???''(8:bdmnnn# 	"& :#YLL#9Lnvv$i;Z;Zz;Z;Z;Z1[1[] ] ^ ^ ^j3.///b!!! & &*b00!#<"D"DZQT"U"UVVV!"sttt3H?H''(?8TTT!*s"2333!"%%% **>::I" (-44ZDDEEE&&y111j3&'''# (,33JsCCDDD$$Y///j3&'''"*s*+++%    & L)@ L:AA"cJJKKK% (%%'''& )&&((((() ) GNNtUYZZ[[[[[s   .G )G:9G:c                 8    d}|t          | j                  z  }|S )NzParforDiagnostics:
)r  r  r`  r7  s     rg   __str__zParforDiagnostics.__str__  s!    #	T$#$$$ri   c                 
    d}|S )Nr  ra   r  s     rg   rd  zParforDiagnostics.__repr__  s     ri   rq   )r   )r~   r   r   rj  ra  r  propertyr  setterr  r  r  r  r  r  r  r  r  r&  r1  rK  rd  rq  r}  r  r  r  rd  ra   ri   rg   r  r    s               X      ' ' ' '% % %
A A A  

 
 
& & &P  &
 
 
8 8 8t  :* * *X*) *) *)X? ? ?B^D ^D ^D@: : :>     2n\ n\ n\ n\`  
    ri   r  c                   *    e Zd ZdZi dfdZd Zd ZdS )PreParforPasszwPreprocessing for the Parfor pass. It mostly inlines parallel
    implementations of numpy functions if available.
    Nc	                     || _         || _        || _        || _        || _        || _        || _        |t          }|| _        ddd| _	        d S )Nr   )replaced_funcreplaced_dtype)
r  r  	calltypes	typingctx	targetctxoptionsswappedswap_functions_mapreplace_functions_mapstats)	r`  r  r  r  r  r  r  r  r  s	            rg   ra  zPreParforPass.__init__  s_    """ ($6!%:"
 



ri   c                     t          | j        | j        | j        | j                   | j        j        r|                     | j        j                   t          | j        j                  | j        _        dS )z(Run pre-parfor processing pass.
        N)
r7   r  r  r  r  r  r=  _replace_parallel_functionsr  r5   rc  s    rg   r  zPreParforPass.run  sn     	 dl $	@ 	@ 	@< 	B,,T\-@AAA*4<+>??ri   c           	      	     j         ddlm t          |                                          r                                \  }t          j                  D ]\\  }t          |t          j
                  r;|j        } j        |j                 |j        t          t          j                  r?j        dk    r4 fd}t#          |          r j        dxx         dz  cc<    nŌt          t          j                  rj        dk    rj        dk    r j        j        j                 }t          |t(          j        j                  rX|j        }j        }|j        }	t          j        |t7          d	          |	          }
t(          j                            t<                     j        |
j        <   t          j        d
t<          |	          }t          j
        ||
|	          }tA          |          }|dk    rd}t          j        |t7          d          |	          }t)          j!        |           j        |j        <   t          j
        t          j"        ||	          ||	          }t          j        |t7          d          |	          }tG          t<          j                  }tH          j%        j        &                    |          }|'                     j(         j        |j                 fi            t(          j)        &                    |           j        |j        <   t          j        *                    |
d|	          }t          j
        |||	          }t          j        |t7          d          |	          }t(          j        +                    |           j        |j        <   t          j        ,                    ||gd|	          }t          j
        |||	          }t[           j        |j                  j        |j                            j.        |<   ||_        j        /                    d|           j        /                    d|           j        /                    d|           j        /                    d|            j        dxx         dz  cc<    n^dS dS )z
        Replace functions with their parallel implementation in
        replace_functions_map if available.
        The implementation code is inlined to enable more optimization.
        r   )inline_closure_callr  c                     t          j        j                  } t          j                  }j                            |d           }|t          |          dk    rt          |d         t          j	                  ryt          j
        |d         j                 t          j        j                  rDt                              |d         d           }|!j                            d|d                    t%          |d u           t'          fdj        D                       }fdj        D             }	  |g|R i |}n	#  d }Y nxY wt%          |d u            t+          j        |          j        |i |j        }t1          j        j        j        j        j                  }t6          |d<   t8          |d<   t:          |d<   t<                              |d           }||j        ||j        <    j        ||j        j         |j
        j!                  \  }}	tE          |d	
          }
|
D ]H}|#                                D ]1\  }}|d         dk    r ||j$        | j%                 j&        g|<    n2IdS )Nr   r   r   c              3   <   K   | ]}j         |j                 V  d S rq   r  rZ  )re   rm   r`  s     rg   r  zRPreParforPass._replace_parallel_functions.<locals>.replace_func.<locals>.<genexpr>  s,      (Q(Q!af)=(Q(Q(Q(Q(Q(Qri   c                 <    i | ]\  }}|j         |j                 S ra   r  )re   r  rm   r`  s      rg   
<dictcomp>zSPreParforPass._replace_parallel_functions.<locals>.replace_func.<locals>.<dictcomp>  s(    'U'U'UDAq4<+?'U'U'Uri   r   r   r  F)topological_orderingrx   T)'r?   r  r[  r9   r  r  r   r   r	   rg  r  rZ  r   r   r   replace_functions_ndarrayr|   insertr<   r  kwsr   pysignaturebindr  r  __globals__r   r=  r  replace_functions_checkers_mapr  r  r  r3   r  r~   r  rq  )func_defcallname	repl_functypskws_typsnew_funcgcheck
new_blocks_
call_tabler  r  r  r  exprr   r  lhs_typr`  r  	work_lists                 rg   replace_funcz?PreParforPass._replace_parallel_functions.<locals>.replace_func  s   '5dlDI'N'NH'4T\4'H'HH(,(B(F(FxQU(V(VI ) 1 #H 2 2 *8A; ? ? !3 *4<8H+I+0>+?!A !A !3 -F,I,I(ST+W[,\,\	#,#8$(I$4$4Q$D$D$D#IT$9:::#((Q(Q(Q(Qty(Q(Q(Q#Q#QD'U'U'U'UDH'U'U'UH0,5Ig,Q,Q,Q,Q,Q,Q0+/#HD$8999#C5#4X#>#>#CT#VX#V#V#[D $	$,*>*C*O P PA).AgJ&+AdG(,AfI %C$F$FxGK%M %ME$005
%*,?,?a,11hPTP^,0$,PY-[ -[MJ *8
Y^)_)_)_J )3 . .,0JJLL !. !.DAq'(t/@'@'@6>	@RT\^c^hij^k^o5p
(- (A $(4s   ?E Er  r   getattrr   	$np_g_varr   boolbool_z$np_typ_varz$dtype_attr_varz
$dtype_varra   r  N)0r  numba.core.inline_closurecallr  r  r  popr;  r  r   r	   Assigntargetr  rZ  r  r  rp  r;   r  rs  r   r   r   r   scoperq  rg  r    miscModuler=  Globalr  StringLiteralConstfind_templater   corerR   get_call_typer  	functionsr  DTyper  rQ   r  r  )r`  r  r  instrlhsr  typr   r  rq  g_np_varg_npg_np_assign	dtype_strtyp_vartyp_var_assigndtype_attr_vartemptfuncdtype_attr_getattrdtype_attr_assign	dtype_vardtype_getattrdtype_assignr  r  r   r  r  r  r  s   `                       @@@@@@@rg   r  z)PreParforPass._replace_parallel_functions  s    ,EEEEEE((	 x	"$==??LE5%ej11 v" v"5eRY// u",C"l384G ;D!$00 q"TW5F5F0( 0( 0( 0( 0( 0( 0( 0( 0( 0( 0( 0(b !.. " J7771<777!E" %T2733 ;"98L8L)w.. #l4:?;%c5>+?@@ 6" %(IE$)KE"')C')ve];5O5OQT'U'UH:?*:K:KE:R:RDL7#%9T5##>#>D*,)D(C*H*HK ),E

I(F22,3	&(f %}]'C'CS'J 'JG9>9L ):+ :+DL6-/Y "C 8 8'3.H .HN .0VE=IZ;[;[]`-a-aN#0#=#=D$)J$4$=$=d$C$CE!//glA[@]_abbb@E@X@XY]@^@^DL)<=137TW1X1X.02	:Ln^a0b0b- )+umL6Q6QSV(W(WI;@>;O;OPU;V;VDL8,.GLL'TVX[,\,\M+-9]Is+S+SL<E $Y^ <dl7<>X=Z =ZDN=9 +4EK!J--a>>>!J--a1BCCC!J--a@@@!J--a=== J'7888A=888!Eq  x	" x	" x	" x	" x	"ri   )r~   r   r   rj  ra  r  r  ra   ri   rg   r  r    s_          #%D
 
 
 
$@ @ @A" A" A" A" A"ri   r  c                 j    t           j        j        j        j        j        D ]}|j        | k    r|c S d S rq   )r   r  r   	templatesbuiltin_registryr  r  )rp  fts     rg   r  r  ;  sB    j):D  6R<<III  ri   c                   ,    e Zd ZdZ e            fdZdS )ParforPassStateszCThis class encapsulates all internal states of the ParforPass.
    c                    || _         || _        || _        || _        || _        || _        || _        |
| _        |
j        | _	        |
j
        | _
        |
j        | _        t          j        | j        | j         | j        | j                  | _        t          j                            t#          |j                                                             || _        |	| _        d|	vri |	d<   d S d S )Nr   )r  r  r  r  r  r   r  diagnosticsr  swapped_fnsr  r  rZ   ArrayAnalysisr   _the_max_labelr*  r   r  r  r}  metadata)r`  r  r  r  r   r  r  r  r}  r  r  s              rg   ra  zParforPassStates.__init__E  s     """&&&3&2"-"@,:NDL$,
 
 	&&s7>+>+>+@+@'A'ABBB
 H$$"$HY %$ri   N)r~   r   r   rj  r  ra  ra   ri   rg   r  r  A  s@         
 /.00% % % % % %ri   r  c                   *    e Zd ZdZd Zd Zd Zd ZdS )ConvertInplaceBinop0Parfor subpass to convert setitem on Arrays
    c                 "    || _         g | _        dS zV
        Parameters
        ----------
        pass_states : ParforPassStates
        Npass_states	rewrittenr`  r  s     rg   ra  zConvertInplaceBinop.__init__b       'ri   c           	      z   | j         }t          |          }|D ]}||         }g }|j                            |          }|j        D ]i}t          |t          j                  r
|j        }	|j	        }
t          |
t          j
                  r|
j        dk    r|
j        }|
j        }|
j        }|j        |j                 }|j        |j                 }t          |t"          j        j                  rt          |t"          j        j                  r`|                     |||
j        ||          }| j                            t1          ||d                     |t          j        ||	|          g}t          |t2                    r|                    |           T|                    |           k||_        d S )Ninplace_binopoldnewreason)r  r0   rZ   get_equiv_setr  r   r	   r  r  r  r  rp  rq  r  rhsr  rZ  r   r   r   _inplace_binop_to_parforimmutable_fnr  rf  r  r  r  )r`  r  r  
topo_orderr  r  new_bodyr{  r  r  r  rq  r  r  
target_typ	value_typ	new_instrs                    rg   r  zConvertInplaceBinop.runk  s   &$V,,
   	" 	"E5MEH#2@@GGI + +eRY// Q,C ;D!$00 QTW5O5O"h!% $%0%8%E
$/$7
$C	%j%.2FGG 	Q))U^5IJJ Q,0,I,I)(+T->-O -O	 $ 5 5$(U	0?%A %A %A!" !" !" *3BIfc34O4O(PeT** +OOE****OOE****!EJJ;	" 	"ri   c           
         | j         }|j        }|j        |j                 }|j        }	t          j        ||          }
|j        |j                 }|                    |          }t          |j        |||          \  }}t                      }t          j        ||          }t          |j        |||          \  }}t          j        |t          d          |          }|j        |j        |j        <   t
          j                            |||          }t          |j        ||          |j        |<   |j                            t          j        |||                     t          j        |t          d          |          }|	|j        |j        <   t
          j                            |||          }t          |	||          |j        |<   |j                            t          j        |||                     t          j        |t          d          |          }|	|j        |j        <   t
          j                            ||||          }|j                            t          j        |||                     | j         j                            |	|j                  }t          |||          |j        |<   t          j        ||||          }t          t0          j        |||	          |j        |<   |j                            |           t5          ||
i |||d|j                  }||i|_        t:          j        dk    r#t?          d           |                                  |S )generate parfor from setitem node with a boolean or slice array indices.
        The value can be either a scalar or an array variable, and if a boolean index
        is used for the latter case, the same index must be used for the value too.
        
$value_varz$target_var$expr_out_var)r  r7  r   zparfor from inplace_binop)!r  r  r  rZ  r   r	   Block	get_shape_mk_parfor_loopsr!   _make_index_varrg  r    r  getitemrQ   r  r  rf  r  binopr  unify_pairsSetItemr   nonerl  r}  rx  r   DEBUG_ARRAY_OPTrc   r  )r`  r{  rq  rp  r  r  r  r  arr_typel_typrw  r   	size_vars
index_vars	loopnests
body_label
body_blockry  index_var_typ	value_vargetitem_call
target_varexpr_out_var
binop_exprunified_typesetitem_noder   s                              rg   r  z,ConvertInplaceBinop._inplace_binop_to_parfor  s   
 &%fk2XeS))
'
3	''//	 !11DiQVX[ \ \
I  \\
XeS))
#2#UJ
$D $D 	= F5-"="=sCC	.7oIN+wui==.7OY/7 /7l+ryy#FFGGG VE=#?#?EE
/5JO,wvy#>>.7G]/, /,l+ryz3GGHHH ve]?%C%CSII17L-. W]]2z9cBB
ry\3GGHHH'1==fioVV,5,-6 -6j) z&)\3GG.7J/8 /8l+|,,,	:r3	9-{/@B B&
3!Q&&-...KKMMMri   c                 v    t           j        }| j        j                            |t          |          i           S rq   operatorr*  r  r  resolve_function_typer  r`  r|   fntys      rg   _type_getitemz!ConvertInplaceBinop._type_getitem  /    )??eDkkSUVVVri   N)r~   r   r   rj  ra  r  r  rE  ra   ri   rg   r
  r
  _  sa           #" #" #"J> > >@W W W W Wri   r
  c                 R    t          | t          j                  r| j        n| j        S rq   )r   r	   r-  r   ry  r  s    rg   get_index_varrH    s!     BJ//@177Q[@ri   c                   ,    e Zd ZdZd Zd ZddZd ZdS )ConvertSetItemPassr  c                 "    || _         g | _        dS r  r  r  s     rg   ra  zConvertSetItemPass.__init__  r  ri   c           
         | j         }t          |          }|D ]]}||         }g }|j                            |          }|j        D ]&}t          |t          j        t          j        f          r|j	        }	|j
        }
t          |          }|j        }|j        |
j                 }|j        |j                 }|j        |j                 }t          |t          j        j                  rmt          |t          j        j                  rVt          |j        t          j                  r6|j        |j        k    r%t          |t          j                  rG|                     ||	|
||          }| j                            t3          ||d                     |}nt          |t          j        j                  rt5          t6          |j        |j                  }t          |t          j                  rj|j        dk    r_|j        j        |j        k    rJ|                     ||	|
||j                  }| j                            t3          ||d                     |}n|                     |          }t          |t          j!                  r1tE          tG          tI          d |j                                      }n$t          |t          j%        j&                  rd}nd}|qt          |t          j        j                  r||j        k    rG|                     ||	|
|||          }| j                            t3          ||d	                     |}|                    |           (||_        _d S )
Nmasked_assign_broadcast_scalarr  r*  masked_assign_arrayc                 @    t          | t          j        j                  S rq   )r   r   r  	SliceTyper  s    rg   r8  z(ConvertSetItemPass.run.<locals>.<lambda>  s    jEJ<P.Q.Q ri   r   r   )r   slice)'r  r0   rZ   r  r  r   r	   StaticSetItemr-  rq  r  rH  r  r  rZ  r   r   r   r   Booleanr   Number_setitem_to_parforr  rf  r  r;   r?   r  r  rp  r   r'  r  r   r  filterr  rP  )r`  r  r  r  r  r  r  r{  r  rq  r  r   r  r  	index_typr   r!  val_defr   sliced_dimss                       rg   r  zConvertSetItemPass.run  s   & %V,,
   I	" I	"E5MEH#2@@GGI D' D'eb&6
%CDD B2)C"\F)%00E!KE!,!4V[!AJ + 3EJ ?I + 3EJ ?I!*en.BCC 92&y%.2FGG 82&yFF82&Oy~==))U\BB 6,0,C,CI(+VUE-C -C	 $ 5 5$(U	/O%Q %Q %Q!" !" !" )2!+Iu~7K!L!L 6*/@S05
+< +<$.w$@$@ 	!6$+J)$;$;$+M$6%*$D$D040G0G	,/1O 1OI$(N$9$9(,I4I)K )K )K%& %& %& -6E %.$7$7$>$>E))U_EE 0 /2$v$Q$Q$-O85 85 36 36 /7 /7 ",Iuz7K!L!L 0 /0./
 !& 1%/	5>;O%P%P !2!,	!>!>,0,C,CI(+VUE -D -P -P	 $ 5 5(,I4;)= )= )=!" !" !" )2&&&&!EJJSI	" I	"ri   Nc           
      	   | j         }|j        }|j        |j                 }	|	j        }
|j        |j                 }t          j        ||          }|rt          |t          j	                  st          |t          j
                  sJ |}t          j        |t          d          |          }t
          j                            |||          }t          j                            |	|          j        }||j        |j        <   |                     |	|f          |j        |<   |                    t          j        |||                     |}n8t          |t          j                  sJ |                    |          }|j        }g }g }|D ]x}t          j        |t          d          |          }|                    |           t          j        |j        |j        <   |                    t5          |d|d                     yt7                      }t          j        ||          }t9          |j        |||          \  }}t;          ||i |||d|j                  }|r||i|_        |}d}nt7                      }t          j        ||          }t7                      }t          j        ||          }||||||i|_        t          j        |t          d          |          }||j        |j        <   t
          j                            |||          }|j         !                    t          j        |||          t          j"        ||||          g           |j        |j                 } t          | t          j#        j$                  rt          j        |t          d          |          }!| j        |j        |!j        <   t
          j                            |||          }tK          | j        | |          |j        |<   |j                             t          j        ||!|                     n|}!t          j&        |||!|          }"tK          t          j'        |j        |j                 ||
          |j        |"<   |j                             |"           |r-|j                             t          j(        ||                     tR          j*        dk    r#tW          d	           |,                                 |S )
r#  z$subarrparfor_indexr   r   )setitemr7  Nz	$mask_varr$  zparfor from setitem)-r  r  r  rZ  r   r	   r&  r   r   r  rP  rg  r    r  r*  r   	arraydeclget_array_index_typeresultrE  r  rf  r  ArrayCompatibler'  uintpr]  r!   r)  rl  r}  rx  r  r  Branchr   r   rQ   r-  r.  Jumpr   r/  rc   r  )#r`  r{  rq  r  r   r  r   r  r  r0  r1  rW  rw  r2  
subarr_varr9  
subarr_typbool_typr4  r3  size_varry  r5  r6  r7  r   
true_block	end_label
true_label	end_blockmask_varmask_valr   r8  r>  s#                                      rg   rU  z%ConvertSetItemPass._setitem_to_parfor7  s   
 &%fk2'
3	XeS))
 	' i99 ;i99; ; ; I}Y'?'?EEJ7??65#>>L)>>SSZJ3=K
0262D2DgyEY2Z2ZK!,/bij#FFGGGFF i)>??@@@!++F33I H 	
! 	B 	BHumN&C&CSIIIi(((27+K	/XiHa@@AAAA  \\
XeS))
#2#UJ
$D $D 	=	:r3	9'):< < 	 *J7F#JII $J%--J"I,,I *J *J )I "F ve];%?%?EEH19K.wui==HO""y8S11y:y#>>$   
  '
3	i!566 	umL&A&A3GGI2;/K	/7??5)SAAL2;M3; 3;K!,/O""29\9c#J#JKKKKIz&)YDD.7J+FK8-/Q /Ql+|,,, 	<O""279c#:#:;;;!Q&&'(((KKMMMri   c                 v    t           j        }| j        j                            |t          |          i           S rq   r@  rC  s      rg   rE  z ConvertSetItemPass._type_getitem  rF  ri   rq   )r~   r   r   rj  ra  r  rU  rE  ra   ri   rg   rJ  rJ    sm           P" P" P"d\ \ \ \|W W W W Wri   rJ  c                 Z   t          |          }|j        }|dk    s|rt          j        |t	          d          |          }t
          j                            t
          j        |          | |j	        <   t          j
                            t          |          |          }t          j        |||          }	|j                            |	           |t
          j                            t
          j        |          fS |dk    r|d         t
          j        fS t!          j        d|          )a   When generating a SetItem call to an array in a parfor, the general
    strategy is to generate a tuple if the array is more than 1 dimension.
    If it is 1 dimensional then you can use a simple variable.  This routine
    is also used when converting pndindex to parfor but pndindex requires a
    tuple even if the iteration space is 1 dimensional.  The pndindex use of
    this function will use force_tuple to make the output index a tuple even
    if it is one dimensional.
    r   z$parfor_index_tuple_varr   z,Parfor does not handle arrays of dimension 0rq  )r   rq  r	   rg  r    r   
containersUniTuplera  rZ  r  build_tupler  r  r  rf  r   UnsupportedRewriteError)
r  r  r3  r6  force_tuplendimsrq  	tuple_var
tuple_calltuple_assigns
             rg   r)  r)    s    
OOE
.CqyyKyF5-%#' #'(+- -	"'"2";";K#  # 	W((j)9)93??
yY<<|,,,%*33EKGGGG	!!}ek)),:
 
 
 	
ri   c           	          g }g }|D ]s}t          j        |t          d          |          }|                    |           t          j        | |j        <   |                    t          |d|d                     t||fS )zN
    Create loop index variables and build LoopNest objects for a parfor.
    r[  r   r   )r	   rg  r    rf  r   ra  rZ  r]  )r  r2  r  rq  r4  r3  rg  ry  s           rg   r(  r(    s     IJ > >F5-"?"?EE	)$$$"'+	)Q!<<====y  ri   c                   B    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
S )ConvertNumpyPassz]
    Convert supported Numpy functions, as well as arrayexpr nodes, to
    parfor nodes.
    c                 "    || _         g | _        d S rq   r  r  s     rg   ra  zConvertNumpyPass.__init__      &ri   c           	      B   | j         }t          |          }g }|D ]}||         }g }|j                            |          }|j        D ]K}	t          |	t          j                  r|	j        }
|	j	        }| j         j
        |j                 }|                     |          rt          | j        |
          rF|                     |||
          }|,| j                            t%          |	|d                     |}	nit          |
t          j                  rO|
j        dk    rD|                     |||
|          }| j                            t%          |	|d                     |}	|                    |j                   |                    |	           M||_        d S )Nnumpy_allocatorr  	arrayexpr)r  r0   rZ   r  r  r   r	   r  r  r  r  rZ  _is_C_or_F_orderr;   _is_supported_npycall_numpy_to_parforr  rf  r  r  rp  _arrayexpr_to_parfor)r`  r  r  r  
avail_varsr  r  r  r{  r  r  r  r  r!  s                 rg   r  zConvertNumpyPass.run  s   &$V,,
 
 	" 	"E5MEH#2@@GGI ' 'eRY// 0 ;D,C".6sx@G,,W55 . !;TBB .(,(=(=id(S(SI(4 $ 5 5d(-(1+<7" 7" 7" !# !# !#
 )2'bg66 .47k;Q;Q(,(A(A )3j)B )BI N11$$)$-'23 3 3   
 %.E%%ch///&&&&!EJJ=	" 	"ri   c                    t          |t          j        j                  r|j        dk    o
|j        dk    S |t          u rG| j        j        |         }t          |t          j        j                  o|j        dk    o
|j        dk    S dS )NCr   F	r   r   r   r   layoutr   r  r  r  r`  arr_namer  s      rg   _is_C_orderzConvertNumpyPass._is_C_order  s    h 455 	?c)?hma.??__"*84CsEN$899 !J#%!HqL" 5ri   c                 <   t          |t          j        j                  r!|j        dk    s|j        dk    o
|j        dk    S |t          u rR| j        j        |         }t          |t          j        j                  o |j        dk    p
|j        dk    o
|j        dk    S dS )Nr  Fr   Fr  r  s      rg   r  z!ConvertNumpyPass._is_C_or_F_order  s    h 455 	Os*Dho.D[(-Z[J[[__"*84CsEN$899 !Z3&;#**;!HqL" 5ri   c                    | j         }|j        }|j        }|j        }|j        |j                 }	|	j        }
|                    |          }t          |j        |||          \  }}t          j
        ||          }t          |j        |j        |j        |t          |          |
|||j        |j                 	  	        |_        t!                      }t          j
        ||          }t          j        |t%          d          |          }|
|j        |j        <   t'          |j        |||          \  }}|j                            t+          |j        |j        |j        |j        |||||||                     d                    t1          |j                            f}t3          ||i ||||d         |j                  }t          j        ||||          }t9          t:          j        |j        |j                 ||
          |j        |<   |j                            |           ||i|_         tB          j"        dk    r#tG          d           |$                                 |S )zegenerate parfor from arrayexpr node, which is essentially a
        map with recursive tree.
        r%  zarray expression {}r   r   zparfor from arrayexpr)%r  r  rq  r  r  rZ  r   r'  r(  r	   r&  r"   r  r  r  r  r!   rg  r    r)  r  _arrayexpr_tree_to_irr  r(  repr_arrayexprrl  r}  r-  rQ   r   r.  rf  rx  r   r/  rc   r  )r`  r{  r  r  r  r  r  rq  r  r0  r1  r2  r3  r4  rw  r5  r6  r;  ry  r7  patr   r>  s                          rg   r  z%ConvertNumpyPass._arrayexpr_to_parfor	  sX    &	g~%ch/ '',,	 01DiQVX[ \ \
I XeS))
"!!6)feS)	+ +

  \\
XeS))
ve]?%C%CSII17L-.#2
J$@ $@ 	= 	!#%#% 	 	 	 %++N9>,J,JKKM	:r3	9cRSfVaVghhz#y,DD.7J+CH5}f/N /Nl+|,,,&
3!Q&&)***KKMMMri   c                     t          | j        j        |          \  }}t          |t                    r|                    d          sdS |dv rdS |dk    r|t          v rdS dS )zLcheck if we support parfor translation for
        this Numpy call.
        r=  Fr   onesTnumpy.random)r9   r  r  r   r  
startswithrW   )r`  r  	call_namemod_names       rg   r  z&ConvertNumpyPass._is_supported_npycallC  sz     ,D,<,DdKK	88S)) 	h.A.A'.J.J 	5)))4~%%)|*C*C4uri   c                     t          | j        j        |          \  }}|j        }t	          |j                  }|dv s|dk    r|                     ||||||          S t          j        d| |j	                  )Nr  r  zparfor translation failed for rp  )
r9   r  r  r|   r  r  _numpy_map_to_parforr   rt  rq  )r`  r{  r  r  r  r  r|   r  s           rg   r  z!ConvertNumpyPass._numpy_to_parforQ  s    +D,<,DdKK	8y48nn)))X-G-G,,Y	3cSWXXX,3T33
 
 
 	
ri   c                    | j         }|j        }|j        }	|j        |j                 }
|
j        }|                    |          }|!t          j        dk    rt          d           dS t          |j        |||	          \  }}t          j        ||	          }t          |j        |j        |j        |t!          |          |||	|j        |j                 	  	        |_        t%                      }t          j        ||	          }t          j        |t)          d          |	          }||j        |j        <   t+          |j        |||          \  }}|dk    rt          j         |d          |	          }n|dk    rt          j         |d          |	          }n|t.          v rt1          ||           t3          ||j                  \  }}|j                            |           |j        |j        j                                     t;          j                    ||          |j        |<   |}n"t?          d                     |                    t          j!        |||	          }|j        "                    |           t          j#        ||||	          }tI          tJ          j&        |j        |j                 ||          |j        |<   |j        "                    |           tO          ||i |	||d	                     |          d
f|j(                  }||i|_)        t          j        dk    r#t          d           |*                                 |S )z8generate parfor from Numpy calls that are maps.
        Nr   z3Could not convert numpy map to parfor, unknown sizer%  r   r   r  z,Map of numpy.{} to parfor is not implemented{} functionzNumPy mappingzgenerated parfor for numpy map:)+r  r  rq  r  rZ  r   r'  r   r/  rc   r(  r	   r&  r"   r  r  r  r  r!   rg  r    r)  r  rW   _remove_size_arg_get_call_arg_typesr  r[  r  r   ContextNotImplementedErrorr(  r  rf  r-  rQ   r   r.  rl  r}  rx  r  )r`  r{  r  r  r|   r  r  r  r  rq  r0  r1  r2  r3  r4  rw  r5  r6  r;  ry  r7  r  new_arg_typsnew_kw_typesvalue_assignr>  r   s                              rg   r  z%ConvertNumpyPass._numpy_map_to_parfor\  sB    &	g%ch/ '',,	%**KLLL4 01DiQVX[ \ \
I XeS))
"!!6)feS)	+ +

  \\
XeS))
ve]?%C%CSII17L-.#2
J$@ $@ 	= HVVAYY,,EE&  HVVAYY,,EE,&&Y---)<k)*+ *+&L,!%%d+++*5*=din*M*[*[  ,+> +>K!$'EE%>EEiPPR R R yc::|,,,z#y,DD.7J+CH5}f/N /Nl+|,,,	:r3	9&--i99?K#)+ + '
3!Q&&3444KKMMMri   N)r~   r   r   rj  ra  r  r  r  r  r  r  r  ra   ri   rg   r|  r|    s           $" $" $"L	 	 		 	 	8 8 8t  	
 	
 	
B B B B Bri   r|  c                   *    e Zd ZdZd Zd Zd Zd ZdS )ConvertReducePassz:
    Find reduce() calls and convert them to parfors.
    c                 "    || _         g | _        d S rq   r  r  s     rg   ra  zConvertReducePass.__init__  r~  ri   c           	         | j         }t          |          }|D ]}||         }g }|j                            |          }|j        D ]}d }	t          |t          j                  r|j        }
|j	        }|j
        }t          t          |j        |          }|dk    s|dk    rt          | j        |||j        |
          }	|	r,| j                            t%          |	|d                     |	}|                    |           ||_        d S )N)r   r   )r   
_functoolsr   )r  r  r  )r  r0   rZ   r  r  r   r	   r  rq  r  r  r;   r9   r  _reduce_to_parforr|   r  rf  r  )r`  r  r  r  r  r  r  r{  r  r   rq  r  r  r  s                 rg   r  zConvertReducePass.run  s:   &$V,,
 	" 	"E5MEH#2@@GGI ' 'eRY// ')C,C ;D$]K4GNNH $:::#'???!&t'=y#'+y#"7 "7 '--d & %#+/ / /   
 !'&&&&!EJJri   c                 ,   | j         }|j        }|d         }|d         }t          |j        |j                  }	d}
d}t          t          |j        |j        |	          }|r|\  }}
}}|d         }|                    ||n|
          }|dS t          |j        |||          \  }}|rt          d          |}t          j        ||          }|j                            t          j        |||                     t#                      }|                     |||||          \  }}|rt          d          |
t'          |                                          }t+          |                                          }t          j        ||          }|||<   t          j        |t/          d          |          }||j        |j        <   t          j                            |
||          }|j                            t          j        |||          t          j        ||||          g           t9          ||||||d                    |          d	f|j                  }t>          j         dk    r#tC          d
           |"                                 |S )zy
        Convert a reduce call to a parfor.
        The call arguments should be (call_name, array, init_value).
        r   r   Nr   unreachablec              3   0   K   | ]}|r|nd          V  dS r   Nra   re   rm   r3  s     rg   r  z6ConvertReducePass._reduce_to_parfor.<locals>.<genexpr>  s0      OOQA8qq:a=OOOOOOri   	$mask_valr  	reductionzparfor from reduction)#r  r  r?   r  rZ  r;   
_find_maskr  r'  r(  AssertionErrorr  r	   r&  r  rf  r  r!   _mk_reduction_bodyr   r  r   rg  r    r  r*  r  rb  rl  r(  r}  r   r/  rc   r  )r`  r{  r  r|   rq  r  r  r  r   arr_defrl  mask_indicesmask_query_resultmask_typr   r2  r4  
mask_indexacc_varrw  r5  ry  rx  rj  false_labelr6  maskrm  r   r3  s                                @rg   r  z#ConvertReducePass._reduce_to_parfor  s   
 &	G	a !4fkBB "*k.A;CVX_`` 	I7H4FHh7'',2FHUU	4 01DiQVX[ \ \
I
 	P /// XeS))
ry7C@@AAA  \\
#66y %sJ I  I	9 	& /// Y^^--..Jinn..//K%--J$.Ij!6%{!;!;SAAD-5K	*wxC@@HO""y4--yz;<<$   
 	:y#y!M$8$8$C$C$/$12=2CE E !Q&&)***KKMMMri   c           	         ddl m} | j        }t          |j        |          }	 ||j        |	          }
|j        |j                 }|j        }t          j	        ||          }t          |j        |||          \  }}t          j        |t          d          |          }||j        |j        <   t          j                            |||          }t          |||          |j        |<   |                    t          j        |||                     t'          |
|j        j        j        j        |j        |j        ||f|j        |j                  }|j        }t5                      }t          j	        ||          }|||<   t7          |j                                                  }|j        |         }|j                            |j                   |j        |_        t?          |||g           tA          |||           ||fS )zZ
        Produce the body blocks for a reduction function indicated by call_name.
        r   )check_reduce_funcz$val)!r  r  r  r?   r  r  rZ  r   r	   r&  r)  rg  r    r  r*  rQ   r  rf  r  r>   r  r[  r  r  r  r  r!   r   r  r  r  rA   rB   )r`  r  r  rq  r3  r   r  r  r  reduce_funcfcoder0  in_typr6  ry  index_var_typetmp_varr9  reduce_f_irrx  ri  rk  first_reduce_labelfirst_reduce_blocks                           rg   r  z$ConvertReducePass._mk_reduction_body	  s   
 	DCCCCC&$[%8)DD!!+"5{CC%fk2XeS))
$3
J%@ %@!	> &f 5 5s;;,2GL)wvy#>>.7G^/- /-l+")L'3??@@@)%(3(;(C(H(T(3(=(3(=)/(8(3(;(3(=? ?  &	LL	HUC((	(	) !3!8!8!:!:;;(/0BC16777",/,w.@AAA	7I666)##ri   N)r~   r   r   rj  ra  r  r  r  ra   ri   rg   r  r    s^             >A A AF)$ )$ )$ )$ )$ri   r  c                   B    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
S )ConvertLoopPassz*Build Parfor nodes from prange loops.
    c                 "    || _         g | _        d S rq   r  r  s     rg   ra  zConvertLoopPass.__init__:	  r~  ri   c                 ,  ;<=>?@ABCD | j         Dt                    \  }}t                    }t                    }t	          ||j        |j                  >|                                CCfdC                                D             }g }t          |d           D 	]k\  ?}t          ?j                  dk    st          ?j                  dk    rt          j        s?j        D ]}	|	         j        D ]}
t!          |
t"          j                  rt!          |
j        t"          j                  rc|
j        j        dk    rS|                     |
j        j        j        |          r.d}t3          j        t7          j        ||
j                             t=          ?j                  d         }	|	         j        D ]I}
t!          |
t"          j                  r+t!          |
j        t"          j                  r|
j        j        dk    r|                     |
j        j        j        |          rԈ?fd?j        D             }|
j        j        }|                      |
j        j        j        |          \  }}?j!                 j        d d	         }d AtE          |          D ]^\  }}t!          |t"          j                  r?t!          |j        t"          j                  r |j        j        d
k    r|j#        j        A|} n_AJ |d |         ||dz   d          z   }tI          d?j!                 iDj%                  \  }}|d         }tM          Afd|D                       BB'                    A           |	         j(        }|
j        }Dj)        *                    ?j!                  }t#          j+        ||          }| ,                    |	         ||          |_        fd|D             @t[                      }t#          j+        ||          @|<   tM                      }|D ]"}|.                    |j        |                   }#tM                      }?j        D ]}|.                    >|                   }|/                    |          }|/                    Dfd|D                       }|D ]F}@|         j        d	         }t!          |t"          j0                  r|j#        ?j!        k    r||_#        G@Bfd;d } d }!;>?Dfd}"d}#|dk    r|1                    |d                   sJ te          |"|d                   }$|$r|$\  }%} }&}!n|d         }%t!          |%t"          j3                  sJ Dj%        |%j                 }'t!          |'th          j5                  rSt#          j3        |tm          d          |          <th          j7        Dj%        <j        <   tq          <d|%d          gC<g=n3|9                    |!|%n|           }(tu          Dj%        |(||          \  =Ct          C          dk    sJ =})|!rtw          =fd|!D                       =@ty          @                                                   }*t#          j+        ||          }+t{          Dj%        |=|+d          \  <},|+j        |*j        z   }-|-|*_        |!r	|)d         }.n<}.| t}          d          nd}5d}6|d         }7t          |          dk    r|d         }5|d         }7t          |          dk    r|d         }5|d         }7	 DjD        E                    |d                   }6n)# t          $ r t7          jG        d|
j                  w xY wt!          |6t"          jH                  st7          jG        d|
j                  |6j        }6|6dk    rt7          jG        d|
j                  t#          j3        |tm          d          |          <t!          |5t                    r|5dk    rth          j7        },nth          jJ        },d}#tq          <|5|7|6          gC|,Dj%        <j        <   ty          @                                          }8|@|8         j        z   @|8         _        <fdBD             }9t          @|9           |#r| L                    @B<           t          C|@||!r|.n<|d||fDjN        | 	  	        }:|:g?j!                 _        ?j!                 j        B                    |           ?j!                 j        O                    t#          j0        t=          ?j                  d         |                     | jP        O                    t          ?|:d!"                     |D ]"}|?j!        k    rR                    |           #t          jS        dk    r#t          d#           |:U                                 K	md S )$Nc                 T    g | ]$}|         t          |         j                  f%S ra   )r   r  )re   r  loopss     rg   rh   z'ConvertLoopPass.run.<locals>.<listcomp>F	  s0    LLL!a#eAhm"4"45LLLri   c                     | d         S r  ra   )tups    rg   r8  z%ConvertLoopPass.run.<locals>.<lambda>I	  s
    3q6 ri   r  r   r  z
prange or pndindex loop will not be executed in parallel due to there being more than one entry to or exit from the loop (e.g., an assertion).r   c                 2    g | ]}|v |j         k    |S ra   )header)re   rn   r  r  s     rg   rh   z'ConvertLoopPass.run.<locals>.<listcomp>l	  s:     #G #G #G!$%KKA4D4D %&4D4D4Dri   r  
pair_firstc              3   .   K   | ]\  }}|k    |V  d S rq   ra   )re   tr  
loop_indexs      rg   r  z&ConvertLoopPass.run.<locals>.<genexpr>	  s+      )O)O1qJ!)O)Ori   c                 "    i | ]}||         S ra   ra   )re   rn   r  s     rg   r  z'ConvertLoopPass.run.<locals>.<dictcomp>	  s     C C C!F1I C C Cri   c                 h    h | ].}t          j        |         t          j        j                  ,|/S ra   )r   r  r   r  r  )re   rm   r  s     rg   	<setcomp>z&ConvertLoopPass.run.<locals>.<setcomp>	  sK     0\ 0\ 0\a%/0CA0F
HY%Z%Z0\ 0\ 0\ 0\ri   c                  8   t          j                   }                                 D ]p}|                    t          j                  D ]N}t          |j        t          j                  r-|j        j        | v r| 	                    |j
        j                   Oqg }g }                                D ]}|j        D ]}t          d |                                D                       }|| z  r|                    |           rHt          t          |t          j                             |j        }t          t          |t          j                  o|j        dv            |                    |j        j                   |                    |           ی||fS )zfind expressions that involve getitem using the
                        index variable. Return both the arrays and expressions.
                        c              3   $   K   | ]}|j         V  d S rq   rZ  r  s     rg   r  zCConvertLoopPass.run.<locals>.find_indexed_arrays.<locals>.<genexpr>	  s$      (J(JA(J(J(J(J(J(Jri   r*  static_getitem)r  r  
find_instsr	   r  r   r  rg  rZ  r  r  r  r  ri  issubsetr<   r  rp  rf  )	indicesr  r  arrsexprslvr  rx  loop_index_varss	          rg   find_indexed_arraysz0ConvertLoopPass.run.<locals>.find_indexed_arrays	  s    #')O"<"<%.%5%5%7%7 B BE(-(8(8(C(C B B$.tz26$B$B !B$(JOw$>$>$+KK0@$A$A$AB  " "%.%5%5%7%7 7 7E(-
 
7 
7%((J(J9I9I(J(J(J%J%J#%< !7'){{7';'; %1(0$+JtRY,G,G$H$H$H+/:D$+JtRW,E,E -P'+w2O'O%Q %Q %Q$(KK
$@$@$@$)LL$6$6$6
7  $U{*ri   c                    t          j        |           }t          |o/t          |t          j                  o|j        dk    o
|j        dk               |j        }t          j
        
fdj        D              } 	            \  }}t          |j        gt          |          k               t          |j        |v           t          j        |j                  }t          j        j        |          }t!          d          )zFind the case where size_var is defined by A[M].shape,
                        where M is a boolean array.
                        r  r   c                      g | ]
}|         S ra   ra   )re   rn   live_maps     rg   rh   zDConvertLoopPass.run.<locals>.find_mask_from_size.<locals>.<listcomp>	  s    /P/P/P/P/P/Pri   r  )r?   r  r<   r   r	   r  rp  rs  r  r  r  exitsrZ  r  r  r  r  )rg  size_defarr_var	live_vars
index_arrsindex_exprsr  r_  r  r  r  r  r  s            rg   find_mask_from_sizez0ConvertLoopPass.run.<locals>.find_mask_from_size	  s    $2+2Ex#P#P !VZ"'-J-J !V (y 8!V=E]g=UW W W"*.$'I/P/P/P/PTZ/P/P/P$Q	2E2E2G2G/
K$z2B2B BCCCI =>>>"01Dhn"U"U!+K,?ATV]!^!^ -];;;ri   Tr   r[  c              3   0   K   | ]}|r|nd          V  dS r  ra   r  s     rg   r  z&ConvertLoopPass.run.<locals>.<genexpr>
  sL       /F /F34 56/Hqq:a= /F /F /F /F /F /Fri   )ru  r  r  r   r$  z,Only known step size is supported for prangerp  z/Only constant step size is supported for prangez4Only constant step size of 1 is supported for prangeFc                     i | ]}|S ra   ra   )re   r  ry  s     rg   r  z'ConvertLoopPass.run.<locals>.<dictcomp>X
  s    $K$K$KaQ	$K$K$Kri   r   )rn  r  )old_loopr  r  zparfor from loop)Vr  r3   rN   rK   rL   usemapdefmapr  r  r  r   entriesr  r   DISABLE_PERFORMANCE_WARNINGSr  r   r	   r  r  r  rp  _is_parallel_loopr[  rZ  warningswarnr   NumbaPerformanceWarningrq  r  r|   _get_loop_kindr  r;  r  r-   r  r  r  r  rZ   r  r&  _get_prange_init_blockr!   r  intersectionrc  	has_shaper;   rg  r   Integerr    ra  r]  r'  r(  r  r   r)  r  r8   r   r*  r  rb  r  r?   rz  rt  r  r  intpr'   _replace_loop_access_indicesrl  r}  rf  r  r  r  r/  rc   r  )Er`  r  r  r  cfgusedefssized_loopsmoved_blocksr   entryr  r  body_labelsr|   	loop_kindloop_replacingheader_bodyhbir  li_indexcpsr  rq  r{  rw  ri  bodydefsbl
exit_livesrn  rn   	last_instrl  r  r  unsigned_indexr_  r   r  
in_arr_typr2  
orig_indexfirst_body_blockr6  r7  r  orig_index_varr5  labelsrj  r  r  rm  r  r  rg  first_body_labelindex_var_mapr   r  ry  r3  r  r  rx  r  r  r  r  sE    `                                                         @@@@@@@@@@rg   r  zConvertLoopPass.run>	  sb   &&v..
A%f--"6**#CPP		LLLLuzz||LLLk/A/ABBB n	& n	&GD!4<  A%%TZA)=)=: 8!% 8 8$*5M$6 8 8D !+4 ; ;8$.tz27$C$C8 %)JMV$;$;$($:$:$(JO$8*%F %F %<'4
 !)$*$B(+TX%7 %7!8 !8 !88" &&q)Eu* V& V&tRY// T&&tz27;;T& JMV33 224:?3GTT 4#G #G #G #G #Gty #G #G #GK:?D040C0CDJODXDN1P 1P-I~ #)"5":3B3"?K!%J%.{%;%; " "	T&tRY77 "$.tz27$C$C"$(JM\$A$A)-)9J'*H!E%111 #.ixi"8;xPQz{{;S"SK .q&2E.F.9.AC CFCa&C&))O)O)O)O)O)O)O&O&OO#''
333"5M/E(C + : H H U UI!#%!5!5J&*&A&A&-<F'N 'NJO C C C C{ C C CI *I+-8E3+?+?Ii(  #uuH) F F#+>>'.2D#E#E!$J"j D D%/%5%5hrl%C%C

$11*==E ".. 0\ 0\ 0\ 0\5 0\ 0\ 0\ ] ]E ) 9 9$-aL$5b$9	&y"':: 9%,;;/8I,+ + + + + +4  $H#'L& & & & & & & &6 &*N !J..(2247;;<<< "'':DG!D!D! -GMDFHh%)!WF)&"&99:::%0%8%E
%j%-@@ 
(*umN6S6SUX(Y(YIBG+K/	?%-iFA%F%F$GE*3JJ(1(;(;-9-A =CFGO)Q )QI0@ + 3Ys1 1-J  #5zzA~~~~%/
' F */ /F /F /F /F8D/F /F /F *F *FJ+4S9I9I5J5J+K(%'XeS%9%9
3B'/
J(,4 4 40	=  *1A1FF04(-' 7-7]NN-6N $/"0"?"?? 0( !" #'7t99>>$(GE'+AwHt99>>$(GE'+AwH"'2':'I'I$q''R'R#+ " " "&,&D$R(,'" '" '" !""
 $.dBH#=#= "&,&D$U(,'" '" '" !" $(:D#qyy&,&D$Z(,'" '" '" !" %'F5-2O2OQT$U$U	 &eS11 3eqjj,1KMM,1JM-2N!))UHd!K!K L>K+IN; ,/y~~/?/?+@+@(;FScIdIi;i	"238$K$K$K$K?$K$K$KM M:::% C 99%	C C C#E:y#6B$QNN	$-%-y.$I$/$5U	D D DF 17xF4;',
 4;',33K@@@4;',33BGD<L<LQ<OQT4U4UVVVN))$!%"%+ + +    ) * *++"JJqMMM-220111mV&1n	& n	&s    ]..&^c                     ||vrdS ||         }t          |          dk    oV|d         dk    pJ|d         t          k    p9|d         dk    p-|d         t          k    p|d         dk    p|d         t          k    S )NFr   r   rx   r   )r   r   rx   r   r`  func_varr  r  s       rg   r  z!ConvertLoopPass._is_parallel_loopy
  s    :%%5(#4yy1} A$q'X"5 #@aF9J #@7//#@377o3M#@7j(#@,0Gx,?	Ari   c                 N   | j         }||v sJ ||         }t          |          dk    sJ d}|d         dk    s|d         t          k    r<	 d|j        |         d         |j        |         d         ff}n1# t          $ r d}Y n#w xY w|d         dk    s|d         t
          k    rd}|S )	z(see if prange is user prange or internalr   )r   r7  rx   r  r  )r  )r7  r7  r   )r   r7  )r  r   rx   r  rz  r   )r`  r  r  r  r  kinds         rg   r  zConvertLoopPass._get_loop_kind
  s    &:%%%%(#4yy1}}}}7'''47o+E+E,!K$;H$Ea$H+JabjJklnJo#pp , , , ,	,
 !W
""d1g&9&9!Ds   (A4 4BBc                    d}d}g }t          |j                  D ]\  }}t          |t          j                  rVt          |j        t          j                  r7|j        j        dk    r'|                     |j        j	        j
        |          r|}t          |t          j                  rVt          |j        t          j                  r7|j        j        dk    r'|                     |j        j	        j
        |          r|}|dk    r|dk    rd |D             }	g }
t          t          |dz   |                    D ]b}|j        |         }d |                                D             }|	|z  r|	|z  }	|
                    |           M|                    |           c|                                 |
                                 |j        d|         |
z   |j        |dz   d         z   |_        |S )z
        If there is init_prange, find the code between init_prange and prange
        calls. Remove the code from entry_block and return it.
        r  r  c                     h | ]	}|j         
S ra   r  re   r  s     rg   r  z9ConvertLoopPass._get_prange_init_block.<locals>.<setcomp>
  s    <<<1<<<ri   r   c                     h | ]	}|j         
S ra   r  r!  s     rg   r  z9ConvertLoopPass._get_prange_init_block.<locals>.<setcomp>
  s    >>>QV>>>ri   N)r;  r  r   r	   r  r  r  rp  _is_prange_initr[  rZ  r  r"  rz   ri  rf  reverse)r`  entry_blockr  prange_argsinit_call_indprange_call_ind	init_bodyr   r  arg_related_varssaved_nodes	inst_varss               rg   r  z&ConvertLoopPass._get_prange_init_block
  s   
 	 !122 		$ 		$GAt4++ "
4:rw0O0O "
//,,TZ_-A:NN 0 !4++ $
4:rw0O0O $
//..tz/CZPP 0"#B?b#8#8  =<<<<KeM!O_EEFF + +"'*>>T^^-=-=>>>	#i/ +$	1$&&t,,,,$$T****!!! + 0- @%!&(3(89J9K9K(L!MK ri   c                 ~    ||vrdS ||         }t          |          dk    o|d         dk    p|d         t          k    S )NFr   rr   )r   rr   r  s       rg   r#  zConvertLoopPass._is_prange_init
  sH    :%%5(#4yy1}U$q']":"Td1g>TUri   c                    |                     |j                   t          |          5  t          |          }ddd           n# 1 swxY w Y   |d         }t	                      }|D ]}||         }|j        D ]}	t          |	t          j                  rt          |	j	        t          j
                  r||k    r[|	j	        j        |v rM|	j        j        |vr?|                     |	j        j                   |                     |	j        j                   n}|j        fd}
 |
|	j        j                  t          |
|          v rL |
|	j        j                   |
|	j	        j                  k    r t          j        d|	j        j                  t#          |	          rpt%          |	          }|<t'          t(          | j        j        |d          }|j        |v s||j        |v rt/          |	|           t'          | j        |||           t          |	t2                    r|                     |	j        ||           ̐||z  }dS )z
        Replace array access indices in a loop body with a new index.
        index_set has all the variables that are equivalent to loop index.
        Nr   c                 j    ddl m} 	                     |           j        S # |j        $ r | cY S w xY w)Nr   )r   )
numba.corer   	get_exactunversioned_nameNotDefinedError)rZ  r   r  s     rg   unverz;ConvertLoopPass._replace_loop_access_indices.<locals>.unver
  sV    999999,',t'<'<'M M#)#9 , , ,'+,s   # 22z Overwrite of parallel loop indexrp  T)lhs_only)r  rZ  dummy_return_in_loop_bodyr0   r  r  r   r	   r  r  rg  r  r  mapr   rt  rq  rE   rF   r;   r?   r  r  rG   _replace_multi_dim_indrl  r  rx  )r`  rx  	index_set	new_indexr  first_labeladded_indicesrn   r  r  r4  r   ind_defr  s                @rg   r  z,ConvertLoopPass._replace_loop_access_indices
  s    	in%%%&y11 	0 	0$Y//F	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 	0 Qi
  /	\ /	\AaLE
 -\ -\tRY// &tz26:: [((TZ_	-I-I $ 0	 A A!dk&6777%))$+*:;;;; !&, , , , , !5!122c%6K6KKKPUPUVZVaVfPgPgkpkpquq{  rA  lB  lB  QB  QB"("@ B$(KO# # #  "$'' P4T::E} #ND4D4L$)D: : :G
i// ' 3$+LI$=$=4T9EEE $5w	ENP P P dF++ \55dniQZ[[[[-\` 	]"	s   AAAc                    | j         }t          |du           t          t          |j        |j                 t
          j        t
          j        f                     t          |j	        |          }t          t          |t          j                  o
|j        dk               fd|j        D             |_        dS )zq
        replace individual indices in multi-dimensional access variable, which
        is a build_tuple
        Nrs  c                 *    g | ]}|j         v rn|S ra   r  )re   r  r9  r:  s     rg   rh   z:ConvertLoopPass._replace_multi_dim_ind.<locals>.<listcomp>  s9     ; ; ;"# ,-6Y+>+>iiA ; ; ;ri   )r  r<   r   r  rZ  r   Tuplerr  r?   r  r	   r  rp  r  )r`  ind_varr9  r:  r  ind_def_nodes     ``  rg   r8  z&ConvertLoopPass._replace_multi_dim_ind	  s    
 &t#$$$
;.w|<en-/ / 	0 	0 	0%k&97CC
<11 5 O}4	6 	6 	6; ; ; ; ;'3'9; ; ;ri   N)r~   r   r   rj  ra  r  r  r  r  r#  r  r8  ra   ri   rg   r  r  7	  s           y& y& y&v	A A A  (% % %NV V VD D DL; ; ; ; ;ri   r  c                    t          t          |t          j                  o
|j        dk               |j        }|j        }| |j                 }| |j                 }|j        }t          t          |t          j
        j                             t          |t          j
        j                  r5t          |j        t          j                  r||j        k    r|||j        dfS t          |t          j                  r]t          ||          \  }}	t          |	dk    ot!          |          |k               d}
g }d}|D ]}| |j                 }t          |t          j
        j                  r>t          |j        t          j                  r|}|j        }|                    d           lt          |t          j
        j                  r>t          |j        t          j                  r|}|j        }|                    d           t          |t          j                  r|
dz  }
|                    |           t          |o|
|dz
  k               ||||fS t&          )zcheck if an array is of B[...M...], where M is a
    boolean array, and other indices (if available) are ints.
    If found, return B, M, M's type, and a tuple representing mask indices.
    Otherwise, raise GuardException.
    r*  Nrs  r   r   )r<   r   r	   r  rp  r  r   rZ  r   r   r   r   r   rS  r  r:   r   rf  r  r=   )r  r  r  r  r   r   rW  r   seqrp  count_constsr  rl  indr  s                  rg   r  r    s9    Jw((DWZ9-DEEEMEME
#I
#I>DJy%."6778889en233  79?EM22 7	eY_d22	Iu	/	/ 7 &gu55Rm#8CD(8999 	) 	)C)I9en&:;; )9?EM::)$?##D))))Y(<== )9?EM::)$?##D))))Iu}55 )!##C(((5\TAX5666h,66
ri   c                   *    e Zd ZdZd Zd Zd Zd ZdS )
ParforPasszParforPass class is responsible for converting NumPy
    calls in Numba intermediate representation to Parfors, which
    will lower into either sequential or parallel loops during lowering
    stage.
    c                     | j                             | j        j                   t          j                            t	          j        | j        j                             d S rq   )rZ   r  r  r  r   r  r*  find_max_labelrc  s    rg   _pre_runzParforPass._pre_runS  sV     3444&&#DL$788	: 	: 	: 	: 	:ri   c           	         |                                   | j        j        rLt          | j        | j        | j        | j        | j        | j	        | j
                  }|                                 | j        j        r,t          |                               | j        j                   | j        j        r,t!          |                               | j        j                   | j        j        r,t%          |                               | j        j                   | j        j        r,t)          |                               | j        j                   | j        j        r,t-          |                               | j        j                   | j                            | j        | j        j                   t5          | j        d           dS )zgrun parfor conversion pass: replace Numpy calls
        with Parfors when possible and optimize the IR.zafter parfor passN)rK  r  stencilr   r  r  r  rZ   r  r  r}  r  r\  rJ  r  r=  r|  r  r  r   r  r  r
  r  r  fusionr/   )r`  stencil_passs     rg   r  zParforPass.runZ  s    	< 	&t|T\'+~t7J'+~t~'+z3 3L < 	>t$$(()<===< 	<T""&&t|':;;;<! 	=d##''(;<<<< 	;D!!%%dl&9:::<% 	?%%))$,*=>>> 	t|T\-@AAAt|%899999ri   c                 8    t          | j        | j        |          S )zcheck if an array is of B[...M...], where M is a
        boolean array, and other indices (if available) are ints.
        If found, return B, M, M's type, and a tuple representing mask indices.
        Otherwise, raise GuardException.
        )r  r  r  )r`  r  s     rg   r  zParforPass._find_masku  s     $,g>>>ri   c                 0    t          | j        |||          S )zV
        Create loop index variables and build LoopNest objects for a parfor.
        )r(  r  )r`  r2  r  rq  s       rg   r(  zParforPass._mk_parfor_loops}  s      iDDDri   N)r~   r   r   rj  rK  r  r  r(  ra   ri   rg   rH  rH  K  s_         : : :: : :6? ? ?E E E E Eri   rH  c                   $    e Zd ZdZd Zd Zd ZdS )ParforFusionPassz=ParforFusionPass class is responsible for fusing parfors
    c                    t          | j        j                  }t          | j        | j        | j        | j        d                    t          | j        | j        | j        | j        d                    | j        j        r|dk    rt          | j        j                  | j        _
        t                      | j        _        | j                            | j        j                   t          | j        j        | j        j        | j                  \  }}|D ]0}t#          | j        ||j        | j                  \  |_        |_        1t+          | j        | j        j        | j        d           t-          | j        d           |                     | j        | j        j        | j        | j                   t-          | j        d           t+          | j        | j        j        | j                   t-          | j        d           |                     | j        | j        j        | j        | j                   t-          | j        d           t          | j        | j        | j        | j        d                    d	S d	S d	S )
zrun parfor fusion passr   r   F)up_directionzafter maximize fusion downzafter first fusezafter maximize fusion upzafter fusionN)simplify_parfor_body_CFGr  r  r4   r  r  r  r  rN  r@   _definitionsr  rZ   r  r  get_parfor_paramsr  get_parfor_reductionsrz  r~  r  maximize_fusionr/   fuse_parfors)r`  r  r  r   r  s        rg   r  zParforFusionPass.run  sM   
 -T\-@AA	t|T^T]9=UVVV 	t|T^T]9=UVVV< &	[9>>(9$,:M(N(NDL%-1VVD*##DL$7888 +4<+>+/<+>+/+BD DJAw  M M'<T\=>=>X=A^(M (M$	199 DL$,*=t|INP P P P4<)EFFFd1"l1"l"l, , , 4<);<<<DL$,*=t|LLL4<)CDDDd1"l1"l"l, , , 4<888T\4<yAYZZZZZM&	[ &	[>>ri   c           	         |                                 D ]\  }} |j        |          }d}|rd}g }	d}
|
t          |j                  dz
  k     rq|j        |
         }|j        |
dz            }t	          |t
                    rt	          |t
                    r |j        |          }||_        ||_        t          |||| j        d         ||          \  }}| j	        j
                            |           |fd}| j	        j        |j                                     |j        g           |	                    |           |                     ||||           |
dz  }
*|	                    |           t	          |t
                    r|                     ||||           |
dz  }
|
t          |j                  dz
  k     q|	                    |j        d                    |	|_        |d S )NTFr   r   r   r   r  )r  r  r   r  r   rl  r{  try_fuser  r  r  rf  r  ru  r  fuse_recursive_parfor)r`  rZ   r  r  r  r  r  r{  fusion_happenedr  r   r  	next_stmt
fused_nodefuse_reports                  rg   r[  zParforFusionPass.fuse_parfors  s	   "LLNN  	&  	&LE544U;;I"O! &"'#ej//A--- :a=D %
1q5 1I!$// %Jy&4Q4Q % %AN$@$G$G	)2.7	+2:9dI M)4gw3H 3H/
K (7>>{KKK%1.2O ,8AHH),XXX$OOJ777 66z9gW^___FA$OOD)))!$// V224GWUUUFA/ #ej//A---0 
2///%
; " &< 	ri   c                 V   t          |          }t          | j        || j                   t	          | j        d|           t          j        | j        | j        | j        | j                  }|	                    ||           | 
                    ||||           t          |           d S )Nz$after recursive maximize fusion down)r  rZ  r  r  r/   rZ   r  r  r  r  r[  r  )r`  r   r{  r  r  r  arr_analysiss          rg   r^  z&ParforFusionPass.fuse_recursive_parfor  s    #F++fdl;;;t|%KVTTT%3DNDL04dnN N+++,AAAV$$$$$ri   N)r~   r   r   rj  r  r[  r^  ra   ri   rg   rS  rS    sP         3[ 3[ 3[j" " "H% % % % %ri   rS  c                       e Zd ZdZd ZdS )ParforPreLoweringPasszSParforPreLoweringPass class is responsible for preparing parfors for lowering.
    c           
         t          | j        j        i i | j                   t	          | j        d           t          | j        | j        | j        | j        d                    t	          | j        d           t          j	        dk    rIt          dt          | j                                                             t          d| j                   t          j	        dk    r | j        j                                        D ] \  }}g }|j        }|j        D ]}|                    |           t!          |t"          j                  r|j        }|j        }|j        }| j        |j                 }	t          d|j        |	t/          |	                     |	t0          j        v st!          |	t0          j                  r:t#          j        |t9          d	          |          }
t1          j        |j                  | j        |
j        <   t#          j        |j        |          }t#          j        ||
|          }|                    |           t#          j        |
gd
|          }tA          t0          j!        | j        |
j                           | j        |<   |                    |           t#          j        |gd
|          }tA          t0          j!        |	          | j        |<   |                    |           ||_        | j        j"        r%tG          | j        j$        | j%        | j                   tL          r.tO          | j(        | j        | j        | j        | j                   d
S tS          | j        j        | j*        j+        | j,                  \  }}|D ]0}t[          | j        ||j.        | j                  \  |_/        |_0        1|D ]}|1                    | j                   t          j2        r| j        j3        j4        }tk          |          }|dk    r7| j*        j+        rdnd}t          d6                    ||||                     d
S t          d6                    |                     d
S d
S )zrun parfor prelowering passzafter push call varsr   zafter optimizationr   zvariable types: zcall types: r$  zAdding print for assignment to str_varNr   After fusionr  z0{}, function {} has {} parallel for-loop(s) #{}.zFunction {} has no Parfor.)7push_call_varsr  r  r  r/   r4   r  r  r   r/  rc   r  r  r  r  rf  r   r	   r  rq  r  r  rZ  rs  r   number_domainLiteralrg  r    r  r  PrintrQ   r.  is_generatorfix_generator_typesgenerator_infor   r  lower_parfor_sequentialr  rX  r  rN  r  rY  rz  r~  r  r  r  r  r  r   r(  )r`  block_labelr  	new_blockr  r  rq  r  r  r  rh  	lhs_const
str_assign	str_printir_printr  r   r  rZ  r  r  s                        rg   r  zParforPreLoweringPass.run  sO   
 	t|*BDLAAAt|%;<<<t|T^T]9=UVVVt|%9:::!Q&&$fT\-?-?-A-A&B&BCCC.$.111!Q&&'+|':'@'@'B'B ' '#U	!J 7 7D$$T***!$	22 7"h"k"j"&,sx"8?7TXY`TaTabbb"e&999ZQVQ^=_=_9&(fUM)4L4Lc&R&RG9>9LSX9V9VDL6(*3(?(?I)+9gs)K)KJ%,,Z888(*'D#(F(FI8A%*dl[b[gNh8i8iDN95%,,Y777')xtS'A'AH7@W7U7UDN84%,,X666&

<$ 	. ;T=M $. . .%  	E#dlDNDM[ [ [ [ [ #4DL4G48L4G484K#M #MJ
  M M'<T\=>=>X=A^(M (M$	199  0 0!!$,////+ 
E|+9
OO	q==6:l6I %@NN)? ! :;A6'y*<F <FG G G G G 6==dCCDDDDD
E 
Eri   N)r~   r   r   rj  r  ra   ri   rg   rf  rf    s7         KE KE KE KE KEri   rf  c                 b   t          |j                  }|                    dd           t          |                                          |_        | t
          t          z   v rg |_        | t          v r1t          |j                  dk    r|j                                         | t          v r1t          |j                  dk    r|j                                         | dk    rt          |j                  dk    r|j                                         t          |j                  dk    rL|j                                        }|j                                         |j                            |           | dk    r1t          |j                  dk    r|j                                         dS )	z%remove size argument from args or kwsr   r7  r$  r   randintr%  
triangularN)r  r  r  r  r  rT   rS   r|   rV   r   rU   rf  )r  r  r  dt_args       rg   r  r  @  sZ    tx..CGGFBSYY[[!!DH $666 	(((ty>>QIMMOOO(((ty>>QIMMOOOIty>>QIMMOOOty>>QY]]__FIMMOOOIV$$$L  ty>>QIMMOOO
Fri   c                     g }| j         D ]"}|                    ||j                            #i }| j        D ]\  }}||j                 ||<   t	          |          |fS rq   )r|   rf  rZ  r  r  )r  r  r  r   r  rZ  s         rg   r  r  h  sw    Ly / /GCH-....LX / /	c$SX.T,,ri   c                 
   |j                  }|j        }|j        }g }t          |t                    r|\  }}g }|D ]`}t          j        |t          d          |          }||j         <   |t          | ||||||||	|
          z  }|	                    |           a|t          j        v r&|d         j                  }t          |          dk    r|d         j                  }|                    |||fi           }t
          j                            ||d         |d         |          }|t           j        k    r!t%          |d         |d         |          \  }}n?|                    ||fi           }t
          j                            ||d         |          }|||<   |j        }|	                    t          j        |||                     t,          j        D ]"}t          ||          rt1          ||
|          }t          j        |t          |          |          }|         |j         <   t3          j        |                     |                    }t          |t
          j                  r|j        dk    r|j        dk    rt          j        |t          d          |          }t<          j                             tB                    |j         <   t          j"        d	tB          |          }t          j        |||          }t
          j        #                    |d|          }|	                    |           t
          j        $                    ||d
|          }|j                  %                    |t	          fd|D                       i           }|||<   |j        }|	                    t          j        |||                     |	                    t          j        |||                     $nt          |t
          j                  ru|j                  } t          | t<          j&                  r | j'        }tQ          ||||	|||||
  
        }n| }|}|	                    t          j        |||                     nnt          |t
          j)                  rTtU          j+                    ,                    |j-                  }|	                    t          j        |||                     t          |          dk    r t]          j/        d|dd|j                  0                    |j         d           ||j         <   |S )zgenerate IR from array_expr's expr tree recursively. Assign output to
    expr_out_var and returns the whole IR as a list of Assign nodes.
    z$arg_out_varr   r   r   rp  r  sqrtz$math_g_varr  ra   c              3   2   K   | ]}|j                  V  d S rq   r  )re   r   r  s     rg   r  z(_arrayexpr_tree_to_ir.<locals>.<genexpr>  s)      $G$GWQV_$G$G$G$G$G$Gri   z.Don't know how to translate array expression 'r7  'N)1rZ  r  rq  r   r  r	   rg  r    r  rf  rP   supported_array_operatorsr   rB  r  r+  rA  truediv_gen_np_divideunaryr   r  rZ   	MAP_TYPES_find_func_varr  r  r?   rp  rs  r   r  r  r  r  r  r  r  r   r   _gen_arrayexpr_getitemr  r   r  resolve_value_typer  r   rt  r  )!r  r  r  r  r{  rw  r;  r  parfor_index_tuple_varall_parfor_indicesr  r1  r  rq  out_irrp  arr_expr_argsarg_varsr   arg_out_varel_typ1el_typ2func_typir_exprTfunc_var_namer  func_var_def
g_math_varg_mathg_math_assigncall_typvar_typs!     `                              rg   r  r  t  s?    \&'FE

CF$ Q: M  	) 	)C&n(E(EsKKK(.GK$%+G,5,3,5,5,6,7,/,B,>,6
8 
8 
8F OOK((((222hqk./G8}}!!!(1+"23$::2@G@IJLN N'--HQK!cJJ)))(6 Xa[&')C )C%Hg %::2z2NN'--HQK==!)Ig)FMM")G\3??@@@) 	E 	EA"a   E !/wJC P P P6%})E)EsKK)0)?&#}W-C-CM-R-RSSlBG44 2I9U9UZfZkouZuZu"$&m0L0Lc"R"RZ05
0A0A$0G0GWZ_- ic::V%'Yvz3%G%G]$&GOOJ$L$L\]]=111',,x2sCC"8=1??u$G$G$G$Gh$G$G$GGGM M%-	'"!-bihDDEEEbisCCDDD1	E2 
D"&	!	! :$)$gu{++ 	]F,&"
 
GG FGbis;;<<<<	D"(	#	# :!!44TZ@@bilC88999
6{{a,FTFFFF
 
 
 	
 KK!4(((!'GLMri   c                    | j         }| j        }t          j        |t	          d          |          }t
          j                            t                    ||j	        <   t          j
        dt          |          }t          j        |||          }t          j                            |d|          }	t          j        |t	          d          |          }
t          t          j                  }|||
j	        <   t          j        |	|
|          }t          j                            |
| |gd|          }|                    t%          j                    || j	                 ||j	                 gi           }|                    ||g           ||fS )zgenerate np.divide() instead of / for array_expr to get numpy error model
    like inf for division by zero (test_division_by_zero).
    r  r   dividez	$div_attrra   )r  rq  r	   rg  r    r   r  r  r=  rZ  r  r  r  r  r#   r  r  r  r   r  r  )arg1arg2r  r  r  rq  r  r  r  div_attr_callattr_varfunc_var_typattr_assigndiv_callr  s                  rg   r  r    sG    JE
(Cve];77==H"Z..u55GHM9T5#&&D)D(C00KGOOHh<<Mve];77==H#EL11L)GHM)M8S99Kw||HtTlB<<H))749-wty/ABBH HH
MM;,---Xri   c
           	      ^    |j         }
|}||j                 }||j                 j        }t          |          }                     |          pg } fd|D             }|dk    rt          j        |j        t          d          |
          }t          j
                            |j        dd          }|||j        <   t          j        dt          j        ||g|||          }|j                            |           |}t          j        d|j                   }t          j        |j        t          d          |
          }t          j        ||j        <   t          j        |||
          }|	                    |           |}n|dk    r
|d	         }nt/          d
 |D                       r||z
  }t          j        |j        t          d          |
          }t          j                            t          j        |          ||j        <   t          j        d|j                   }t          j        |j        t          d          |
          }t          j        ||j        <   t          j        |||
          }|	                    |           g }t5          t7          |                    D ]L}||         }||         }|dk    r|                    |           .|                    |||z                       Mt9          t5          |                    }t
          j                            ||
          }t          j        |||
          }|	                    |           |}t
          j                            |||
          }tA          |||j                 ||j                           ||<   |S )a  if there is implicit dimension broadcast, generate proper access variable
    for getitem. For example, if indices are (i1,i2,i3) but shape is (c1,0,c3),
    generate a tuple with (i1,0,i3) for access.  Another example: for (i1,i2,i3)
    and (c1,c2) generate (i2,i3).
    c                 :    g | ]}                     |          S ra   )get_equiv_const)re   rm   r{  s     rg   rh   z*_gen_arrayexpr_getitem.<locals>.<listcomp>  s'    CCCA9,,Q//CCCri   r   z$ravelr   r  )r   r   r  r   z$const_ind_0r  c                     g | ]}|d uS rq   ra   r  s     rg   rh   z*_gen_arrayexpr_getitem.<locals>.<listcomp>*  s    111atm111ri   z$parfor_index_tuple_var_bcast)!rq  rZ  r   r   r'  r	   rg  r  r    r   r   r   r   r   gen_np_callr=  r   r  r  r  ra  r  rf  r&  rq  rr  r"  rz   r  r  rs  r*  rQ   ) r{  r   r  r  r1  r  r  r  rw  r  rq  ry  r  rv  num_indicesr2  size_consts	ravel_var	ravel_typstmts
const_node	const_varconst_assign
ind_offsetrw  r3  r   rg  
size_constrx  ry  r  s    `                               rg   r  r    s_     'C&Isx GCH"E())K##C((.BICCCCCCCKzzF39mH&=&=sCC	N((w}1S(QQ	"+	$Wek9seYX_ajkku%%%Xa))
F39mN&C&CSII	"'+	yY<<l###			!&r*			11[111	2	2  5(
F39m+'- '-.13 3	"'"2";";EK"O"O	 Xa))
F39mN&C&CSII	"'+	yY<<l###
%,,'' 	F 	FA |H$QJQ!!),,,,!!"4Z!^"DEEEE(:..//
W((S99
yY<<l###	gooc9c22G"6738+<#*9>#:< <IgNri   c                     |D ].}| |         }t          |t                    r|j        |k    r|c S /t          j        d|          )zAfind variable in typemap which represents the function func.
    zufunc call variable not foundrp  )r   rR   
typing_keyr   rt  )r  r[  r  rq  r  r  s         rg   r  r  K  s[       AJa"" 	q|t';';HHH

()Hc
R
R
RRri   c           
         t           j                            t          j        |j                             d}i }t          t          |j                                                            j        }|j        	                                D ]#\  }}	t          ||	|||||          \  }}|	||<   $||_        |rt          |j                  |_        t          |d           t          ||||d                    t          |d           d S )NFr  z after parfor sequential loweringr   z after parfor sequential simplify)r   r  r*  rJ  r  nextiterr  r  r  _lower_parfor_sequential_blockr2   r/   r4   )
r  r  r  r  r  parfor_foundr  r  rr  r  s
             rg   rq  rq  V  s   ""8#:7>#J#JKKKLJgn++--..//5E ' 4 4 6 6 ( (e$B
GY% % %!\ #(
;GN 7&w~667>???Wgy(9*=>>>7>?????ri   c           
      B   t          |j                  }|dk    rd}|j        |         }|j        j        }	t	          j        ||	          }
|j        d |         |
_        |j        |dz   d          |_        t                      }|
j                            t	          j        ||	                     t          |j        |          ||<   |
|| <   t                      } t          |j                  }t          |          D ]}|j        |         }t                      }t                      }t          ||j        |j        |j        |||	          }||j        d         _        |j        d         j        }|||<   t%          |||||	          }|j        |j        d         _        |||<   |dk    rE|j        j                            t	          j        ||	                     | |j        d         _        n*|||         j        d         _        ||j        d         _        |}!t-          |j                                                  }|j        |         j                            t	          j        ||	                     t3          |j                                                  }||j        d         _        |j                                        D ]1\  }}t7          |||||||          \  }}t          ||          ||<   2t          |j                  }|dk    | |fS )Nr  Tr   r   r  )_find_first_parforr  rw  rq  r	   r&  r!   rf  rc  rJ   r   rv  rz   r$   r  r  r  r  r%   r_  falsebrtruebrr   rx  r  r   r  r  )rr  r  r  r  r  r  r  r   r  rq  
prev_block
init_labelrv  r  range_labelheader_labelrange_blockphi_varheader_blockprev_header_labelbody_last_labelbody_first_labelrn   r   s                           rg   r  r  j  s    	5:&&A
r''z!}o!XeS))
*RaR.
ZA'
\\
rwz377888!/!G!G
:",
; llDO$$u 	- 	-Aq)H$,,K%<<L( K +7KR '!&r*1G&1J{#)'7I*/6 6L+3+BLb!('3J|$Avv$++BGK,E,EFFF0;!"%--@K
,-226=0A!"%- , dn113344',33GL#&&	( 	( 	( t~224455'7"$n**,, 	5 	5FQ<1j'9l  OA| +1e44JqMMuz**u r''v $$ri   c                 p    t          |           D ]%\  }}t          |t                    r|j        s|c S &dS Nr  )r;  r   rl  rm  r  r   r  s      rg   r  r    sF    t__  	DdF## 	D,G 	HHH2ri   c                 f   t                      }g }t                      }t          |           \  }}t          |           }|D ]}	| |	         }
t          |
j                  D ]\  }}t          j        |
j        |
j                  }|
j        d|         |_        t          d|i          j	        d         }||z  }t          ||||          }t          |
j        ||j                  \  |_        |_        |                    |j                   |                    |           |||	         z  }||fS )zfind variables used in body of parfors from outside and save them.
    computed as live variables at entry of first block.
    Nr   )r  rK   r0   _find_parforsr  r	   r&  r  rq  r  get_parfor_params_inner#_combine_params_races_for_ssa_namesrn  rz  r  ru  rf  )r  options_fusionr  r  r   pre_defsr  all_defsr  r  r  r   r   dummy_blockbefore_defsrz  s                   rg   rX  rX    s=    JGuuH"6**KAx ((J $ $u&uz22 	# 	#IAv(5;	::K$z"1"~K*A{+;<<CAFK#H,.+ F +NVV\+ +'FM6< NN69%%%NN6""""HUO#wri   c                       fdt          |          }t          t          |                    }|D ]4t          fd|D                       r|                               4 ||z  |fS )zReturns `(params|races1, races1)`, where `races1` contains all variables
    in `races` are NOT referring to the same unversioned (SSA) variables in
    `params`.
    c                 h    	                      |           j        S # t          j        $ r | cY S w xY wrq   )r1  r2  r	   r3  )r  r  s    rg   	unversionz6_combine_params_races_for_ssa_names.<locals>.unversion  sD    	??1%%66! 	 	 	HHH	s    11c              3   6   K   | ]}           |k    V  d S rq   ra   )re   pvrvr  s     rg   r  z6_combine_params_races_for_ssa_names.<locals>.<genexpr>  s0      ::ryy}}"::::::ri   )r  r  r7  r&  discard)r  rz  rn  races1unver_paramsr  r  s   `    @@rg   r  r    s    
     ZZFIv..//L  :::::\::::: 	NN2F?F""ri   c                 F   t          |           }t          |          }t          |          }t          |||j        |j                  }t          |||          \  }}	t          |          }
|
dk    rSt          j	        r0|rdnd}t          d                    || j        |
|                     t          |          || j        <   t          |            t          |                                          }|d         }|d         }|j        |         |z  }||         |z  }|S )Nr   ri  r  z2{}, parallel for-loop {} has nested Parfor(s) #{}.r   )r  rN   rK   rL   r  r  rX  r   r   r  rc   r(  ru  r  r  r  r  )r   r  r  r  r  r  r  r  r  r  r  r  keylistrw  first_non_init_blockr  rz  s                    rg   r  r    s1   ''F
!&
)
)Cv&&GVW^W^LLH%fnkJJMJJI1}}' 	A.< 8NN!7  ()/fiJ*@ *@A A A "&j!1!1FI   X]]__%%GJ"1:.,x7K*+k9FMri   c              #   j   K   t          |           D ] \  }}t          |t                    r||fV  !d S rq   )r;  r   rl  r  s      rg   r  r    sI      T??  4dF## 	T'MMM ri   c                     t          t          | |j                  }t          |t          j                  r,|j        dk    r!d |j        D             d |D             k    rdS dS )Nrs  c                     g | ]	}|j         
S ra   r  r  s     rg   rh   z&_is_indirect_index.<locals>.<listcomp>  s    ,,,qAF,,,ri   c                     g | ]	}|j         
S ra   r  r  s     rg   rh   z&_is_indirect_index.<locals>.<listcomp>  s    0N0N0NA0N0N0Nri   TF)r;   r?   rZ  r   r	   r  rp  r  )r  r   nest_indices	index_defs       rg   _is_indirect_indexr    si    nguz::I)RW%% ),-*G*G,,IO,,,0N0N0N0N0NNN45ri   c           
         | D ]}|j         D ]}t          |t          j        t          j        f          rt          |          }t          |t          j                  r<|j        |k    st          |||          r |	                    |j
        j                   |	                    |j
        j                   t          |t          j                  rt          |j        t          j                  r|j        j        dv r|j        j        }	|j        j        j        }
t          |	t          j                  r3|	j        |k    st          ||	|          r|	                    |
           _|	                    |
           vt          |t                     r+t#          |j                                        |||||           d S )Nr  )r  r   r	   rR  r-  rH  rg  rZ  r  r  r  r  r  r  rp  r   rl  ,get_array_indexed_with_parfor_index_internalrx  r  )rx  r   ret_indexedret_not_indexedr  r  r  r  setarray_indexgetarray_indexgetarray_names              rg   r  r    s     " "H !	 !	D$!12: >??  !.t!4!4~rv66 :#(E11' '%' ' 2
  OODK$45555#''(89999T29-- TZ11*-#@@@!%!1 $
 0 5~rv66 7#(E11' '%' ' 2
  OOM2222#''6666D&)) <N))++#   7!	" "ri   c                 j    t                      }t                      }t          | |||||           ||fS rq   )r  r  )rx  r   r  r  r  r  s         rg   #get_array_indexed_with_parfor_indexr  G  sG     %%KeeO0   ''ri   c                    t          | j                                                  }g }| j                                        D ]s}|j        D ]i}t          |t          j        t          j        f          rAt          |          j
        | j        j
        k    r|                    |j        j
                   jtt          t          |          t          |          z            }t!          |          S )zhget arrays that are written to inside the parfor and need to be passed
    as parameters to gufunc.
    )r   rx  r  r  r  r   r	   rR  r-  rH  rZ  ry  rf  r  r  r  r  )r   parfor_params
last_labeloutputsr  r  s         rg   get_parfor_outputsr  W  s     V%**,,--JG&&(( 1 1H 	1 	1D4""2BJ!?@@ 1d##(F,<,AAAt{/000	1
 3w<<#m"4"4455G'??ri   _RedVarInfor   reduce_nodesredopT)frozenc	                    |i }|g }|t          t                    }|t          t                    }|i }t          |          }	t          |	          }
|
dd         }
t	          |           t          |
          D ]}t          |j        |         j                  D ]`}t          |t          j
                  r|j        j        |v s|j        j        |v r|j        }|j        }|j        |v r|n||j                 }g }t          |t          j                  r	|j        g}n=t          |t          j                  r#d |j                                        D             }||                             |           |D ]}|||<   t%          j        |          }|j        |v r||j                 ||j        <   ||                             |           t          |t*                    rt-          | |||||d||	  	         b|                                D ]\  }}|j        }||v r||vr||                                          t3          |||         |           }|[|                    |           t5          ||           t7          t8          |          }||\  }}nd}d}t;          |||          ||<   ||fS )zfind variables that are updated using their previous values and an array
    item accessed with parfor index, e.g. s = s+A[i]
    Nr   c                     g | ]	}|j         
S ra   r  r!  s     rg   rh   z)get_parfor_reductions.<locals>.<listcomp>  s     H H HA H H Hri   r  )r   r  r  r0   r  r"  rx  r  r   r	   r  r  rZ  r  rg  r  ri  r  r  r  rf  rl  rY  r  r$  get_reduce_nodes%check_conflicting_reduction_operatorsr;   get_reduction_initr  )r  r   r  r  
reductionsreduce_varnames
param_usesparam_nodesvar_to_paramr  r  r  r  r  r  	cur_param	used_varsr  stmt_cpparam
param_namer  gri_outr   r  s                            rg   rY  rY  p  s)    
  &&
!$''''F ((JABBJ   *%% R RV-e49:: 	R 	RD4++ 7)]::)\99kj#&8}#<#<CC,sxBX		c26** I!$
IIRW-- I H H1E1E1G1G H H HI9%,,Y777" 0 0A&/LOO---:**/8/DIgm,I&--g666$'' R%gt]I{LR R R-	R2 ',,..  y Z
""z'H'H&&(((+E;u3EwOOL '&&z2225e\JJJ 2LAA&&-OHee#H E)4%!-* * *
:& J&&ri   c                 ,   d}|D ]}t          |t          j                  rrt          |j        t          j                  rS|j        j        dk    rC||j        j        }Z||j        j        k    r$d| j        z  }t          j	        ||j
                  dS )zIn prange, a user could theoretically specify conflicting
       reduction operators.  For example, in one spot it is += and
       another spot *=.  Here, we raise an exception if multiple
       different reduction operators are used in one prange.
    Nr  zCReduction variable %s has multiple conflicting reduction operators.)r   r	   r  r  r  rp  fnr2  r   rt  rq  )r	  nodesfirst_red_funcnoder  s        rg   r  r    s     N 
H 
HtRY'' 		Htz27++		HJM?**%!%!TZ]222494JKC 8dhGGG
H 
Hri   c                    t          t          |           dk               t          t          d |                     d         j        }t          t          |t          j                  o|j        dv            |j	        }|j        dk    rs|t          j        k    rt          j        }nV|t          j        k    rt          j        }n9|t          j        k    rt          j        }n|t          j        k    rt          j        }|t          j        k    s|t          j        k    rd|fS |t          j        k    s|t          j        k    rd|fS dS )z^
    Get initial value for known reductions.
    Currently, only += and *= are supported.
    r   c                 @    t          | j        t          j                  S rq   )r   r  r	   r  r  s    rg   r8  z$get_reduction_init.<locals>.<lambda>  s    Z%A%A ri   r  )r  r+  r+  r   NN)r<   r   r  rV  r  r   r	   r  rp  r  rA  r  iaddsubisubmulimulr  itruediv)r  acc_expracc_expr_fns      rg   r   r     s!   
 CJJ!O FAA5IIJJ2NTHJx))Whk=W.WXXX+K{g(,&&"-KKHL(("-KKHL(("-KKH,,,"+Khm##{hm'C'C+~

&
&
*
*
*+~:ri   c                    | j         dk    s| j         dk    r| j        t          j        k    s| j        t          j        k    rt          j        d| j                  t          j        t          j	        t          j
        t          j        t          j        t          j        t          j        t          j        g}| j        |v S | j         dk    rt!          t"          ||           }|dv rdS dS )Nr  r+  zParallel floordiv reductions are not supported. If all divisors are integers then a floordiv reduction can in some cases be parallelized as a multiply reduction followed by a floordiv of the resulting product.r  ))r   r   )r   r   )r   numba.np.npdatetime_helpers)r   r  TF)rp  r  rA  	ifloordivfloordivr   NumbaValueErrorrq  r  r  r  r  r  r  r  r  r;   r9   )rm   r  suppsr  s       rg   supported_reductionr"    s    t!$'//48%%%1B)B)B( +7 :;	@ @ @
 "!# tu}tv~~33 
 
 
 45ri   c                    d}i dfd	fd| j         | j        }t          |          D ]\  }}|j        }|j        }||j         <   t          |t          j                  r|j         v r |          }t          |t          j                  rDt          fd|
                                D                       }	|	v r|dz   t          |          k     rt          ||dz            t          j                  r||dz            j        j        |k    rd}
t          ||dz   d                   D ]4\  }}t          |t          j                  r|j        |k    r
||z   dz   }
 n5|
7|d|dz            ||
|
dz            z   ||dz   |
         z   ||
dz   d         z   }|dz   t          |          k     r<t          ||dz            t          j                  r||dz            j        j        |k    s|j        |k    rt          d|d          t          ||          st          d|z   d	z             fd
t          |          D             }fd|D             }t          |          dk    sJ d |D             }t!          |          }t          j        |j        dz   |j                  ||d         <   t'          ||           ||d         } n|S )z
    Get nodes that combine the reduction variable with a sentinel variable.
    Recognizes the first node that combines the reduction variable with another
    variable.
    NTc                                          | j        d          }t          |t          j                  r||}n||k    rdS  ||          S |s|| n|S )zeLookup definition of ``var``.
        Returns ``None`` if variable definition forms a cycle.
        N)r  )r  rZ  r   r	   rg  )r   varonlyr  lookedup_varcyclic_lookupdefss       rg   r'  z'get_reduce_nodes.<locals>.cyclic_lookup  st     xx$//lBF++ 	N}$,&&t =U;;;;"Ml&:33Mri   c                  :     | i |}|t          d          |S )zZSimilar to cyclic_lookup but raise AssertionError if a cycle is
        detected.
        Nzunexpected cycle in lookup())r  )r|   kwargsr  r'  s      rg   noncyclic_lookupz*get_reduce_nodes.<locals>.noncyclic_lookup$  s2     mT,V,,; !?@@@
ri   c              3   :   K   | ]} |d           j         V  dS TNr  )re   r  r+  s     rg   r  z#get_reduce_nodes.<locals>.<genexpr>6  sG       4 4 +*1d338 4 4 4 4 4 4ri   r   zUse of reduction variable z? other than in a supported reduction function is not permitted.z& in an unsupported reduction function.c                 6    g | ]}|j          |d           fS Tr  )re   rm   r+  s     rg   rh   z$get_reduce_nodes.<locals>.<listcomp>n  s>     6 6 6 !1!1!T!:!:; 6 6 6ri   c                 0    g | ]\  }}|j         k    |S ra   r  )re   rm   rf   rZ  s      rg   rh   z$get_reduce_nodes.<locals>.<listcomp>p  s$    IIIv14ri   c                 2    g | ]\  }}||j         k    ||fS ra   r  r  s      rg   rh   z$get_reduce_nodes.<locals>.<listcomp>r  s'    CCCFQa16kk!Qkkkri   z#initr   r-  )rZ  r2  r;  r  r  r   r	   rg  r  r  ri  r   r  r'  r"  get_expr_argsr  r  rq  r(   )reduction_noder  r  r  r2  r   r  r  r  in_varsfoundjr   jstmtr|   non_red_argsreplace_dictr'  r(  rZ  r+  s                   @@@@rg   r  r    s    LDN N N N N N N     D%6U## H H4kjSXc26"" 	%sx4'7'7-$$Cc27## B	 4 4 4 4#&==??4 4 4 4 4Gw& ECJJ&&$U1q5\29== '1q5\(9=MMM!F$-eAEFFm$<$< 	" 	"5 &eRY77 "EK3<N<N &'UQYF!E) "'vAv!&vfqj'8!9":!&q1uV|!4"5 "'vz{{!3"4
 1s5zz))jqsRY.O.O)!!A#J->BRRR04DDD$%5E % % %   +388 Q$&BEU&U&N'O Q Q Q6 6 6 6!.s!3!36 6 6IIIIIII<((A----CCdCCC#Dzz02sy$w,PSPW0X0X\!_-"3555$QRRyri   c                     | j         dv r| j        | j        gS | j         dk    rd | j        D             S t	          d                    |                     )z-
    Get arguments of an expression node
    )r+  r  r  c                     g | ]}|S ra   ra   r!  s     rg   rh   z!get_expr_args.<locals>.<listcomp>  s    %%%a%%%ri   zget arguments for expression {})rp  r  r  r|   r  r(  )r  s    rg   r2  r2  z  sa     w,,,$(##w&%%49%%%%
?FFtLL
M
MMri   c                    | j         D ]}|d         dk    r|d         d         }t          t          |                    D ]<}t          ||         t          j                  rt          ||         ||          ||<   =|d         d         }t          t          |                    D ]<}t          ||         t          j                  rt          ||         ||          ||<   =d S )Nr   rM  r   )r|  rz   r   r   r	   rg  r*   )r   callbackcbdatar  left_lengthsr   right_lengthss          rg   visit_parfor_pattern_varsr@    s   ? N N1:"""1:a=L3|,,-- N Nl1orv66 N&6|A<Df'N 'NLO#AJqMM3}--.. N NmA.77 N'7a8H<Df(N (NM!$N Nri   c                    t           j        dk    r?t          d|            t          dt          |                                                     | j        D ]}t          |j        ||          |_        t          |j	        t          j                  rt          |j	        ||          |_	        t          |j        t          j                  rt          |j        ||          |_        t          |j        t          j                  rt          |j        ||          |_        t          d| j        i||           t!          | ||           t          | j        ||           d S )Nr   zvisiting parfor vars for:zcbdata: r  )r   r/  rc   r  r  rv  r*   r_  r   r  r	   rg  r  r  r)   rw  r@  rx  )r   r<  r=  rn   s       rg   visit_vars_parforrB    s7   "")6222j&00111 @ @+A,<hOOagrv&& 	B&qw&AAAGafbf%% 	@%afh??AFafbf%% 	@%afh??AFF%&&999fh777v6222
Fri   c                 x   |t                      }|t                      }t          |           }t          |          \  }}t          |          }t	          |                                          }t          |            |                                }|                                |         }	|	                                
                                D ]}
|	|
j        z  }	|D ]^}||	v r:|                    ||         |z
             |                    ||                    @|                    ||         |z
             _d | j        D             }|d | j        D             z  }|d | j        D             z  }|                    ||z
             |t          |           z  }t          j        ||          S )zzlist variables written in this parfor by recursively
    calling compute_use_defs() on body and combining block defs.
    Nc                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   r   r  r	   rg  rZ  re   rn   s     rg   r  zparfor_defs.<locals>.<setcomp>  D       :GRV4 4	  ri   c                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   r   r  r	   rg  rZ  rF  s     rg   r  zparfor_defs.<locals>.<setcomp>  D       *FBF3 3	  ri   c                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   r   r  r	   rg  rZ  rF  s     rg   r  zparfor_defs.<locals>.<setcomp>  rJ  ri   )r  r  )r  r  rK   rN   r   r  r  r  
dominatorsr  r  r  r*  rv  get_parfor_pattern_varsr   _use_defs_result)r   use_setdef_setr  usesr(  r  r  r  definitely_executedr  r  	loop_varss                rg   parfor_defsrU    s    %%%%''F!&))JD$
!&
)
)CV[[]]##J    !!J..**:6		""$$ ) )ty( 	2 	2'''
 NN4;0111NN4;''''NN4;01111 $/  I   #.   I   #.   I NN9w&'''&v...G$GGDDDDri   c                     |t          | j                  z  }t          |           }|t          j        |          z  }t          |            dS )zx
    Reduction variables for parfors and the reduction variables within
    nested parfors must be stack allocated.
    N)r  r~  r  r   must_use_allocar  )r   
alloca_setr  s      rg   _parfor_use_allocarY    sN    
 #fn%%%J''F(*6222J     ri   c                 V   t          |           }t          |          }t          |          }t          |||j        |j                  }t          ||||j                  }d | j        D             }|d | j        D             z  }|d | j        D             z  }|d | j        D             z  }t                      }|	                                D ]v}	|j
        |	xx         |z  cc<   |j
        |	xx         |z  cc<   ||j
        |	         z  }|j        |	xx         |z  cc<   |j        |	xx         |z  cc<   ||j        |	         z  }w G d dt                    }
t          j         |
|                    }|                    |j
        |j                   t!          |            ||z  S )z~insert dels in parfor. input: dead variable set right after parfor.
    returns the variables for which del was inserted.
    c                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   rE  rF  s     rg   r  z%parfor_insert_dels.<locals>.<setcomp>  rG  ri   c                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   rI  rF  s     rg   r  z%parfor_insert_dels.<locals>.<setcomp>  rJ  ri   c                 d    h | ]-}t          |j        t          j                  !|j        j        .S ra   rL  rF  s     rg   r  z%parfor_insert_dels.<locals>.<setcomp>  rJ  ri   c                 &    h | ]}|j         j        S ra   r_  rZ  rF  s     rg   r  z%parfor_insert_dels.<locals>.<setcomp>  s    CCCA!"'CCCri   c                       e Zd Zd ZdS )'parfor_insert_dels.<locals>.DummyFuncIRc                     || _         d S rq   )r  r  s     rg   ra  z0parfor_insert_dels.<locals>.DummyFuncIR.__init__  s     DKKKri   N)r~   r   r   ra  ra   ri   rg   DummyFuncIRra    s#        	! 	! 	! 	! 	!ri   rc  )r  rN   rK   rL   r  r  rM   rv  r  r  r  escapingobjectr   PostProcessor_patch_var_delsr  )r   curr_dead_setr  r  r  r  dead_maprT  dead_setr  rc  	post_procs               rg   parfor_insert_delsrl    s+     ''F
!&
)
)Cv&&GVW^W^LLH fhGGH $/  I   #.   I   #.   I CC1BCCCCI uuH - -%   M1   %   I-   H%e,,%   M1   %   I-   H%e,,! ! ! ! !f ! ! ! &{{6':':;;Ih/1BCCC   iri   c           	          t          |          \  }}t          || j        ||           \  }}|                                D ]}d}	|	rt	          | |||||          }	|	dS )zm
    Reorder statements to maximize parfor fusion. Push all parfors up or down
    so they are adjacent.
    TN)r3   rH   	arg_namesr  maximize_fusion_inner)
r  r  r  rU  r  r  	alias_maparg_aliasesr  order_changeds
             rg   rZ  rZ  !  s    
 #6**MJ3!'!(!2!(!(	 I{  
 
 	1 ' % * ) + , M  	
 
ri   c                 H   d}d}|t          |j                  dz
  k     r|j        |         }|j        |dz            }	|rt          ||	| |||          nt          |	|| |||          }
|
r|	|j        |<   ||j        |dz   <   d}|dz  }|t          |j                  dz
  k     |S )NFr   r   r   T)r   r  _can_reorder_stmts)r  r  r  rp  rq  rU  rr  r   r  r`  can_reorders              rg   ro  ro  9  s    M	A c%*oo!
!
!z!}JqsO	 (E)$	7*4iN N N-?	4Y.E .E 	  	!%EJqM"EJqsO M	Q c%*oo!
!
! ri   c                     t                      }| D ]O}||v r|                    ||                   }||v r|                    |          }|                    |           P|S rq   )r  r  r  )the_setrp  rq  retr   s        rg   expand_aliasesry  M  sj    
%%C  	>>))IaL))C))K((C



Jri   c                    t          | t                    r<t          |t                    s&t          |t          j                  st          |t          j                  r=t          |j        t                      |          st          t          ||j                  rt          d |                                 D             ||          }t          t          |           ||          }t          d |                                D             ||          }t          t          |          ||          }	t          ||z  |	|z  z            dk    rdS dS )zw
    Check dependencies to determine if a parfor can be reordered in the IR block
    with a non-parfor statement.
    c                     h | ]	}|j         
S ra   r  r!  s     rg   r  z%_can_reorder_stmts.<locals>.<setcomp>g  s    'I'I'I1'I'I'Iri   c                     h | ]	}|j         
S ra   r  r!  s     rg   r  z%_can_reorder_stmts.<locals>.<setcomp>k  s    'N'N'N1'N'N'Nri   r   TF)r   rl  r	   rm  r  r6   r  r  r;   is_assert_equivry  ri  get_parfor_writesr1   r   )
r  r`  r  r  rp  rq  stmt_accessesstmt_writesnext_accessesnext_writess
             rg   rt  rt  W  s]    	4   9f--9bh// Iry11 ")/355*EE	
 _gy?? ''I'I8H8H'I'I'I'0+? ?$%6t%<%<%.= =&'N'N	8K8K8M8M'N'N'N'0+? ?$_Y%?%?%.= =m+.0 1 1456 645ri   c                 4    t          | |          \  }}|dk    S )NrX   )r9   )r  r  r>  r  s       rg   r}  r}  t  s!    '66Ix&&ri   c                    t          | t                    sJ t                      }| j                                        }| j        |d<   |                                D ]e}|j        D ][}|                    t          |                     t          |t                    r"|                    t          |                     \f|S r  )r   rl  r  rx  r  rw  r  r  r*  r1   r~  )r   writesr  r  r  s        rg   r~  r~  y  s    ff%%%%%UUF""$$F"F2J 7 7J 	7 	7DMM/$//000$'' 7/55666	7 Mri   FusionReport)firstsecondmessagec           
          t          d|d|           d}|j        |j        k    r0t          d           d}t          |j        |j        |          }d|fS t	          |j                  t	          |j                  k    rst          d           d}d}||j        t	          |j                  fz  }	||j        t	          |j                  fz  }
t          |j        |j        ||	|
fz            }d|fS t	          |j                  } fd	}fd
}t          |          D ]}|j        |         }|j        |         } ||j        |j                  r, ||j        |j                  r ||j	        |j	                  st          d|           d}|d ||j                  d ||j                  d ||j	                  dz  }|d ||j                  d ||j                  d ||j	                  dz  }t          |j        |j        ||z            }d|fc S 	t          |j                  |_        t          ||          \  }}}}|st          |||||          d         }nd}|s|r?t          d           d}t          |j        |j        ||j        |j        fz            }d|fS t          |j                  }t!                      }|j                                        D ]}||z  }|t'          |          z  }|t!          |j                  z  }t          |j                  }t          d|j        i          j        d         }|j                                        D ]}||z  }|                    |          }t	          |          dk    rt1          |j                                        |j        j        |                                |          \  }fd|D             }t9          |          r?t          d           d}t          |j        |j        ||j        |j        fz            }d|fS t;          ||          S )zItry to fuse parfors and return a fused parfor, otherwise return None
    ztry_fuse: trying to fuse 
r5  Nz$try_fuse: parfors different lowerersz!- fusion failed: lowerer mismatchz/try_fuse: parfors number of dimensions mismatchz4- fusion failed: number of loops mismatched, %s, %s.z(parallel loop #%s has a nest of %s loopsc                 <    | |k    p                     | |          S rq   )is_equiv)rm   rf   r{  s     rg   r  ztry_fuse.<locals>.is_equiv  s"    Av1++Aq111ri   c                     t          | t          j                  s| S | j        } dv r| d         v rd         |          }|S | S )z.get original variable name by user if possiblevar_rename_map)r   r	   rg  rZ  )r  user_varnamer  s     rg   get_user_varnamez"try_fuse.<locals>.get_user_varname  sY    !RV$$ 	HFx''A:J1K,K,K#$45a8Lri   z/try_fuse: parfor dimension correlation mismatchz7- fusion failed: loop dimension mismatched in axis %s. zslice(r  z) != rk  r   Tz1try_fuse: parfor cross iteration dependency foundzK- fusion failed: cross iteration dependency found between loops #%s and #%sc              3   b   K   | ])}t          |         t          j                   p|v V  *d S rq   )r   r   r`  )re   rm   p2arraynotindexedr  s     rg   r  ztry_fuse.<locals>.<genexpr>  sC      ssfg*WQZ1FGGGa1PaKassssssri   z)try_fuse: parfor2 depends on parfor1 bodyzT- fusion failed: parallel loop %s has a dependency on the body of parallel loop %s. )dprintr  r  ru  r   rv  rz   r  r  r  r@   r  rW  has_cross_iter_deprK   rx  r  r  r  r~  r~  rw  r  r  r  ry  rZ  r  r&  fuse_parfors_inner) r{  parfor1parfor2r  r  r  r  r  r  r  r  rv  r  r  r   nest1nest2p1_cross_depp1_ipp1_ia	p1_non_iap2_cross_depp1_body_usedefsp1_body_defsr(  
p2_usedefsp2_usesrR  overlapr  
unsafe_varr  s    `  ` `                         @rg   r]  r]    s    ('4AAA F '/))56661gj'*c::V| 7#g&8"9"999@AAAD8GJG$6 7 788GJG$6 7 788gj'*cRHnEEV|"##E2 2 2 2 2     5\\    "1%"1%ek22 
	 UZ00
	 UZ00
	  DaHHHKCC.>.>u{.K.K.K.K  ,,,,.>.>uz.J.J.J.JL LCC*:*:5;*G*G*G*G  ,,,,.>.>uz.J.J.J.JL LC!'*gj#'BBF<
	  -W^<<G,>wQX,Y,Y)L%	 )'7GUES\]]^_` | BCCC,gj'* #wz7:&> >@ @V|
 'w'899O55L&--//  %g...L C(((L!'"344J7#5677>qAG!((**  4''00G
7||qB$$&&"&&((	    tsssskrsss
z?? 	 >???1C!'*gj$'7:wz*B$BD DF<gw///ri   c                    | j         j                            |j         j                   t          |j                                                  }|j        |         j        }t          | j                                                  }t          | j                                                  }| j        |         j                            |           | j                            |j                   | j                            |           t          | j
                  }|j        j        | j        i}t          |          D ],}| j
        |         j        ||j
        |         j        j        <   -t          | j        |           t!          | |          }	t#          |	          }	t%          | |	           t'          d |                                D                       }
t+          | j        |
           | j                            |j                   t.          j        r-t3          d                    |j        | j                             d}|                    |j        | j                  }t9          | j        |j        |          }| |fS )N)entry_labelc              3   $   K   | ]}|j         V  d S rq   r  r  s     rg   r  z%fuse_parfors_inner.<locals>.<genexpr>  s$      66Q!&666666ri   z1Parallel for-loop #{} is fused into for-loop #{}.zE- fusion succeeded: parallel for-loop #{} is fused into for-loop #{}.)rw  r  r  r   rx  r  r   r*  r  r   rv  ry  rZ  rz   r_  r'   r  r2   r  r  r  remove_duplicate_definitionsr|  r   r  rc   r(  ru  r  )r  r  parfor2_first_labelparfor2_first_blockparfor1_first_labelparfor1_last_labelrv  
index_dictr   r  namesetr  r  s                rg   r  r    s\    ""7#5#:;;; g/446677!+,?@Eg/446677W.335566().556IJJJ W.///-... "##E#('*;<J5\\  @G@RA 	7%a(7<=="J///  5HIIIF6""F&)))66*"3"3"5"566666G !2G<<<G,---# 'AHHj'*& & 	' 	' 	' RC
**WZ
,
,C'*gj#66FF?ri   c                 2   |                                  D ]\  }}|j        }g }t                      }|D ][}t          |t          j                  r*|j        j        }||v r||v r1|                    |           |	                    |           \||_        dS )zsRemove duplicated definition for variables in the given nameset, which
    is often a result of parfor fusion.
    N)
r  r  r  r   r	   r  r  rZ  r  rf  )	r  r  r  r  r  r  definedr  rZ  s	            rg   r  r  !  s       uz%% 	" 	"D$	** &{'7??w KK%%%OOD!!!!


Fri   c           
      d   d | j         D             t                      }|i }|t                      }|t                      }d fd}| j                                        D ]>}|j        D ]2}	t          |	t          j        t          j        f          rYt          |	j	        j
                 t          j        j                  r) ||	j        |	j	        j
        ||||          r
d|||fc c S t          |	t          j                  rt          |	j        t          j                  r/|	j        j
        v r                     |	j	        j
                   t          |	j        t          j                  r'|	j        j        }
|
dv rit          |	j        j        j
                 t          j        j                  r3 ||	j        j        |	j        j        j
        ||||          r
d|||fc c S |
dk    r<t+          fd|	j                                        D                       r
d|||fc c S d |	j                                        D             }                    |          r|                    |          s|                    |	j	        j
                   4@d	|||fS )
Nc                 &    h | ]}|j         j        S ra   r_  rF  s     rg   r  z%has_cross_iter_dep.<locals>.<setcomp>I  s    @@@q$@@@ri   c                    t          | t                    rt          |           } d| vr||v rdS |                    |           dS ||v rdS |                    |           t	          |           }||vr| ||<   dS ||         | k    S )aA  Returns True if there is a reason to prevent fusion based
           on the rules described above.
           new_position will be a list or tuple of booleans that
           says whether the index in that spot is a parfor index
           or not.  array_accessed is the array on which the access
           is occurring.TF)r   r  r  r  r   )new_positionarray_accessedindex_positionsindexed_arraysnon_indexed_arraysnpsizes         rg   add_check_positionz.has_cross_iter_dep.<locals>.add_check_positionk  s     lD)) 	/ ..L |## //t #&&~666u
 ///4>***\""(( '3OF#5 v&,66ri   c                    t          | t          j                  rt          | j                 t          j                  rZt          t          |           }|@|\  }}t          fd|D                       rfd|D             }	 
|	||||          S dS dS | j        v r 
d||||          S | j        v rdS  
d||||          S dS )zLooks at the indices of a getitem or setitem to see if there
           is a reason that they would prevent fusion.
           Returns True if fusion should be prohibited, False otherwise.
        Nc                 4    g | ]}|j         v p|j         vS ra   r  )re   rm   derived_from_indicesr  s     rg   rh   z;has_cross_iter_dep.<locals>.check_index.<locals>.<listcomp>  sF     M M M?@ Vw. ;&::M M Mri   c                 "    g | ]}|j         v S ra   r  )re   rm   r  s     rg   rh   z;has_cross_iter_dep.<locals>.check_index.<locals>.<listcomp>  s     .R.R.RQqv/@.R.R.Rri   Tr/  F)r   r	   rg  rZ  r   r  r;   r:   allr   InternalError)
stmt_indexr  r  r  r  r  fbs_resind_seqr  new_index_positionsr  r  r  r  s        `    rg   check_indexz'has_cross_iter_dep.<locals>.check_index  sq    j"&)) 4	'*/2EODD /B 3WjII&!(JGQ  M M M M MDKM M M N N $ /S.R.R.R'.R.R.R+  212E2@2A2@2D	 F  F F  $t  4 ?g-- .-g.<.=.<.@	B B B
  _(<<<  4
 .-h.<.=.<.@	B B B 4ri   Tr  r  c                 d    g | ],}t          |j                 t          j        j                  -S ra   )r   rZ  r   r   r   )re   rm   r  s     rg   rh   z&has_cross_iter_dep.<locals>.<listcomp>  s>     != != != ! ",GAFOU^=Q!R!R != != !=ri   c                     g | ]	}|j         
S ra   r  r  s     rg   rh   z&has_cross_iter_dep.<locals>.<listcomp>  s    GGG1GGGri   F)rv  r  rx  r  r  r   r	   r-  rR  r  rZ  r   r   r   r   r  r  rg  r  r  rp  r&  ri  
isdisjoint)r   r  r  r  r  r  r  r  r   r  rp  rhs_varsr  r  s    ``         @@rg   r  r  5  s]   ( A@f.?@@@G
 55, ! UU07 07 07dDJ DJ DJ DJ DJ DJ DJ DJN $$&& 6C 6CF 5	C 5	CD$R-= >?? 3Cgdk&679MNN Y"{4:#';#3#2#1#5#79 9 Y  $_nFXXXXXXXD"),, 'C dj"&11 $Cz'11DK$4555  2  
BG44  CB:::%gdj.>.C&DenFZ[[ a*{4:+;+/:+;+@+:+9+=+? A  A a (,_nN`'` ` ` ` ` ` v   != != != !=%)Z%9%9%;%;!= != != > > ]#'.J\#\\\\\\  HG
0D0D0F0FGGGH $..x88 C0;;HEEC,001ABBBk5	Cn />3EEEri   c                  <    t           j        dk    rt          |   d S d S r  )r   r/  rc   )r   s    rg   r  r    s%    ""q				 #"ri   c                     t                      }| j        D ]f}|d         dk    rX|d         d         }|d         d         }||z   D ]6}t          |t          j                  r|                    |j                   7g|S )z: get the variables used in parfor pattern information
    r   rM  r   )r  r|  r   r	   rg  r  rZ  )r   outr  r>  r?  r  s         rg   rN  rN  #  s     %%C? $ $1:"""1:a=L#AJqMM!-/ $ $a(( $GGAFOOOJri   c                 *	   t          | j                  5  t          | j                  }ddd           n# 1 swxY w Y   |d         }i }	t          | j        |         j        | j        ||	|           t          |	                                          }
|D ]}||k    r	| j        |         j        D ]}t          |t          j
                  rOt          |j        t          j                  r0|j        j        dk    r |j        j        j        | j        j        k    rkt          d |                                D                       }||
z  }|D ]}|	                    |d           |D ]G}||k    r	| j        |         }|	                                }t          |j        | j        |||           H| j                                        }t'          |                                          }t)          |||          \  }}t          j        |t          j        dd                    }||         j                            |           t1          |          }t3          |          }t5          |||j        |j                  }t          |                                          }|                                D ]3\  }}g }d |j                                        D             }|                    |          D ]\  }}|||         z  }tA          |j                  D ]}||z  } | D ]}!|||!         z  }t          |t          j!        t          j"        f          r?tG          |          j        | j        j        k    r|j$        j        |vr|j$        j        |vr||d |                                D             z  }|                    |           |%                                 ||_        5|                    |j                   ||         j                                         	 tM          | |||||           tO          | j(        j                  dk    }"| j        )                                D ]}|"tO          |j                  dk    z  }"|"rdS | S )	z7 remove dead code inside parfor including get/sets
    Nr   r*  c              3   $   K   | ]}|j         V  d S rq   r  r!  s     rg   r  z%remove_dead_parfor.<locals>.<genexpr>O  s$      <<a16<<<<<<ri   parfors_dummyr  c                     h | ]	}|j         
S ra   r  r!  s     rg   r  z%remove_dead_parfor.<locals>.<setcomp>n  s    AAAqAFAAAri   c                     h | ]	}|j         
S ra   r  r!  s     rg   r  z%remove_dead_parfor.<locals>.<setcomp>|  s    :::A:::ri   )*r6  rx  r0   _update_parfor_get_setitemsr  ry  r  r  r   r	   r  r  r  rp  r   rZ  ri  r  r  r   _add_liveness_return_blockrc  Locrf  rN   rK   rL   r  r  r  
terminator
successorsr"  rR  r-  rH  r  r$  remove_dead_parfor_recursiver   rw  r  )#r   liveslives_n_aliasesrq  rp  r  r  r  r;  first_block_saved_values
saved_arrsrn   r  varnamesrm_arrsr   r  saved_valuesr  r  return_labelrw  jumpr  r  r  	alias_setr  r  in_livesout_blk_dataalias_livesr  is_emptys#                                      rg   remove_dead_parforr  1  s    
#6#3	4	4 3 3 !1223 3 3 3 3 3 3 3 3 3 3 3 3 3 3 )K!%*) 	
 
 
 -224455J 6 6$Q', 	6 	6D4++ 
4:rw0O0O 
22
(-1A1FFF<<4>>+;+;<<<<<H+G 6 6(,,Q55556	6  G G #/4466#EJ0@)(4o	G 	G 	G 	G
 ""$$FV[[]]##J8RYZZL)7<!<!<==D
:""4(((
!&
)
)Cv&&GVW^W^LLHINN$$%%I  uAAE$4$>$>$@$@AAA!nnU33 	* 	*NGU))HHUZ(( 	" 	"D"Y.K  ) )IaL(4""2BJ!?@@ d##(F,<,AAA 00 33::)9)9::::HOOD!!!!

KK	
:!!! !{IwA A A 6$)**a/H!((** ) )C
OOq(( tMs   6::c                 j   | D ]}t          |t          j        t          j        f          ryt	          |          j        |j        k    r\|j        j        |vrN|                    |j        j        g           D ]}|                    |d           |j	        ||j        j        <   t          |t          j
                  rt          |j	        t          j                  rm|j	        }|j        dk    r[t          |j        t          j                  r<|j        j        |j        k    r'|                    |j	        j        |          |_	        H|                                D ]Q}|                    |j        d           |                    |j        g           D ]}|                    |d           RdS )zS
    replace getitems of a previously set array in a block of parfor loop body
    Nr*  )r   r	   rR  r-  rH  rZ  r  r  r  r  r  r  rp  r   rg  ri  )	
block_bodyry  rp  r  r  r  wr  r  s	            rg   r  r    s   
  * *tb.
;<< 		$$	66KE))]]4;#3R88 * *  D)))) .2ZL)*dBI&& 	:dj"'+J+J 	*Cv""z#)RV'D'D"9>Y^33!-!1!1#).#!F!FDJ !! 	* 	*AQVT***]]162.. * *  D))))*	* Fri   c           	         | j                                         }t          |                                          }|dk    sJ t	          |                                          }	 t          |||          \  }	}
||         j        }t          j        |t          d          t          j
        dd                    }t          j        ||j        <   t          j        |||	t          j
        dd                    }||         j                            |           | j        |d<   |d         j                            t          j        |t          j
        dd                               t'          ||||||           |                    |
j                   |d         j                                         ||         j                                         dS )zIcreate a dummy function from parfor and call remove dead recursively
    r   z$branchcondr  r  N)rx  r  r   r  r   r  r  r	   rg  r    r  r   booleanrZ  rb  r  rf  rw  rc  r+   r  )r   r  rq  rp  r  r  r  r  r  r  rw  r  
branchcondbranchs                 rg   r  r    s    ""$$F6;;==))aV[[]]##J
 9PPL) :$E}];;RVOUW=X=XYYJ$}GJOYz#3\26/[]C^C^__F
:""6*** !F1I
1IN"'"2BF?B4O4OPPQQQ Wgy+NNNKK	
1IN
:!!!
Fri   c                   	 t          |                                           }|dz   }| |         j        | |         j        	t	          j        	          | |<   t	          j        	t          d                    }t          j	        
                    t          j        d          ||j        <   	fd|D             }t          j                            |          }| |         j                            t	          j        ||                     | |         j                            t	          j        |                     ||fS )Nr   z
$tuple_varr   c                 <    g | ]}t          j        |          S ra   )r	   rg  )re   r  rq  r  s     rg   rh   z._add_liveness_return_block.<locals>.<listcomp>  s'    6661q#&&666ri   )r   r  rq  r  r	   r&  rg  r    r   rq  rr  ra  rZ  r  rs  r  rf  r  Return)
r  r  r  r  r  rw  r  rx  rq  r  s
           @@rg   r  r    s%   V[[]]##J>L


 C:$E8E3//F< umL993??I#.77Q GIN66666666I$$Y44J
<$$RYz9c%J%JKKK
<$$RYy#%>%>???""ri   c                 t    t          |           }t          j        ||||||           t          |            d S rq   )r  r   rH   r  )r   r|   r  r  rp  rq  r  s          rg   find_potential_aliases_parforr    sG    ''F#gw	;@ @ @   
Fri   c           
      8   d}|                                  D ]}|j        D ]u}t          |t                    r\|dz  }|}|j        t          |j                                                           }|j        }t          j	        dd          }t          j
        |t          d          |          }|j                            t          j        t          j        d|          ||                     |j                            t          j        ||                     t!          |j                  |_        |j        t          |j                                                           }|j                                         t%          |j                   w|S )z%simplify CFG of body loops in parforsr   r   r  r  $const)r  r  r   rl  rx  r   r  r  r	   r  rg  r    rf  r  r  r  r5   r  rV  )	r  r  r  r  r   
last_blockr  rq  consts	            rg   rV  rV    se   I ; ;J 	; 	;D$'' ;Q	 $-c&2B2G2G2I2I.J.JK
"(f_b11umH&=&=sCC&&ry!S1A1A5#'N'NOOO&&ry'<'<===#/0@#A#A #-c&2B2G2G2I2I.J.JK
##%%%()9:::!	;" ri   c                    | j                                         }|!t          |                                          }|dk    sJ | j        |d<   |d         j                            t          j        ||d         j	                             |
                                D ]^}t          |j                  dk    s|j        d         j        s2|j                            t          j        ||j	                             _|S )z5wrap parfor blocks for analysis/optimization like CFGNr   r  )rx  r  r   r  rw  r  rf  r	   rc  rq  r  r   is_terminator)r   r  r  r  s       rg   r  r    s    ""$$F&++--((???? !F1I
1IN"'+vay}==>>> ? ?uz??a
2(DJbgk59==>>>Mri   c                 D   |=t          |                                          }|                    |           || _        t          | j                                                  }t	          | j        j        d         t          j                  sJ | j        j                                         | j        	                                D ]V}t	          |j        d         t          j                  r/|j        d         j
        |k    r|j                                         WdS )zb
    unwrap parfor blocks after analysis/optimization.
    Allows changes to the parfor loop.
    Nr  )r   r  r  rx  r   rw  r  r	   rc  r  r  )r   r  init_block_labelr  r  s        rg   r  r  *  s    
 v{{}}--

#$$$! 6+002233f',R0"':::::     !((**  uz"~rw// 	JrN!%555JNN
Fri   c                    t          |           }t          ||          \  }}t          ||          \  }}t          |            |d         }| j                                        D ]"}|d ||         D             z  }|||         z  }#t          | j                                                  }	||	         |d         z  }
t          j        dk    rt          d|
d|           |
|fS )z&find copies generated/killed by parforr   c                     h | ]\  }}|S ra   ra   )re   rn   r7  s      rg   r  z$get_copies_parfor.<locals>.<setcomp>S  s    88841aQ888ri   r   zcopy propagate parfor gens:kill_set)
r  r,   r-   r  rx  r  r   r   r/  rc   )r   r  r  in_copies_parforout_copies_parforin_gen_copiesin_extra_killr  r  r  genss              rg   get_copies_parforr  F  s    ''F*8*I*I''#3FG#D#D M=    QH!&&(( ) )88=#78888M%(( V%**,,--JZ(=+;;D""+T:xHHH>ri   c                    t          | j                  D ]1\  }}|d         dk    r dt          |d         |          f| j        |<   2| j        D ]P}t          |j        |          |_        t          |j        |          |_        t          |j        |          |_        Qt          |           }	g }
|                                D ]G\  }}|
	                    t          j        |||         t          j        dd                               H|
|	d         j        z   |	d         _        t          |	|          \  }}t          |	|||||           t!          |            |	d         j        t#          |
          d         |	d         _        dS )z*apply copy propagate recursively in parforr   rM  r   dummyr  N)r;  r|  r(   rv  r  r  r  r  r  rf  r	   r  r  r  r,   r.   r  r   )r   var_dictname_var_tabler  r  save_copiesr   r  rn   r  assign_listlhs_namer  r   r  s                  rg   apply_copies_parforr  b  s     00 : :
71:"""+"71:x88":FOA  6 6$QWh77#AFH55#AFH55''FK!)) ; ;#29S.*B%'VGR%8%8: : 	; 	; 	; 	; 6!9>1F1IN*8*I*I''!1>7"K1 1 1   AY^C$4$4$5$56F1IN
Fri   c                    |                                  D ]?}g }t                      i }|j        D ]}fd}	|srt          |t                    r]|j        j        D ]}
 |	|
           |j                                        }t          ||d           |	                    |           } |	|           |
                                D ]}|t          |j        |          z  }|	                    |           ||_        t          |          dk    r9|                                D ]\  }}||         ||<   d|i}t          ||           AdS )zpush call variables to right before their call site.
    assuming one global/getattr is created for each call site and control flow
    doesn't change it.
    c                    t          | t          j                  r| j        }| j        }t          |t          j                  r&| |j        <                       |j                   d S t          |t          j                  rO|j	        dk    rF|j        j        v s|j        j        v r,| |j        <                       |j                   d S d S d S d S d S )Nr  )
r   r	   r  r  r  r  rZ  r  r  rp  )r  r  r  
block_defssaved_getattrssaved_globalss      rg   process_assignz&push_call_vars.<locals>.process_assign  s    dBI.. 
5*C+C"3	22 526ch/"sx00000#C11 5cf	6I6IINm;;#&9>^#C#C7;N384&NN3844444
5 
55 56I6I#C#Cri   T)nestedr   N)r  r  r  r   rl  rw  rx  r  rj  rf  ri  _get_saved_call_nodesrZ  r   r  rI   )r  r  r  r  r  r  r  rename_dictr  r  r   pblocksr  r  temp_blocksr  s    ``            @rg   rj  rj    s   
  .8 .8 UU
 J 	" 	"D5 5 5 5 5 5 5  %jv66 %- & &A"N1%%%%.--//w~wW[\\\\%%%t$$$^^%% [ [1!&-2@*k[ [ [OOD!!!!
{a#))++ ( (1$QZ

e*Kk;777
Fri   c                     g }| |vrc| |v s| |v r[d }| |v r |||          d|||           d} n0| |v r, |||          d|||           ||          j         j         j        } | |vr| |v W| |v [|                                 |S )al   Implement the copying of globals or getattrs for the purposes noted in
        push_call_vars.  We make a new var and assign to it a copy of the
        global or getattr.  We remember this new assignment node and add an
        entry in the renaming dictionary so that for this block the original
        var name is replaced by the new var name we created.
    c                    t          | t          j                  sJ t          j        | j        j        t          |          | j        j                  }t          j        t          j	        | j
                  || j                  }|                    |           |                    | j        j                   |j        j        || j        j        <   d S rq   )r   r	   r  rg  r  r  r    rq  r  r  r  rf  r  rZ  )objvar_baser  r  r  renamed_varrenamed_assigns          rg   rename_global_or_getattrz7_get_saved_call_nodes.<locals>.rename_global_or_getattr  s    c29--...&!1!.x!8!8!$1 1K  Yt}SY'?'?'2'*w0 0N LL(((NN3:?++++9+@+EK
(((ri   z$push_global_to_block_PA_DONEz$push_getattr_to_block)r  rZ  r$  )fnamer  r  r  r  r  r  s          rg   r  r    s     E
""(>(>+0N+B+B
	F 
	F 
	F M!!$$]5%9;R%*JE E EEEn$$$$^E%:<T%*JE E E"5)/5:E+ 
""(>(>+0N+B+B* 
MMOOOLri   c                    t          | t                    r| d         }t          |t                    st          |d          r|j        }nd}| d         }t          |          dk    r)d                    |t          |d                             S d|z   dz   }d                    |                    d |D                                 S t          | t          j
        j        j                  r#| j        }|                    d	          rd
|z  S |S t          | t          j
        j        j                  rt!          | j                  S dS )zMExtract operators from arrayexpr to represent it abstractly as a string.
    r   r~   r  r   z({}({}))r  z({})c                 ,    g | ]}t          |          S ra   )r  r  s     rg   rh   z"repr_arrayexpr.<locals>.<listcomp>  s     *M*M*M!N1,=,=*M*M*Mri   $z'%s' (temporary variable))r   r  r  hasattrr~   r   r(  r  r!  r   r  r	   rg  rZ  r  r  r  r  )r  oprr|   rZ  s       rg   r  r    s7    )U## l#s## 	sJ'' l|t99>>$$S.a*A*ABBB)c/C==*M*Mt*M*M*M!N!NOOO	Iuz}0	1	1 	~??3 	0477K	Iuz}2	3	3 IO$$$sri   c                 |    g }| j         D ]}|                    ||                    t          |          |_        dS )zpostproc updates generator_info with live variables after transformations
    but generator variables have types in return_type that are updated here.
    N)
state_varsrf  r  state_types)rp  r   r  new_state_typesr  s        rg   ro  ro    sK     O& + +wqz****#O44K
Fri   c                 ~    |i }|i }t          |           }t          |||          \  }}t          |            ||fS rq   )r  r3   r  )r   r  reverse_call_tabler  s       rg   get_parfor_call_tabler-    s^    
!''F%3FJ4F&H &H"J"   )))ri   c                 t    |i }t          |           }t          j        ||          }t          |            |S rq   )r  r   get_tuple_tabler  )r   tuple_tabler  s      rg   get_parfor_tuple_tabler1    s@    ''F*6;??K   ri   c                     |t                      }t          |           }t          j        ||          }t	          |            |S rq   )r  r  r   get_array_accessesr  )r   accessesr  s      rg   get_parfor_array_accessesr5    sC    55''F*68<<H   Ori   c                     t          |           }t          ||          }||         |d<   |                    |           t          | |           d S r   )r  r8   r  r  )r   r  r  s      rg   parfor_add_offset_to_labelsr7  ,  sR    ''F!&&11FvF1I
JJv(((
Fri   c                 j    t          |           }t          j        |          }t          |            |S rq   )r  r   rJ  r  )r   r  	max_labels      rg   parfor_find_max_labelr:  8  s3    ''F'//I   ri   c                    |j         }t          |           }d | j        D             }t          |                                          }||         j        fd|D             }||         j        }|||         j        z   ||         _        ||_         |                                 ||_         |||         _        t          |            d S )Nc                     g | ]	}|j         
S ra   r  rF  s     rg   rh   z$parfor_typeinfer.<locals>.<listcomp>D  s    >>>q!">>>ri   c           	      f    g | ]-}t          j        t          j        d d          |          .S )r   F)rq  use_literal_type)r	   r  r  )re   r  rq  s     rg   rh   z$parfor_typeinfer.<locals>.<listcomp>J  s:    iiiYZRYrxsUKKKQPSTTiiiri   )	r  r  rv  r   r  rq  r  build_constraintr  )	r   typeinferersave_blocksr  r3  first_blockindex_assignssave_first_block_bodyrq  s	           @rg   parfor_typeinferrE  A  s    $K''F>>F,=>>>J fkkmm$$K


!Ciiii^hiiiM";/4,vk/B/GGF;K  """$K4F;     ri   c                     |t          t                    }t          | j        |           t          d| j        i|           |S )z)get variable definition table for parforsNr   )r   r  r@   rx  rw  )r   definitionss     rg   build_parfor_definitionsrH  V  sH    !$'' f&444q&+,k:::ri   c           	   #     K   t          |                                           }| |         j        }t          j        |t          d          t          j        dd                    }| |         j                            t          j	        |t          j        dd                               dV  | |         j        
                                 dS )zLadds dummy return to last block of parfor loop body for CFG computation
    r  r  r  N)r   r  r  r	   rg  r    r  r  rf  r  r  )rx  r  r  r  s       rg   r6  r6  c  s      
 Y^^%%&&Jj!'EF5-1126/23N3NOOEj%%
	%44557 7 7	EEEj""$$$$$ri   c                       e Zd Zd ZdS )ReduceInferc                     |rJ t          |          dk    rt          j        d          t          |d         t          j                  sJ t          |d         j        g|R  S )Nr$  zlen(args) != 3r   )r   r   NumbaAssertionErrorr   r   r   rQ   r   )r`  r|   r  s      rg   genericzReduceInfer.generics  sd    t99>>,-=>>>$q'5;/////a.....ri   N)r~   r   r   rN  ra   ri   rg   rK  rK  q  s#        / / / / /ri   rK  c                  J    t           j        rd} t          j        |           dS )zKCheck if the platform supports parallel=True and raise if it does not.
    zDThe 'parallel' target is not currently supported on 32 bit hardware.N)r   	IS_32BITSr   r  )r  s    rg   ensure_parallel_supportrQ  {  s1      2,S1112 2ri   r  )NNNNNr  r/  )NNNrq   (  rj  r   pytypesr  r  rt  textwrapr  r8  rx  	functoolsr   collectionsr   r   r   
contextlibr   rA  dataclassesr   r  llvmliter	   lirnumba.core.imputilsr
   numba.core.irr   r0  r   r   r   r   r   r   r   r   r   r   r   numba.np.npdatetime_helpersr   r   numba.np.numpy_supportr   r   numba.core.typing.templatesr   r   numba.stencils.stencilparforr   numba.core.extendingr   r   numba.core.ir_utilsr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   numba.core.analysisrK   rL   rM   rN   numba.core.controlflowrO   numba.core.typingrP   rQ   numba.core.types.functionsrR   numba.parfors.array_analysisrS   rT   rU   rV   rW   rX   rY   r=  r   numba.parforsrZ   numba.cpython.builtinsnumba.stencilsr[   r  TextWrapperrk   ro   r  rr   rv   re  rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r)  r4  r  rN  r  r   r   r   r   rY  r  r]  r  Stmtrl  r  array_analysis_extensionsr  r  r  r  r
  rH  rJ  r)  r(  r|  r  r  r  rH  rS  rf  r  r  r  r  r  r  rq  r  r  rX  r  r  r  r  r  r  r  r  rY  r  r   r"  r  r2  r@  rB  visit_vars_extensionsrU  ir_extension_usedefsrY  ir_extension_use_allocarl  ir_extension_insert_delsrZ  ro  ry  rt  r}  r~  r  r]  r  r  r  r  rN  r  r  remove_dead_extensionsr  r  r  alias_analysis_extensionsrV  r  r  r  copy_propagate_extensionsr  apply_copy_propagate_extensionsrj  r  r  ro  r-  call_table_extensionsr1  tuple_table_extensionsr5  array_accesses_extensionsr7  add_offset_to_labels_extensionsr:  find_max_label_extensionsrE  typeinfer_extensionsrH  build_defs_extensionsr6  rK  rQ  ra   ri   rg   <module>r|     s                				              < < < < < < < < < < % % % % % %  & & & & & &        2 2 2 2 2 2     r r r r r r r r r r r r r r r r r r r r r r r r r r " " " " " " " " J J J J J J J J : : : : : : : : F F F F F F F F 4 4 4 4 4 4 @ @ @ @ @ @ @ @, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,\H H H H H H H H H H H H * * * * * * 0 0 0 0 0 0 0 0 / / / / / /> > > > > > > > > > > > > > > > * ) ) ) ) )       ( ( ( ( ( (     ( ( ( ( ( ( 
"h"UKKK0 0 0 # 
   
+  
    f        D  @	 	 		 	 		 	 	  "  
' 
' 
'  ,  .  .  8  
 48 4G 4G 4G 4G 4GlI I I0 :999''(('))'''-1  "  (   > > >
 > > >
 G G G G G G z.66*:;; ','7HH&,'7HH#|M;??#|M;??$]K@@$]K@@" "     v   :I( I( I( I( I(RWbg I( I( I(X    4C ( 0N N N N N N N Nba" a" a" a" a"F a" a" a"F  % % % % % % % %<sW sW sW sW sW sW sW sWlA A A~W ~W ~W ~W ~W ~W ~W ~WB
 
 
 
:! ! !Z Z Z Z Z Z Z ZzS$ S$ S$ S$ S$ S$ S$ S$l`; `; `; `; `; `; `; `;F. . .b6E 6E 6E 6E 6E! 6E 6E 6Erf% f% f% f% f%' f% f% f%RPE PE PE PE PE, PE PE PEf% % %P	- 	- 	-n n nb  2J J JZS S S@ @ @(D% D% D%N       F# # #0  4    ( ( (V( ( (   $ n)))   QU;?P' P' P' P'dH H H&  6  8l l l\N N NN N N  & *; v &1E 1E 1E 1Eh )4 f %
! 
! 
! ,>   (+  +  + \ -? !& )   2 59   (    :' ' '

 
 
 z.*H*H*HIIl0 l0 l0^( ( (V  0 gF gF gF gFT    d d dL  B +=  '( ( (T# # #(   .K "6 *  0       8  2 .? "6 *  > 4G ( 05 5 5 5p  B  8  	* 	* 	* 	* *? v &    +A  '    .G "6 *   4O ( 0   .C "6 *! ! !& *:	 v &	 	 	 	 *B v &% % % f/ / / / /" / / /2 2 2 2 2ri   