o
    8ήcK>                    @   s>  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Zd dl	Z
d dlZd dlmZ d dlmZmZmZmZmZm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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0 d d	l1m2Z2 d
d Z3edg dddZ4dd Z5G dd de0Z6dd Z7dd Z8dd Z9dd Z:dd Z;dd Z<d d! Z=d"d# Z>d$d% Z?d&d' Z@d(d) ZAd*d+ ZBd,d- ZCd.d/ ZDd0d1 ZEd2d3 ZFd4d5 ZGd6d7 ZHd8d9 ZId:d; ZJd<d= ZKd>d? ZLd@dA ZMdBdC ZNdDdE ZOdFdG ZPdHdI ZQdJdK ZRdLdM ZSdNdO ZTdPdQ ZUdRdS ZVdS )T    N)make_dataclass)parfor)typesirconfigcompilersigutilscgutils)add_offset_to_labelsreplace_var_namesremove_delslegalize_namesmk_unique_varrename_labelsget_name_var_tablevisit_vars_innerget_definitionguardget_call_tableis_pureget_np_ufunc_typget_unused_var_nameis_const_callfixup_var_define_in_scopetransfer_scopefind_max_labelget_global_func_typ)	signature)ensure_parallel_support)NumbaParallelSafetyWarningNotDefinedErrorCompilerErrorInternalError)ParforLoweringBuilderc           E      C   s$  ddl m} t  | jj}| j}| j}| jj}t|| j_t	j
r+td| jt| j | jj}| j}t	j
r=td |  |jj}	|jj}
t	j
rStd|jdt|j |jjD ]}t	j
ratd| | | qW|jD ]}||vr|| }t|
||	}| |j| qji }i }tjj||j|| j|| t	j
rtd| td	| |jd
usJ tjj||j}|j |j!}}t	j
rtd| td| t"|}i }|dkr|jj}
|jj}	t#| |
|	d}|j$tj%j&j'j(t)tj%j&j'j(dd}|j*|j+|g dt,j-dd}t.|D ]}|| }| jj| }t|
||	}t/|}|j0}t	j
r3td||||t,1||t| t2|t,j3j4rA|j5d }nd}|j$t%j6t7t%j6t,8t,j-|fdt,1|id} |g}!t2|t,j3j4r|j*tj9:|d|	t,8t,j-|j5dd}"t.|j5D ]}#|j*tj9;|"|#d
|	t,j-dd}$|!<|$ q|j=|!dd}%|j>?|}&|j@|&t,1|d}'|j+| |%|'gd}(|j*|(|dd})|)||j< || jA}*|*d
urt2|t,j3j4r|j$t%jBt7t%jBt,8t,j-|j5|fdt,1|id}+|j@|*|dd},|j+|+|"|,|'gd}-|j*|-|d d}.nI|j@|*|d d}.n@|}.t	jCrUd!tD| d" }/t,E|/}0|j@|/|0d#d}1tjF|1|gd
|	d$}2tGt,jH||1j ||j | jjI|2< td%|2 | |2 ||j }3|J|3}4tKL||4}5|
Md&|	}6|3||6j< |5| j|6j< tKjN|| O|j|4d'}7|P|7jQ|5 |jR|)|6|.d( W d
   n	1 sw   Y  q|jS }8d)|8_T||jUd jVj }9|jUdd
 D ]}:||:jVj |9ksJ qd*tjj_WztX| |||||8i tY||9|j
