
    xKggp                    	   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jB                        ZdF ZeezjH                  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y)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                     | j                         D ].  }t        j                  |      D cg c]  }t        |       c} 0 y c c}w N)
splitlines_txtwrapperwrapprint)xlys      X/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/numba/parfors/parfor.pyprint_wrappedri   j   s8    \\^&++A./.aq./ /s   Ac                       y r`    rk       rh   init_prangerm   s   s    
rl   c                      d } | S )Nc                       y r`   rk   rk   rl   rh   no_opz#init_prange_overload.<locals>.no_opx   s    rl   rk   )rp   s    rh   init_prange_overloadrq   v   s    Lrl   c                       e Zd Zd Zy)internal_prangec                     t        | S r`   )range)clsargss     rh   __new__zinternal_prange.__new__~   s    d|rl   N)__name__
__module____qualname__rx   rk   rl   rh   rs   rs   |   s    rl   rs   c                     |j                   dk(  rd }|S |j                   dk(  r>t        |j                  t        j                  t        j
                  f      rd }|S d }|S d }|S )Nr   c                     | d   S Nrk   rk   in_arrs    rh   min_1z min_parallel_impl.<locals>.min_1       ":rl      c                 p   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t         j                  j                  j                  t        |             D ]  }t        || |         } |S r`   )numbaparforsparforrm   min_checkerlencpythonbuiltinsget_type_max_valuedtypers   r   r   valis      rh   r   z min_parallel_impl.<locals>.min_1   {    $$002CK(mm,,??M--==c&kJA*3q	:C K
rl   c                 p   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t         j                  j                  j                  t        |             D ]  }t        || |         } |S r`   )r   r   r   rm   r   r   r   r   r   r   rs   minr   s      rh   r   z min_parallel_impl.<locals>.min_1   {    $$002CK(mm,,??M--==c&kJAc6!9-C K
rl   c                 J   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t        j                  | j                        D ]  }t        || |         } |S r`   )r   r   r   rm   r   r   r   r   r   r   r   shaper   r   s      rh   r   z min_parallel_impl.<locals>.min_1   n    MM  ,,.F$--((;;FLLIC^^FLL1#vay) 2Jrl   ndim
isinstancer   r   
NPDatetimeNPTimedelta)return_typeargr   s      rh   min_parallel_implr      sk     xx1}	8 L5 
Qcii%"2"2E4E4E!FG. L L	 Lrl   c                     |j                   dk(  rd }|S |j                   dk(  r>t        |j                  t        j                  t        j
                  f      rd }|S d }|S d }|S )Nr   c                     | d   S r~   rk   r   s    rh   max_1z max_parallel_impl.<locals>.max_1   r   rl   r   c                 p   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t         j                  j                  j                  t        |             D ]  }t        || |         } |S r`   )r   r   r   rm   max_checkerr   r   r   get_type_min_valuer   rs   r   r   s      rh   r   z max_parallel_impl.<locals>.max_1   r   rl   c                 p   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t         j                  j                  j                  t        |             D ]  }t        || |         } |S r`   )r   r   r   rm   r   r   r   r   r   r   rs   maxr   s      rh   r   z max_parallel_impl.<locals>.max_1   r   rl   c                 J   t         j                  j                  j                          t	        t        |              t         j                  j                  j                  | j                        }t        j                  | j                        D ]  }t        || |         } |S r`   )r   r   r   rm   r   r   r   r   r   r   r   r   r   r   s      rh   r   z max_parallel_impl.<locals>.max_1   r   rl   r   )r   r   r   s      rh   max_parallel_implr      si    
xx1}	8 L5 
Qcii%"2"2E4E4E!FG. L L	 Lrl   c                 $   t         j                  j                  j                          t	        t        |              | j                         }t         j                  j                  j                  |j                        }t        j                  j                  d|      }t         j                  j                  j                  t        |            D ]1  }t        j                  j                  |||         }t        ||      }3 |j                  S Nr   )r   r   r   rm   argmin_checkerr   ravelr   r   r   r   r   
IndexValuers   r   indexr   Ainit_valivalr   	curr_ivals         rh   argmin_parallel_implr          	MM$$&3v;A}}%%88AH??%%a2D]]!!11#a&9OO..q!A$7	4# : ::rl   c                 $   t         j                  j                  j                          t	        t        |              | j                         }t         j                  j                  j                  |j                        }t        j                  j                  d|      }t         j                  j                  j                  t        |            D ]1  }t        j                  j                  |||         }t        ||      }3 |j                  S r   )r   r   r   rm   argmax_checkerr   r   r   r   r   r   r   r   rs   r   r   r   s         rh   argmax_parallel_implr      r   rl   c                    t         j                  j                  j                          | j                  d   }|j                  d   }d}t         j                  j                  j                  |      D ]  }|| |   ||   z  z  } |S r   )r   r   r   rm   r   rs   )abrf   msr   s         rh   dotvv_parallel_implr      ss    	MM$$&	
A	
A 	
A]]!!11!4	QqTAaD[ 5Hrl   c                 L   t         j                  j                  j                          | j                  }|j                  \  }}t        j                  || j                        }t         j                  j                  j                  |      D ]  }|| |   ||d d f   z  z  } |S r`   )	r   r   r   rm   r   npzerosr   rs   )r   r   rf   r   ncr   s          rh   dotvm_parallel_implr      s    	MM$$&	A77DAq 	AGGA ]]!!11!4	QqTAadG^ 5Hrl   c                 v   t         j                  j                  j                          | j                  \  }}|j                  }t        j                  || j                        }t         j                  j                  j                  |      D ])  }d}t        |      D ]  }|| ||f   ||   z  z  } |||<   + |S r   )
r   r   r   rm   r   r   emptyr   rs   ru   )	r   r   r   r   rf   r   r   r   js	            rh   dotmv_parallel_implr      s    	MM$$&77DAq	A 	AGGA]]!!11!4qA1a41Q4A !	 5
 Hrl   c                 .   t        |t        j                  j                        rqt        |t        j                  j                        rL|j                  |j                  cxk(  r
dk(  rt
        S  |j                  dk(  r|j                  dk(  rt        S y y y y )Nr      )r   r   npytypesArrayr   r   r   )r   atypbtyps      rh   dot_parallel_implr     sx    4--.4--.99		&Q&&& '
 YY!^		Q&& !/^ 	/ 	/rl   c                 v     | d      |j                   dk(  rd }|S |j                   dk(  rfd}|S fd}|S )Nr   c                     | d   S r~   rk   r   s    rh   sum_1z sum_parallel_impl.<locals>.sum_1  r   rl   r   c                     t         j                  j                  j                          }t         j                  j                  j	                  t        |             D ]
  }|| |   z  } |S r`   r   r   r   rm   rs   r   r   r   r   zeros      rh   r   z sum_parallel_impl.<locals>.sum_1  sU    MM  ,,.C]]))99#f+Fvay  GJrl   c                     t         j                  j                  j                          }t        j                  | j
                        D ]
  }|| |   z  } |S r`   r   r   r   rm   r   r   r   s      rh   r   z sum_parallel_impl.<locals>.sum_1  sH    MM  ,,.C^^FLL1vay  2Jrl   r   )r   r   r   r   s      @rh   sum_parallel_implr     sH    q>D
xx1}	  L 
Q	 L	 Lrl   c                 v     | d      |j                   dk(  rd }|S |j                   dk(  rfd}|S fd}|S )Nr   r   c                     | d   S r~   rk   r   s    rh   prod_1z"prod_parallel_impl.<locals>.prod_1*  r   rl   c                     t         j                  j                  j                          }t         j                  j                  j	                  t        |             D ]
  }|| |   z  } |S r`   r   r   r   r   ones      rh   r   z"prod_parallel_impl.<locals>.prod_1-  sU    MM  ,,.C]]))99#f+Fvay  GJrl   c                     t         j                  j                  j                          }t        j                  | j
                        D ]
  }|| |   z  } |S r`   r   r   s      rh   r   z"prod_parallel_impl.<locals>.prod_14  sH    MM  ,,.C^^FLL1vay  2Jrl   r   )r   r   r   r   s      @rh   prod_parallel_implr   &  sH    
a.C
xx1}	  M 
Q	 M	 Mrl   c                 v     | d      |j                   dk(  rd }|S |j                   dk(  rfd}|S fd}|S )Nr   c                     | d   S r~   rk   r   s    rh   mean_1z"mean_parallel_impl.<locals>.mean_1B  r   rl   r   c                     t         j                  j                  j                          }t         j                  j                  j	                  t        |             D ]
  }|| |   z  } |t        |       z  S r`   r   r   s      rh   r   z"mean_parallel_impl.<locals>.mean_1E  s^    MM  ,,.C]]))99#f+Fvay  Gs6{?"rl   c                     t         j                  j                  j                          }t        j                  | j
                        D ]
  }|| |   z  } || j                  z  S r`   )r   r   r   rm   r   r   sizer   s      rh   r   z"mean_parallel_impl.<locals>.mean_1L  sQ    MM  ,,.C^^FLL1vay  2v{{?"rl   r   )r   r   r   r   s      @rh   mean_parallel_implr   =  sH    q>D
xx1}	  M 
Q	# M	# Mrl   c                 \    |j                   dk(  rd }|S |j                   dk(  rd }|S d }|S )Nr   c                      yr   rk   r   s    rh   var_1z var_parallel_impl.<locals>.var_1V  s    rl   r   c                 l   | j                         }t        j                  j                  j	                          d}t        j                  j                  j                  t        |             D ]8  }| |   |z
  }|t        j                  |t        j                  |      z        z  }: |t        |       z  S r   )
meanr   r   r   rm   rs   r   r   realconjr   r   ssdr   r   s        rh   r   z var_parallel_impl.<locals>.var_1Y  s    AMM  ,,.C]]))99#f+FQi!mrwwsRWWS\122 G V$$rl   c                 H   | j                         }t        j                  j                  j	                          d}t        j
                  | j                        D ]8  }| |   |z
  }|t        j                  |t        j                  |      z        z  }: || j                  z  S r   )r   r   r   r   rm   r   r   r   r   r   r   r   s        rh   r   z var_parallel_impl.<locals>.var_1d  s}    AMM  ,,.C^^FLL1Qi!mrwwsRWWS\122 2 $$rl   r   )r   r   r   s      rh   var_parallel_implr   T  s>    
xx1}	0 L- 
Q		%* L		% Lrl   c                     d }|S )Nc                 (    | j                         dz  S )Ng      ?)varr   s    rh   std_1z std_parallel_impl.<locals>.std_1q  s    zz|s""rl   rk   )r   r   r   s      rh   std_parallel_implr   p  s    #Lrl   )r   c                \  
 t        | j                        

fd}d }
fd}d }
fd}d }t        d |D              rd }	nd	 }	t        |      d
k(  r||S |S t        |      dk(  r||S |S t        |      dk(  r||S |S t        |      dk(  r|	S t	        dj                  |            )Nc                 4    t        j                  d| d      S Nr   r   r   arange)stopinferred_dtypes    rh   arange_1z&arange_parallel_impl.<locals>.arange_1x  s    yyD!^44rl   c                 2    t        j                  d| d|      S r   r   )r   r   s     rh   arange_1_dtypez,arange_parallel_impl.<locals>.arange_1_dtype{  s    yyD!U++rl   c                 4    t        j                  | |d      S Nr   r   )startr   r  s     rh   arange_2z&arange_parallel_impl.<locals>.arange_2~  s    yya88rl   c                 2    t        j                  | |d|      S r  r   )r  r   r   s      rh   arange_2_dtypez,arange_parallel_impl.<locals>.arange_2_dtype  s    yya//rl   c                 4    t        j                  | ||      S r`   r   )r  r   stepr  s      rh   arange_3z&arange_parallel_impl.<locals>.arange_3  s    yydN;;rl   c                 2    t        j                  | |||      S r`   r   )r  r   r  r   s       rh   arange_3_dtypez,arange_parallel_impl.<locals>.arange_3_dtype  s    yydE22rl   c              3   P   K   | ]  }t        |t        j                           y wr`   )r   r   Complex).0r   s     rh   	<genexpr>z'arange_parallel_impl.<locals>.<genexpr>  s     
6A:a's   $&c                    t         j                  j                  j                          || z
  |z  }t	        j
                  |j                        }t	        j
                  |j                        }t        t        t        ||      d            }t        j                  ||      }t         j                  j                  j                  |      D ]  }	| |	|z  z   ||	<    |S r   )r   r   r   rm   mathceilr   imagintr   r   r   r   rs   )
r  r   r  r   nitems_cnitems_rnitems_initemsarrr   s
             rh   arange_4z&arange_parallel_impl.<locals>.arange_4  s    MM  ,,.u,Hyy/Hyy/HS84a89F((65)C]]))99&AT)A BJrl   c                 X   t         j                  j                  j                          t	        j
                  || z
  |z        }t        t        |d            }t        j                  ||      }| }t         j                  j                  j                  |      D ]  }| ||z  z   ||<    |S r   )r   r   r   rm   r  r  r  r   r   r   rs   )	r  r   r  r   r  r  r  r   r   s	            rh   r  z&arange_parallel_impl.<locals>.arange_4  s    MM  ,,.yy$,$!67HXq)*F((65)CC]]))99&AT)A BJrl   r   r         zparallel arange with types {})r   r   anyr   
ValueErrorformat)r   r   rw   r  r  r  r
  r  r  r  r  s             @rh   arange_parallel_implr%  u  s    k//0N5,90<3 
6
66			 4yA~ =x<n<	Ta!Mx=~=	Ta!Mx=~=	Ta8??EFFrl   c                     t        | j                        d }fd}t        |      dk(  r|S t        |      dk(  r|S t        dj	                  |            )Nc                 0    t        j                  | |d      S )N2   )r   linspace)r  r   s     rh   
linspace_2z*linspace_parallel_impl.<locals>.linspace_2  s    {{5$++rl   c                    t         j                  j                  j                          t	        j
                  |      }|dz
  }|| z
  }| |d<   t         j                  j                  j                  |      D ]  }| |||z  z  z   ||<    |S )Nr   r   )r   r   r   rm   r   r   rs   )r  r   numr  divdeltar   r   s          rh   
linspace_3z*linspace_parallel_impl.<locals>.linspace_3  s    ((*hhsE"AguA%%55c:AUa#g..CF ;
rl   r   r   zparallel linspace with types {})r   r   r   r#  r$  )r   rw   r*  r/  r   s       @rh   linspace_parallel_implr0    sX    [&&'E, 4yA~	Ta:AA$GHHrl   c                     t         S r`   )r   rr   s     rh   <lambda>r4        %9rl   c                     t         S r`   )r   r2  s     rh   r4  r4    r5  rl   )argminnumpyargmaxr9  r   r9  r   r9  aminr9  amaxr9  )sumr9  )prodr9  )r   r9  )r   r9  )stdr9  )dotr9  )r   r9  )r)  r9  c                 4    |j                   dk(  rd }|S 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                  j                          t         j                  j                  j	                  t        |             D ]  }|| |<   	 y r`   r   r   s      rh   fill_1z"fill_parallel_impl.<locals>.fill_1  sH    MM  ,,.]]))99#f+Fq	 Grl   c                     t         j                  j                  j                          t        j                  | j
                        D ]  }|| |<   	 y r`   r   r   s      rh   rH  z"fill_parallel_impl.<locals>.fill_1  s;    MM  ,,.^^FLL1q	 2rl   r   )r   r  r   rH  s       rh   fill_parallel_implrJ    s'    
 xx1}	 M	
 Mrl   fillc                 $    | dk(  rt        d      y )Nr   zDzero-size array to reduction operation maximum which has no identityr#  arr_sizes    rh   r   r          1} < > 	> rl   c                 $    | dk(  rt        d      y )Nr   zDzero-size array to reduction operation minimum which has no identityrM  rN  s    rh   r   r     rP  rl   c                 $    | dk(  rt        d      y )Nr   z*attempt to get argmin of an empty sequencerM  rN  s    rh   r   r         1}EFF rl   c                 $    | dk(  rt        d      y )Nr   z*attempt to get argmax of an empty sequencerM  rN  s    rh   r   r     rS  rl   checker_implnamefuncr   r   r   r   )r7  r:  r<  r=  r>  r@  c                   "    e Zd ZdZd Zd Zd Zy)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                 <    || _         || _        || _        || _        y r`   )index_variabler  r   r  )selfr[  r  r   r  s        rh   __init__zLoopNest.__init__  s    ,
		rl   c                 z    dj                  | j                  | j                  | j                  | j                        S )Nz3LoopNest(index_variable = {}, range = ({}, {}, {})))r$  r[  r  r   r  r\  s    rh   __repr__zLoopNest.__repr__  s-    Et**DJJ		499M	Orl   c                    g }|j                  | j                         t        | j                  t        j
                        r|j                  | j                         t        | j                  t        j
                        r|j                  | j                         t        | j                  t        j
                        r|j                  | j                         |S r`   )appendr[  r   r  r	   Varr   r  )r\  all_usess     rh   	list_varszLoopNest.list_vars  s    xt**+
TZZ
(??4::&
TYY
'??499%
TYY
'??499%rl   N)ry   rz   r{   __doc__r]  r`  re  rk   rl   rh   rY  rY    s    
O	rl   rY  c                   \     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kD  sJ |g| _        || _        |	| _        |
| _        g | _        i | _        d | _        t(        j*                  r)d}t-        |j/                  | j
                  ||             y y )Nr   )oplocr   z9Parallel for-loop #{} is produced from pattern '{}' at {})superrh  r]  type
id_counterid
loop_nests
init_block	loop_body	index_varparams	equiv_setr   patternsflagsri  rj  redvarsreddictlowererr   DEBUG_ARRAY_OPT_STATSrd   r$  )r\  rr  rs  rt  rm  ru  rw  patternry  ri  rj  fmt	__class__s               rh   r]  zParfor.__init__-  s     	fd$ 	% 	

 t*''T
" %$""" 7|a 	
 '=#

 ''OC#**''7C) * (rl   c                     dt        | j                        z   t        | j                        z   t        | j                        z   t        | j
                        z   S )Nzid=)strrq  reprrr  rt  ru  r_  s    rh   r`  zParfor.__repr___  sG    s477|#d4??&;; !#'#78 	8rl   c                 T    | j                   D cg c]  }|j                   c}S c c}w r`   )rr  r[  )r\  re   s     rh   get_loop_nest_varszParfor.get_loop_nest_varsc  s$    *.//:/Q  /:::s   %c                 :   g }| j                   j                         D ])  \  }}|j                  D ]  }||j                         z  } + | j                  D ]  }||j                         z  } | j
                  j                  D ]  }||j                         z  } |S )zslist variables used (read/written) in this parfor by
        traversing the body and combining block uses.
        )rt  itemsbodyre  rr  rs  )r\  rd  rf   r   stmtloops         rh   re  zParfor.list_varsf  s     NN((*DAqDNN,,  + OOD((H $ OO((D((H ) rl   c                     |'| j                   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
        )rw  typemapget_shape_classes)r\  r   r  save_typemapress        rh   r  zParfor.get_shape_classesw  sP     >>11L%,DNN"nn..s3%1DNN"
rl   c                    |xs t         j                  }t        dj                  | j                        j                  dd      |       t        d| j                  |       t        d| j                  |       t        d| j                  |       | j                  D ]  }t        ||        t        d|       | j                  j                  |       t        | j                  j                               D ]'  \  }}t        d	|d
|       |j                  |       ) t        dj                  | j                        j                  dd      |       y )Nzbegin parfor {}   -)filezindex_var = z	params = zraces = zinit block:zlabel :zend parfor {})sysstdoutrd   r$  rq  centerru  rv  rj  rr  rs  dumpsortedrt  r  )r\  r  loopnestoffsetblocks        rh   r  zParfor.dump  s    !szz ''088SAMndnn48k4;;T2j$**40H(& (m$'T"#DNN$8$8$:;MFE)5JJt < 	%%dgg.66r3?dKrl   c                    | j                   d}t        |      | j                   D ]  }|j                  |      }|d}t        |      t        |t        j
                        s>|j                  t        j                  kD  s\d}t        j                  |||j                  t        j                  fz  | j                         y)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.)rv  r#  getr   r   	BaseTuplecountr   PARFOR_MAX_TUPLE_SIZEr   UnsupportedParforsErrorrm  )r\  r  msgptys        rh   validate_paramszParfor.validate_params  s     ;;CS/!AQBz/ o%"eoo.88f:::OC !88 "((F,H,HI:J"hh( (! rl   r`   )ry   rz   r{   rp  setr]  r`  r  re  r  r  r  __classcell__)r  s   @rh   rh  rh  )  s7    J $)%0*d8;"$L(rl   rh  c                     |j                   }t        |       }|j                  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_blocksrw  )r   rw  r  rZ   r  parfor_blocksbackup_equivsets          rh   _analyze_parforr    s~     $$G&v.M %//33At<ON}i0/%003F'6!!!$r6Mrl   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y)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| _
        y )N__numba_parfor_gufuncF)rW  dictreplaced_fnsinternal_namer   listfusion_infonested_fusion_infofusion_reports
hoist_info	has_setupr_  s    rh   r]  zParforDiagnostics.__init__  sK    	 F4&t,"-d"3 rl   c                 Z   || _         | j                   j                  j                  | _        | j                   j                  | _        || _        | j                  | j                  v rd| _        n!d| j                  d| j
                  | _        | j                         | _
        d| _        y )NzInternal parallel functionz	Function , T)r  func_idfunc_qualnamerV  rm  linefusion_enabledr  purposeget_parforsinitial_parforsr  )r\  r  r  s      rh   setupzParforDiagnostics.setup  s    LL((66	LL$$	,*7DL + 15		499EDL  $//1rl   c                     | j                   S r`   
_has_setupr_  s    rh   r  zParforDiagnostics.has_setup  s    rl   c                     || _         y r`   r  )r\  states     rh   r  zParforDiagnostics.has_setup  s	    rl   Nc                 4    t        | j                               S r`   )r   r  r\  blockss     rh   count_parforszParforDiagnostics.count_parfors  s    4##%&&rl   c                 T    t        |      }| j                  ||       t        |       y r`   )r  _get_parforsr  )r\  r   parfors_listr  s       rh   _get_nested_parforsz%ParforDiagnostics._get_nested_parfors  s$    #F+&,/V$rl   c                     |j                         D ]J  \  }}|j                  D ]6  }t        |t              s|j	                  |       | j                  ||       8 L y r`   )r  r  r   rh  rb  r  )r\  r  r  labelblkr  s         rh   r  zParforDiagnostics._get_parfors  sL     ,,.JE3dF+ ''-,,T<@ ! )rl   c                 V    g }| j                  | j                  j                  |       |S r`   )r  r  r  )r\  r  s     rh   r  zParforDiagnostics.get_parfors  s'    $,,--|<rl   c                 |   g }| j                   j                         D ]  \  }}|j                  dg       }|D ]  }t        |j                  t
        j                        s(|j                  j                  dk(  sBt        t        | j                  |j                        }|j|dk(  sp|j                  |         |S )Nhoistedcall)r   r9  )r  r  r  r   valuer	   Exprrl  r;   r9   r  rb  )r\  allocspf_iddatar  instr  s          rh   hoisted_allocationsz%ParforDiagnostics.hoisted_allocations  s    ??002KE488Ir*Ddjj"''2zz}}.$]DLL$**M+8J0J"MM$/  3 rl   c                    t        j                  |      }|i k(  rg t               fS t               }|j                         D ]  }|D ]  }|j	                  |         t        |j                               }||z
  }|
t               }t               }t        t        t        |j                               j                  |            dz         D ]7  }|j                  |      }	|	|	||<   |	g k(  r|j	                  |       3g ||<   9 g }
t        |j                               D ]  }|
j                  ||           |
|fS )zf
        compute adjacency list of the fused loops
        and find the roots in of the lists
        r   )copydeepcopyr  valuesaddkeysru   r   unionr  r  rb  )r\  _ar   vtxvre   potential_rootsroots	not_rootsr   rf   s              rh   compute_graph_infoz$ParforDiagnostics.compute_graph_info  s   
 MM"7su9eA
  
 affh-#%=EE E	s3qvvx=..s34q89A%%(C!a ! : !AHHQqTN " %xrl   c                 4    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 ]7  }|dz  }||   g k(  r|t        | |         z  }" | ||||      \  }}||z  }|}9 ||fS r  )r   )	fadjnadjrootnfusednserialknfns
count_roots	           rh   r  z/ParforDiagnostics.get_stats.<locals>.count_root=  sg    $Z17b=c$q'l*F'dAvwGFBbLF G   7?"rl   r   rk   )r\  r  r  r  r  r  r  s         @rh   	get_statszParforDiagnostics.get_stats7  s*    		# %T4q!<wrl   c                     g }|j                  ||          ||   D ],  }||   g k7  s|j                  | j                  ||             . |S )zf
        returns a list of nodes reachable in an adjacency list from a
        specified root
        )extendreachable_nodes)r\  adjr  fusersr  s        rh   r   z!ParforDiagnostics.reachable_nodesJ  sR    
 c$i TA1v|d223:;  rl   c                    ||   d   }|j                   d   }t        d|j                  j                  dz
        }| j                  j                  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 ]L  }|s||   D ]#  }|j                  | j                  ||             % |s4t        dt        |      dz
        c S  |j                  j                         D ]S  }|j                   D ]B  }|j                  j
                  |k(  st        d|j                  j                  dz
        c c S  U | j                  j"                  j                         D ]w  }	 |j                   j%                  |      }t'        |dz
  dd      D ]F  }|j                   |   }t        |t(              r#t        d|j                  j                  dz
        } n y |S # t*        $ r Y w xY w)zX
        pd_id - the parfors id
        parfors_simple - the simple parfors map
        r   r   internalr   )rx  r   rm  r  r  filenamer  r  r  r   tuplerb  sort_pf_by_liner   rt  r  r  r  r   ru   rh  r#  )r\  r  parfors_simplepfr~  r  r  r  nrootsr  frootsgraphsreported_loctmpr  r  r  r  idxr   s                       rh   r  z!ParforDiagnostics.sort_pf_by_lineV  s    E"1%++a.1bffkkAo&<<##,,..t/F/FGf..t/?/?@f gu%qzZ'&qz!}((H4q,"3"3a"788 C%%(Z #

4+?+?>+R S &0"'*1c#hl'; ;  &  "||224$'HHD#xx00H<'*1dhhmma.?'@ @ %-  5  $||2299;!"%((.."4C%*37Ar%:'*xx{'1$'?+.q$((--!2C+DD$)	 &;  <   * ! !s   AI&I	IIc           	         t               }t        | j                  d       D ]  }|j                  d   }|j                  d   }|j                  }t        |t              ra|d   dk(  rY|d   dk(  r9dj                  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 r`   )rm  r  re   s    rh   r4  z6ParforDiagnostics.get_parfors_simple.<locals>.<lambda>  s    QUUZZrl   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  rx  rm  r   r  joinreversedr  ri   rq  )	r\  print_loop_searchr	  r
  	r_patternr~  rm  replfnr  s	            rh   get_parfors_simplez$ParforDiagnostics.get_parfors_simple  s    --3GHB AIkk!nG&&C'5)1:)qzZ/!$(4
13F*G!H%ajm/57T$U	 v-$9	 z1$7	 qLC cRUUC$;;<%'i$8N255!- I. rl   c                 j   | j                  | j                        \  }}| j                  | j                        \  }}t        |      t        |      kD  rt        |      }|}nt        |      }|}t	        t        |      |      D ]  }|j                  g         t               }	|r!|D ]  }
||
   g k7  s|	j                  |
        ||	z  }i }|D ]  }| j                  ||      }d||f||<    i }|	D ]  }| j                  ||      }d||f||<    |j                         }|j                  |       |S )Nfusenest)r  r  r  r   ru   rb  r  r  r  r  update)r\  r	  r  r  r  _nrootslimr  re   r  r3  	all_rootsfroots_linesr  nroots_lines	all_liness                   rh   get_all_lineszParforDiagnostics.get_all_lines  sE    ..t/?/?@f//0G0GHgt9s4y d)CCd)CCs3x%AJJrN &
 7b=JJqM  VO	 A''>:D!'DL  A''>:D!'DL  !%%'	&rl   c           	      \   | j                   j                  j                  }| j                         }| j                   j                  j
                  }	 t        j                  |      j                         }|r|rt        |D cg c]  }t        |       c}      }t        t              }	|j                         D ]J  \  }
}||
   d   j                  |k(  s| j                  |
|      }|	|   j!                  t#        |
             L t        dg|	j%                         D cg c]  }t        |       c}z         }|d|t        t#        |            dz   z  z   z   }g }|j!                  d       |j!                  d|z         |j!                  |dz  dz          d}t        d| j                   j                  j&                  dz
        }t)        ||      D ]  \  }}|	j+                  |d       }|d	d
j-                  |      z   }nd}|j/                  d      }t        |      }|r|j1                  |dz  ||      }n|j1                  |dz  ||      }|j!                  |||d  z           t3        dj-                  |             y t3        d       y # t        $ r d }Y +w xY wc c}w c c}w )Nr   r   
zParallel loop listing for %sr  z	|loop #IDz{0:{1}}| {2}r   #r   r  zNo source available)r  rm  r  r  r  rW  inspect	getsourcera   OSErrorr   r   r   r  r  r  rb  r  r  r  	enumerater  r  stripr$  rd   )r\  r	  purpose_strr  r  	func_namelinesre   	src_widthmap_line_to_pfr  r  
match_linemax_pf_per_liner]   newlinesr  lstartnor  pf_idspfstrstrippedsrclenrf   s                            rh   source_listingz ParforDiagnostics.source_listing  so   <<##,,""$LL((--		%%i0;;=E ^U3USVU34I(.N&,,.1 "!$Q'00H<!%!5!5a!HJ":.55c!f= / "1#9N9N9P(Q9PAQ9P(Q"QRO_CJ!8K%L!LMEHOOD!OO:[HIOOECK+56 CDLL,,11A56F%eV4D'++B5%$))F"33EE::d+X

53;u=A

53;u=A1VW: 56 5 $))H%&'(I  	E	 4 )Rs   #J J$"J)
J! J!c                     dt               j                   j                        \  }} j                   j                        \  }}t        |      t        |      kD  rt        |      }|}nt        |      }|}t	        t        |      |      D ]  }|j                  g          fd}	 fd}
d}g }t        |j                               D ]5  \  }}|\  }}}|dk(  r||vs |
d||d|      }#|dk(  r |	|||||      }5J  y )N+--c                     fd||   g k7  r)t        d|z          | ||d       t        d       |dz   }|S )Nc           	         t        |z  dz  |ddz          ||   D ]  }||   g k(  rg }|j                  |dz   z  dz  |ddz          | |   g k7  rA|
vr=j                  | |      }|D ]&  }|j                  |dz   z  dz  |ddz          ( 
j                  |       t        dj                  |              	| |||dz           y )Nr  
(parallel)r   r+  )ri   rb  r   r  )fadj_nadj_nrootdepthr  r  fusedr   facprint_greportedr\  swords           rh   rM  zHParforDiagnostics.print_unoptimised.<locals>.print_nest.<locals>.print_g  s    cEkC/ue\2ZZ[uAQx2~ 

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

3%!)+<s+BRWYZ\hEi+i j &+ *%diin5ua; &rl   Parallel region %s:r   r+  r   ri   rd   )	rG  rH  therootrN  	region_idrM  rL  r\  rO  s	      ` @rh   
print_nestz7ParforDiagnostics.print_unoptimised.<locals>.print_nest  sM    < < W~#3i?@ugq1d%M	rl   c                 T   g }t        d|z         |j                  |z  dz  
|ddz          ||   g k7  rCt        	j                  ||            }|D ]#  }|j                  |z  dz  
|ddz          % |dz   }t        dj	                  |             t        d       |S )NrP  r  rF  r   r+  )ri   rb  r  r   r  rd   )r  r  r  rJ  rS  r  rK  r  rL  r\  rO  s           rh   
print_fusez7ParforDiagnostics.print_unoptimised.<locals>.print_fuse,  s    C/);<JJsU{S(ul+SST5zRt33C?@AJJsU{S0q,3WWX !AI$))C.)$Krl   r   r   fr!  )r   r  r  r  ru   rb  r  r  )r\  r5  r  r  r  r#  r$  r  re   rT  rV  rS  rN  r  infoopt_tyr  r  rL  rO  s   `                 @@rh   print_unoptimisedz#ParforDiagnostics.print_unoptimised  s   %j..t/?/?@f//0G0GHgt9s4y d)CCd)CCs3x%AJJrN &	.	 	 /JD$!%FE3( *3sAy II6!&tT5(IN	q 0rl   c           	          dt               j                   j                        \  }} j                   j                        \  }}t        |      t        |      kD  rt        |      }|}nt        |      }|}t	        t        |      |      D ]  }|j                  g         t                fd}	 fd}
d}g }t        |j                               D ]5  \  }}|\  }}}|dk(  r||vs |
d||d|      }#|dk(  r |	|||||      }5J  rgt        j                               D ]J  \  }}d}|d	   }|d
   }|d   }|dk7  r|dz  }t        ||||||fz         5|dz  }t        ||||fz         L y t        d       y )NrC  c                     	fd||   g k7  rDt        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 k7  rO|vrKt        j                  | |            }|dz  }|dj                  |D cg c]  }t        |       c}      z  }|dz  }j	                  |       t        |       
   dxx   t        |      z  cc<   nt        |dz           	| |||dz          
   dxx   dz  cc<    y c c}w )	Nr  z(serial, fused with loop(s): r  )rK  r   
serialized)r  r   r  r  rb  ri   r   )rG  rH  rI  rJ  r  r  rK  re   rL  rM  rS  rN  r\  summaryrO  s           rh   rM  zFParforDiagnostics.print_optimised.<locals>.print_nest.<locals>.print_g[  s   uA++5!Y.OOCQx2~ " 8r>ax.?$*4+?+?q+I$JE#;;C499e-Dec!fe-D#EECs
 *%c*	*73s5zA3%cCi0ua;I&|494 & .Es   "C'rP  r  rF  r   r  rK  r`  r   r+  rQ  )
rG  rH  rR  rN  rS  rM  rL  r\  ra  rO  s
      ``@rh   rT  z5ParforDiagnostics.print_optimised.<locals>.print_nestZ  sn    : :$ W~#3i?@5'<HI.5QR%S	"ugq1d%M	rl   c           	      `   t        d|z         |z  dz  |ddz   }g }||   g k7  rKt        	j                  ||            }|dz  }|dj                  |D cg c]  }t	        |       c}      z  }|t        |      dd
|<   |dz  }t        |       t        d	       |d
z   }|S c c}w )NrP  r  z	(parallelr^  r  r   rb  r_  r+  r   )ri   r  r   r  r  r   rd   )r  r  r  rJ  rS  r  rK  re   rL  r\  ra  rO  s           rh   rV  z5ParforDiagnostics.print_optimised.<locals>.print_fusev  s    /);<+#5%&MMCE5zRt33C?@//tyy%!8%Q#a&%!899*/#e*TU!VGI3JC#$K!AI "9s   B+
r   r   rW  r!  z5
 
Parallel region %s (loop #%s) had %s loop(s) fusedr  rK  r`  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  ru   rb  r  r  r  ri   )r\  r5  r  r  r  r#  r$  r  re   rT  rV  rS  rN  r  rX  rY  r  r  r  r  r  r  rK  r`  rL  ra  rO  s   `                       @@@rh   print_optimisedz!ParforDiagnostics.print_optimisedF  s    %j..t/?/?@f//0G0GHgt9s4y d)CCd)CCs3x%AJJrN & &	8	" 	 /JD$!%FE3( *3sAy II6!&tT5(IN	q 0 w}}/1$y'
|_
? + ,C "#D%T(J"JK3JC!#D%(8"89 0 BCrl   c                 <   d}t        d       | j                  j                         D ]  \  }}|j                  dg       }|D ]  }t	        |j
                  t        j                        s(	 |j
                  j                  }|dk(  rd}|j                  }t        |||fz         	 t        j                  j                  |j                        }	t#        j$                  |	      }
|
rI|j&                  r=t        d|
|j&                  dk  rdn|j&                  d	z
     j)                         z          t        d
       d}  |st        d       y y # t        $ r, t        j                  j!                  |j                        }	Y w xY w# t*        t,        f$ r Y Ww xY w)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)rd   r  r  r  r   r  r	   r  attrrm  ri   ospathrelpathr  r#  abspath	linecachegetlinesr  r2  KeyErrorAttributeError)r\  foundr  r  r  r  rf  r  rm  rh  r5  s              rh   allocation_hoistz"ParforDiagnostics.allocation_hoist  sc   $%??002KE488Ir*Ddjj"''2#zz7?$;C
 #'((C)#e*<=E')wws||'D %.$6$6t$<E$ -.@5chhYZl`c`h`hkl`lCmCsCsCu.u v)*]^$(E)  32 89  $. E')wws||'DE %n5 s7   ,9F&)EA-F2FFFFFFc                    t        d       t        d       d}| j                  r| j                  j                         D ]  \  }}|j                  dd       }|j                  dd       }|s|st        d|z         =t        d|z         |r)t        d       |D cg c]  }t        d	|z         c} d
}|syt        d       |D cg c]  \  }}t        d|d|       c}} d
} |st	        d       t	        d       y c c}w c c}}w )Nr-  zInstruction hoisting:Fr  not_hoistedzloop #%s has nothing to hoist.z	loop #%s:z  Has the following hoisted:    %sTz   Failed to hoist the following:z    z: zNo instruction hoisting foundzP--------------------------------------------------------------------------------)rd   r  r  r  ri   )r\  hoist_info_printedr  r  r  rr  rg   re   s           rh   instruction_hoistz#ParforDiagnostics.instruction_hoist  s    b	%&"??#446t((9d3"hh}d;{:UBCkE)*8929:'QU8a<(':)-&<=>IJkdaU1a01kJ)-&  7  "9:h ; Ks   DD	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y t        d       t        t        dz         t        d|z  j                  t        d             t        t        dz         t        d       |rt        dj                  t        d              j                  |      } j                         }|r t        d|z         t        dt        z          j                  j
                  j                  }	 t        j                  j!                  |      }|r j%                  ||       d! j'                         }|D cg c]  }|j(                   }}t+        |      }|s|	rRt,        s-t        dj                  t        d             d}t        |       nd}t        |       t        t        dz         |dkD  rQ !fd}|r7 j.                  D ](  }|\  }}}t        d|d|d       t        d |z         *  j0                  i k7  r!|	rt        d!        | j0                  d"d#       |	rj j2                  rd$}nd%}t        d&j5                  ||dj7                  |D cg c]  }d'|z  	 c}                   t        t        dz         t        d       |