\};}<}=}>}?W d+tjj_Wnd+tjj_Ww d,g|< }<t"|}@t"|<t"| |@ }At	j
r#td-|< td.|A td/| td0| td1|@ tZ|j[|A|@|<|=|j|}Bt	j
r8td2|B d3d4 |jUD }Ct	j
rOtd5|jU td6|C t\| |;|B|=|<|>|C||||j|9|j|? |dkrot]||| || |^ D ]}D| tj_|Dj|	d7 qs|| j_t	j
rtd8 d
S d
S )9a  Lowerer that handles LLVM code generation for parfor.
    This function lowers a parfor IR node to LLVM.
    The general approach is as follows:
    1) The code from the parfor's init block is lowered normally
       in the context of the current function.
    2) The body of the parfor is transformed into a gufunc function.
    3) Code is inserted into the main function that calls do_scheduling
       to divide the iteration space for each thread, allocates
       reduction arrays, calls the gufunc function, and then invokes
       the reduction function across the reduction arrays to produce
       the final reduction values.
    r   )get_thread_countzlowerer.fndesc_lower_parfor_parallelzinit_block =  zlower init_block instr = 	alias_maparg_aliasesNzparfor_redvars:zparfor_reddict:)lowererscopeloc )fobjftypeargs)r/   num_threads_var)rhstypnamereduction_info   dtype)r-   r.   r/   kwsshaperedarr_shaperedshapeonedimtuple_size_varr3   )cvalr2   redarrinit_val)r=   r2   r3   redtosetzres_print1 for redvar :	str_constr/   varargr+   res_print_redvarz$loop_index)intp)objindexvalnumpyTFschedzfunc_args = znum_inputs = parfor_outputs = parfor_redvars = znum_reductions = zgu_signature = c                 S   s   g | ]
}|j |j|jfqS r,   )startstopstep.0lr,   r,   D/tmp/pip-target-vg8gfxp4/lib/python/numba/parfors/parfor_lowering.py
<listcomp>X      z*_lower_parfor_parallel.<locals>.<listcomp>zloop_nests = loop_ranges = )r+   z_lower_parfor_parallel done)`numba.np.ufunc.parallelr$   r   contexttyping_contextbuilderfndesctypemapcopyr   DEBUG_ARRAY_OPTprinttypevarmapdump
init_blockr+   r*   body
lower_instracesr   Var_alloca_varr3   numbaparforsr   find_potential_aliases_parforparamsfunc_irget_parfor_outputsredvarsreddictlenr#   bind_global_functionnpufuncparallel_iget_num_threadsr   assigncallr   rF   rangeredtyp_to_redarraytyper6   DType
isinstancenpytypesArrayndimemptyr   UniTupleExprgetattrstatic_getitemappendmake_tuple_variable
_typingctxresolve_value_typemake_const_variabler?   fullDEBUG_ARRAY_OPT_RUNTIMEstrStringLiteralPrintr   none	calltypesget_value_typer	   alloca_onceredefine	for_rangeloadvarstorerH   setitemflagserror_model
loop_nestsindex_variablesequential_parfor_lowering_create_gufunc_for_parfor_bodybool_create_shape_signatureget_shape_classescall_parallel_gufunc#_parfor_lowering_finalize_reductionvaluesDel)Er)   r   r$   	typingctx	targetctxr[   orig_typemapr]   rb   r+   r*   instrracevarrvtyprvr'   r(   parfor_output_arraysparfor_redvarsparfor_reddictnredvarsredarrspfbdrget_num_threadsr0   ired_name
redvar_typredvarredarrvar_typreddtype	redarrdimglbl_np_emptysize_var_listredshape_varj	onedimvarsize_varr=   dt
empty_call
redarr_varr?   full_func_nodeinit_val_var	full_callr@   res_print_strstrconsttyplhs	res_printnum_thread_typentllvm_typealloc_loop_varnumba_ir_loop_index_varloopr   index_var_typrS   func	func_argsfunc_sigfunc_arg_typesexp_name_to_tuple_varnum_reductions
num_inputsgu_signatureloop_rangesvr,   r,   rT   r%   +   s  







	






















r%   _ReductionInforedvar_inforedvar_namer   r   
redarr_typr?   T)frozenc              	   C   st   |  D ]3\}}|jj| }|jj|j }||}	t|| |||||	d}
|
jjdur.tnt	}|| |||
 qdS )zYEmit code to finalize the reduction from the intermediate values of
    each thread.
    r   N)
itemsr\   r]   r3   r   r   r   redop_lower_trivial_inplace_binops_lower_non_trivial_reduce)r   r   r)   r   thread_count_varr   r   r   r   r?   reduce_infohandlerr,   r,   rT   r     s$   


r   c                       s   e Zd Z fddZ  ZS ) ParforsUnexpectedReduceNodeErrorc                    s   t  d|  d S )Nz!Unknown reduce instruction node: )super__init__)selfinst	__class__r,   rT   r     s   z)ParforsUnexpectedReduceNodeError.__init__)__name__
__module____qualname__r   __classcell__r,   r,   r   rT   r     s    r   c                 C   s   |j jD ]1}t||rnt||jr'|jj}t||||}|j||j	j
d nt|t| |||jr5 nqtjrO|j}|| j d|j d| d| dS dS )z+Lower trivial inplace-binop reduction.
    r<   z	: parfor z reduction  =N)r   reduce_nodes_lower_var_to_var_assign!_is_inplace_binop_and_rhs_is_initr   valuefn_emit_binop_reduce_callstorevartargetr3   r   _fix_redvar_name_ssa_mismatchr   r   print_variabler+   r   )r   r)   r   r   r   r   redvar_resultvarnamer,   r,   rT   r     s,   
r   c           
         s  |j  d |jj |j ||j}t|j	|K}|j
}|jjD ];}t||r,n)t|tjrQt fdd| D rQt|||}||  || nt|t| |||j r_ nq$W d   n1 sjw   Y  tjr|j }	|| j d|	 d|	 dS dS )zFLower non-trivial reduction such as call to `functools.reduce()`.
    #initc                 3   s    | ]}|j  kV  qd S Nr<   rR   var	init_namer,   rT   	<genexpr>      z,_lower_non_trivial_reduce.<locals>.<genexpr>Nz: parfor non-trivial reduction r   )r   r\   r]   
setdefaultr   r   r3   r	   r   r[   rH   r   r   r   r}   r   Assignany	list_vars_emit_getitem_callr   rf   r   r   r   r   r   r+   )
r   r)   r   r   num_thread_llvalr   tidr   elemr   r,   r  rT   r     s:   
r   c                 C   sB   t |tjrt |jtjr| |jj}| j||jjd dS dS )zaLower Var->Var assignment.

    Returns True if-and-only-if `inst` is a Var->Var assignment.
    r<   TF)	r}   r   r	  r   rh   r   r3   r   r   )r)   r   loadedr,   r,   rT   r     s
   r   c                 C   sT   dd }|j }|j}|j}||jj}|| f}t|j|tj	}	|
|||	|}
|
S )z%Emit call to ``redarr_var[idx]``
    c                 S   s   | | S r  r,   )r>   rH   r,   r,   rT   reducer_getitem  s   z+_emit_getitem_call.<locals>.reducer_getitem)r[   rY   r   r   r   r3   r   r   r   rF   compile_internal)idxr)   r   r  r[   ctxr   arg_arrr/   sigr  r,   r,   rT   r    s   r  c              
   C   s   dd }dd }t j|t j|t j|t j|t j|i|  }|j}|j}|j}	|	|j
j}
tjr]|j
j|j}tj|j
|gd|jd}|jj}ttj||j
j ||j |jj|< || |	|j}||
|jf}t|jtj|	|j}|||||}|S )z;Emit call to the ``binop`` for the reduction variable.
    c                 S   s"   |}t | D ]}||| 7 }q|S r  rz   thread_countr>   initcr   r,   r,   rT   reduction_add     z._emit_binop_reduce_call.<locals>.reduction_addc                 S   s"   |}t | D ]}||| 9 }q|S r  r  r  r,   r,   rT   reduction_mul  r  z._emit_binop_reduce_call.<locals>.reduction_mulNrC   )operatoriaddisubimul	ifloordivitruedivrY   r[   r   r   r   r3   r   r   r*   getr   r   r   r+   r\   r]   r   r   r   r   rf   r?   r   uintpr  )binopr)   r   r   r  r  kernelr  r[   r   r  init_varr   r]   arg_thread_countr/   r  r   r,   r,   rT   r     sB   

r   c                 C   sN   t | tjsdS | j}t |tjsdS |jdkrdS |jj| dkr%dS dS )zDIs ``inst`` an inplace-binop and the RHS is the reduction init?
    Finplace_binopr   T)r}   r   r	  r   r   opr1   r3   )r   r   r1   r,   r,   rT   r   F  s   
r   c           
      C   s   | j j}t|tjrDz||}W n ty    ||jjk}Y nw |j	}|jj	}||k}|rD||jjkrD|
|jj}	|j|	|d dS dS )z5Fix reduction variable name mismatch due to SSA.
    r<   TF)rd   r*   r}   r   r	  	get_exactr    r   r3   unversioned_namer   r   )
r   r)   r   r   r*   reduction_varis_same_source_varredvar_unver_nametarget_unver_namerI   r,   r,   rT   r   U  s    	r   c              	      s  t jr!td||| |dd D ]}td|t||d qt|| }fdd|dd D }	t }
|	D ]}|rI|D ]}|
| qAq;|
rRt|
d nd}|	d|f |
| |d }|
| i t	d	}|
D ]}|dkrt
||< |d7 }qqt
|}d
|i  fddg }g }d}d}t jrtd| td|	 td| t|	|D ]7\}}|d }|rtfdd|D }nd}||kr|t|gt|dd   q|| ||7 }q||fS )z&Create shape signature for GUFunc
    r   r5   Nargumentr]   c                    s$   g | ]}|vr |d ndqS )r4  )r,   r  )r   rg   r]   r,   rT   rU     s   $ z+_create_shape_signature.<locals>.<listcomp>r   alatest_alphac                    s,   | dkr||  S  d  d7  < t  d S )Nr   r7  r5   )chr)r  	class_map)
alpha_dictr,   rT   
bump_alpha  s   z+_create_shape_signature.<locals>.bump_alphar,   r/   classesthreadcount_ordinalc                 3   s    | ]} |V  qd S r  r,   )rR   r  )r;  r9  r,   rT   r    r  z*_create_shape_signature.<locals>.<genexpr>)r   r_   r`   ra   rr   setaddmaxinsertordr8  ziptupler   list)r   r   r   r/   r   rg   r]   r   
num_inoutsr<  	class_set_class	max_classthread_num_classalphabetnr=  gu_singu_soutcountsyms_sinclsargdim_symsr,   )r:  r;  r9  r   rg   r]   rT   r   x  sZ   