rn j8                  i k7  r_t        d(j                  t        d             t        d)       d*}d+} | j8                  ||       t        t        dz         t        d        j;                  |      } |rBt=        d,j                  t        d              j?                  |        t=        t        dz         |rBt=        d-j                  t        d              jA                  |        t=        t        dz         t        d       t        t        dz         t        d       |s|rt        d.j                  d/d             |r jC                          |r jE                          y y t        d0j5                  ||             y # t        $ r# t        j                  j#                  |      }Y >w xY wc c}w c c}w )1Nz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 r-  zLooking for parallel loopsr  z
Found %s parallel loops.rC  z Fusing loops zPAttempting fusion of parallel loops (combines loops with similar properties)...
z+Performing sequential lowering of loops...
r  c                 p    t              fd}j                  |       \  } ||       y )Nc                 t    fd|D ])  }t        |d        |d       t        d       + y )Nc                 |    | |   D ]3  }t        |z  dz  |dz          | |   g k7  s' | ||dz          5 y )Nr  r   ri   )r  r  rJ  r  rL  node_msgrM  rO  s       rh   rM  zYParforDiagnostics.dump.<locals>.dump_graph_indented.<locals>.print_graph.<locals>.print_gC  sK    !$TA)#+*;5RSU]>^*^_"1v| 'Q	 : "+rl   r  r   r-  r{  )	r  r  r3  rM  rL  rf   r|  root_msgrO  s	      @rh   print_graphzHParforDiagnostics.dump.<locals>.dump_graph_indented.<locals>.print_graphB  s7    ;
 #%5!X&FG1a(%b) #rl   )r   r  )	r   r}  r|  r~  r  rL  rf   r\  rO  s	    ``  @@rh   dump_graph_indentedz3ParforDiagnostics.dump.<locals>.dump_graph_indented@  s6    %j	* 	*  22155Au%rl   z  Trying to fuse loops #z and #r  rs  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: {}).z#%sz 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  rm  r  r#  ri   
_termwidthr  r  r  r  rg  rh  ri  rj  rA  r  rq  r   sequential_parfor_loweringr  r  r  r$  r  r  r)  rd   rZ  rd  rp  ru  )"r\  levelrV  r  r3  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  rh  r   re   
parfor_ids	n_parforsr  r  reportl1l2after_fusionr}  r|  r(  rO  s"   `                                @rh   r  zParforDiagnostics.dump  s   ~~?@@||##11||%8K G & 26t<KG!$#$!&#$!&"' L #' #' PQQI"&F?%)"A:#' %)"A:"&&*#!Nj ej3&'>LTTU_adefj3&'b 6==j#NO001BC""$6>?#
*+ <<##,,	- 77??8,D  < ""$$+,GqaddG
,
O	 "6-.55j#FG8c"Dc"j3./r>& #"11F"(KBC!2r"RS!(S.1 2
 2%'!">?'(8(8:bdmn#&&#YL#9Lnvv$iz;Zz!EAIz;Z1[] ^j3./b! &**b0!#<"D"DZQT"UV!"st3H?H'(?(?8T!*s"23!"% **>:I"-44ZDE&&y1j3&'#,33JsCD$$Y/j3&'"*s*+%  &)@:AA"cJK%%%'&&&( ' GNNtUYZ[Q  	- 77??8,D		- -d <[s   S (T T(S=<S=c                 :    d}|t        | j                        z  }|S )NzParforDiagnostics:
)r  r  r\  r3  s     rh   __str__zParforDiagnostics.__str__  s!    #	T$##$$rl   c                 
    d}|S )Nr  rk   r  s     rh   r`  zParforDiagnostics.__repr__  s     rl   r`   )r   )ry   rz   r{   rf  r]  r  propertyr  setterr  r  r  r  r  r  r  r   r  r  r)  rA  rZ  rd  rp  ru  r  r  r`  rk   rl   rh   r  r    s          '%
A

&P&
8t:*X*)X?B^D@:> 2n\`
rl   r  c                   (    e Zd ZdZi dfdZd Zd Zy)PreParforPasszwPreprocessing for the Parfor pass. It mostly inlines parallel
    implementations of numpy functions if available.
    Nc	                     || _         || _        || _        || _        || _        || _        || _        |t        }|| _        ddd| _	        y )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	            rh   r]  zPreParforPass.__init__  sV    """ ($6!%:"

rl   c                 B   t        | j                  | j                  | j                  | j                         | j
                  j                  r%| j                  | j                  j                         t        | j                  j                        | j                  _        y)z(Run pre-parfor processing pass.
        N)
r7   r  r  r  r  r  r9  _replace_parallel_functionsr  r5   r_  s    rh   r  zPreParforPass.run  sf     	 dll $	@<<,,T\\-@-@A*4<<+>+>?rl   c           	      z
     j                   ddlm t        |j	                               rj                         \  }t        j                        D ]  \  }t        |t        j                        s"|j                  } j                  |j                     |j                  t        t        j                        rAj                   dk(  r2 fd}t#        |      s j$                  dxx   dz  cc<    n*t        t        j                        sɉj                   dk(  sىj&                  dk(  s j                  j                  j                     }t        |t(        j*                  j,                        s2|j.                  }j0                  }|j2                  }	t        j4                  |t7        d	      |	      }
t(        j8                  j;                  t<               j                  |
j                  <   t        j>                  d
t<        |	      }t        j                  ||
|	      }tA        |      }|dk(  rd}t        j4                  |t7        d      |	      }t)        jB                  |       j                  |j                  <   t        j                  t        jD                  ||	      ||	      }t        j4                  |t7        d      |	      }tG        t<        j.                        }tH        jJ                  j(                  jM                  |      }|jO                   jP                   j                  |j                     fi        t(        jR                  jM                  |       j                  |j                  <   t        j                  jU                  |
d|	      }t        j                  |||	      }t        j4                  |t7        d      |	      }t(        j*                  jW                  |       j                  |j                  <   t        j                  jY                  ||gd|	      }t        j                  |||	      }t[         j                  |j                      j                  |j                            j\                  |<   ||_        j                  j_                  d|       j                  j_                  d|       j                  j_                  d|       j                  j_                  d|        j$                  dxx   dz  cc<    n ryy)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                  j                  |d       }|t        |      dk(  rt        |d   t        j                        rxt        j                  |d   j                     t        j                  j                        r:t        j                  |d   d       }|j                   j#                  d|d          t%        |d u       t'        fdj                   D              }j(                  D ci c]  \  }}|j                  |j                     ! }}}	  |g|i |}t%        |d u        t+        j,                  |      j.                  |i |j                   }t1        j0                  j                  j2                  j                  j4                        }t6        |d<   t8        |d<   t:        |d<   t<        j                  |d       }	|	|	j                  ||	j                  <    j                  ||j>                  j@                  |j                  jB                        \  }
}tE        |
d	      }|D ]N  }|jG                         D ]9  \  }}|d   d
k(  s||jH                  | jJ                     jL                  g|<    N P yc c}}w #  d }Y zxY w)Nr   r   r   c              3   P   K   | ]  }j                   |j                       y wr`   )r  rV  )r  re   r\  s     rh   r  zRPreParforPass._replace_parallel_functions.<locals>.replace_func.<locals>.<genexpr>  s     (Qy!aff)=ys   #&r   r   r  F)topological_orderingrs   T)'r?   r  rW  r9   r  r  r   r   r	   rc  r  rV  r   r   r   replace_functions_ndarrayrw   insertr<   r  kwsr   pysignaturebindr  r  __globals__r   r9  r  replace_functions_checkers_mapr  r  r  r3   r  ry   r  rm  )func_defcallname	repl_functypsr  re   kws_typsnew_funcgcheck
new_blocks_
call_tabler  r  r  exprr   r  lhs_typr\  r  	work_lists                  rh   replace_funcz?PreParforPass._replace_parallel_functions.<locals>.replace_func  s   '5dllDII'NH'4T\\4'HH(,(B(B(F(FxQU(VI ) 1 #H 2 *8A; ? *4<<8H8H+I+0>>+?+?!A,E,I,I(ST+W[,\	#,#8$(II$4$4Q$D#IT$9:#((Qtyy(Q#QDLPHH'UHDAq4<<+?(?HH'U0,5g,Q,Q,Q $HD$89#C5#4#4X#>#C#CT#VX#V#[#[D $		$,,*>*>*C*C*O*O PA).AgJ&+AdG(,AfI %C$F$FxGK%ME$005

%**,?a,11hPTP^P^,0$,,PY-[MJ *8
Y^)_J )3,0JJLDAq'(t/@'@6>	@R@RT\^c^h^hij^k^o^o5p
(- -9 )3
 $(? (V0+/s   3$KK K!r  r   getattrr   	$np_g_varr   boolbool_z$np_typ_varz$dtype_attr_varz
$dtype_varrk   r  N)0r  numba.core.inline_closurecallr  r  r  popr1  r  r   r	   Assigntargetr  rV  r  r  rl  r;   r  rf  r   r   r   r   scoperm  rc  r    miscModuler9  Globalr  StringLiteralConstfind_templater   corerR   get_call_typer  	functionsr  DTyper  rQ   r  r  )r\  r  r  instrlhsr  typr   r  rm  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   `                       @@@@@@@rh   r  z)PreParforPass._replace_parallel_functions  s    ,,E(	$==?LE5%ejj15eRYY/,,C"ll3884G ;;D!$0TWW5F0( 0(b !. JJ71<7!$T277398L))w. #ll4::??;%c5>>+?+?@ %(IIE$)KKE"'))C')vve];5OQT'UH:?**:K:KE:RDLL7#%99T5##>D*,))D(C*HK ),E
I(F2,3	&(ff %}]'CS'JG9>9L9L ):+DLL6-/YY "C 8'3.HN .0VVE=IZ;[]`-aN#0#=D$)JJ$4$4$=$=d$CE!//gllA[@]_ab@E@X@XY]@^DLL)<)<=137TW1X.02		:Ln^a0b- )+umL6QSV(WI;@>>;O;OPU;VDLL8,.GGLL'TVX[,\M+-99]Is+SL<E $Y^^ <dll7<<>X=ZDNN=9 +4EK!JJ--a>!JJ--a1BC!JJ--a@!JJ--a= JJ'78A=8!m 2 rl   )ry   rz   r{   rf  r]  r  r  rk   rl   rh   r  r    s     #%D
$@A"rl   r  c                     t         j                  j                  j                  j                  j
                  D ]  }|j                  | k(  s|c S  y r`   )r   r  r   	templatesbuiltin_registryr  r  )rl  fts     rh   r  r  ;  s9    jj))::DD66R<I Erl   c                   $    e Zd ZdZ e       fdZy)ParforPassStateszCThis class encapsulates all internal states of the ParforPass.
    c                    || _         || _        || _        || _        || _        || _        || _        |
| _        |
j                  | _	        |
j                  | _
        |
j                  | _        t        j                  | j                  | j                   | j                  | j                        | _        t        j                  j!                  t#        |j$                  j'                                      || _        |	| _        d|	vri |	d<   y y )Nr   )r  r  r  r  r  r   r  diagnosticsr  swapped_fnsr  r  rZ   ArrayAnalysisr   _the_max_labelr"  r   r  r  ry  metadata)r\  r  r  r  r   r  r  r  ry  r  r  s              rh   r]  zParforPassStates.__init__E  s     """&&&33&22"-"@"@,::NNDLL$,,
 	&&s7>>+>+>+@'AB
 H$"$HY %rl   N)ry   rz   r{   rf  r  r]  rk   rl   rh   r  r  A  s    
 /0%rl   r  c                   (    e Zd ZdZd Zd Zd Zd Zy)ConvertInplaceBinop0Parfor subpass to convert setitem on Arrays
    c                      || _         g | _        yzV
        Parameters
        ----------
        pass_states : ParforPassStates
        Npass_states	rewrittenr\  r  s     rh   r]  zConvertInplaceBinop.__init__b       'rl   c           	         | j                   }t        |      }|D ]  }||   }g }|j                  j                  |      }|j                  D ]  }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&                        rt        |t"        j$                  j&                        r_| j)                  |||
j*                  ||      }| j,                  j/                  t1        ||d             |t        j                  ||	|      g}t        |t2              r|j5                  |       |j/                  |        ||_         y )Ninplace_binopoldnewreason)r  r0   rZ   get_equiv_setr  r   r	   r  r  r  r  rl  rm  r  rhsr  rV  r   r   r   _inplace_binop_to_parforimmutable_fnr  rb  r  r  r  )r\  r  r  
topo_orderr  r  new_bodyrw  r  r  r  rm  r  r  
target_typ	value_typ	new_instrs                    rh   r  zConvertInplaceBinop.runk  s   &&$V,
  E5MEH#22@@GIeRYY/,,C ;;D!$0TWW5O"hh!% $%0%8%8%E
$/$7$7

$C	%j%..2F2FG))U^^5I5IJ,0,I,I)(+T->->-O	 $ 5 5$(U	0?%A!" *3BIIfc34O(PeT*OOE*OOE*1 $2 "EJ;  rl   c           
      l   | j                   }|j                  }|j                  |j                     }|j                  }	t        j                  ||      }
|j                  |j                     }|j                  |      }t        |j                  |||      \  }}t               }t        j                  ||      }t        |j                  |||      \  }}t        j                  |t        d      |      }|j                  |j                  |j                  <   t
        j                  j                  |||      }t        |j                  ||      |j                   |<   |j"                  j%                  t        j&                  |||             t        j                  |t        d      |      }|	|j                  |j                  <   t
        j                  j                  |||      }t        |	||      |j                   |<   |j"                  j%                  t        j&                  |||             t        j                  |t        d      |      }|	|j                  |j                  <   t
        j                  j)                  ||||      }|j"                  j%                  t        j&                  |||             | j                   j*                  j-                  |	|j                        }t        |||      |j                   |<   t        j.                  ||||      }t        t0        j2                  |||	      |j                   |<   |j"                  j%                  |       t5        ||
i |||d|j6                        }||i|_        t:        j<                  dk\  rt?        d       |jA                          |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  r-  r   zparfor from inplace_binop)!r  r  r  rV  r   r	   Block	get_shape_mk_parfor_loopsr!   _make_index_varrc  r    r  getitemrQ   r  r  rb  r  binopr  unify_pairsSetItemr   nonerh  ry  rt  r   DEBUG_ARRAY_OPTrd   r  )r\  rw  rm  rl  r  r  r  r  arr_typel_typrs  r  	size_vars
index_vars	loopnests
body_label
body_blockru  index_var_typ	value_vargetitem_call
target_varexpr_out_var
binop_exprunified_typesetitem_noder   s                              rh   r  z,ConvertInplaceBinop._inplace_binop_to_parfor  s   
 &&%%fkk2XXeS)
''

3	''/	 !11D1DiQVX[ \
I  \
XXeS)
#2##UJ
$D 	= FF5-"=sC	.7ooINN+wwui=.7OOY/7l+ryyy#FG VVE=#?E
/5JOO,wwvy#>.7G]/,l+ryyz3GH vve]?%CSI17L--. WW]]2z9cB
ryy\3GH''11==fiooV,5,-6j) zz&)\3G.7JJ/8l+|,	:r3	9-{/@/@B&
3!!Q&-.KKMrl   c                     t         j                  }| j                  j                  j	                  |t        |      i       S r`   operatorr  r  r  resolve_function_typer  r\  rw   fntys      rh   _type_getitemz!ConvertInplaceBinop._type_getitem  3    ))??eDkSUVVrl   N)ry   rz   r{   rf  r]  r  r  r0  rk   rl   rh   r  r  _  s    #"J>@Wrl   r  c                 f    t        | t        j                        r| j                  S | j                  S r`   )r   r	   r  r   ru  r  s    rh   get_index_varr3    s"     BJJ/177@Q[[@rl   c                   *    e Zd ZdZd Zd ZddZd Zy)ConvertSetItemPassr  c                      || _         g | _        yr  r  r  s     rh   r]  zConvertSetItemPass.__init__  r  rl   c           
         | j                   }t        |      }|D ]  }||   }g }|j                  j                  |      }|j                  D ]q  }t        |t        j                  t        j                  f      r2|j                  }	|j                  }
t        |      }|j                  }|j                  |
j                     }|j                  |j                     }|j                  |j                     }t        |t        j                   j"                        rt        |t        j                   j"                        r{t        |j$                  t        j&                        rV|j(                  |j(                  k(  r<t        |t        j*                        r@| j-                  ||	|
||      }| j.                  j1                  t3        ||d             |}nt        |t        j                   j"                        rt5        t6        |j8                  |j                        }t        |t        j:                        rp|j<                  dk(  r`|j>                  j                  |j                  k(  r<| j-                  ||	|
||j                        }| j.                  j1                  t3        ||d             |}n|jA                  |      }t        |t        jB                        r*tE        tG        tI        d |j                                    }n)t        |t        jJ                  jL                        rd}nd}|st        |t        j                   j"                        r||j(                  k(  r@| j-                  ||	|
|||      }| j.                  j1                  t3        ||d	             |}|j1                  |       t ||_         y )
Nmasked_assign_broadcast_scalarr   r  masked_assign_arrayc                 J    t        | t        j                  j                        S r`   )r   r   r  	SliceTyper  s    rh   r4  z(ConvertSetItemPass.run.<locals>.<lambda>  s    jEJJ<P<P.Qrl   r   r   )r   slice)'r  r0   rZ   r  r  r   r	   StaticSetItemr  rm  r  r3  r  r  rV  r   r   r   r   Booleanr   Number_setitem_to_parforr  rb  r  r;   r?   r  r  rl  r   r  r  r   r  filterr  r;  )r\  r  r  r  r  r  r	  rw  r  rm  r  r   r  r
  	index_typr  r  val_defr   sliced_dimss                       rh   r  zConvertSetItemPass.run  s   && %V,
  E5MEH#22@@GIeb&6&6

%CD))C"\\F)%0E!KKE!,!4!4V[[!AJ + 3 3EJJ ?I + 3 3EJJ ?I!*enn.B.BC&y%..2F2FG&yF&OOy~~=))U\\B,0,C,CI(+VUE-C	 $ 5 5$(U	/O%Q!" )2!+Iu~~7K7K!L*/@S@S05

+<$.w$@$+JJ)$;$+MM$6$6%**$D040G0G	,/1OI$(NN$9$9(,I4I)K%& -6E %.$7$7$>E))U__E /2$v$Q$-OO85 36 /7 ",Iuzz7K7K!L /0./
 !& 1%/	5>>;O;O%P!,	!>,0,C,CI(+VUE -D -P	 $ 5 5(,I4;)=!" )2&I $J "EJS  rl   Nc           
      
   | j                   }|j                  }|j                  |j                     }	|	j                  }
|j                  |j                     }t        j                  ||      }|rt        |t        j                        st        |t        j                        sJ |}t        j                  |t        d      |      }t
        j                  j                  |||      }t        j                   j#                  |	|      j$                  }||j                  |j                  <   | j'                  |	|f      |j(                  |<   |j+                  t        j,                  |||             |}n9t        |t        j.                        sJ |j1                  |      }|j                  }g }g }|D ]w  }t        j                  |t        d      |      }|j+                  |       t        j2                  |j                  |j                  <   |j+                  t5        |d|d             y t7               }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                  |||      }|j@                  jC                  t        j,                  |||      t        jD                  ||||      g       |j                  |j                     } t        | t        jF                  jH                        rt        j                  |t        d      |      }!| j                  |j                  |!j                  <   t
        j                  j                  |||      }tK        | j                  | |      |j(                  |<   |j@                  j+                  t        j,                  ||!|             n|}!t        jL                  |||!|      }"tK        t        jN                  |j                  |j                     ||
      |j(                  |"<   |j@                  j+                  |"       |r/|j@                  j+                  t        jP                  ||             tR        jT                  dk\  rtW        d	       |jY                          |S )
r  z$subarrparfor_indexr   r   )setitemr-  Nz	$mask_varr  zparfor from setitem)-r  r  r  rV  r   r	   r  r   r   r  r;  rc  r    r  r  r   	arraydeclget_array_index_typeresultr0  r  rb  r  ArrayCompatibler  uintprY  r!   r  rh  ry  rt  r  r  Branchr   r   rQ   r  r  Jumpr   r  rd   r  )#r\  rw  rm  r  r   r  r   r  r  r  r  rB  rs  r  
subarr_varr$  
subarr_typbool_typr  r  size_varru  r   r!  r"  r   
true_block	end_label
true_label	end_blockmask_varmask_valr  r#  r)  s#                                      rh   r@  z%ConvertSetItemPass._setitem_to_parfor7  sO   
 &&%%fkk2''

3	XXeS)
 i9i9; : I}Y'?EJ77??65#>L))>>SZZJ3=K
0262D2DgyEY2ZK!!,/biij#FGF i)>)>?@?!++F3I H 	
!HumN&CSIIi(27++K	/XiHa@A	 "  \
XXeS)
#2##UJ
$D 	=	:r3	9'):):< *J7F#JI $J%-J"I,I *J *J )I "F vve];%?EH19K.wwui=HOO""yy8S1yy:y#>$ 
  ''

3	i!5!56umL&A3GI2;//K	/77??5)SAL2;M3;K!!,/OO""299\9c#JKIzz&)YD.7JJ++FKK8-/Ql+|,OO""2779c#:;!!Q&'(KKMrl   c                     t         j                  }| j                  j                  j	                  |t        |      i       S r`   r+  r.  s      rh   r0  z ConvertSetItemPass._type_getitem  r1  rl   r`   )ry   rz   r{   rf  r]  r  r@  r0  rk   rl   rh   r5  r5    s     P"d\|Wrl   r5  c                 l   t        |      }|j                  }|dkD  s|rt        j                  |t	        d      |      }t
        j                  j                  t
        j                  |      | |j                  <   t        j                  j                  t        |      |      }t        j                  |||      }	|j                  j                  |	       |t
        j                  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rm  )r   rm  r	   rc  r    r   
containersUniTuplerL  rV  r  build_tupler  r  r  rb  r   UnsupportedRewriteError)
r  r  r  r!  force_tuplendimsrm  	tuple_var
tuple_calltuple_assigns
             rh   r  r    s     
OE
..CqyKFF5-%#'(+-	"'"2"2";";KK# 	WW((j)93?
yyY<|,%**33EKKGGG	!!}ekk)),,:
 	
rl   c           	          g }g }|D ]m  }t        j                  |t        d      |      }|j                  |       t        j
                  | |j                  <   |j                  t        |d|d             o ||fS )zN
    Create loop index variables and build LoopNest objects for a parfor.
    rF  r   r   )r	   rc  r    rb  r   rL  rV  rY  )r  r  r  rm  r  r  rR  ru  s           rh   r  r    su     IJFF5-"?E	)$"'++	)Q!<=	 
 y  rl   c                   @    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)ConvertNumpyPassz]
    Convert supported Numpy functions, as well as arrayexpr nodes, to
    parfor nodes.
    c                      || _         g | _        y r`   r  r  s     rh   r]  zConvertNumpyPass.__init__      &rl   c           	      \   | j                   }t        |      }g }|D ]  }||   }g }|j                  j                  |      }|j                  D ]Q  }	t        |	t        j                        r"|	j                  }
|	j                  }| j                   j                  |j                     }| j                  |      rt        | j                  |
      r?| j                  |||
      }|| j                   j#                  t%        |	|d             |}	nft        |
t        j&                        rL|
j(                  dk(  r=| j+                  |||
|      }| j                   j#                  t%        |	|d             |}	|j#                  |j                         |j#                  |	       T ||_         y )Nnumpy_allocatorr   	arrayexpr)r  r0   rZ   r  r  r   r	   r  r  r  r  rV  _is_C_or_F_orderr;   _is_supported_npycall_numpy_to_parforr  rb  r  r  rl  _arrayexpr_to_parfor)r\  r  r  r  
avail_varsr  r  r	  rw  r  r  r  r  r  s                 rh   r  zConvertNumpyPass.run  sx   &&$V,
 
E5MEH#22@@GIeRYY/ ;;D,,C"..66sxx@G,,W5 !;!;TB(,(=(=id(SI(4 $ 5 5d(-(1+<7" !#
 )2'bgg6477k;Q(,(A(A )3j)BI NN11$$)$-'23 
 %.E%%chh/&3 $4 "EJ=  rl   c                 Z   t        |t        j                  j                        r |j                  dk(  xr |j
                  dkD  S |t        u r_| j                  j                  |   }t        |t        j                  j                        xr  |j                  dk(  xr |j
                  dkD  S y)NCr   F	r   r   r   r   layoutr   r  r  r  r\  arr_namer  s      rh   _is_C_orderzConvertNumpyPass._is_C_order  s    h 4 45??c)?hmma.??_""**84CsENN$8$89 !JJ#%!HHqL" rl   c                    t        |t        j                  j                        r1|j                  dk(  xs |j                  dk(  xr |j
                  dkD  S |t        u rp| j                  j                  |   }t        |t        j                  j                        xr1 |j                  dk(  xs |j                  dk(  xr |j
                  dkD  S y)Nrs  Fr   Frt  rv  s      rh   rm  z!ConvertNumpyPass._is_C_or_F_order  s    h 4 45OOs*Dhoo.D[(--Z[J[[_""**84CsENN$8$89 !ZZ3&;#***;!HHqL" rl   c                 P   | j                   }|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                  j)                  t+        |j,                  |j                  |j                  |j                  |||||||             dj/                  t1        |j                              f}t3        ||i ||||d   |j4                        }t        j6                  ||||      }t9        t:        j<                  |j                  |j
                     ||
      |j                  |<   |j                  j?                  |       ||i|_         tB        jD                  dk\  rtG        d       |jI                          |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  rm  r  r  rV  r   r  r  r	   r  r"   r  r  r  r  r!   rc  r    r  r  _arrayexpr_tree_to_irr  r$  repr_arrayexprrh  ry  r  rQ   r   r  rb  rt  r   r  rd   r  )r\  rw  r  rl  rq  r  r  rm  r  r  r  r  r  r  rs  r   r!  r&  ru  r"  patr   r)  s                          rh   rp  z%ConvertNumpyPass._arrayexpr_to_parfor	  sV    &&		gg~~%%chh/ '',	 01D1DiQVX[ \
I XXeS)
"!!!6!6)feS)	+

  \
XXeS)
vve]?%CSI17L--.#2
J$@ 	= 	!##%%##%%	 %++N9>>,JKM	:r3	9cRSfVaVgVghzz#y,D.7JJ++CHH5}f/Nl+|,&
3!!Q&)*KKMrl   c                     t        | j                  j                  |      \  }}t        |t              r|j                  d      sy|dv ry|dk(  r	|t        v ryy)zLcheck if we support parfor translation for
        this Numpy call.
        r9  Fr   onesTnumpy.random)r9   r  r  r   r  
startswithrW   )r\  r  	call_namemod_names       rh   rn  z&ConvertNumpyPass._is_supported_npycallC  s\     ,D,<,<,D,DdK	88S)h.A.A'.J))~%)|*Crl   c                    t        | j                  j                  |      \  }}|j                  }t	        |j
                        }|dv s|dk(  r| j                  ||||||      S t        j                  d| |j                        )Nr  r  zparfor translation failed for r[  )
r9   r  r  rw   r  r  _numpy_map_to_parforr   r_  rm  )r\  rw  r  r  r  r  rw   r  s           rh   ro  z!ConvertNumpyPass._numpy_to_parforQ  s    +D,<,<,D,DdK	8yy488n))X-G,,Y	3cSWXX,,,TF3
 	
rl   c                    | j                   }|j                  }|j                  }	|j                  |j                     }
|
j
                  }|j                  |      }|t        j                  dk\  rt        d       y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                  j5                  |       |j                  |j6                  j                     j9                  t;        j<                         ||      |j                  |<   |}nt?        djA                  |            t        jB                  |||	      }|j"                  jE                  |       t        jF                  ||||	      }tI        tJ        jL                  |j                  |j                     ||      |j                  |<   |j"                  jE                  |       tO        ||i |	||d	jA                  |      d
f|jP                        }||i|_)        t        j                  dk\  rt        d       |jU                          |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  rm  r  rV  r   r  r   r  rd   r  r	   r  r"   r  r  r  r  r!   rc  r    r  r  rW   _remove_size_arg_get_call_arg_typesr  rW  r  r   ContextNotImplementedErrorr$  r  rb  r  rQ   r   r  rh  ry  rt  r  )r\  rw  r  r  rw   r  r  r  r  rm  r  r  r  r  r  rs  r   r!  r&  ru  r"  r  new_arg_typsnew_kw_typesvalue_assignr)  r   s                              rh   r  z%ConvertNumpyPass._numpy_map_to_parfor\  s    &&		gg%%chh/ '',	%%*KL 01D1DiQVX[ \
I XXeS)
"!!!6!6)feS)	+

  \
XXeS)
vve]?%CSI17L--.#2
J$@ 	= HHVAY,E& HHVAY,E,&Y-)<k))*+&L,!!%%d+*5*=*=diinn*M*[*[ ,+>K!!$'E%>EEiPR R yyc:|,zz#y,D.7JJ++CHH5}f/Nl+|,	:r3	9&--i9?K#))+ '
3!!Q&34KKMrl   N)ry   rz   r{   rf  r]  r  rx  rm  rp  rn  ro  r  rk   rl   rh   rg  rg    s2    $"L		8t	
Brl   rg  c                   (    e Zd ZdZd Zd Zd Zd Zy)ConvertReducePassz:
    Find reduce() calls and convert them to parfors.
    c                      || _         g | _        y r`   r  r  s     rh   r]  zConvertReducePass.__init__  ri  rl   c           	      @   | j                   }t        |      }|D ]  }||   }g }|j                  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                   j#                  t%        |	|d             |	}|j#                  |        ||_         y )N)r   r   )r   
_functoolsr   )r  r  r  )r  r0   rZ   r  r  r   r	   r  rm  r  r  r;   r9   r  _reduce_to_parforrw   r  rb  r  )r\  r  r  r  r  r  r	  rw  r  r   rm  r  r  r  s                 rh   r  zConvertReducePass.run  s   &&$V,
E5MEH#22@@GIeRYY/))C,,C ;;D$]K4G4GNH $::#'??!&t'='=y#'+yy#"7--d & %#+/ 
 !'&' $( "EJ1  2 	rl   c                    | j                   }|j                  }|d   }|d   }t        |j                  |j                        }	d}
d}t        t        |j                  |j                  |	      }|r|\  }}
}}|d   }|j                  ||n|
      }|yt        |j                  |||      \  }}|rt        d      |}t        j                  ||      }|j                  j                  t        j                   |||             t#               }| j%                  |||||      \  }}|rt        d      |
t'        |j)                               }t+        |j)                               }t        j                  ||      }|||<   t        j,                  |t/        d      |      }|j                  |j                  <   t        j0                  j3                  |
||      }|j                  j5                  t        j                   |||      t        j6                  ||||      g       t9        ||||||dj;                  |      df|j<                        }t>        j@                  dk\  rtC        d	       |jE                          |S )
zy
        Convert a reduce call to a parfor.
        The call arguments should be (call_name, array, init_value).
        r   r   Nr   unreachablez	$mask_valr  	reductionzparfor from reduction)#r  r  r?   r  rV  r;   
_find_maskr  r  r  AssertionErrorr  r	   r  r  rb  r  r!   _mk_reduction_bodyr   r  r   rc  r    r  r  r  rM  rh  r$  ry  r   r  rd   r  )r\  rw  r  rw   rm  r  r  r  r   arr_defrW  mask_indicesmask_query_resultmask_typr   r  r  
mask_indexacc_varrs  r   ru  rt  rU  false_labelr!  maskrX  r   r  s                                @rh   r  z#ConvertReducePass._reduce_to_parfor  sb   
 &&		G	a !4!4fkkB "*k.A.A;CVCVX_`7H4FHh7'',2FHU	 01D1DiQVX[ \
I
 // XXeS)
ryy7C@A  \
#66y %sJ I	9 // Y^^-.Jinn./K%-J$.Ij!66%{!;SAD-5K		*wwxC@HOO""yy4-yyz;<$ 
 	:y#y!M$8$8$C$/$12=2C2CE !!Q&)*KKMrl   c           	         ddl m} | j                  }t        |j                  |      }	 ||j                  |	      }
|j
                  |j                     }|j                  }t        j                  ||      }t        |j
                  |||      \  }}t        j                  |t        d      |      }||j
                  |j                  <   t        j                  j                  |||      }t        |||      |j                   |<   |j#                  t        j$                  |||             t'        |
|j                  j(                  j*                  j,                  |j.                  |j0                  ||f|j
                  |j                         }|j2                  }t5               }t        j                  ||      }|||<   t7        |j2                  j9                               }|j2                  |   }|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  rV  r   r	   r  r  rc  r    r  r  rQ   r  rb  r  r>   r  rW  r  r  r  r  r!   r   r  r  r  rA   rB   )r\  r  r  rm  r  r   r  r  r  reduce_funcfcoder  in_typr!  ru  index_var_typetmp_varr$  reduce_f_irrt  rT  rV  first_reduce_labelfirst_reduce_blocks                           rh   r  z$ConvertReducePass._mk_reduction_body	  s   
 	D&&$[%8%8)D!+"5"5{C%%fkk2XXeS)
$3
J%@!	> &&f 5s;,2GLL)wwvy#>.7G^/-l+"))L'3?@)%(3(;(;(C(C(H(H(T(T(3(=(=(3(=(=)/(8(3(;(;(3(=(=?  &&	L	HHUC(	(	) !3!3!8!8!:;(//0BC1667",//,w.@A	7I6)##rl   N)ry   rz   r{   rf  r]  r  r  r  rk   rl   rh   r  r    s    >AF)$rl   r  c                   @    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)ConvertLoopPassz*Build Parfor nodes from prange loops.
    c                      || _         g | _        y r`   r  r  s     rh   r]  zConvertLoopPass.__init__:	  ri  rl   c                   @ABCDEFG | j                   Gt        |      \  }}t        |      }t        |      }t	        |||j
                  |j                        B|j                         }|j                         D cg c]  }||   t        ||   j                        f! }}g }	t        |d       D 	]  \  C}
t        Cj                        dk7  st        Cj                        dk7  rt        j                  sCj                  D ]  }||   j                  D ]  }t!        |t"        j$                        st!        |j&                  t"        j(                        sC|j&                  j*                  dk(  s]| j-                  |j&                  j.                  j0                  |      sd}t3        j4                  t7        j8                  ||j:                                 .t=        Cj                        d   }||   j                  D ]y  }t!        |t"        j$                        st!        |j&                  t"        j(                        sD|j&                  j*                  dk(  s^| j-                  |j&                  j.                  j0                  |      sCj                  D cg c]  }||v r|Cj>                  k7  r| }}|j&                  j@                  }| jC                  |j&                  j.                  j0                  |      \  }}|Cj>                     j                  d d }d EtE        |      D ]x  \  }}t!        |t"        j$                        s!t!        |j&                  t"        j(                        sF|j&                  j*                  dk(  s`|jF                  j0                  E|} n EJ |d  ||dz   d  z   }tI        d|Cj>                     iGjJ                        \  }}|d   }tM        Efd	|D              FFjO                  E       ||   jP                  }|j:                  }GjR                  jU                  Cj>                        }t#        jV                  ||      }| jY                  ||   ||      |_
        |D ci c]  }|||   
 c}Dt[               }t#        jV                  ||      D|<   tM               }|D ]   }|j]                  |j                  |         }" tM               }Cj                  D ]  }|j]                  B|         } |j_                  |      } | j_                  | D !ch c]5  }!t!        GjJ                  |!   t`        jb                  jd                        s|!7 c}!      } |D ]P  }D|   j                  d   }"t!        |"t"        jf                        s0|"jF                  Cj>                  k(  sJ||"_#        R DFfd
@d }#d }$@BCGfd}%d}&|dk(  r|ji                  |d         sJ tk        |%|d         }'|'r|'\  }(}#})}$n|d   }(t!        |(t"        jl                        sJ GjJ                  |(j0                     }*t!        |*t`        jn                        rZt#        jl                  |tq        d      |      }+t`        jr                  GjJ                  |+j0                  <   tu        |+d|(d      g}|+gAn0|jw                  |$|(n|#      },ty        GjJ                  |,||      \  A}t        |      dkD  sJ A}-|$rt{        Afd|$D              ADt}        Dj                                  }.t#        jV                  ||      }/t        GjJ                  |A|/d      \  }+}0|/j                  |.j                  z   }1|1|._
        |$r|-d   }2n|+}2|#t        d      d}9d}:|d   };t        |      dk(  r
|d   }9|d   };t        |      dk(  r|d   }9|d   };	 Gj                  j                  |d         }:t!        |:t"        j                        s!t7        j                  d|j:                        |:j&                  }:|:dk7  r!t7        j                  d|j:                        t#        jl                  |tq        d      |      }+t!        |9t              r|9dk\  rt`        jr                  }0nt`        j                  }0d}&tu        |+|9|;|:      g}|0GjJ                  |+j0                  <   t}        Dj                               }<|D|<   j                  z   D|<   _
        FD =ci c]  }=|=|+ }>}=t        D|>       |&r| j                  DF|+       t        ||D||$r2n|+|d||fGj                  | 	      }?|?g|Cj>                     _
        |Cj>                     j                  j                  |       |Cj>                     j                  j                  t#        jf                  t=        Cj                        d   |             | j                  j                  t        C|?d             |D ]#  }|Cj>                  k7  s|j                  |       % t        j                  dk\  s_t        d       |?j                          | 	 y c c}w c c}w c c}w c c}!w # t        $ r" t7        j                  d|j:                        w xY wc c}=w )Nc                     | d   S r  rk   )tups    rh   r4  z%ConvertLoopPass.run.<locals>.<lambda>I	  s    3q6rl   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   r  
pair_firstc              3   4   K   | ]  \  }}|k(  s|  y wr`   rk   )r  tr  
loop_indexs      rh   r  z&ConvertLoopPass.run.<locals>.<genexpr>	  s     )O1qJ!s   c                  b   t        j                         } j                         D ]  }|j                  t        j                        D ]e  }t        |j                  t        j                        s(|j                  j                  | v sA| j                  |j                  j                         g  g }g }j                         D ]  }|j                  D ]  }t        d |j                         D              }|| z  s)|j                  |       r;t        t        |t        j                               |j                  }t        t        |t        j                         xr |j"                  dv        |j%                  |j                  j                         |j%                  |         ||fS )zfind expressions that involve getitem using the
                        index variable. Return both the arrays and expressions.
                        c              3   4   K   | ]  }|j                     y wr`   rV  r  re   s     rh   r  zCConvertLoopPass.run.<locals>.find_indexed_arrays.<locals>.<genexpr>	  s     (J9IA9I   r  static_getitem)r  r  
find_instsr	   r  r   r  rc  rV  r  r  r  r  re  issubsetr<   r  rl  rb  )	indicesr  r  arrsexprslvr  rt  loop_index_varss	          rh   find_indexed_arraysz0ConvertLoopPass.run.<locals>.find_indexed_arrays	  sC    #'))O"<%.%5%5%7E(-(8(8(C$.tzz266$B$(JJOOw$>$+KK0@0@$A )D &8
  " "%.%5%5%7E(-

%((J9I(J%J#%<'){{7';(0$+JtRYY,G$H+/::D$+JtRWW,E -P'+ww2O'O%Q$(KK

$@$)LL$6 )3 &8  $U{*rl   c                 \   t        j                  |       }t        |xr< t        |t        j
                        xr  |j                  dk(  xr |j                  dk(         |j                  }t        j                  j                  D cg c]  }|   	 c} } 
       \  }}t        |j                  gt        |      k(         t        |j                  |v       t        j                  |j                        }t        j                  j                  |      }t!        d      c c}w )zFind the case where size_var is defined by A[M].shape,
                        where M is a boolean array.
                        r  r   r  )r?   r  r<   r   r	   r  rl  rf  r  r  r  exitsrV  r  r  r  r  )rR  size_defarr_varrf   	live_vars