"

r   c                 C   s&   t | jD ]\}}td|d| qd S )N    r&   )	enumeratere   r`   )blockr   r   r,   r,   rT   _print_block  s   rW  c                 C   s(   |   D ]\}}td| t| qdS )z%Pretty-print a set of IR blocks.
    zlabel: N)r   r`   rW  )	body_dictlabelrV  r,   r,   rT   _print_body  s   

rZ  c                 C   sF   |   }t| }t| }|| j}|| jt|| |S r  )	r^   minkeysr@  r+   re   r   r   Jump)	loop_bodyblocksfirst_label
last_labelr+   r,   r,   rT   wrap_loop_body  s   
rb  c                 C   s(   t |  }| | jd d | | _d S )Nr5  )r@  r\  re   )r^  ra  r,   r,   rT   unwrap_loop_body  s   rc  c                 C   s:   | |v rdS | |v r| |  ||  dS | |  dS )a_  If the variable is already defined more than once, do nothing.
       Else if defined exactly once previously then transition this
       variable to the defined more than once set (remove it from
       def_once set and add to def_more set).
       Else this must be the first time we've seen this variable defined
       so add to def_once set.
    N)r?  remove)a_defdef_oncedef_morer,   r,   rT   add_to_def_once_sets  s   
rh  c                 C   sH  |  tj}|D ]}|jj}t||| |j}	t|	tjr*t|	jt	j
r*|	jj||< t|	tjrD|	jdkrD|	jj|v rD|	jj|	jf||< t|	tjrw|	jdkrw|	jj|v rw||	jj \}
}|
|v rq||
 }t||spt|