index_arrsindex_exprsr  rJ  r  r  live_mapr  r  s             rh   find_mask_from_sizez0ConvertLoopPass.run.<locals>.find_mask_from_size	  s    $2+2E2Ex#P !VZ"''-J !V (y 8!V=E]]g=UW"*..$'IITZZ/PZZ/P$Q	2E2G/
K$z2B BCI =>"01D1Dhnn"U!+K,?,?ATATV]!^ -];; 0Qs   
D)Tr   rF  c              3   0   K   | ]  }|r|nd      yw)r   Nrk   )r  re   r  s     rh   r  z&ConvertLoopPass.run.<locals>.<genexpr>
  s%      /F8D1 56q:a=/H8Ds   )r`  r  r   r   z,Only known step size is supported for pranger[  z/Only constant step size is supported for prangez4Only constant step size of 1 is supported for prangeFr   )rj  r  )old_loopr  r  zparfor from loop)Xr  r3   rN   rK   rL   usemapdefmaploopsr  r   r  r  entriesr  r   DISABLE_PERFORMANCE_WARNINGSr   r	   r  r  r  rl  _is_parallel_looprW  rV  warningswarnr   NumbaPerformanceWarningrm  r  headerrw   _get_loop_kindr1  r  r-   r  r  r  r  rZ   r  r  _get_prange_init_blockr!   r  intersectionr   r  r  rN  	has_shaper;   rc  Integerr    rL  rY  r  r  r  r   r  r  r8   r   r  r  rM  r  r?   rm  r_  r  r  intpr'   _replace_loop_access_indicesrh  ry  rb  r  r  r  r  rd   r  )Hr\  r  r  r  cfgusedefsr  r  sized_loopsmoved_blocksr   entryr  r  rf   body_labelsrw   	loop_kindloop_replacingheader_bodyhbir  li_indexcpsr  rm  rw  rs  rT  bodydefsbl
exit_livesrj  re   	last_instrW  r  r  unsigned_indexrJ  r   r  
in_arr_typru  r  
orig_indexfirst_body_blockr!  r"  r  orig_index_varr   labelsrU  r  r  rX  r  r  rR  first_body_labelr  index_var_mapr   r  r  r  r  rt  r  r  r  sH                                                                   @@@@@@@@rh   r  zConvertLoopPass.run>	  s	   &&&v.
A%f-"6*#CP		?Dzz|L|!a#eAhmm"45|Lk/ABBGD!4<< A%TZZA)=::!%$*5M$6$6D !+4 ;$.tzz277$C$(JJMMV$;$($:$:$(JJOO$8$8*%F'4
 !)$*$B$B(+TXX%7!8 %7 ".$ &q)Eu**tRYY/&tzz277; JJMMV3 224::??3G3GT 04yy #Gy!$%KA4D %&yK #G::??D040C0CDJJOODXDXDN1P-I~ #)"5":":3B"?K!%J%.{%;	T&tRYY7$.tzz277$C$(JJMM\$A)-)9)9J'*H! &< &121 #.ix"8;xPQz{;S"SK .q&2E.F.9.A.ACFCa&C&))O)O&OO#''
3"5M//E((C + : : H H UI!#%!5J&*&A&A&-<F'NJO7B C{!F1I{ CI *I+-88E3+?Ii(  #uH)#+>>'..2D#E *!$J"jj%/%5%5hrl%C
 )$11*=E "..5 0\5a%/0C0CA0F

HYHY%Z 125 0\ ]E )$-aL$5$5b$9	&y"'':%,,;/8I,	 )+4  $H#'L&6 &*N !J.(2247;<; "'':DG!D!GMDFHh%)!WF)&"&&9:9%0%8%8%E
%j%--@(*umN6SUX(YIBG++K//	?%-iFA%F$GE*3J(1(;(;-9-A =CGO)QI0@ + 3 3Ys1-J  #5zA~.~%/
' */ /F8D/F *FJ+4S9I5J+K(%'XXeS%9
3B'//
J(,40	=  *1A1F1FF04(-'-7]N-6N $/"0"??$ !" #'7t9>$(GE'+AwHt9>$(GE'+AwH"'2':':'I'I$q''R $.dBHH#=&,&D&D$U(,'" !" $(::D#qy&,&D&D$Z(,'" !" %'FF5-2OQT$U	 &eS1eqj,1KKM,1JJM-2N!))UHd!K L>K++INN; ,/y~~/?+@(;FScIdIiIi;i	"238;J$K?aQ	\?M$K M:% 99%	C#E:y#6BN	$-%-y.$I$/$5$5U	DF 17xF4;;',
 4;;',,33K@4;;',,33BGGD<LQ<OQT4UVNN))$!%"%+  )+"JJqM ) --201m +1 C ML#GN !D&0\` $, "&,&D&D$R(,'" !""D %Ls*   =$j	%j	j::j j"
k+kc                     ||vry||   }t        |      dkD  xrF |d   dk(  xs< |d   t        k(  xs. |d   dk(  xs$ |d   t        k(  xs |d   dk(  xs |d   t        k(  S )NFr   r   rs   r   )r   r   rs   r   r\  func_varr  r  s       rh   r  z!ConvertLoopPass._is_parallel_loopy
  s    :%(#4y1} A$q'X"5 #@aF9J #@7//#@377o3M#@7j(#@,0Gx,?	Arl   c                 "   | j                   }||v sJ ||   }t        |      dkD  sJ d}|d   dk(  s|d   t        k(  r)	 d|j                  |   d   |j                  |   d   ff}|S |d   dk(  s|d   t
        k(  rd}|S # t        $ r d}Y |S w xY w)	z(see if prange is user prange or internalr   )r  r-  rs   r  r  )r  )r-  r-  r   )r   r-  )r  r   rs   r  rm  r   )r\  r  r  r  r  kinds         rh   r  zConvertLoopPass._get_loop_kind
  s    &&:%%%(#4y1}}7''47o+E,!K$;$;H$Ea$H+JaJabjJklnJo#pp  !W
"d1g&9!D  , , ,s   &A? ?BBc                 p   d}d}g }t        |j                        D ]  \  }}t        |t        j                        rot        |j
                  t        j                        rK|j
                  j                  dk(  r2| j                  |j
                  j                  j                  |      r|}t        |t        j                        st        |j
                  t        j                        s|j
                  j                  dk(  s| j                  |j
                  j                  j                  |      s|}  |dk7  r|dk7  r|D 	ch c]  }	|	j                   }
}	g }t        t        |dz   |            D ]e  }|j                  |   }|j                         D 	ch c]  }	|	j                   }}	|
|z  r|
|z  }
|j                  |       U|j                  |       g |j!                          |j!                          |j                  d| |z   |j                  |dz   d z   |_        |S c c}	w c c}	w )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  r   N)r1  r  r   r	   r  r  r  rl  _is_prange_initrW  rV  r  r  ru   re  rb  reverse)r\  entry_blockr  prange_argsinit_call_indprange_call_ind	init_bodyr   r  r  arg_related_varssaved_nodes	inst_varss                rh   r  z&ConvertLoopPass._get_prange_init_block
  s   
 	 !1!12GAt4+
4::rww0O

/,,TZZ__-A-A:N !4+
4::rww0O

/..tzz/C/CZP"# 3 B?b#8 1<<1<KeM!O_EF"''*-1^^-=>-=QVV-=	>#i/$	1$&&t,$$T* G ! + 0 0- @%!&(3(8(89J9K(L!MK !  = ?s   H.H3c                 b    ||vry||   }t        |      dkD  xr |d   dk(  xs |d   t        k(  S )NFr   rm   )r   rm   r  s       rh   r  zConvertLoopPass._is_prange_init
  sA    :%(#4y1}U$q']":"Td1g>TUrl   c                    |j                  |j                         t        |      5  t        |      }ddd       d   }t	               }|D ]*  }||   }|j
                  D ]  }	t        |	t        j                        rBt        |	j                  t        j                        r||k(  r{|	j                  j                  |v rc|	j                  j                  |vrK|j                  |	j                  j                         |j                  |	j                  j                         n|j                  fd}
 |
|	j                  j                        t        |
|      v rd |
|	j                  j                         |
|	j                  j                        k7  r+t        j                  d|	j                  j                         t#        |	      rxt%        |	      }|{t'        t(        | j*                  j,                  |d      }|j                  |v s||j                  |v rt/        |	|       t'        | j0                  |||       t        |	t2              s| j5                  |	j6                  ||        - ||z  }y# 1 sw Y   OxY w)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                 v    ddl m} 	 j                  |       j                  S # |j                  $ r | cY S w xY w)Nr   )r   )
numba.corer   	get_exactunversioned_nameNotDefinedError)rV  r   r  s     rh   unverz;ConvertLoopPass._replace_loop_access_indices.<locals>.unver
  s:    9,',t'<'M'M M#)#9#9 ,'+,s   $ 88z Overwrite of parallel loop indexr[  T)lhs_only)r  rV  dummy_return_in_loop_bodyr0   r  r  r   r	   r  r  rc  r  r  mapr   r_  rm  rE   rF   r;   r?   r  r  rG   _replace_multi_dim_indrh  r  rt  )r\  rt  	index_set	new_indexr  first_labeladded_indicesrf   r  r  r  r   ind_defr  s                @rh   r  z,ConvertLoopPass._replace_loop_access_indices
  s#    	inn%&y1$Y/F 2 Qi
 AaLE

tRYY/&tzz266: [(TZZ__	-I $ 0 0	 A!dkk&6&67%))$++*:*:; !&, !!1!12c%6KKPUVZVaVaVfVfPgkpquq{q{  rA  rA  lB  QB"("@"@ B$(KKOO#  "$'4T:E} #ND4D4D4L4L$)D:G

i/ ' 3$+LLI$=4T9E $55w	ENP dF+55dnniQZ[[ # d 	]"	y 21s   JJc                    | j                   }t        |du       t        t        |j                  |j                     t
        j                  t
        j                  f             t        |j                  |      }t        t        |t        j                        xr |j                  dk(         |j                  D cg c]  }|j                  |v r|n| c}|_        yc c}w )zq
        replace individual indices in multi-dimensional access variable, which
        is a build_tuple
        Nr^  )r  r<   r   r  rV  r   Tupler]  r?   r  r	   r  rl  r  )r\  ind_varr  r  r  ind_def_noder  s          rh   r  z&ConvertLoopPass._replace_multi_dim_ind	  s    
 &&t#$
;..w||<enn-/ 	0%k&9&97C
<1 5 OO}4	6 (4'9'9;'9! ,-66Y+>iAE'9; ;s   <CN)ry   rz   r{   rf  r]  r  r  r  r  r  r  r  rk   rl   rh   r  r  7	  s6    y&v	A(%NVDL;rl   r  c                 &   t        t        |t        j                        xr |j                  dk(         |j
                  }|j                  }| |j                     }| |j                     }|j                  }t        t        |t        j                  j                               t        |t        j                  j                        rCt        |j                  t        j                        r||j                  k(  r|||j                  dfS t        |t        j                        rgt        ||      \  }}	t        |	dk(  xr t!        |      |k(         d}
g }d}|D ]  }| |j                     }t        |t        j                  j                        rDt        |j                  t        j                        r |}|j                  }|j#                  d       {t        |t        j                  j                        rDt        |j                  t        j$                        r |}|j                  }|j#                  d       t        |t        j$                        s|
dz  }
|j#                  |        t        |xr |
|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  Nr^  r   r   )r<   r   r	   r  rl  r  r   rV  r   r   r   r   r   r>  r  r:   r   rb  r  r=   )r  r  r  r  r   r  rB  r   seqrl  count_constsr  rW  indr  s                  rh   r  r    s    Jw(DWZZ9-DEMMEMME

#I

#I>>DJy%.."6"6789enn2239??EMM2	eY__d22	Iu	/ &gu5Rm#8CD(89C)I9enn&:&:;9??EMM:$??##D)Y(<(<=9??EMM:$??##D)Iu}}5!##C(# & 	5\TAX56h,66
rl   c                   (    e Zd ZdZd Zd Zd Zd Zy)
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                  j                         t        j
                  j                  t	        j                  | j                  j                               y r`   )rZ   r  r  r  r   r  r"  find_max_labelr_  s    rh   _pre_runzParforPass._pre_runS  sL     3 34&&##DLL$7$78	:rl   c           	      f   | j                          | j                  j                  rgt        | j                  | j
                  | j                  | j                  | j                  | j                  | j                        }|j                          | j                  j                  r.t        |       j                  | j                  j                         | j                  j                  r.t!        |       j                  | j                  j                         | j                  j"                  r.t%        |       j                  | j                  j                         | j                  j&                  r.t)        |       j                  | j                  j                         | j                  j*                  r.t-        |       j                  | j                  j                         | j.                  j1                  | j                  | j                  j2                         t5        | j                  d       y)zgrun parfor conversion pass: replace Numpy calls
        with Parfors when possible and optimize the IR.zafter parfor passN)r)  r  stencilr   r  r  r  rZ   r  r  ry  r  rG  r5  r  r9  rg  r  r  r   r  r  r  r  r  fusionr/   )r\  stencil_passs     rh   r  zParforPass.runZ  sh    	<<&t||T\\'+~~t7J7J'+~~t~~'+zz3L <<t$(()<)<=<<T"&&t||':':;<<!!d#''(;(;<<<D!%%dll&9&9:<<%%%))$,,*=*=> 	t||T\\-@-@At||%89rl   c                 D    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     rh   r  zParforPass._find_masku  s     $,,g>>rl   c                 2    t        | j                  |||      S )zV
        Create loop index variables and build LoopNest objects for a parfor.
        )r  r  )r\  r  r  rm  s       rh   r  zParforPass._mk_parfor_loops}  s      iDDrl   N)ry   rz   r{   rf  r)  r  r  r  rk   rl   rh   r&  r&  K  s    ::6?Erl   r&  c                   "    e Zd ZdZd Zd Zd Zy)ParforFusionPassz=ParforFusionPass class is responsible for fusing parfors
    c                 f   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                  j                         t        | j                  j                  | j                  j                  | j                         \  }}|D ];  }t#        | j                  ||j$                  | j
                        \  |_        |_        = t+        | j                  | j                  j                  | j                  d       t-        | j                  d       | j/                  | j                  | j                  j                  | j                  | j                         t-        | j                  d       t+        | j                  | j                  j                  | j                         t-        | j                  d       | j/                  | j                  | j                  j                  | j                  | j                         t-        | j                  d       t        | j                  | j                  | j
                  | j                  d          y	y	y	)
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  r,  r@   _definitionsr  rZ   r  r  get_parfor_paramsr  get_parfor_reductionsrv  rz  r{  maximize_fusionr/   fuse_parfors)r\  r  r  r   r  s        rh   r  zParforFusionPass.run  s7   
 -T\\-@-@A	t||T^^T]]9=UV 	t||T^^T]]9=UV<<9>(9$,,:M:M(NDLL%-1VD*##DLL$7$78 +4<<+>+>+/<<+>+>+/+B+BDJAw '<T\\=>=>XX=A^^(M$	19  DLL$,,*=*=t||INP4<<)EFd11"ll11"ll"ll, 4<<);<DLL$,,*=*=t||L4<<)CDd11"ll11"ll"ll, 4<<8T\\4<<yAYZM $2rl   c           	         |j                         D ]  \  }} |j                  |      }d}|sd}g }	d}
|
t        |j                        dz
  k  rj|j                  |
   }|j                  |
dz      }t	        |t
              rt	        |t
              r |j                  |      }||_        ||_        t        |||| j                  d   ||      \  }}| j                  j                  j                  |       |kd}| j                  j                  |j                     j                  |j                  g       |	j                  |       | j                  ||||       |
dz  }
/|	j                  |       t	        |t
              r| j                  ||||       |
dz  }
|
t        |j                        dz
  k  rj|	j                  |j                  d          |	|_        |r y )NTFr   r   r   r   r  )r  r  r   r  r   rh  rw  try_fuser  r  r  rb  r  rq  r  fuse_recursive_parfor)r\  rZ   r  r  r  r  r  rw  fusion_happenedr	  r   r  	next_stmt
fused_nodefuse_reports                  rh   r9  zParforFusionPass.fuse_parfors  s   "LLNLE5444U;I"O!"'#ejj/A-- ::a=D %

1q5 1I!$/Jy&4Q %AN$@$@$G	)2.7	+2:9dI MM)4gw3H/
K ((77>>{K%1.2O ,,88AHH),,X$OOJ7 66z9gW^_FA$OOD)!$/224GWUFA/ #ejj/A--0 

2/%
; " +B 	rl   c                 l   t        |      }t        | j                  || j                         t	        | j                  d|       t        j                  | j                  | j                  | j                  | j                        }|j                  ||       | j                  ||||       t        |       y )Nz$after recursive maximize fusion down)r  r8  r  r  r/   rZ   r  r  r  r  r9  r  )r\  r   rw  r  r  r  arr_analysiss          rh   r<  z&ParforFusionPass.fuse_recursive_parfor  s    #F+fdll;t||%KVT%33DNNDLL04dnnN+,AV$rl   N)ry   rz   r{   rf  r  r9  r<  rk   rl   rh   r1  r1    s    3[j"H%rl   r1  c                       e Zd ZdZd Zy)ParforPreLoweringPasszSParforPreLoweringPass class is responsible for preparing parfors for lowering.
    c           
      R
   t        | j                  j                  i i | j                         t	        | j                  d       t        | j                  | j                  | j                  | j                  d          t	        | j                  d       t        j                  dk\  rCt        dt        | j                  j                                      t        d| j                         t        j                  dk\  rb| j                  j                  j                         D ]:  \  }}g }|j                  }|j                  D ]  }|j                  |       t!        |t"        j$                        s0|j&                  }|j(                  }|j*                  }| j                  |j,                     }	t        d|j,                  |	t/        |	             |	t0        j2                  v st!        |	t0        j4                        st#        j6                  |t9        d	      |      }
t1        j:                  |j,                        | j                  |
j,                  <   t#        j<                  |j,                  |      }t#        j$                  ||
|      }|j                  |       t#        j>                  |
gd
|      }tA        t0        jB                  | j                  |
j,                           | j                  |<   |j                  |       t#        j>                  |gd
|      }tA        t0        jB                  |	      | j                  |<   |j                  |        ||_        = | j                  jD                  r5tG        | j                  jH                  | jJ                  | j                         tL        rBtO        | jP                  | j                  | j                  | j                  | j                         y
tS        | j                  j                  | jT                  jV                  | jX                        \  }}|D ];  }t[        | j                  ||j\                  | j                        \  |_/        |_0        = |D ]  }|jc                  | j                          t        jd                  r| j                  jf                  jh                  }tk        |      }|dkD  r8| jT                  jV                  rdnd}t        djm                  ||||             y
t        djm                  |             y
y
)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  rd   r  r  r  r  rb  r   r	   r  rm  r  r  rV  ro  r   number_domainLiteralrc  r    r  r  PrintrQ   r  is_generatorfix_generator_typesgenerator_infor   r  lower_parfor_sequentialr  r6  r  r,  r  r7  rv  rz  r{  r  r}  r  r  r   r$  )r\  block_labelr  	new_blockr  r  rm  r  r  r  rF  	lhs_const
str_assign	str_printir_printr  r   r  rV  r  r  s                        rh   r  zParforPreLoweringPass.run  s   
 	t||**BDLLAt||%;<t||T^^T]]9=UVt||%9:!!Q&$fT\\-?-?-A&BC.$..1!!Q&'+||':':'@'@'B#U	!JJD$$T*!$		2"hh"kk"jj"&,,sxx"8?7TXY`Tab"e&9&99ZQVQ^Q^=_&(ffUM)4Lc&RG9>9L9LSXX9VDLL6(*3(?I)+9gs)KJ%,,Z8(*'D#(FI8A%**dll[b[g[gNh8iDNN95%,,Y7')xxtS'AH7@W7UDNN84%,,X6' '( '