|| nt|
|| t|	tjr|	jdkr|	jD ]}t|tjr|j}|| }t|ddrt||| qqdS )a  Effect changes to the set of variables defined once or more than once
       for a single block.
       block - the block to process
       def_once - set of variable names known to be defined exactly once
       def_more - set of variable names known to be defined more than once
       getattr_taken - dict mapping variable name to tuple of object and attribute taken
       module_assigns - dict mapping variable name to the Global that they came from
    r   ry   mutableFN)
find_instsr   r	  r   r3   rh  r   r}   Globalpytypes
ModuleTyper   r   r,  attrr   r   r/   rh   r   )rV  rf  rg  getattr_takenr]   module_assignsassignments
one_assignre  r1   base_obj	base_attrbase_mod_nameargvaravtyper,   r,   rT   compute_def_once_block  s6   
""

rx  c           	   	   C   sh   |   D ]-\}}t|||||| |jD ]}t|tjr0t|j||||| t|j||||| qqdS )zCompute the set of variables defined exactly once in the given set of blocks
       and use the given sets for storing which variables are defined once, more than
       once and which have had a getattr call on them.
    N)	r   rx  re   r}   r   Parforrd   compute_def_once_internalr^  )	r^  rf  rg  ro  r]   rp  rY  rV  r   r,   r,   rT   rz  #  s   
rz  c                 C   s.   t  }t  }i }i }t| ||||| ||fS )zRCompute the set of variables defined exactly once in the given set of blocks.
    )r>  rz  )r^  r]   rf  rg  ro  rp  r,   r,   rT   compute_def_once5  s   r{  c                 C   s    t | tjsJ || j | S r  )r}   r   rh   r?  r3   )r  varsetr,   r,   rT   	find_vars?  s   r}  c           	      C   s4  | j j|v r|| df tjdkrtd| d dS t }t| jt	| |
|}tjdkr7td| d|d| t|d	krlt| jd |rltjdkrStd
| || j j  ||  t|| j j tjjsj|| j jg7 }dS t|d	kr|| df tjdkrtd| d dS || df tjdkrtd| d dS )Nzstored arrayr5   Instructionz: could not be hoisted because the created array is stored.Fz_hoist_internal:zuses:zdiff:r   zWill hoist instructionT
dependencyz. could not be hoisted because of a dependency.znot purez, could not be hoisted because it isn't pure.)r   r3   r   r   r_   r`   r>  r   r   r}  
differencerr   r   r}   r   r~   r   )	r   dep_on_param
call_tablehoistednot_hoistedr]   stored_arraysusesdiffr,   r,   rT   _hoist_internalD  s4   






r  c                 C   s   |j D ]:}t|tjtjfr'| |jj t||j	j ddr&||j	j qt|t
jr=t| ||j| t| ||j| qd S )Nri  F)re   r}   r   StaticSetItemSetItemr?  r   r3   r   r   r   ry  find_setitems_blockrd   find_setitems_bodyr^  )setitemsitemssetrV  r]   r   r,   r,   rT   r  c  s   
r  c                 C   s$   |  D ]\}}t| ||| qdS )z
      Find the arrays that are written into (goes into setitems) and the
      mutable objects (mostly arrays) that are written into other arrays
      (goes into itemsset).
    N)r   r  )r  r  r^  r]   rY  rV  r,   r,   rT   r  q  s   r  c                 C   sf   t | tjr1t | jtjr1| jjdkr1| jjj|v r1|| jjj }|dtgkr1t	| ||||||S dS )Nry   r   F)
r}   r   r	  r   r   r,  r   r3   rt   r  )r   r  r  r  r  r]   r  	call_listr,   r,   rT   empty_container_allocator_hoistz  s   

r  c                 C   s  t  | }g }g }t||\}}t|\}	}
t }t }t|||| tt||}tjdkr>t	d|d|d|d|d| 
 |D ]}t
||| q@| D ]~\}}g }|jD ]q}t|||	||||rcqVt|tjr{|jj|v r{t|||	||||rzqVnGt|tjrg }tjdkrt	d |  |jjD ])}t|||	||||rqt|tjr|jj|v rt|||	||||rq|| q||j_|| qV||_qM||fS )Nr5   zhoist - def_once:z	setitems:z	itemsset:zdep_on_param:zparfor_params:r   )r^   r{  r   r>  r  rE  r  r   r_   r`   rh  r   re   r  r}   r   r	  r   r3   r  r   ry  rc   rd   r   )parfor_paramsr^  r]   wrapped_blocksr  r  r  rf  rg  r  reverse_call_tabler  r  sirY  rV  	new_blockr   new_init_blockib_instr,   r,   rT   hoist  s`   





r  c                 C   s   t | tjj S r  )r}   r   r~   r   )redtyper,   r,   rT   redtyp_is_scalar  s   r  c                 C   s2   d}t | tjjr|| j7 }| j} tj| |dS )ziGo from a reducation variable type to a reduction array type used to hold
       per-worker results.
    r5   C)r}   r   r~   r   r   r6   )redtypr   r,   r,   rT   r{     s
   
r{   c                 C   s(   t | tjjs	J tj| j| j| jS )zYGiven a reduction array type, find the type of the reduction argument to the gufunc.
    )r}   r   r~   r   r6   r   layout)redarraytypr,   r,   rT   redarraytype_to_sig  s   r  c                 C   s2   t | }| D ]\}}||kr|| ||< q|S )aQ   We use ir_utils.legalize_names to replace internal IR variable names
        containing illegal characters (e.g. period) with a legal character
        (underscore) so as to create legal variable names.
        The original variable names are in the typemap so we also
        need to add the legalized name to the typemap as well.
    )r   r   )namesr]   outdictxyr,   r,   rT   legalize_names_with_typemap  s   r  c                 C   s    t | tjr| jdkr| jS | S )Nr   )r}   r   ArrayCompatibler   r6   )r  r,   r,   rT   to_scalar_from_0d  s   
r  c
           d   	      sX  t jdkr	td |jj}
t|j}t| t|j	}dd |j	D }|j
}tjj||}| jjtjj| j||| jj\}}ttt|t| t| }t jdkr{td|dt| td|dt| td|dt| td	|dt| g }i }i }d
}g }|D ]}| }t|tjst|tjr|j}|j}|t jksJ g }t|D ] }dt | }|!| |!| ||f||< |d7 }||< q|||< |!| qt|tj"st|tj#r$|j}|j}|t jksJ g }t|D ]"}dt | }|!| |!| ||f||< |d7 }|| |< q|||< |!| q|!| q|}t jdkr;td|dt| |	$t|}	|	D ]} d|  }!t%&t'|!|
 qDt(|	|| jj g }"g }#|D ]/}$|$d }%|"!|% t)|$ }&|#!|& t*|&}'|%v r|% |'ksJ qc|'|%< qc|| |" }t jdkrtd|dt| td|dt| td|dt| t+| t,|| | t jdkrtdt- dt t,|  fdd|D }(t jdkrtdt - dt  td|(dt|( |D ]})td|) td|) dt|)  qfdd|D }*fdd|| D |# }+t jdkrBtd|* td|+ t.| |},fdd|D }|}-g }d}.tt|-D ])}/|.r|/t|k rt|*|/ tj/j0r|!|-|/ d  q^|!|-|/  q^t.|  t1|}0t2d|0}1t jdkrtd|dt| d t3t4|5d!d" }2t jrtd#t|2d|2 d$}3|3d%|2 d& d'6| d( 7 }3t7td)}4|- D ]\}5}6|5 }7|3d*|5  7 }3t|7tj#st|7tjrd+}8nd}8|8rt8t9| j|5}9d,}:t jrtd-|9t|9 |9d,urUt|9t:j;r;|9j<d.kr;t8t9| j|9j=}:t jr:td/|:t|: nt|9t:j>rU|9j? }:t jrUtd/|:t|:|:j? |:d,urt|:t:j@sht|:t:jAr}|:jB};t jrwtd0|;t|; |;|4|:j?< n7t|:tjCjDr|:j?Ed1d
 }<t jrtd2|<|:jFt|:jF |:jF|4|<< nt jrtd3 tGd4t |5 |5j|3d5|7jFjH d1 7 }3tI|6|7jJD ]\}=}>|3|>d6 |=  d7 7 }3qn|3d8d'6fd9d|6D  7 }3t|6dkr|3d77 }3|3d:7 }3qtt|D ] }/|.rt|*|/ tj/j0r|3d*|-|/  d; ||/  d: 7 }3qd<}?t|"d