/ (C2 <<$$ ; ;T=M=M $.%#dllDNNDMM[ #4DLL4G4G48LL4G4G484K4K#MJ
 '<T\\=>=>XX=A^^(M$	19  !!$,,/  ++||++99
O	q=6:ll6I6IN)? ! :;A6'y*<FG 6==dCD ,rl   N)ry   rz   r{   rf  r  rk   rl   rh   rD  rD    s    KErl   rD  c                 L   t        |j                        }|j                  dd       t        |j	                               |_        | t
        t        z   v rg |_        | t        v r2t        |j                        dk(  r|j                  j                          | t        v r2t        |j                        dk(  r|j                  j                          | dk(  rt        |j                        dk(  r|j                  j                          t        |j                        dk(  rO|j                  j                         }|j                  j                          |j                  j                  |       | dk(  r2t        |j                        dk(  r|j                  j                          y)	z%remove size argument from args or kwsr   r-  r   r   randintr!  
triangularN)r  r  r  r  r  rT   rS   rw   rV   r   rU   rb  )r  r  r  dt_args       rh   r  r  @  s!    txx.CGGFBSYY[!DH $66 	((tyy>QIIMMO((tyy>QIIMMOItyy>QIIMMOtyy>QYY]]_FIIMMOIIV$L tyy>QIIMMO
rl   c                     g }| j                   D ]   }|j                  ||j                            " i }| j                  D ]  \  }}||j                     ||<    t	        |      |fS r`   )rw   rb  rV  r  r  )r  r  r  r   r  rV  s         rh   r  r  h  sj    LyyGCHH-.  LXX	c$SXX.T  ,,rl   c                 
   |j                      }|j                  }|j                  }g }t        |t              r|\  }}g }|D ]Z  }t        j                  |t        d      |      }||j                   <   |t        | ||||||||	|
      z  }|j                  |       \ |t        j                  v r	|d   j                      }t        |      dk(  rz|d   j                      }|j                  |||fi       }t
        j                  j                  ||d   |d   |      }|t         j"                  k(  rPt%        |d   |d   |      \  }}n8|j                  ||fi       }t
        j                  j'                  ||d   |      }|||<   |j(                  }|j                  t        j*                  |||             t,        j.                  D ]  }t        ||      st1        ||
|      }t        j                  |t        |      |      }|   |j                   <   t3        j4                  | j7                  |            }t        |t
        j                        r|j8                  dk(  r|j:                  dk(  rt        j                  |t        d      |      }t<        j>                  jA                  tB              |j                   <   t        jD                  d	tB        |      }t        j*                  |||      }t
        j                  jG                  |d|      }|j                  |       t
        j                  jI                  ||d
|      }|j                      jK                  |t	        fd|D              i       }|||<   |j(                  }|j                  t        j*                  |||             |j                  t        j*                  |||              nt        |t
        j                        ru|j                      } t        | t<        jL                        r!| jN                  }tQ        ||||	|||||
      }n| }|}|j                  t        j*                  |||             nmt        |t
        jR                        rStU        jV                         jY                  |jZ                        }|j                  t        j*                  |||             t        |      dk(  r&t]        j^                  d|dd|j                        ja                  |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   r[  r  sqrtz$math_g_varr  rk   c              3   <   K   | ]  }|j                        y wr`   r  )r  r   r  s     rh   r  z(_arrayexpr_tree_to_ir.<locals>.<genexpr>  s     $GhWQVV_hs   z.Don't know how to translate array expression 'r3  'N)1rV  r  rm  r   r  r	   rc  r    r|  rb  rP   supported_array_operatorsr   r-  r  r  r,  truediv_gen_np_divideunaryr   r  rZ   	MAP_TYPES_find_func_varr  r  r?   rl  rf  r   r  r  r  r  r  r  r  r   r   _gen_arrayexpr_getitemr  r   r  resolve_value_typer  r   r_  r  )!r  r  r  r  rw  rs  r&  r  parfor_index_tuple_varall_parfor_indicesrq  r  r  rm  out_irrl  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!     `                              rh   r|  r|  t  s    \&&'FE


CF$ M C&&n(EsKK(.GK$$%+G,5,3,5,5,6,7,/,B,>,6
8 
8F OOK( ! 222hqk../G8}!!(1+"2"23$::2@G@IJLN''--HQK!cJ)))(6 Xa[&')C%Hg %::2z2N''--HQK=!)Ig))FMM"))G\3?@))A"a  !/wJC P66%})EsK)0)?&#}}W-C-CM-RSlBGG4I9UZfZkZkouZu"$&&m0Lc"RZ05

0A0A$0GWZ__- iic:V%'YYvz3%G]$&GGOOJ$L\]]=1'',,x2sC"8==1??u$Gh$GGM%-	'"!--biihDEbiisCD1 *2 
D"&&	!$))$gu{{+]]F,&"
G FGbiis;<	D"((	#!44TZZ@biilC89
6{a,,<T!HAF
 	
 KK!!4(!'GLMrl   c                 .   | j                   }| j                  }t        j                  |t	        d      |      }t
        j                  j                  t              ||j                  <   t        j                  dt        |      }t        j                  |||      }t        j                  j                  |d|      }	t        j                  |t	        d      |      }
t        t        j                        }|||
j                  <   t        j                  |	|
|      }t        j                  j!                  |
| |gd|      }|j#                  t%        j&                         || j                     ||j                     gi       }|j)                  ||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_attrrk   )r  rm  r	   rc  r    r   r  r  r9  rV  r  r  r  r  r#   rz  r  r  r   r  r  )arg1arg2ri  r  r  rm  r  r  r  div_attr_callattr_varfunc_var_typattr_assigndiv_callro  s                  rh   ra  ra    s7    JJE
((Cvve];7=H"ZZ..u5GHMM99T5#&D))D(C0KGGOOHh<Mvve];7=H#ELL1L)GHMM))M8S9Kww||HtTlB<H))7499-wtyy/ABBHH
MM;,-Xrl   c
           	         |j                   }
|}||j                     }||j                     j                  }t        |      }| j	                  |      xs g }|D cg c]  }| j                  |       }}|dk(  r?t        j                  |j                  t        d      |
      }t        j                  j                  |j                  dd      }|||j                  <   t        j                  dt         j"                  ||g|||      }|j$                  j'                  |       |}t        j(                  d|j                         }t        j                  |j                  t        d      |
      }t        j*                  ||j                  <   t        j,                  |||
      }|	j/                  |       |}n|dk(  r|d   }nt1        |D cg c]  }|d	u c}      r||z
  }t        j                  |j                  t        d
      |
      }t        j2                  j5                  t        j*                  |      ||j                  <   t        j(                  d|j                         }t        j                  |j                  t        d      |
      }t        j*                  ||j                  <   t        j,                  |||
      }|	j/                  |       g }t7        t9        |            D ]:  }||   }||   }|dk(  r|j/                  |       $|j/                  |||z             < t;        t7        |            }t        j<                  j?                  ||
      }t        j,                  |||
      }|	j/                  |       |}t        j<                  jA                  |||
      } tC        |||j                     ||j                           || <   | S c c}w c c}w )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).
    r   z$ravelr   rs  )r   r   ru  r   z$const_ind_0r  Nz$parfor_index_tuple_var_bcast)"rm  rV  r   r   r  get_equiv_constr	   rc  r  r    r   r   r   r   r   gen_np_callr9  r   r  r  r  rL  r  rb  r"  r\  r]  r  ru   r  r  r^  r  rQ   )!rw  r   rg  rh  r  r  r  r  rs  ri  rm  ru  rx  ra  num_indicesr  re   size_consts	ravel_var	ravel_typstmts
const_node	const_varconst_assign
ind_offsetrb  r  r   rR  
size_constrc  rd  rp  s!                                    rh   re  re    s.     ''C&Isxx GCHH""E()K##C(.BI9BCA9,,Q/KCzFF399mH&=sC	NN((w}}1S(Q	"+	$$Wekk9seYX_ajku%XXa)
FF399mN&CSI	"'++	yyY<l#		!&r*		[1[atm[1	2 5(
FF399m+'-.13	"'"2"2";";EKK"O	 XXa)
FF399mN&CSI	"'++	yyY<l#
%,'A |H$QJQ!!),!!"4Z!^"DE ( (:./
WW((S9
yyY<l#	ggooc9c2G"67388+<#*9>>#:<IgNi D, 2s   OOc                     |D ]+  }| |   }t        |t              s|j                  |k(  s)|c S  t        j                  d|      )zAfind variable in typemap which represents the function func.
    zufunc call variable not foundr[  )r   rR   
typing_keyr   r_  )r  rW  rq  rm  r  r  s         rh   rd  rd  K  sG     AJa"q||t';H	 
 
(
()Hc
RRrl   c           
          t         j                  j                  t        j                  |j                               d}i }t        t        |j                  j                                     j                  }|j                  j                         D ]  \  }}	t        ||	|||||      \  }}|	||<   ! ||_        |rt        |j                        |_        t        |d       t        ||||d          t        |d       y )NFr  z after parfor sequential loweringr   z after parfor sequential simplify)r   r  r"  r(  r  nextiterr  r  r  _lower_parfor_sequential_blockr2   r/   r4   )
r  r  r  r  r  parfor_foundr  r  rP  r  s
             rh   rO  rO  V  s    ""8#:#:7>>#JKLJgnn++-./55E ' 4 4 6e$B
GY%!\ #(
; !7  GN&w~~67>?Wgy(9*=>7>?rl   c           
      |   t        |j                        }|dk7  rd}|j                  |   }|j                  j                  }	t	        j
                  ||	      }
|j                  d | |
_        |j                  |dz   d  |_        t               }|
j                  j                  t	        j                  ||	             t        |j                  |      ||<   |
|| <   t               } t        |j                        }t        |      D ]9  }|j                  |   }t               }t               }t        ||j                  |j                  |j                   |||	      }||j                  d   _        |j                  d   j"                  }|||<   t%        |||||	      }|j&                  |j                  d   _        |||<   |dk(  rN|j                  j                  j                  t	        j                  ||	             | |j                  d   _        n+||   j                  d   _        ||j                  d   _        |}< t-        |j.                  j1                               }|j.                  |   j                  j                  t	        j                  |	             t3        |j.                  j1                               }|j                  d   _        |j.                  j5                         D ])  \  }}t7        |||||||      \  }}t        ||      ||<   + t        |j                        }|dk7  r| |fS )Nr  Tr   r   r  )_find_first_parforr  rs  rm  r	   r  r!   rb  rN  rJ   r   rr  ru   r$   r  r   r  r  r%   r[  falsebrtruebrr   rt  r  r   r  r  )rP  r  r  r  r  r  r  r   r  rm  
prev_block
init_labelra  r  range_labelheader_labelrange_blockphi_varheader_blockprev_header_labelbody_last_labelbody_first_labelrf   r   s                           rh   r  r  j  s    	5::&A
r'zz!}oo!!XXeS)
**Ra.
ZZA'
\
rwwz378!/!G
:",
; lDOO$uAq)H$,K%<L(K +7KR '!&&r*11G&1J{#)'7I*/6L+3+B+BLb!('3J|$Av$$++BGGK,EF0;!!"%-@K
,-2226=0A!!"%- ,7 < dnn1134',,33GGL#&	( t~~2245'7"$nn**,FQ<1j'9lOA| +1e4JqM	 -
 uzz*u r'v $$rl   c                 l    t        |       D ]&  \  }}t        |t              s|j                  r$|c S  yNr  )r1  r   rh  ri  r  r   r  s      rh   r  r    s0    t_	DdF#D,G,GH % rl   c                 T   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                  |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  rm  r  get_parfor_params_inner#_combine_params_races_for_ssa_namesrj  rv  r  rq  rb  )r  options_fusionr  r  r   pre_defsr  all_defsr  r  r  r   r   dummy_blockbefore_defsrv  s                   rh   r6  r6    s    JGuH"6*KAx (Ju&uzz2IAv((5;;		:K$zz"1~K*A{+;<CCAFK#H,.+F +NVV\\+'FM6< NN699%NN6" 3 	HUO## $ wrl   c                       fdt        |      }t        t        |            }|D ]*  t        fd|D              r|j	                         * n ||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                 r    	 j                  |       j                  S # t        j                  $ r | cY S w xY wr`   )r  r  r	   r  )r  r  s    rh   	unversionz6_combine_params_races_for_ssa_names.<locals>.unversion  s7    	??1%666!! 	H	s    66c              3   4   K   | ]  }       |k(    y wr`   rk   )r  pvrvr  s     rh   r  z6_combine_params_races_for_ssa_names.<locals>.<genexpr>  s     :\ry}"\s   )r  r  r  r"  discard)r  rv  rj  races1unver_paramsr  r  s   `    @@rh   r  r    s\    
 ZFIv./L:\::NN2	  F?F""rl   c                    t        |       }t        |      }t        |      }t        |||j                  |j
                        }t        |||      \  }}	t        |      }
|
dkD  rUt        j                  r-|rdnd}t        dj                  || j                  |
|             t        |      || j                  <   t        |        t        |j!                               }|d   }|d   }|j
                  |   |z  }||   |z  }|S )Nr   rG  r  z2{}, parallel for-loop {} has nested Parfor(s) #{}.r   )r  rN   rK   rL   r  r  r6  r   r   r}  rd   r$  rq  r  r  r  r  )r   r  r  r  r  r  r  r  r  r  r  r  keylistrs  first_non_init_blockr  rv  s                    rh   r  r    s    'F
!&
)Cv&GVW^^W^^LH%fnkJMJJI1}''.<N!7  ()/fiiJ*@A "&j!1FII X]]_%GJ"1:..,x7K*+k9FMrl   c              #   `   K   t        |       D ]  \  }}t        |t              s||f  y wr`   )r1  r   rh  r  s      rh   r  r    s+     T?4dF#T'M #s   ".	.c                     t        t        | |j                        }t        |t        j
                        rO|j                  dk(  r@|j                  D cg c]  }|j                   c}|D cg c]  }|j                   c}k(  ryyc c}w c c}w )Nr^  TF)r;   r?   rV  r   r	   r  rl  r  )r  r   nest_indices	index_defre   s        rh   _is_indirect_indexr    sm    nguzz:I)RWW%),,-*G%OO,OqAFFO,0NA0NN -0Ns   B,Bc           
         | D ]  }|j                   D ]  }t        |t        j                  t        j                  f      rt        |      }t        |t        j                        rB|j                  |k(  st        |||      r&|j                  |j                  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                        r/|	j                  |k(  st        ||	|      r|j                  |
       |j                  |
       t        |t               st#        |j$                  j'                         |||||         y )Nr  )r  r   r	   r=  r  r3  rc  rV  r  r  r  r  r  r  rl  r   rh  ,get_array_indexed_with_parfor_index_internalrt  r  )rt  r   ret_indexedret_not_indexedr  r  r  r  setarray_indexgetarray_indexgetarray_names              rh   r  r    sk    HHD$!1!12:: >?!.t!4~rvv6#((E1' '%'  OODKK$4$45#''(8(89T299-TZZ1**--#@@!%!1!1 $

 0 0 5 5~rvv6#((E1' '%'  OOM2#''6D&)<NN))+# 7  rl   c                 R    t               }t               }t        | |||||       ||fS r`   )r  r  )rt  r   r  r  r  r  s         rh   #get_array_indexed_with_parfor_indexr  G  s9     %KeO0 ''rl   c                    t        | j                  j                               }g }| j                  j                         D ]  }|j                  D ]  }t        |t        j                  t        j                  f      s.t        |      j                  | j                  j                  k(  s[|j                  |j                  j                           t        t        |      t        |      z        }t!        |      S )zhget arrays that are written to inside the parfor and need to be passed
    as parameters to gufunc.
    )r   rt  r  r  r  r   r	   r=  r  r3  rV  ru  rb  r  r  r  r  )r   parfor_params
last_labeloutputsr  r  s         rh   get_parfor_outputsr  W  s     V%%**,-JG&&(HHD4""2"2BJJ!?@d#((F,<,<,A,AAt{{//0  ) 3w<#m"445G'?rl   _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                        rP|j                  j                  |v s|j                  j                  |v r|j                  }|j                  }|j                  |v r|n||j                     }g }t        |t        j                        r|j                  g}nKt        |t        j                        r1|j                  j!                         D cg c]  }|j                   }}||   j#                  |       |D ]  }|||<   	 t%        j&                  |      }|j                  |v r||j                     ||j                  <   ||   j)                  |       t        |t*              st-        | |||||d||	         |j/                         D ]  \  }}|j                  }||v s||vs||   j1                          t3        |||   |       }|B|j)                  |       t5        ||       t7        t8        |      }||\  }}nd}d}t;        |||      ||<    ||fS c c}w )zfind variables that are updated using their previous values and an array
    item accessed with parfor index, e.g. s = s+A[i]
    Nr   r  )r   r  r  r0   r  r  rt  r  r   r	   r  r  rV  r  rc  r  re  r  r  r  rb  rh  r7  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                            rh   r7  r7  p  s    
  &