kr4|3d*|? d5 7 }3|3d=7 }3tI|"|D ]A\}%}$|3d*|$  d6 |%  d> |? d? 7 }3t jKry|3d@7 }3|3dA|$  d7 |$  dB 7 }3|3dC|%  d7 |%  dB 7 }3q9t|D ]+}@t|@d D ]}A|3d*7 }3q|@}B|3dD|(|@  dE t |B dF t |B|  dG 7 }3qt jKrt|d D ]}A|3d*7 }3q|3dH7 }3t|D ]}@|3dI|(|@  dJ |(|@  d7 7 }3q|3d:7 }3t|d D ]}A|3d*7 }3q|3|1dK 7 }3tI|"|D ]1\}%}$t jKr|3dL|$  d: 7 }3|3dM|%  d: 7 }3|3d*|%  d> |? dN |$  dO 7 }3q|3dP7 }3t jrAtdQt|3dO|3 tdR|4t|4 i }CtL|3|4|C |C|2 }Dt jrZtdSt|DdO|D tMN|D}Et jrytdTt|E |EO  tdUt| t+| t1|EjP}Fi }G|1gtQ  |( }H|F- D ]\}=}$|=|HvrtR|=|G|=< qt.|EjP|G t jrtdV |EO  tj/0|ddWg|* }It jrtdXt|IdO|I tS|EjPd }JtT||J}tS|d }Kt jKrn|- D ]\}L}M|M }N|NU  |Mj}
|MjV}O|MjWD ]n}P|N!|P t|Pt:jXrf|PjYj? tjZvrqdY[|PjYj?}Qt\|Q}Rt:]|OtRdZ|
}St:jXt:j^|Q|
d[|S|
d\}T|R|Sj?< |N!|T t:j_|S|PjYgd,|
d]}U|N!|U tj`jabtjc|Sj? |PjYj? }V|V| jj|U< q|N||L< qt jrztd^ t+| td|}Wte|||W\}X}Y|EjPtf|EjPg  }Z|ZjWd,d_ |X |ZjWd_ g |Z_Wth| | jid` }[|X|Yda|[jj|jk< t jrtdb t+| |EjP- D ]|\}L}Mtl|MjWD ]p\}}Pt|Pt:jXr<|PjYj?|1kr<|Pj}
|MjV}Ot:m|O|
}\|MjWd,| |\_W|MjW|d d, |M_Wtf|g }]|\!t:n|]|
 |- D ]\}^}_to|_|O|EjP|^< qtp|g }`|M|EjP|K< |\|EjP|L< |EjP|` !t:n|K|
  nq͐q t jrMtdc |EO  tq|EjP|E_Pt|EjP t jrntdd |EO  tde| tdf |jr}a|st jr|tdg d+|_rts|EjP tMt|||E|Itjc||}b|a|_rtbtjcg|IR  }ct jrtdh|c |b|,|c|+|fS )ia~  
    Takes a parfor and creates a gufunc function for its body.
    There are two parts to this function.
    1) Code to iterate across the iteration space as defined by the schedule.
    2) The parfor body that does the work for a single point in the iteration space.
    Part 1 is created as Python text for simplicity with a sentinel assignment to mark the point
    in the IR where the parfor body should be added.
    This Python text is 'exec'ed into existence and its IR retrieved with run_frontend.
    The IR is scanned for the sentinel assignment where that basic block is split and the IR
    for the parfor body inserted.
    r5   z'starting _create_gufunc_for_parfor_bodyc                 S   s   g | ]}|j jqS r,   )r   r3   rQ   r,   r,   rT   rU         z2_create_gufunc_for_parfor_body.<locals>.<listcomp>zparfor_params = r&   rL   zparfor_inputs = rM   r   expanded_tuple_var_z$parfor_inputs post tuple handling = zVariable %s used in parallel loop may be written to simultaneously by multiple workers and may result in non-deterministic or unintended results._arrzloop_indices = zloop_body = zparam_dict = c                       g | ]} | qS r,   r,   rR   r   )ind_dictr,   rT   rU     r  zind_dict = zlegal_loop_indices = zpd = z
pd type = c                    s   g | ]}t  | qS r,   )r  r  r4  r,   rT   rU     s    c                    r  r,   r,   r  r4  r,   rT   rU     r  znew param_types:znew func_arg_types:c                    r  r,   r,   r  
param_dictr,   rT   rU     r  Fparam__sentinel__zlegal parfor_params = z__numba_parfor_gufunc_%s-_zgufunc_name  zdef z(sched, z, z):
)rt   rj   rT  TNz	func_def:ry   znamed_tuple_def:zgval:(zname:z0Didn't find definition of namedtuple for globls.zCould not find definition of z = =,z = (c                    r  r,   r,   rR   r  r  r,   rT   rU     r  z)
z = np.ascontiguousarray(!ParallelAcceleratorGufuncThreadIdz*numba.np.ufunc.parallel._iget_thread_id()
[z]
z<    print("thread id =", ParallelAcceleratorGufuncThreadId)
zF    print("initial reduction value",ParallelAcceleratorGufuncThreadId,z.shape)
z>    print("reduction array",ParallelAcceleratorGufuncThreadId,zfor z in range(sched[z	], sched[z] + np.uint8(1)):
zprint("z",z = 0
zD    print("final reduction value",ParallelAcceleratorGufuncThreadId,zD    print("final reduction array",ParallelAcceleratorGufuncThreadId,z] = 
z    return None
zgufunc_txt = zglobls:zgufunc_func = zgufunc_ir dump zloop_body dump zgufunc_ir dump after renaming r  zgufunc_param_types = z{} =rB   )r   r+   )r   r   r+   rC   zparfor loop bodyr5  parfor_diagnostics)r  r  zAfter hoistingz#gufunc_ir last dump before renamingzgufunc_ir last dumpr   r]   z(No aliases found so adding noalias flag.z5finished create_gufunc_for_parfor_body. kernel_sig = )ur   r_   r`   rd   r+   r^   r^  r   rr   r   rm   rj   rk   r   ro   r\   r]   get_parfor_reductionsrn   r   sortedrE  r>  ra   r}   r   r   NamedUniTuplerO  r6   PARFOR_MAX_TUPLE_SIZErz   r   r   Tuple
NamedTupler  warningswarnr   replace_var_with_arrayr{   r  rZ  r  r   r   r~   r   r   r   hexhashreplacejoinrt   r   r   r   r   r,  r   Argr3   rk  FreeVarr   
containersBaseNamedTuplesplitinstance_classr!   r   rC  fieldsr   execr   run_frontendrc   r_  r   r   r   r
   clearr*   re   r	  r   number_domainformatr   rh   Constr   coretypingr   r   rb  r  r[  r\  rc  metadata
hoist_infoidrU  Blockr]  r   r@  r   noaliasr   
compile_ir)dr)   r   r]   r   r   r   localshas_aliasesr   rg   r+   r^  
parfor_dimloop_indicesr  parfor_outputsr   r   parfor_inputstuple_expanded_parfor_inputstuple_var_to_expanded_namesexpanded_name_to_tuple_varnext_expanded_tuple_varparfor_tuple_paramspipi_typetuple_counttuple_dtypethis_var_expansionr   expanded_nametuple_typesracemsgparfor_redarrsparfor_red_arg_typesr  arrredarraytype	redarrsiglegal_loop_indicespdparam_typesr   parfor_argsparfor_params_origascontigpindexloop_body_var_tablesentinel_namegufunc_name
gufunc_txtgloblstup_var	exp_namestup_type	named_tupfunc_defnamed_tuple_defgvalnamed_tuple_namer3   
field_namegufunc_thread_id_vareachdimindent	sched_dimloclsgufunc_func	gufunc_ir	var_tablenew_var_dictreserved_namesgufunc_param_typesgufunc_stub_last_label	new_labelrY  rV  r  r*   r   strvalr   r   
assign_lhs
print_noder  r  r  r  start_blockdiagnostics
prev_blockbody_first_labelrS   bbody_last_label	old_aliaskernel_func
kernel_sigr,   )r  r  r]   rT   r     sb  











	














   
	$












 









	
r   c                 C   sF  g }|j D ]}t|tjr|jj| v rtd|j}t|jj	t
d|j}tj||j< t|||j}|| t|jj	t
d|j}	||jj ||	j< |t|j|	|j t|j||	|j}
ttjtj||jj ddtj||jj ||
< ||
 qt|tjrt| d|ji|| t| |j|| || q|S )Nr   z$const_ind_0z$valr5   r  )re   r}   r   r	  r   r3   r  r+   rh   r*   r   r   r&  r   r   r  r   r   r~   r   rF   r   ry  replace_var_with_array_internalrd   r^  )varsrV  r]   r   r  r   
const_node	const_varconst_assignval_varsetitem_noder,   r,   rT   replace_var_with_array_in_block  s,   

(
r-  c                 C   s&   |  D ]\}}t| ||||_qd S r  )r   r-  re   )r'  r^  r]   r   rY  rV  r,   r,   rT   r&    s   r&  c                 C   sD   t | ||| | D ]}|| }||d  tj|dd||< q	d S )Nr5   r  )r&  popr   r~   r   )r'  r^  r]   r   r   el_typr,   r,   rT   r    s   r  c           \         s  j j ddlm}m} tjr5td td|j|j	|j
|j td| td| td| td| t|\}}|j|jj}|\}}|  |||||d	d
d}|j}|j  tjrftd|| fdd}t|}t|D ];}|| \}}}||}||}|dksJ ||}|||f||< tjrtd|||| t d|||| qutjd}tj|}tj|}tj} tj }!tj| }"tj|!}#!tj d}$!tj d}%|%j"}&#| }'|$d |$d}(tjrtd|j% |j%r| })|"}*n|!})|#}*tj& |)!tj |dd}+tj& |)!tj |dd},t|D ]T}|| \}}}|j"|&krG '||&}|j"|&krS '||&}|j"|&kr_ '||&} (||%} )| *|+!tj |g  )| *|,!tj |g q2tj+ j,tj-|!g dd}-tj+ j,tj-tj. |!gdd}.t+ j,tj-tjtjj/g d}/ 0|/g }0 0|-g }1t1  2d|0|0"d t d|0 j34 t5d W d   n	1 sw   Y  tj-|!|!|!|"|"g}2tj+ j,|2dd}3 0|3|0!tj ||+|,g}4 0|.|$g !tj |d  }5 6|4|5}6 j7|)|6d!d}7tjr;dnd}8tj-|"|!|"|"|!|*| g}9|j%rXtj+ j,|9d"d}:n	tj+ j,|9d#d}: 0|:!tj ||+|,|4|7!tj|8g fd$d%|D };t|}<t||< }= fd&d'fd(d%|d|= D |; }>t|>}?t|d }@tj& |!tjd|? d)d}g }A ) 8|7|| |A9!tj|' i }Bt|?D ]}|>| }C|| }D|| }E *|!tj|d g}F||=kr*:|E |C}Gt; |Gj<|Ej=}Htt|HD ]
}I|A9|H|I  q ) 8|Gj>||F qt?|Etj@r|D|v rt|EjAtjBkrCC|EjAntjd}Jt& |J}K )|C|K  ) 8|K||F |C|Kf|B|D< |A9!tj#|J q؈:|E |C}Gt; |Gj<|Ej=}Htt|HD ]
}I|A9|H|I  q ) 8|Gj>||F q||@k rt?|EtjDsC|Entjd}Jt& |J}L )|C|L nt?|EtjDsԈC|Entjd}Jt& |J}L ) 8|L||F qi }Mg }N|(d g}N!tjd | |M|(d < t|t|>ksJ t|t|ksJ t|t|| ks%J t|t|jdd ks5J tE||>||| D ]\}D}C}E}Ot?|EtjFjGrT|Ej=t|O }nd}tjretd*|Dd+|Od,|Ed-| |OD ]Y}Ptjrttd.|Dd/|E |D|v r!tjd|M|P< n:|E |C}Gt; |GjH|Ej=}Q|Q| |M|P< |P|Nvrtjrtd0|Pd1| t |Pd2 |M|P  |N9|P |d }qgq>t|Md }Rtj& | |Rd3d}Q )|4|Q d}|ND ](}Ptjrt |Pd2 |M|P   )|M|P  *|Q!tj|g |d }q|?d t|A }Stj& | !tj|Sd4d}T )!tjd | |' |T t|?D ]}|$}U *|T!tjd| g}F )|U|F q.tt|AD ]}I *|T!tjd|? |I g}F )|A|I |F qNtI|}Vtj-tj. ||"|"|g}Wt+ j,|W|}XjJK|j tjrt d5|X  0|X||Q|T|Vg tjrt d6|X  0|.|1g |BL D ]!\}Y}Z|Z\}C}K *|K!tjdg}[ ) M|[N|Y qjJK|j dS )7zF
    Adds the call to the gufunc function from the main function.
    r   )build_gufunc_wrapper_launch_threadsmake_parallel_loopzouter_sig = rW   	expr_argsexpr_arg_typesr   FT)cache