!$''F (JABJ *%V--e499:D4+))]:))\9kkjj#&88}#<C,sxxBX		c266*!$
IRWW-151E1E1G H1GA1GI H9%,,Y7"A&/LO # ---::*/8/DIgmm,I&--g6$'%gt]I{LR- ; &4 ',,.y ZZ
"z'H&&(+E;u3EwOL '&&z25e\J 2LA&&-OHe#H E)4%!-*
:&/ /: J&&W !Is   -Kc                    d}|D ]  }t        |t        j                        st        |j                  t        j                        sC|j                  j
                  dk(  s]||j                  j                  }v||j                  j                  k7  sd| j                  z  }t        j                  ||j                         y)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  rl  fnr  r   r_  rm  )r  nodesfirst_red_funcnoder  s        rh   r  r    s     NtRYY'tzz277+JJMM?*%!%!TZZ]]22494J4JKC 88dhhGG rl   c                    t        t        |       dk\         t        t        d |             d   j                  }t        t        |t        j                        xr |j                  dv        |j                  }|j                  dk(  r|t        j                  k(  rt        j                  }nk|t        j                  k(  rt        j                  }nG|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 y)z^
    Get initial value for known reductions.
    Currently, only += and *= are supported.
    r   c                 J    t        | j                  t        j                        S r`   )r   r  r	   r  r  s    rh   r4  z$get_reduction_init.<locals>.<lambda>  s    Z%Arl   r  )r  r  r  r   NN)r<   r   r  rA  r  r   r	   r  rl  r  r,  r  iaddsubisubmulimulr`  itruediv)r  acc_expracc_expr_fns      rh   r  r    s
   
 CJ!O FA5IJ2NTTHJx)Whkk=W.WX++K{{g(,,&"--KHLL("--KHLL("--KH,,,"++Khmm#{hmm'C+~

&
**
*+~rl   c                 N   | 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yy)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)rl  r  r,  	ifloordivfloordivr   NumbaValueErrorrm  r  r  r  r  r  r  r  r`  r;   r9   )re   r  suppsr  s       rh   supported_reductionr    s    tt!$$'/448%%%1B1B)B(( +7 :;	@ @
 ""!!# ttu}ttv~3 
 
 rl   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                        syt        fd|	j                         D              }
||
v s|dz   t        |      k  rt        ||dz      t        j                        r||dz      j                  j                  |k7  rtd}t        ||dz   d       D ]9  \  }}t        |t        j                        s!|j                  |k(  s1||z   dz   } n |#|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                  |k7  rt        d|d      t        |	|      st        d|z   d	z         t        |	      D cg c]  }|j                    |d      f }}|D cg c]  \  }}|j                   |k7  s| }}}t        |      dk(  sJ |D cg c]  \  }}||j                   k7  s||f }}}t!        |      }t        j                  |j"                  |d
z   |j$                        ||d   <   t'        |	|       ||d } |S  |S c c}w c c}}w c c}}w )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                  | j                  d      }t        |t        j                        r||}n||k(  ry ||      S |s|| S |S )zeLookup definition of ``var``.
        Returns ``None`` if variable definition forms a cycle.
        N)r  )r  rV  r   r	   rc  )r   varonlyr  lookedup_varcyclic_lookupdefss       rh   r   z'get_reduce_nodes.<locals>.cyclic_lookup  s[     xx$/lBFF+}$,& U;;"l&:3MMrl   c                  2     | i |}|t        d      |S )zZSimilar to cyclic_lookup but raise AssertionError if a cycle is
        detected.
        zunexpected cycle in lookup())r  )rw   kwargsr  r   s      rh   noncyclic_lookupz*get_reduce_nodes.<locals>.noncyclic_lookup$  s*     T,V,; !?@@
rl   c              3   D   K   | ]  } |d       j                     ywTNr  )r  r  r  s     rh   r  z#get_reduce_nodes.<locals>.<genexpr>6  s&      4#2a +1d388#2s    r   zUse of reduction variable z? other than in a supported reduction function is not permitted.z& in an unsupported reduction function.z#initr   r  )rV  r  r1  r  r  r   r	   rc  r  r  re  r   r  r#  r  get_expr_argsr  r  rm  r(   )reduction_noder  r  r  rV  r  r   r  r  r  in_varsfoundjr   jstmtre   rw   rg   non_red_argsreplace_dictr   r  r  s                      @@@rh   r  r    s<    LDN D%66U#4kkjjSXXc266"sxx4'7$Cc277# 4#&==?4 4Gw& ECJ&$U1q5\299=1q5\((99=MM!F$-eAEFm$<5 &eRYY7EKK3<N &'UQYF! %= ) "'vA!&vfqj!9":!&q1uV!4"5 "'vz{!3"4
 1s5z)jqsRYY.O!!A#J-->>BRR004DD$45E4H I% %  +38$&BEU&U&N'O Q Q "/s!36!3A !1!T!:;!3  615Iv14I<(A---.2CdFQa166k!QdC#Dz02syy$w,PSPWPW0X\!_-"35$QRyS $R 6ICs   3LL.L
L"Lc                     | j                   dv r| j                  | j                  gS | j                   dk(  r| j                  D cg c]  }| c}S t	        dj                  |             c c}w )z-
    Get arguments of an expression node
    )r  r  r  zget arguments for expression {})rl  r  r  rw   r  r$  )r  r  s     rh   r  r  z  se     ww,,$((##ww&99%9a9%%
?FFtL
MM &s   	A*c                    | j                   D ]  }|d   dk(  s|d   d   }t        t        |            D ]3  }t        ||   t        j
                        s!t        ||   ||      ||<   5 |d   d   }t        t        |            D ]3  }t        ||   t        j
                        s!t        ||   ||      ||<   5  y )Nr   r+  r   )rx  ru   r   r   r	   rc  r*   )r   callbackcbdatar~  left_lengthsr   right_lengthss          rh   visit_parfor_pattern_varsr    s    ??1:""1:a=L3|,-l1orvv6&6|A<Df'NLO . $AJqMM3}-.mA.7'7a8H<Df(NM!$ / #rl   c                    t         j                  dk\  r/t        d|        t        dt        |j	                                      | j
                  D ]  }t        |j                  ||      |_        t        |j                  t        j                        rt        |j                  ||      |_	        t        |j                  t        j                        rt        |j                  ||      |_        t        |j                  t        j                        st        |j                  ||      |_         t        d| j                  i||       t!        | ||       t        | j"                  ||       y )Nr   zvisiting parfor vars for:zcbdata: r  )r   r  rd   r  r  rr  r*   r[  r   r  r	   rc  r   r  r)   rs  r  rt  )r   r  r  rf   s       rh   visit_vars_parforr    s   ")62j&01+A,<,<hOaggrvv&&qww&AAGaffbff%%affh?AFaffbff%%affh?AF  F%%&&9fh7v62
rl   c                    |
t               }|
t               }t        |       }t        |      \  }}t        |      }t	        |j                               }t        |        |j                         }|j                         |   }	|j                         j                         D ]  }
|	|
j                  z  }	 |D ]I  }||	v r,|j                  ||   |z
         |j                  ||          3|j                  ||   |z
         K | j                  D ch c]=  }t        |j                  t         j"                        s(|j                  j$                  ? }}|| j                  D ch c]=  }t        |j&                  t         j"                        s(|j&                  j$                  ? c}z  }|| j                  D ch c]=  }t        |j(                  t         j"                        s(|j(                  j$                  ? c}z  }|j                  ||z
         |t+        |       z  }t-        j.                  ||      S c c}w c c}w c c}w )zzlist variables written in this parfor by recursively
    calling compute_use_defs() on body and combining block defs.
    )r  r  )r  r  rK   rN   r   r  r  r  
dominatorsr  r  r  r"  rr  r   r  r	   rc  rV  r   r  get_parfor_pattern_varsr   _use_defs_result)r   use_setdef_setr  usesr  r  r  r  definitely_executedr  r  rf   	loop_varss                 rh   parfor_defsr     s    %%'F!&)JD$
!&
)CV[[]#J  !J..*:6		""$tyy( %''
 NN4;01NN4;'NN4;01  %///:GGRVV4/   #...*FFBFF3. I #...*FFBFF3. I NN9w&'&v..G$$GGDDs$   )H;<H;%)I I ;)I%Ic                     |t        | j                        z  }t        |       }|t        j                  |      z  }t        |        y)zx
    Reduction variables for parfors and the reduction variables within
    nested parfors must be stack allocated.
    N)r  rz  r  r   must_use_allocar  )r   
alloca_setr  s      rh   _parfor_use_allocar$    s>    
 #fnn%%J'F(**622J rl   c                 <   t        |       }t        |      }t        |      }t        |||j                  |j
                        }t        ||||j
                        }| j                  D ch c]=  }t        |j                  t        j                        s(|j                  j                  ? }}|| j                  D ch c]=  }t        |j                  t        j                        s(|j                  j                  ? c}z  }|| j                  D ch c]=  }t        |j                  t        j                        s(|j                  j                  ? c}z  }|| j                  D ch c]  }|j                  j                   c}z  }t!               }	|j#                         D ]  }
|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  }	  G d dt(              }t+        j,                   ||            }|j/                  |j$                  |j&                         t1        |        |	|z  S c c}w c c}w c c}w c c}w )z~insert dels in parfor. input: dead variable set right after parfor.
    returns the variables for which del was inserted.
    c                       e Zd Zd Zy)'parfor_insert_dels.<locals>.DummyFuncIRc                     || _         y r`   )r  r  s     rh   r]  z0parfor_insert_dels.<locals>.DummyFuncIR.__init__  s	     DKrl   N)ry   rz   r{   r]  rk   rl   rh   DummyFuncIRr'    s    	!rl   r)  )r  rN   rK   rL   r  r  rM   rr  r   r  r	   rc  rV  r   r  r[  r  r  r  escapingobjectr   PostProcessor_patch_var_delsr  )r   curr_dead_setr  r  r  r  dead_maprf   r  dead_setr  r)  	post_procs                rh   parfor_insert_delsr2    sM     'F
!&
)Cv&GVW^^W^^LH fhGH %///:GGRVV4/   #...*FFBFF3. I #...*FFBFF3. I 1B1BC1BA!""''1BCCI uH% M1 % I- H%%e,,% M1 % I- H%%e,, !f ! &&{6':;Ih//1B1BC iA Ds*   *)J
J
=)J'J)J=J)Jc           	          t        |      \  }}t        || j                  ||       \  }}|j                         D ]  }d}	|	st	        | |||||      }	|	r y)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  r3  r  r  	alias_maparg_aliasesr  order_changeds
             rh   r8  r8  !  sn    
 #6*MJ3!'!(!2!2!(!(	I{ 1 ' % * ) + ,M  !rl   c                 V   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  r|S )NFr   r   r   T)r   r  _can_reorder_stmts)r  r  r  r6  r7  r3  r8  r   r  r>  can_reorders              rh   r5  r5  9  s    M	A c%**o!
!zz!}JJqsO	 ( *$	7*4iN-?	4Y.E 	 %EJJqM"EJJqsO M	Q c%**o!
! rl   c                     t               }| D ]@  }||v r|j                  ||         }||v r|j                  |      }|j                  |       B |S r`   )r  r  r  )the_setr6  r7  retr   s        rh   expand_aliasesr?  M  sT    
%C	>))IaL)C))K(C
  Jrl   c                    t        | t              r)t        |t              st        |t        j                        st        |t        j                        r:t        |j                  t               |      st        t        ||j                        rt        | j                         D ch c]  }|j                   c}||      }t        t        |       ||      }t        |j                         D ch c]  }|j                   c}||      }	t        t        |      ||      }
t        ||	z  |
|z  z        dk(  ryyc c}w c c}w )zw
    Check dependencies to determine if a parfor can be reordered in the IR block
    with a non-parfor statement.
    r   TF)r   rh  r	   rK  r  r6   r  r  r;   is_assert_equivr?  re  rV  get_parfor_writesr1   r   )r  r>  r  r  r6  r7  r  stmt_accessesstmt_writesnext_accessesnext_writess              rh   r:  r:  W  s    	4 9f-9bhh/Iryy1!)//35*E_gy?&8H'I8H18H'I'0+?$%6t%<%.=&	8K8K8M'N8M18M'N'0+?$_Y%?%.=m+.0 1456 (J (Os   (D<1Ec                 *    t        | |      \  }}|dk(  S )NrX   )r9   )r  r  r4  r  s       rh   rA  rA  t  s    '6Ix&&rl   c                 f   t        | t              sJ t               }| j                  j	                         }| j
                  |d<   |j                         D ]X  }|j                  D ]G  }|j                  t        |             t        |t              s.|j                  t        |             I Z |S r  )r   rh  r  rt  r  rs  r  r  r"  r1   rB  )r   writesr  r  r  s        rh   rB  rB  y  s    ff%%%UF""$F""F2JJJDMM/$/0$'/56  !
 Mrl   FusionReport)firstsecondmessagec           
      0	    t        d|d|       d}|j                  |j                  k7  r2t        d       d}t        |j                  |j                  |      }d|fS t	        |j
                        t	        |j
                        k7  rt        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                        rzt        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|rKt        d       d}t        |j                  |j                  ||j                  |j                  fz        }d|fS t        |j                        }t!               }|j"                  j%                         D ]  }||z  }	 |t'        |      z  }|t!        |j(                        z  }t        |j                        }t        d|j*                  i      j,                  d   }|j,                  j%                         D ]  }||z  }	 |j/                  |      }t	        |      dk7  rt1        |j                  j%                         |j2                  j4                  |j7                         |      \  }fd|D        }t9        |      rKt        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 
r+  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                 6    | |k(  xs j                  | |      S r`   )is_equiv)re   rg   rw  s     rh   rP  ztry_fuse.<locals>.is_equiv  s    Av1++Aq11rl   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	   rc  rV  )r  user_varnamer  s     rh   get_user_varnamez"try_fuse.<locals>.get_user_varname  sO    !RVV$HFFx'A:J1K,K#$45a8Lrl   z/try_fuse: parfor dimension correlation mismatchz7- fusion failed: loop dimension mismatched in axis %s. zslice(r  z) != r_  r   Tz1try_fuse: parfor cross iteration dependency foundzK- fusion failed: cross iteration dependency found between loops #%s and #%sc              3   f   K   | ](  }t        |   t        j                         xs |v  * y wr`   )r   r   rK  )r  re   p2arraynotindexedr  s     rh   r  ztry_fuse.<locals>.<genexpr>  s7     skrfg*WQZ1F1FGGa1PaKaakrs   .1z)try_fuse: parfor2 depends on parfor1 bodyzT- fusion failed: parallel loop %s has a dependency on the body of parallel loop %s. )dprintr|  rJ  rq  r   rr  ru   r  r   r  r@   r  r5  has_cross_iter_deprK   rt  r  r  r  rB  rz  rs  r  r  r  ru  rV  r  r"  fuse_parfors_inner) rw  parfor1parfor2r  r  r  r  r  r  r  r  ra  rP  rT  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_usesr  overlapr  
unsafe_varrV  s    `  ` `                         @rh   r;  r;    s"    ('4A F '//)561gjj'**c:V| 7#g&8&8"99@AD8GJJG$6$6 788GJJG$6$6 788gjj'**cRHnEV|""#E2 5\""1%""1%ekk2UZZ0UZZ0DaHKC.>u{{.K ,.>uzz.JL LC*:5;;*G ,.>uzz.JL LC!'**gjj#'BF<  -W^^<G,>wQX,Y)L%	)'7GUES\]^_`|BC,gjj'** #wzz7::&> >@V|
 'w'8'89O5L&&--/ 0%g..L C((L!'"3"34J7#5#567>>qAG!!((*4 + ''0G
7|qB$$&""&&(	  tkrs
z?>?1C!'**gjj$'7::wzz*B$BDF<gw//rl   c                    | j                   j                  j                  |j                   j                         t        |j                  j                               }|j                  |   j                  }t        | j                  j                               }t        | j                  j                               }| j                  |   j                  j                  |       | j                  j                  |j                         | j                  j                  |       t        | j                        }|j                  j                  | j                  i}t        |      D ]?  }| j                  |   j                  ||j                  |   j                  j                  <   A t        | j                  |       t!        | |      }	t#        |	      }	t%        | |	       t'        d |j)                         D              }
t+        | j                  |
       | j,                  j                  |j,                         t.        j0                  r/t3        dj5                  |j6                  | j6                               d}|j5                  |j6                  | j6                        }t9        | j6                  |j6                  |      }| |fS )N)entry_labelc              3   4   K   | ]  }|j                     y wr`   r  r  s     rh   r  z%fuse_parfors_inner.<locals>.<genexpr>  s     6"5Q!&&"5r  z1Parallel for-loop #{} is fused into for-loop #{}.zE- fusion succeeded: parallel for-loop #{} is fused into for-loop #{}.)rs  r  r  r   rt  r  r   r"  r  r   rr  ru  rV  ru   r[  r'   r  r2   r  r  r  remove_duplicate_definitionsrx  r   r}  rd   r$  rq  rJ  )rZ  r[  parfor2_first_labelparfor2_first_blockparfor1_first_labelparfor1_last_labelra  
index_dictr   r  namesetr  r  s                rh   rY  rY    s<    ""7#5#5#:#:; g//4467!++,?@EEg//4467W..3356()..556IJ W../-. ""#E##(('*;*;<J5\@G@R@RA~ 	7%%a(77<<=  ""J/  5HIF6"F&)6*"3"3"566G !2!2G<G,,-##AHHjj'**& 	' RC
**WZZ
,C'**gjj#6FF?rl   c                 6   | j                         D ]  \  }}|j                  }g }t               }|D ]]  }t        |t        j
                        r0|j                  j                  }||v r||v r<|j                  |       |j                  |       _ ||_         y)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  rV  r  rb  )	r  rr  r  r  r  r	  definedr  rV  s	            rh   rl  rl  !  s     uzz%D$		*{{''7?w KK%OOD!  
 ' rl   c                     | j                   D ch c]  }|j                  j                   c}t               }|i }|
t               }|
t               }d fd}| j                  j                         D ]  }	|	j                  D ]  }
t        |
t        j                  t        j                  f      rqt        |
j                  j                     t        j                  j                        r5 ||
j                  |
j                  j                  ||||      r
d|||fc c S t        |
t        j                         st        |
j"                  t        j$                        r@|
j"                  j                  v sj'                  |
j                  j                         t        |
j"                  t        j(                        sD|
j"                  j*                  }|dv rt        |
j"                  j"                  j                     t        j                  j                        rI ||
j"                  j                  |
j"                  j"                  j                  ||||      r
d|||fc c S |dk(  rjt-        |
j"                  j/                         D cg c]3  }t        |j                     t        j                  j                        5 c}      r
d|||fc c S |
j"                  j/                         D cg c]  }|j                   }}j1                  |      r|j1                  |      r|j'                  |
j                  j                           d|||fS c c}w c c}w c c}w )Nc                     t        | t              rt        |       } d| vr||v ry|j                  |       y||v ry|j                  |       t	        |       }||vr| ||<   y||   | k7  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         rh   add_check_positionz.has_cross_iter_dep.<locals>.add_check_positionk  s     lD) .L |# / #&&~6
 //>*\"( '3OF# v&,66rl   c                    t        | t        j                        rt        | j                     t        j
                        rvt        t        |       }|b|\  }}t        |D 	cg c]   }	|	j                  v xs |	j                  |v" c}	      r'|D 	cg c]  }	|	j                  v  }
}	 |
||||      S yy| j                  v r d||||      S | j                  |v ry d||||      S yc c}	w c c}	w )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.
        TTF)r   r	   rc  rV  r   r  r;   r:   allr   InternalError)
stmt_indexrx  ry  rz  r{  derived_from_indicesfbs_resind_seqr  re   new_index_positionsr}  r  r  r  s              rh   check_indexz'has_cross_iter_dep.<locals>.check_index  sN    j"&&)'*//2EOOD 3WjI&!(JGQ DKMDKq VVw. ;&::;DKM N KR.R'Qqvv/@'+.R  22E2@2A2@2D	 F F  $   ??g- .g.<.=.<.@	B B
  __(<<  
 .h.<.=.<.@	B B WM /Ss   $%C/C4Tr  r  F)rr  r[  rV  r  rt  r  r  r   r	   r  r=  r  r   r   r   r   r  r  rc  r  r  rl  r"  re  
isdisjoint)r   r  r  ry  rz  r{  rf   r  r  r   r  rl  re   rhs_varsr}  r  s    ``           @@rh   rX  rX  5  s   ( /5.?.?@.?q$$.?@G
 5, ! U07dDJN $$&FFD$R-=-= >?gdkk&6&679M9MN"4::#';;#3#3#2#1#5#79  $_nFXXXD")), djj"&&1zz'1DKK$4$45 

BGG4B::%gdjj.>.>.C.C&DennFZFZ[*4::+;+;+/::+;+;+@+@+:+9+=+? A (,_nN`'` ` v  %)ZZ%9%9%;!=%; ",GAFFOU^^=Q=Q!R%;!= >#'.J\#\\ 15

0D0D0FG0F10FHG $..x80;;HE,001A1ABk  'p />3EEEg AH!=
  Hs   M1"8M6M;c                  <    t         j                  dk\  r	t        |   y y r  )r   r  rd   )r   s    rh   rW  rW    s    "q	 #rl   c                     t               }| j                  D ][  }|d   dk(  s|d   d   }|d   d   }||z   D ]8  }t        |t        j                        s|j                  |j                         : ] |S )z: get the variables used in parfor pattern information
    r   r+  r   )r  rx  r   r	   rc  r  rV  )r   outr~  r  r  r  s         rh   r  r  #  sr     %C??1:""1:a=L#AJqMM!-/a(GGAFFO 0	 # Jrl   c                 	   t        | j                        5  t        | j                        }ddd       d   }i }	t        | j                  |   j                  | j
                  ||	|       t        |	j                               }