is_parforszparallel function = c                    s&   t | tjr| jS  tj| S r  )r}   r   rh   r   r3   get_constantr   r&  )r   )rY   r)   r,   rT   
load_range@  s   z(call_parallel_gufunc.<locals>.load_ranger5   z'call_parallel_gufunc loop_ranges[{}] = zloop range[{}]: %d %d (%d)
   z%Parfor has potentially negative start
dim_starts)sizer3   	dim_stopsget_parallel_chunksizer<   set_parallel_chunksizer   z<=znum_threads: %d
)z@Invalid number of threads. This likely indicates a bug in Numba.Nget_sched_size   rK   do_scheduling_signeddo_scheduling_unsignedc                    s   g | ]
}  | jqS r,   )r   r3   r  )r)   
redarrdictr,   rT   rU     rV   z(call_parallel_gufunc.<locals>.<listcomp>c                    s8   | v r|  \}} |} ||}|S  | S )a?  Given a variable name, if that variable is not a new name
           introduced as the extracted part of a tuple then just return
           the variable loaded from its name.  However, if the variable
           does represent part of a tuple, as recognized by the name of
           the variable being present in the exp_name_to_tuple_var dict,
           then we load the original tuple var instead that we get from
           the dict and then extract the corresponding element of the
           tuple, also stored and returned to use in the dict (i.e., offset).
        )r   extract_value)r  orig_tupoffsetr  res)r[   r   r)   r,   rT   load_potential_tuple_var  s   


z6call_parallel_gufunc.<locals>.load_potential_tuple_varc                    s   g | ]} |qS r,   r,   r  )rH  r,   rT   rU     r  pargszvar =zgu_sig =ztype =zi =zvar = z type = z
dim_sym = z, i = z = %d
pshapepstepszbefore calling kernel %p
zafter calling kernel %p
)OrY   r[   rX   r0  r1  r   r_   r`   r/   return_typerecvrpysigr   normalize_signaturelibraryget_functionr\   llvm_func_namer3   _ensure_finalizedrr   rz   r  r	   printfllvmliter   IntTypePointerTyper   r   rF   r&  r7  ra   get_abi_sizeofr.  signedr   sextsubr   gepget_or_insert_functionmoduleFunctionTypeVoidTypebitwidthry   if_unlikelyicmp_signed	call_convreturn_user_excRuntimeErrormulallocabitcastr   
make_arrayunpack_tuplestridesr   datar}   r  r6   booleanget_data_typeBooleanrC  r~   r   r8   get_null_valueactive_code_libraryadd_linking_libraryr   loadgetvar)\r)   cresr   	outer_sigr3  r4  r   rp   rq   rC  rd   r   rg   r   r0  r1  r/   rL  	llvm_funcsinsoutinfowrapper_namer8  num_dimr   rN   rO   rP   byte_t
byte_ptr_tbyte_ptr_ptr_tintp_tuintp_t
intp_ptr_tuintp_ptr_tzerooneone_typesizeof_intp	sched_sig
sched_typesched_ptr_typer:  r<  get_chunksizeset_chunksizer   num_threadscurrent_chunksizeget_sched_size_fntyr?  num_divisions
multiplier
sched_sizerK   
debug_flagscheduling_fntydo_schedulingr   r   ninoutsall_argsnum_argsnum_inpsarray_stridesrv_to_arg_dictrR  r  atydstaryrl  r   r2   rv_argptrsig_dim_dictoccurrencesgu_sigdim_symshapesnshapes	num_stepsstepsstepsizerm  fntyr   kr   only_elem_ptrr,   )r[   rY   r   rH  r)   rC  rT   r     sf  




















 




r   )Wr^   r  r   rl  r  dataclassesr   llvmlite.irrU  rJ   rt   rj   numba.parforsr   
numba.corer   r   r   r   r	   numba.core.ir_utilsr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   numba.core.typingr   numba.parfors.parforr   numba.core.errorsr   r    r!   r"   #numba.parfors.parfor_lowering_utilsr#   r%   r   r   r   r   r   r   r  r   r   r   r   rW  rZ  rb  rc  rh  rx  rz  r{  r}  r  r  r  r  r  r  r{   r  r  r  r   r-  r&  r  r   r,   r,   r,   rT   <module>   s|     T  S$&4#E>
	4    