|D ]  }||k(  r	| j                  |   j                  D ]  }t        |t        j                        rut        |j                  t        j                        rQ|j                  j                  dk(  r8|j                  j                  j                  | j
                  j                  k(  rt        d |j!                         D              }||
z  }|D ]  }|	j#                  |d          |D ]J  }||k(  r	| j                  |   }|	j%                         }t        |j                  | j
                  |||       L | j                  j%                         }t'        |j                               }t)        |||      \  }}t        j*                  |t        j,                  dd            }||   j                  j/                  |       t1        |      }t3        |      }t5        |||j6                  |j8                        }t        |j                               }|j;                         D ]b  \  }}g }|j<                  j!                         D ch c]  }|j                   }}|j?                  |      D ]  \  }} |||   z  } tA        |j                        D ]  }||z  }!|!D ]
  }|||   z  } t        |t        jB                  t        jD                  f      r]tG        |      j                  | j
                  j                  k(  r1|jH                  j                  |vr|jH                  j                  |vr||j!                         D ch c]  }|j                   c}z  }|j/                  |        |jK                          ||_        e |j#                  |j                         ||   j                  j#                          	 tM        | |||||       tO        | jP                  j                        dk(  }"| j                  jS                         D ]  }|"tO        |j                        dk(  z  }" |"ry| S # 1 sw Y   xY wc c}w c c}w )z7 remove dead code inside parfor including get/sets
    Nr   r  c              3   4   K   | ]  }|j                     y wr`   r  )r  r  s     rh   r  z%remove_dead_parfor.<locals>.<genexpr>O  s     <+;a166+;r  parfors_dummyr  )*r  rt  r0   _update_parfor_get_setitemsr  ru  r  r  r   r	   r  r  r  rl  r   rV  re  r  r  r   _add_liveness_return_blockrN  Locrb  rN   rK   rL   r  r  r  
terminator
successorsr  r=  r  r3  r  r  remove_dead_parfor_recursiver   rs  r  )#r   liveslives_n_aliasesr7  r6  r  r  r  r  first_block_saved_values
saved_arrsrf   r  varnamesrm_arrsr   r  saved_valuesr  r  return_labelrb  jumpr  r  r  	alias_setr  r	  r  in_livesout_blk_dataalias_livesis_emptys#                                      rh   remove_dead_parforr  1  s0    
#6#3#3	4 !1!12 
5 )K!%**) 	
 -2245J$$Q',,D4+
4::rww0O

2

((--1A1A1F1FF<4>>+;<<H+G(,,Q5  -     #/446#EJJ0@0@)(4o	G  ""$FV[[]#J8RYZL)77<!<=D
:""4(
!&
)Cv&GVW^^W^^LHINN$%Iu$)$4$4$>$>$@A$@qAFF$@A!nnU3NGU))H 4UZZ(D"Y.K IaL( !4""2"2BJJ!?@d#((F,<,<,A,AA  0  3)9:)9A)9::HOOD! ) 	
' '* KK	
:! !{IwA 6$$))*a/H!!((*C

Oq(( +MA 
5	4r B ;s   SSS
Sc                    | D ]  }t        |t        j                  t        j                  f      rt	        |      j
                  |j
                  k(  ry|j                  j
                  |vra|j                  |j                  j
                  g       D ]  }|j                  |d        |j                  ||j                  j
                  <   t        |t        j                        rt        |j                  t        j                        r|j                  }|j                  dk(  rtt        |j                  t        j                        rP|j                  j
                  |j
                  k(  r-|j                  |j                  j
                  |      |_	        |j                         D ]Q  }|j                  |j
                  d       |j                  |j
                  g       D ]  }|j                  |d        S  y)zS
    replace getitems of a previously set array in a block of parfor loop body
    Nr  )r   r	   r=  r  r3  rV  r  r  r  r  r  r  rl  r   rc  re  )	
block_bodyru  r6  r  r  r  wr  r  s	            rh   r  r    si   
 tb..

;<$$$	6KKE)]]4;;#3#3R8  D) 9 .2ZZL))*dBII&:djj"''+J**Cvv"z#))RVV'D99>>Y^^3!-!1!1#))..#!FDJ !AQVVT*]]1662.  D) / ") 4 rl   c           	         | j                   j                         }t        |j                               }|dkD  sJ t	        |j                               }	 t        |||      \  }	}
||   j                  }t        j                  |t        d      t        j                  dd            }t        j                  ||j                  <   t        j                  |||	t        j                  dd            }||   j                  j!                  |       | j"                  |d<   |d   j                  j!                  t        j$                  |t        j                  dd                   t'        ||||||       |j)                  |
j                         |d   j                  j)                          ||   j                  j)                          y)zIcreate a dummy function from parfor and call remove dead recursively
    r   z$branchcondr  r  N)rt  r  r   r  r   r  r  r	   rc  r    r  r   booleanrV  rM  r  rb  rs  rN  r+   r  )r   r  r7  r6  r  r  r  r  r  r  rb  r  
branchcondbranchs                 rh   r  r    sr    ""$F6;;=)aV[[]#J
 9PL) :$$E}];RVVOUW=XYJ$}}GJOOYYz#3\266/[]C^_F
:""6* !!F1I
1INN"''"2BFF?B4OPQ Wgy+NKK	
1INN
:!
rl   c                    t        | j                               }|dz   }| |   j                  }| |   j                  }t	        j
                  ||      | |<   t	        j                  |t        d      |      }t        j                  j                  t        j                  d      ||j                  <   |D cg c]  }t	        j                  |||       }	}t        j                  j                  |	|      }
| |   j                  j!                  t	        j"                  |
||             | |   j                  j!                  t	        j$                  ||             ||fS c c}w )Nr   z
$tuple_varr   )r   r  rm  r  r	   r  rc  r    r   r\  r]  rL  rV  r  r^  r  rb  r  Return)r  r  r  r  r  rm  r  rb  r  r  rc  s              rh   r  r    s"   V[[]#J>L


 
 C:$$E88E3/F< umL93?I#..77QGINN0561q#&I6$$Y4J
<$$RYYz9c%JK
<$$RYYy#%>?""	 7s   5Ec                 d    t        |       }t        j                  ||||||       t        |        y r`   )r  r   rH   r  )r   rw   r  r  r6  r7  r  s          rh   find_potential_aliases_parforr    s3    'F##gw	;@ 
rl   c           
      J   d}| j                         D ]  }|j                  D ]y  }t        |t              s|dz  }|}|j                  t        |j                  j                                  }|j                  }t        j                  dd      }t        j                  |t        d      |      }|j                  j                  t        j                  t        j                  d|      ||             |j                  j                  t        j                  ||             t!        |j                        |_        |j                  t        |j                  j                                  }|j                  j#                          t%        |j                         |  |S )z%simplify CFG of body loops in parforsr   r   r  r  $const)r  r  r   rh  rt  r   r  r  r	   r  rc  r    rb  r  r  r  r5   r  r4  )	r  r  r  r  r   
last_blockr  rm  consts	            rh   r4  r4    s9   IJJD$'Q	 $--c&2B2B2G2G2I.JK
"((ff_b1umH&=sC&&ryy!S1A5#'NO&&ryy'<=#/0@0@#A #--c&2B2B2G2G2I.JK
##%()9)9:!  !$ rl   c                    | j                   j                         }|t        |j                               }|dkD  sJ | j                  |d<   |d   j
                  j                  t        j                  ||d   j                               |j                         D ]m  }t        |j
                        dk(  s|j
                  d   j                  r5|j
                  j                  t        j                  ||j                               o |S )z5wrap parfor blocks for analysis/optimization like CFGr   r  )rt  r  r   r  rs  r  rb  r	   rN  rm  r  r   is_terminator)r   rj  r  r  s       rh   r  r    s    ""$F&++-(?? !!F1I
1INN"''+vay}}=>uzz?a

2(D(DJJbggk599=> ! Mrl   c                 Z   |1t        |j                               }|j                  |       || _        t        | j                  j                               }t	        | j
                  j                  d   t        j                        sJ | j
                  j                  j                          | j                  j                         D ]a  }t	        |j                  d   t        j                        s+|j                  d   j                  |k(  sH|j                  j                          c y)zb
    unwrap parfor blocks after analysis/optimization.
    Allows changes to the parfor loop.
    Nr  )r   r  r  rt  r   rs  r  r	   rN  r  r  )r   r  init_block_labelr  r  s        rh   r  r  *  s    
 v{{}-

#$! 6++0023f'',,R0"'':::   !!((*uzz"~rww/JJrN!!%55JJNN	 +
 rl   c                    t        |       }t        ||      \  }}t        ||      \  }}t        |        |d   }| j                  j                         D ]%  }|||   D 	
ch c]  \  }	}
|		 c}
}	z  }|||   z  }' t        | j                  j                               }||   |d   z  }t        j                  dk\  rt        d|d|       ||fS c c}
}	w )z&find copies generated/killed by parforr   r   zcopy propagate parfor gens:kill_set)
r  r,   r-   r  rt  r  r   r   r  rd   )r   r  r  in_copies_parforout_copies_parforin_gen_copiesin_extra_killr  r  rf   r3  r  genss                rh   get_copies_parforr  F  s    'F*8*I''#3FG#D M=  QH!!&&(=#78#741aQ#788M%(( )
 V%%**,-JZ(=+;;D"+T:xH> 9s    C
c                    t        | j                        D ],  \  }}|d   dk(  sdt        |d   |      f| j                  |<   . | j                  D ]S  }t        |j                  |      |_        t        |j
                  |      |_        t        |j                  |      |_        U t        |       }	g }
|j                         D ]B  \  }}|
j                  t        j                  |||   t        j                  dd                   D |
|	d   j                  z   |	d   _        t        |	|      \  }}t        |	|||||       t!        |        |	d   j                  t#        |
      d |	d   _        y)z*apply copy propagate recursively in parforr   r+  r   dummyr  N)r1  rx  r(   rr  r  r   r  r  r  rb  r	   r  r  r  r,   r.   r  r   )r   var_dictname_var_tabler  r  save_copiesr   r~  rf   r  assign_listlhs_namer  r  r  s                  rh   apply_copies_parforr  b  sT     0
71:""+"71:x8":FOOA 1 $QWWh7#AFFH5#AFFH5 
  'FK!)#299S.*B%'VVGR%8: 	; * !6!9>>1F1IN*8*I''!1>7"K1 AY^^C$4$56F1IN
rl   c                    | j                         D ]*  }g }t               i }|j                  D ]  }fd}	|sot        |t              r_|j
                  j                  D ]
  }
 |	|
        |j                  j                         }t        ||d       |j                  |       { |	|       |j                         D ]  }|t        |j                  |      z  }  |j                  |        ||_        t        |      dkD  s|j                         D ]  \  }}||   ||<    d|i}t        ||       - y)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                  |j                         y t        |t        j                        rl|j                  dk(  r\|j                  j                  v s|j                  j                  v r+| |j                  <   j                  |j                         y y y y y )Nr  )
r   r	   r  r  r  r  rV  r  r  rl  )r  r  r  
block_defssaved_getattrssaved_globalss      rh   process_assignz&push_call_vars.<locals>.process_assign  s    dBII.**C++C"3		226chh/"sxx0#C1cff	6IIINNm;#&99>>^#C7;N3884&NN3884 $D 7J1 /rl   T)nestedr   N)r  r  r  r   rh  rs  rt  r  rH  rb  re  _get_saved_call_nodesrV  r   r  rI   )r  r  r  r  r  r  r	  rename_dictr  r  r   pblocksr  r  temp_blocksr  s    ``            @rh   rH  rH    s9   
  U
 JJD5 jv6--A"1% ...--/w~wW[\%t$^^%1!&&-2@*k[ [ & OOD!5 6 
{a#))+1$QZ
 , e*Kk;7] !` rl   c                     g }| |vre| |v s| |v r]d }| |v r |||    d|||       d} n6| |v r2 |||    d|||       ||    j                   j                   j                  } | |vr
| |v rX| |v r]|j                          |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                  || j                  j                  <   y r`   )r   r	   r  rc  r  r  r    rm  r  r  r  rb  r  rV  )objvar_baser  r  r  renamed_varrenamed_assigns          rh   rename_global_or_getattrz7_get_saved_call_nodes.<locals>.rename_global_or_getattr  s    c299-.-&&!1!1!.x!8!$1K  YYt}}SYY'?'2'*ww0N LL(NN3::??++9+@+@+E+EK

(rl   z$push_global_to_block_PA_DONEz$push_getattr_to_block)r  rV  r  )fnamer  r  r  r  r  r  s          rh   r  r    s     E
"(>+0N+B
	F M!$]5%9;R%*JEEn$$^E%:<T%*JE"5)//55::E+ 
"(>+0N+B* 
MMOLrl   c           
         t        | t              r| d   }t        |t              st        |d      r|j                  }nd}| d   }t        |      dk(  rdj                  |t        |d               S d|z   dz   }dj                  |j                  |D cg c]  }t        |       c}            S t        | t        j                  j                  j                        r$| j                  }|j                  d      rd	|z  S |S t        | t        j                  j                  j                        rt!        | j"                        S yc c}w )
zMExtract operators from arrayexpr to represent it abstractly as a string.
    r   ry   r  r   z({}({}))r  z({})$z'%s' (temporary variable))r   r  r  hasattrry   r   r$  r}  r  r   r  r	   rc  rV  r  r  r  r  )rl  oprrw   re   rV  s        rh   r}  r}    s    )U#l#s#sJ'll|t9>$$S.a*ABB)c/C==t*Mt!N1,=t*M!NOO	Iuzz}}00	1~~??30477K	Iuzz}}22	3IOO$$ +Ns   Ec                 r    g }| j                   D ]  }|j                  ||           t        |      |_        y)zpostproc updates generator_info with live variables after transformations
    but generator variables have types in return_type that are updated here.
    N)
state_varsrb  r  state_types)rN  r   r  new_state_typesr  s        rh   rM  rM    s;     O&&wqz* '#O4K
rl   c                 f    |i }|i }t        |       }t        |||      \  }}t        |        ||fS r`   )r  r3   r  )r   r  reverse_call_tabler  s       rh   get_parfor_call_tabler    sO    
!'F%3FJ4F&H"J" )))rl   c                 f    |i }t        |       }t        j                  ||      }t        |        |S r`   )r  r   get_tuple_tabler  )r   tuple_tabler  s      rh   get_parfor_tuple_tabler    s7    'F**6;?K rl   c                 v    |
t               }t        |       }t        j                  ||      }t	        |        |S r`   )r  r  r   get_array_accessesr  )r   accessesr  s      rh   get_parfor_array_accessesr    s8    5'F**68<H Orl   c                 |    t        |       }t        ||      }||   |d<   |j                  |       t        | |       y r   )r  r8   r  r  )r   r  r  s      rh   parfor_add_offset_to_labelsr  ,  s>    'F!&&1FvF1I
JJv(
rl   c                 \    t        |       }t        j                  |      }t        |        |S r`   )r  r   r(  r  )r   r  	max_labels      rh   parfor_find_max_labelr  8  s*    'F''/I rl   c           
         |j                   }t        |       }| j                  D cg c]  }|j                   }}t	        |j                               }||   j                  }|D cg c]/  }t        j                  t        j                  d|d      ||      1 }	}||   j                  }
|	||   j                  z   ||   _
        ||_         |j                          ||_         |
||   _
        t        |        y c c}w c c}w )Nr   F)rm  use_literal_type)r  r  rr  r[  r   r  rm  r	   r  r  r  build_constraintr  )r   typeinferersave_blocksr  rf   r  first_blockrm  r  index_assignssave_first_block_bodys              rh   parfor_typeinferr  A  s    $$K'F,2,=,=>,=q!"",=J> fkkm$K


!
!C^hi^hYZRYYrxxsUKQPST^hMi";/44,vk/B/G/GGF;K  "$K4F;  ? js   C:'4C?c                     |t        t              }t        | j                  |       t        d| j                  i|       |S )z)get variable definition table for parforsr   )r   r  r@   rt  rs  )r   definitionss     rh   build_parfor_definitionsr  V  s?    !$' f&&4q&++,k:rl   c           	   #     K   t        | j                               }| |   j                  }t        j                  |t        d      t        j                  dd            }| |   j                  j                  t        j                  |t        j                  dd                   d | |   j                  j                          yw)zLadds dummy return to last block of parfor loop body for CFG computation
    r  r  r  N)r   r  r  r	   rc  r    r  r  rb  r  r  )rt  r  r  r  s       rh   r  r  c  s     
 Y^^%&Jj!''EFF5-1266/23NOEj%%
		%457	j""$s   CCc                       e Zd Zd Zy)ReduceInferc                     |rJ t        |      dk7  rt        j                  d      t        |d   t        j
                        sJ t        |d   j                  g| S )Nr   zlen(args) != 3r   )r   r   NumbaAssertionErrorr   r   r   rQ   r   )r\  rw   r  s      rh   genericzReduceInfer.generics  sV    wt9>,,-=>>$q'5;;///a...rl   N)ry   rz   r{   r  rk   rl   rh   r  r  q  s    /rl   r  c                  R    t         j                  rd} t        j                  |       y)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    rh   ensure_parallel_supportr
  {  s*     ,,S11 rl   r  )NNNNNr  r  )NNNr`   (  rf  r   pytypesr  r  rg  textwrapr  r.  rk  	functoolsr   collectionsr   r   r   
contextlibr   r,  dataclassesr   r  llvmliter	   lirnumba.core.imputilsr
   numba.core.irr   r  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   r9  r   numba.parforsrZ   numba.cpython.builtinsnumba.stencilsr[   r  TextWrapperrb   ri   r  rm   rq   r+  rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r%  r0  r  rJ  r  r   r   r   r   rU  r  rY  r  Stmtrh  r  array_analysis_extensionsr  r  r  r  r  r3  r5  r  r  rg  r  r  r  r&  r1  rD  r  r  r|  ra  re  rd  rO  r  r  r6  r  r  r  r  r  r  r  r  r7  r  r  r  r  r  r  r  visit_vars_extensionsr   ir_extension_usedefsr$  ir_extension_use_allocar2  ir_extension_insert_delsr8  r5  r?  r:  rA  rB  rJ  r;  rY  rl  rX  rW  r  r  r  remove_dead_extensionsr  r  r  alias_analysis_extensionsr4  r  r  r  copy_propagate_extensionsr  apply_copy_propagate_extensionsrH  r  r}  rM  r  call_table_extensionsr  tuple_table_extensionsr  array_accesses_extensionsr  add_offset_to_labels_extensionsr  find_max_label_extensionsr  typeinfer_extensionsr  build_defs_extensionsr  r  r
  rk   rl   rh   <module>r5     sF     	      < < %  &   2  r r r r " J : F 4 @, , , , , , , , , , , ,\H H * 0 /> > *    (  ( 
"h""UK0 # 
 
+ 
f  D@			"
',..8
 48 4GlI0 :9''(('))'''-1 "(   > >
 > >
 G G G G .66*:; ''7H&'7H#M;?#M;?$]K@$]K@" v :I(RWWbgg I(X  4C ( ( 0N Nba"F a"F% %<sW sWlA~W ~WB
:!Z ZzS$ S$l`; `;F.b6E! 6Erf%' f%RPE, PEf%P	-nb2JZS@(D%N F#04(V( $ ) QU;?P'dH&68l\NN& *;  v &1Eh )4  f %
! ,>     (+ \ -? ! !& )2 59(:'

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