B
      ›\Q÷  ã               @   s(  d dl mZmZm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Zd dlm  mZ d dlm  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 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. d dl/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5 d d	lm6Z6 d d
l7m8Z8 d dl9m:Z: d dl;m<Z<m=Z= d dl>Z>ddl?m@Z@ dd„ ZAeAejBejC< dd„ ZDdd„ ZEdd„ ZFdd„ ZGdd„ ZHdd„ ZIdd„ ZJdd„ ZKd d!„ ZLd"d#„ ZMd$d%„ ZNd&d'„ ZOd(d)„ ZPd*d+„ ZQd,d-„ ZRd.d/„ ZSd0d1„ ZTd2d3„ ZUd4d5„ ZVd6d7„ ZWd8d9„ ZXd:d;„ ZYd<d=„ ZZdS )>é    )Úprint_functionÚdivisionÚabsolute_importN)ÚOrderedDicté   )ÚcompilerÚirÚtypesÚsixÚcgutilsÚsigutilsÚloweringÚparfor)Ú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Úfind_callnameÚget_call_tableÚis_pureÚget_np_ufunc_typÚget_unused_var_nameÚfind_potential_aliases)Úcompute_use_defsÚcompute_live_mapÚcompute_dead_mapsÚcompute_cfg_from_blocks)Ú	signature)Úconfig)ÚParallelOptions)Úexec_)Úprint_wrappedÚensure_parallel_support)ÚParallelSafetyWarningc       Y      C   s.  ddl m} tƒ  | jj}| j}| jj}t |¡| j_| jj}| j}t	j
rZtdƒ | ¡  |jj}|jj}	t	j
r†td|jdt|jƒƒ x*|jjD ]}
t	j
r¤td|
ƒ |  |
¡ qW x:|jD ]0}||krº|| }t |	||¡}|  |j|¡ qºW i }i }tj ||j|| j||¡ t	j
r,td|ƒ td|ƒ |jd	ks<t‚tj ||j¡}tj ||j| jj ¡\}}t!|ƒ}i }|d
krD|ƒ }|jj}	|jj}x®t"|ƒD ] }| jj||  }t |	|| |¡}t#|ƒ}|j$}t	j
ròtd|||t% &|¡ƒ t'|t%j(j)ƒr|j*d }nd}t |	t+dƒ|¡}t,t-j.ƒ}| /|t% 0t%j1|¡t% &|¡fi ¡}|||j< t 2tj3dt-j.|d||¡}|  |¡ t |	t+dƒ|¡} t 2t 4||¡| |¡}!t%j1|| j< |  |!¡ t |	t+dƒ|¡}"t% 0t%j1|¡||"j< | g}#t'|t%j(j)ƒr²t |	t+dƒ|¡}$t% 0t%j1|j*¡||$j< tj5 6|d|¡}%t 2|%|$|¡}&|  |&¡ xft"|j*ƒD ]X}'t |	t+dƒ|¡}(tj5 7|$|'d	|¡})t%j1||(j< t 2|)|(|¡}*|  |*¡ |#|(g7 }#qVW tj5 8|#|¡}+t 2|+|"|¡},|  |,¡ tj5j9||"gi |d}-t |	t+dƒ|¡}.|||.j< t 2|-|.|¡}/|| jj |-< |  |/¡ |.||j< |||  d
 }0|0d	kr¨t'|t%j(j)ƒrjt |	t+dƒ|¡}1t,t-j:ƒ}2| /|2t% 0t%j1|j*¡|t% &|¡fi ¡}3|2||1j< t 2tj3dt-j:|d|1|¡}4|  |4¡ t |	t+dƒ|¡}5t 2t 4|0|¡|5|¡}6|||5j< |  |6¡ tj5j9|1|$|5gi |d}7|3| jj |7< t |	t+dƒ|¡}8t 2|7|8|¡}9|||8j< |  |9¡ n<t |	t+dƒ|¡}8t 2t 4|0|¡|8|¡}9|||8j< |  |9¡ n|}8xt"|ƒ ƒD ]‚}'t |	t+dƒ|¡}:t 2t 4|'|¡|:|¡};t%j;||:j< |  |;¡ t <|.|:|8|¡}<t=t%j>||.j ||:j |ƒ| jj |<< |  |<¡ q¸W qžW t |j?¡}=|= @dd¡ ||jAd
 jBj }>x.|jAdd	… D ]}?||?jBj |>ks~t‚q~W dtj_CtD| |||||=i tE|ƒ|>|jƒ
\}@}A}B}C}Ddtj_Cdg|A }At!|ƒ}Et!|Aƒt!|ƒ |E }Ft	j
r8td|Aƒ td |Fƒ td!|ƒ td"|ƒ td#|Eƒ tF|jG|F|E|A|C|B|j|ƒ}Gt	j
rdtd$|Gƒ d%d&„ |jAD ƒ}Ht	j
r’td'|jAƒ td(|Hƒ tH| |@|G|B|A|D|H||||j|>|jƒ t	j
rÈtIjJ K¡  |d
kr"|ƒ }|jj}	|jj}x6t"|ƒD ](}|| }I||I }J| jj|I }t	jLr¶d)}Kt% M|K¡}Lt |	t+d*ƒ|¡}Mtj2tj4|K|d+|M|d,}N|L||Mj< |  |N¡ tjN|M|Jgd	|d-}Ot=t%j>||Mj ||Jj ƒ| jj |O< td)|Oƒ |  |O¡ xbt"|ƒ ƒD ]R}'t |	t+dƒ|¡}:t 2t 4|'|¡|:|¡};t%j;||:j< |  |;¡ t |	t+d.ƒ|¡}Ptj5 O|J|:|¡}Q|||Pj< t=|||Jj ||:j ƒ| jj |Q< t 2|Q|P|¡}R|  |R¡ t |	|Id/ |¡}St 2|P|S|¡}T|Id/ |k	r¤|||Sj< |  |T¡ t	jL
rbd0}Kt% M|K¡}Lt |	t+d*ƒ|¡}Mtj2tj4|K|d+|M|d,}N|L||Mj< |  |N¡ tjN|M|:|P|Sgd	|d-}Ot=t%j>||Mj ||:j ||Pj ||Sj ƒ| jj |O< td)|Oƒ |  |O¡ x²||I d D ]¢}Ut'|Utj2ƒr|UjP}Vt'|Vtj5ƒr|VjQd1kr|VjRj|Sjkr| jj |V }Wt!|WjSƒd2k
sÒt‚|WjSd
 |f}X|WjT|Xd3}W| jj  U|V¡ |W| jj |V< |  |U¡ 
qpW qÄW qôW || j_d	S )4a  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.
    é   )Úget_thread_countÚ_lower_parfor_parallelzinit_block = ú zlower init_block instr = Ú	alias_mapÚarg_aliasesNr   Ú
redvar_typÚ
empty_funcÚempty)ÚlocZnum_threadsZtuple_size_varZredarr_shapeÚshapeZredshapeonedimÚredarrÚ	full_funcÚfullÚinit_valÚredtosetÚ	index_varZerror_modelÚnumpyTFÚschedzfunc_args = znum_inputs = zparfor_outputs = zparfor_redvars = znum_reductions = zgu_signature = c             S   s   g | ]}|j |j|jf‘qS © )ÚstartÚstopÚstep)Ú.0Úlr=   r=   ú4lib/python3.7/site-packages/numba/npyufunc/parfor.pyú
<listcomp>  s    z*_lower_parfor_parallel.<locals>.<listcomp>zloop_nests = zloop_ranges = Ú	res_printÚ	str_const)Úvaluer3   )rG   Útargetr3   )ÚargsÚvarargr3   Zredelemz#initZone_res_printZinplace_binopr   )rI   )VÚparallelr+   r(   ÚcontextZtyping_contextÚfndescÚtypemapÚcopyÚvarmapr$   ÚDEBUG_ARRAY_OPTÚprintÚdumpÚ
init_blockr3   ÚscopeÚtypeÚbodyZ
lower_instÚracesr   ÚVarZ_alloca_varÚnameÚnumbar   Zfind_potential_aliases_parforÚparamsZfunc_irÚAssertionErrorÚget_parfor_outputsÚget_parfor_reductionsÚ	calltypesÚlenÚrangeÚredtyp_to_redarraytypeÚdtyper	   ZDTypeÚ
isinstanceÚnpytypesÚArrayÚndimr   r   Únpr2   Zresolve_function_typeZUniTupleÚintpÚAssignZGlobalÚConstÚExprÚgetattrZstatic_getitemZbuild_tupleÚcallr7   ÚuintpÚSetItemr#   ÚnoneÚflagsÚsetÚ
loop_nestsÚindex_variableZsequential_parfor_loweringÚ_create_gufunc_for_parfor_bodyÚboolÚ_create_shape_signatureÚget_shape_classesÚcall_parallel_gufuncÚsysÚstdoutÚflushÚDEBUG_ARRAY_OPT_RUNTIMEÚStringLiteralÚPrintÚgetitemrG   ÚopÚrhsrI   ÚreplaceÚpop)YÚlowererr   r+   Ú	typingctxÚ	targetctxZorig_typemaprN   rP   r3   rU   ZinstrZracevarZrvtypÚrvr.   r/   Zparfor_output_arraysÚparfor_redvarsÚparfor_reddictÚnredvarsÚredarrsZthread_countÚir0   ZredvarZredarrvar_typZreddtypeÚ	redarrdimr1   Zff_fntyZff_sigZempty_assignZnum_threads_varZnum_threads_assignZsize_varZsize_var_listZredshape_varZredshape_getattrZredshape_assignÚjZ	onedimvarZonedimgetitemZonedimassignZ	size_callZsize_assignZ
empty_callZ
redarr_varZempty_call_assignr8   r6   Z	full_fntyZfull_sigZfull_assignZinit_val_varZinit_val_assignZ	full_callr9   Zredtoset_assignr:   Zindex_var_assignZ
redsetitemrs   Úindex_var_typrB   ÚfuncZ	func_argsÚfunc_sigÚredargstartdimÚfunc_arg_typesÚnum_reductionsÚ
num_inputsÚgu_signatureÚloop_rangesrZ   r5   Zres_print_strÚstrconsttypÚlhsÚ
assign_lhsrE   ZoneelemZoneelemgetitemZoneelemassignZinit_varZinit_assignÚinstr„   ZctZctargsr=   r=   rC   r,   "   sè   



















































*r,   c          	      sÄ  t jrFtd||||ƒ x.|dd… D ]}td|t|ƒˆ|ˆdƒ q$W t|ƒ| }	‡‡‡fdd„|dd… D ƒ}
tƒ }x(|
D ] }|r|x|D ]}| |¡ qŠW q|W |r°t|ƒd nd}|
 d|f¡ | |¡ i ‰t	d	ƒ}x(|D ] }|dkrÞt
|ƒˆ|< |d7 }qÞW d
|i‰ ‡ fdd„‰g }g }d}d}t jrBtd|ƒ td|
ƒ xxt|
|ƒD ]j\}}|d }|r~t‡‡fdd„|D ƒƒ}nd}||	kr¤| ||| d… ¡ n| |¡ ||7 }qNW ||fS )z&Create shape signature for GUFunc
    ry   r*   NZargument)rN   c                s$   g | ]}|ˆkrˆ |ˆd nd‘qS ))rN   )éÿÿÿÿr=   )rA   Úvar)rz   rX   rN   r=   rC   rD   ˜  s    z+_create_shape_signature.<locals>.<listcomp>r   ÚaÚlatest_alphac                s0   | dkr||  S ˆ d  d7  < t ˆ d ƒS d S )Nr   r¢   r*   )Úchr)ÚcÚ	class_map)Ú
alpha_dictr=   rC   Ú
bump_alpha«  s    z+_create_shape_signature.<locals>.bump_alphar=   rI   Úclassesc             3   s   | ]}ˆ |ˆƒV  qd S )Nr=   )rA   r¤   )r§   r¥   r=   rC   ú	<genexpr>¼  s    z*_create_shape_signature.<locals>.<genexpr>)r$   rQ   rR   rV   ra   rt   ÚaddÚmaxÚinsertÚordr£   ÚzipÚtupleÚappend)rz   r˜   r—   rI   r•   r”   rX   rN   r   Z
num_inoutsr¨   Z	class_setZ_classZ	max_classZalphabetÚnZgu_sinZgu_soutÚcountZsyms_sinÚclsÚargZdim_symsr=   )r¦   r§   r¥   rz   rX   rN   rC   ry   †  sN    







ry   c             C   s*   x$t | jƒD ]\}}td|d|ƒ qW d S )Nz    r-   )Ú	enumeraterW   rR   )Úblockr   rž   r=   r=   rC   Ú_print_blockÈ  s    r·   c             C   s,   x&|   ¡ D ]\}}td|ƒ t|ƒ q
W dS )z%Pretty-print a set of IR blocks.
    zlabel: N)ÚitemsrR   r·   )Z	body_dictÚlabelr¶   r=   r=   rC   Ú_print_bodyÌ  s    
rº   c             C   sF   |   ¡ }t| ¡ ƒ}t| ¡ ƒ}|| j}|| j t ||¡¡ |S )N)	rO   ÚminÚkeysr«   r3   rW   r°   r   ÚJump)Ú	loop_bodyÚblocksZfirst_labelÚ
last_labelr3   r=   r=   rC   Úwrap_loop_bodyÔ  s    
rÁ   c             C   s(   t |  ¡ ƒ}| | jd d… | | _d S )NrŸ   )r«   r¼   rW   )r¾   rÀ   r=   r=   rC   Úunwrap_loop_bodyÜ  s    rÂ   c             C   s6   | |kr
n(| |kr(|  | ¡ | | ¡ n
|  | ¡ 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=   rC   Úadd_to_def_once_setsà  s    
rÇ   c             C   sø   |   tj¡}xæ|D ]Þ}|jj}t|||ƒ |j}t|tjƒr^|j	dkr^|jj|kr^|jj||< t|tjƒr˜|j	dkr˜|j
j|kr˜||j
j }	t|	||ƒ t|tjƒr|j	dkrx@|jD ]6}
t|
tjƒrÌ|
j}
||
 }t|ddƒr¶t|
||ƒ q¶W qW dS )zeEffect changes to the set of variables defined once or more than once
       for a single block.
    rn   ro   ZmutableFN)Z
find_instsr   rk   rH   rZ   rÇ   rG   re   rm   rƒ   r“   rI   rY   rn   )r¶   rÅ   rÆ   Úgetattr_takenrN   ZassignmentsZ
one_assignrÄ   r„   Zbase_objZargvarZavtyper=   r=   rC   Úcompute_def_once_blockð  s"    
""rÉ   c             C   sj   xd|   ¡ D ]X\}}t|||||ƒ x>|jD ]4}t|tjƒr*t|j||||ƒ t|j||||ƒ q*W q
W dS )zÞCompute 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¸   rÉ   rW   re   r   ÚParforrT   Úcompute_def_once_internalr¾   )r¾   rÅ   rÆ   rÈ   rN   r¹   r¶   rž   r=   r=   rC   rË     s    rË   c             C   s$   t ƒ }t ƒ }i }t| ||||ƒ |S )zRCompute the set of variables defined exactly once in the given set of blocks.
    )rt   rË   )r¾   rN   rÅ   rÆ   rÈ   r=   r=   rC   Úcompute_def_once&  s
    rÌ   c             C   s    t | tjƒst‚| | j¡ | S )N)re   r   rY   r]   rª   rZ   )r    Zvarsetr=   r=   rC   Ú	find_vars/  s    rÍ   c             C   sØ   t ƒ }t| jt|ƒ | |¡}t|ƒdkr~t| jd |ƒr~tjdkrLt	d| ƒ | 
| ¡ t|| jj tjjƒsz|| jjg7 }dS t|ƒdkr°| 
| df¡ tjdkrÔt	d| dƒ n$| 
| df¡ tjdkrÔt	d| d	ƒ d
S )Nr   r*   zWill hoist instructionTZ
dependencyZInstructionz. could not be hoisted because of a dependency.znot purez, could not be hoisted because it isn't pure.F)rt   r   rG   rÍ   Ú
differencera   r   r$   rQ   rR   r°   re   rH   rZ   r	   rf   rg   )rž   Údep_on_paramÚ
call_tableÚhoistedÚnot_hoistedrN   ZusesZdiffr=   r=   rC   Ú_hoist_internal4  s$    





rÓ   c             C   s`   xZ|j D ]P}t|tjƒs$t|tjƒr4|  |jj¡ qt|tj	ƒrt
| |jƒ t| |jƒ qW d S )N)rW   re   r   ZStaticSetItemrq   rª   rH   rZ   r   rÊ   Úfind_setitems_blockrT   Úfind_setitems_bodyr¾   )Úsetitemsr¶   rž   r=   r=   rC   rÔ   K  s    rÔ   c             C   s$   x|  ¡ D ]\}}t| |ƒ q
W d S )N)r¸   rÔ   )rÖ   r¾   r¹   r¶   r=   r=   rC   rÕ   S  s    rÕ   c          
   C   s<  t   | ¡}g }g }t||ƒ}t|ƒ\}}	tƒ }
t|
|ƒ tt|ƒ |
¡ƒ}xè| ¡ D ]Ü\}}g }xÈ|jD ]¾}t	|t
jƒrš|jj|kršt||||||ƒr˜qhn‚t	|tjƒrg }tjdkrÆtdƒ | ¡  xL|jjD ]@}t	|t
jƒr|jj|krt||||||ƒrqÐ| |¡ qÐW ||j_| |¡ qhW ||_qTW ||fS )Nr*   r   )rO   rÌ   r   rt   rÕ   ÚlistrÎ   r¸   rW   re   r   rk   rH   rZ   rÓ   r   rÊ   r$   rQ   rR   rS   rT   r°   )Úparfor_paramsr¾   rN   Úwrapped_blocksrÏ   rÑ   rÒ   rÅ   rÐ   Zreverse_call_tablerÖ   r¹   r¶   Ú	new_blockrž   Znew_init_blockZib_instr=   r=   rC   ÚhoistW  s>    





rÛ   c             C   s   t | tjjƒ S )N)re   r	   rf   rg   )Zredtyper=   r=   rC   Ú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.
    r*   ÚC)re   r	   rf   rg   rh   rd   )Úredtypr   r=   r=   rC   rc   ƒ  s
    
rc   c             C   s2   t | tjjƒst‚tj | jtd| jd ƒ| j¡S )zÖGiven a reduction array type, find the type of the reduction argument to the gufunc.
       Scalar and 1D array reduction both end up with 1D gufunc param type since scalars have to
       be passed as arrays.
    r*   )	re   r	   rf   rg   r]   rd   r«   rh   Zlayout)Zredarraytypr=   r=   rC   Úredarraytype_to_sig  s    rß   c             C   s6   t | ƒ}x(| ¡ D ]\}}||kr|| ||< qW |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¸   )ÚnamesrN   ZoutdictÚxÚyr=   r=   rC   Úlegalize_names_with_typemap—  s
    rã   c
       N   	      s<  |j j}
t |j¡}t|ƒ t|jƒ}dd„ |jD ƒ}|j}tj	 
||¡}| jj‰tj	 ||| jj¡\}}ttt|ƒt|ƒ t|ƒ ƒƒ}|	 t|ƒ¡}	x$|	D ]}t d| t|
j|
j¡ qžW t|	|ˆ| jjƒ tjdkr$td|dt|ƒƒ td|dt|ƒƒ td|dt|ƒƒ td	|dt|ƒƒ g }g }xd|D ]\}|d
 }| |¡ tˆ| ƒ}| |¡ t|ƒ}|ˆkr„ˆ| |ksŒt ‚n|ˆ|< q2W || | }tjdkrètd|dt|ƒƒ td|dt|ƒƒ td|dt|ƒƒ t!|ƒ t"|| ˆƒ‰tjdkrtdtˆ #¡ ƒdtˆƒƒ t"|ˆƒ‰ ‡ fdd„|D ƒ}tjdkr¤tdtˆ  #¡ ƒdtˆ ƒƒ td|dt|ƒƒ x2|D ]*}td|ƒ tdˆ| dtˆ| ƒƒ qvW ‡fdd„|D ƒ}‡fdd„|| D ƒ| }t$|ˆƒ |}‡fdd„|D ƒ}|}g }d} x`t%t|ƒƒD ]P}!| rJ|!t|ƒk rJt&||! t'j(j)ƒrJ| ||! d ¡ n| ||! ¡ q
W t$|ˆ ƒ t*|ƒ}"t+d|"ƒ}#tjdkr˜td|dt|ƒƒ dt,t-|ƒƒ .dd¡ }$tjrÊtdt|$ƒd|$ƒ d}%|%d|$ d  d! /|¡ d" 7 }%xPt%t|ƒƒD ]@}!| rút&||! t'j(j)ƒrú|%d#||!  d$ ||!  d% 7 }%qúW xht0||ƒD ]Z\}}t1ˆ| ƒr‚|%d#ˆ|  d& ˆ|  d' 7 }%n |%d#ˆ|  d( ˆ|  d% 7 }%qJW xft%|ƒD ]Z}&xt%|&d ƒD ]}'|%d#7 }%qÄW |&}(|%d)||&  d* t2|(ƒ d+ t2|(| ƒ d, 7 }%q²W tj3r|xt%|d ƒD ]}'|%d#7 }%q&W |%d-7 }%x2t%|ƒD ]&}&|%d.||&  d/ ||&  d0 7 }%qJW |%d%7 }%xt%|d ƒD ]}'|%d#7 }%qŠW |%|#d1 7 }%i })xxt0||ƒD ]j\}}t1ˆ| ƒrø|%d#ˆ|  d2 ˆ|  d3 7 }%d|)|< n(|%d#ˆ|  d4 ˆ|  d5 7 }%d6|)|< q¸W |%d77 }%tjrHtd8t|%ƒd3|%ƒ d9t4i}*i }+t5|%|*|+ƒ |+|$ },tjr‚td:t|,ƒd3|,ƒ t6 7|,¡}-tjrÀtd;t|-ƒƒ |- 8¡  td<t|ƒƒ t!|ƒ t*|-j9ƒ}.i }/|#gtˆ :¡ ƒ | }0x,|. #¡ D ] \}1}|1|0krît;|1ƒ|/|1< qîW t$|-j9|/ƒ tjr6td=ƒ |- 8¡  tj'j( )|dd>¡g| }2tjrhtd?t|2ƒd3|2ƒ t<|-j9 =¡ ƒd }3t>||3ƒ}t<| =¡ ƒd }4tj3rÂx"| #¡ D ]\}5}6|6 ¡ }7|7 ?¡  |6j}
|6j@}8xä|6jAD ]Ú}9|7 |9¡ t&|9tBjCƒrÖˆ|9jDjE t'jFkr
qÖd@ G|9jDjE¡}:t' H|:¡};tB I|8t;dAƒ|
¡}<tBjCtBjJ|:|
dB|<|
dC}=|;ˆ|<jE< |7 |=¡ tBjK|<|9jDgdD|
dE}>|7 |>¡ tjL Mt'jNˆ|<jE ˆ|9jDjE ¡}?|?| jj|>< qÖW |7||5< q¨W tjrÚtdFƒ t!|ƒ tO|ƒ}@tP||ˆ|@ƒ\}A}B|-j9tQ|-j9 =¡ ƒ }C|CjAdDdG… |A |CjAdG g |C_AtR|ƒ | jSdH }D|A|BdIœ|DjT|jU< tj	rdtdJƒ t!|ƒ x
|-j9 #¡ D ]ü\}5}6xîtV|6jAƒD ]Ü\}E}9t&|9tBjCƒ	r†|9jDjE|#k	r†|9j}
|6j@}8tB W|8|
¡}F|6jAdD|E… |F_A|6jA|Ed dD… |6_AtQ| =¡ ƒ}G|F tB X|G|
¡¡ x | #¡ D ]\}H}I|I|-j9|H< 
qW t<| =¡ ƒ}J|6|-j9|4< |F|-j9|5< |-j9|J  tB X|4|
¡¡ P 	q†W 	qrP 	qrW tj
rŠtdKƒ |- 8¡  tY|-j9ƒ|-_9t|-j9ƒ tj
rÌtdLƒ |- 8¡  tdM|ƒ tdNˆƒ |jZ}K|
sîtj
rètdOƒ dP|_Zt6 [|||-|2t'jN||¡}L|K|_ZtMt'jNf|2žŽ }Mtjr.tdQ|Mƒ |L||M|)|fS )Ra~  
    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.
    c             S   s   g | ]}|j j‘qS r=   )rv   rZ   )rA   rB   r=   r=   rC   rD   È  s    z2_create_gufunc_for_parfor_body.<locals>.<listcomp>z‘Variable %s used in parallel loop may be written to simultaneously by multiple workers and may result in non-deterministic or unintended results.r*   zparfor_params = r-   zparfor_outputs = zparfor_inputs = zparfor_redvars = Z_arrzloop_indices = zloop_body = zparam_dict = c                s   g | ]}ˆ | ‘qS r=   r=   )rA   Úv)Úind_dictr=   rC   rD     s    zind_dict = zlegal_loop_indices = zpd = z
pd type = c                s   g | ]}ˆ | ‘qS r=   r=   )rA   rä   )rN   r=   rC   rD     s    c                s   g | ]}ˆ | ‘qS r=   r=   )rA   rä   )rN   r=   rC   rD     s    c                s   g | ]}ˆ | ‘qS r=   r=   )rA   rä   )Ú
param_dictr=   rC   rD   &  s    FZparamZ__sentinel__zlegal parfor_params = z__numba_parfor_gufunc_%sú-Ú_zgufunc_name Ú zdef z(sched, z, z):
z    z = np.ascontiguousarray(z)
ú=z[0]
z	=np.copy(zfor z in range(sched[z	], sched[z] + np.uint8(1)):
zprint(ú"z",ú,z = 0
z[0] = Ú
z[:] = z[:]
r   z    return None
zgufunc_txt = ri   zgufunc_func = zgufunc_ir dump zloop_body dump zgufunc_ir dump after renaming rÝ   zgufunc_param_types = z{} =rF   )rG   r3   )rG   rH   r3   N)rI   rJ   r3   zparfor loop bodyrŸ   Zparfor_diagnostics)rÑ   rÒ   zAfter hoistingz#gufunc_ir last dump before renamingzgufunc_ir last dumprs   rN   z(No aliases found so adding noalias flag.Tzkernel_sig = )\rT   r3   rO   r¾   r   ra   ru   r\   r[   r   r^   rM   rN   r_   r`   Úsortedr×   rt   rÎ   ÚwarningsÚwarn_explicitr)   ÚfilenameÚlineÚreplace_var_with_arrayr$   rQ   rR   rV   r°   rc   rß   r]   rº   rã   r¸   r   rb   re   r	   rf   rg   r   r   ÚhexÚhashr…   Újoinr®   rÜ   Ústrr   ri   r&   r   Zrun_frontendrS   r¿   Úvaluesr   r«   r¼   r   ÚclearrU   rW   r   rk   rH   rZ   Znumber_domainÚformatr€   rY   rl   r   Útypingr#   rr   rÁ   rÛ   r»   rÂ   ZmetadataZ
hoist_infoÚidrµ   ZBlockr½   r   ZnoaliasZ
compile_ir)Nr‡   r   rN   rˆ   r‰   rs   ÚlocalsZhas_aliasesr’   rX   r3   r¾   Z
parfor_dimZloop_indicesrØ   Zparfor_outputsr‹   rŒ   Zparfor_inputsZraceZparfor_redarrsZparfor_red_arg_typesr    ZarrZredarraytypeZ	redarrsigZlegal_loop_indicesZpdZparam_typesr–   Zparfor_argsZparfor_params_origZascontigZpindexZloop_body_var_tableZsentinel_nameZgufunc_nameZ
gufunc_txtZeachdimÚindentZ	sched_dimr•   ZgloblsZloclsZgufunc_funcZ	gufunc_irZ	var_tableZnew_var_dictZreserved_namesrZ   Zgufunc_param_typesZgufunc_stub_last_labelZ	new_labelr¹   r¶   rÚ   rU   rž   Zstrvalr›   rœ   r   Z
print_nodeZsigrÙ   rÑ   rÒ   Zstart_blockZdiagnosticsr   Z
prev_blockZbody_first_labelrB   ÚbZbody_last_labelZ	old_aliasZkernel_funcZ
kernel_sigr=   )rå   ræ   rN   rC   rw   §  sþ   










 



$ $&&











 







rw   c       
      C   s  g }x|j D ]ø}t|tjƒrÌ|jj| krÌt d|j¡}t |jj	t
dƒ|j¡}tj||j< t |||j¡}| |¡ t |j||j|j¡}	ttjtj ||jj dd¡tj||jj ƒ||	< | |	¡ qn0t|tjƒrüt| d|ji||ƒ t| |j||ƒ | |¡ qW |S )Nr   z$const_ind_0r*   rÝ   )rW   re   r   rk   rH   rZ   rl   r3   rY   rU   r   r	   rp   r°   rq   rG   r#   rr   rf   rg   rj   r   rÊ   Úreplace_var_with_array_internalrT   r¾   )
Úvarsr¶   rN   r`   rÚ   rž   Z
const_nodeZ	const_varZconst_assignZsetitem_noder=   r=   rC   Úreplace_var_with_array_in_block;  s$    
0
r  c             C   s*   x$|  ¡ D ]\}}t| |||ƒ|_q
W d S )N)r¸   r  rW   )r  r¾   rN   r`   r¹   r¶   r=   r=   rC   r   Q  s    r   c             C   sH   t | |||ƒ x4| D ],}|| }| |d ¡ tj |dd¡||< qW d S )Nr*   rÝ   )r   r†   r	   rf   rg   )r  r¾   rN   r`   rä   Zel_typr=   r=   rC   ró   U  s
    
ró   c       c         s  ˆj ‰ ˆj}ˆj}ddlm}m}m}m} tj	r‚t
dƒ t
d|ƒ t
d|j|j|j|jƒ t
d|ƒ t
d|ƒ t
d|ƒ t
d	|ƒ t |¡\}}|j |jj¡}|\}}|ƒ  |||||i ƒ\}}}|j ¡  tj	ràt
d
||ƒ ‡ ‡fdd„}t|ƒ}xˆt|ƒD ]|}|| \}}} ||ƒ}||ƒ}| dks0t‚|| ƒ} ||| f||< tj	r t
d |¡||| ƒ t |d |¡||| ¡ q W tj d¡}!tj |!¡}"tj |"¡}#ˆ  t j!¡}$ˆ  t j"¡}%tj |$¡}&tj |%¡}'ˆ  #t j"d¡}(ˆ  #t j"d¡})|)j$}*ˆ  %|$¡}+| &d¡},|jd }-| &d¡}.tj	r2t
d|j'ƒ |j'rD|$}/|&}0n|%}/|'}0tj(||/ˆ  #t j"|¡dd}1tj(||/ˆ  #t j"|¡dd}2x´t|ƒD ]¨}|| \}}} |j$|*kr¸| )||*¡}|j$|*krÐ| )||*¡}| j$|*krè| )| |*¡} | *||)¡}| +|| ,|1ˆ  #t j"|¡g¡¡ | +|| ,|2ˆ  #t j"|¡g¡¡ qŽW |ƒ | d }3tj(||/ˆ  #t j"|3¡dd}4tj	rpdnd}5tj -|&|%|0|0|%|0|$g¡}6|j'r¨|j.j/|6dd}7n|j.j/|6dd}7| 0|7ˆ  #t j"|¡|1|2ˆ  #t j"|ƒ ¡|4ˆ  #t j!|5¡g¡ ‡‡fdd„|D ƒ}8t|ƒ}9t|ƒ|9 }:tj	r¦x„t|ƒ ƒD ]v}t |dt1|ƒ d ¡ xJt|d ƒD ]:};t |d| 2| ,|4ˆ  #t j!|| d |; ¡g¡¡¡ qVW t |d¡ q,W ‡fdd„|d |:… D ƒ|8 }<t|<ƒ}=t|ƒd }>tj(||"ˆ  #t j!d|= ¡d!d}g }?| +| 3|4|"¡|¡ |? 4ˆ  #t j!|+¡¡ i }@i }AxVt|=ƒD ]H}|<| }B|| }C|| }D| ,|ˆ  #t j!|d ¡g¡}E||:krˆ  5|D¡ˆ ||Bƒ}Ft 6||Fj7|Dj8¡}Gt 6||Fj9|Dj8¡}Hx&tdt|GƒƒD ]};|? 4|G|; ¡ qÂW |Hdd … |@|< | +| 3|Fj:|"¡|E¡ q8t;|Dt j<ƒrø|C|kr–|Dj=t j>kr6ˆ  ?|Dj=¡n
tj d¡}It (||I¡}J| +|B|J¡ | +| 3|J|"¡|E¡ |B|Jf|A|C< |? 4ˆ  #t j!ˆ  %|I¡¡¡ n`ˆ  5|D¡ˆ ||Bƒ}Ft 6||Fj7|Dj8¡}Gx$tt|GƒƒD ]};|? 4|G|; ¡ qÈW | +| 3|Fj:|"¡|E¡ nˆ||>k r>|Dt j>krˆ  ?|D¡n
tj d¡}It (||I¡}K| +|B|K¡ n.|Dt j>krTˆ  ?|D¡n
tj d¡}It (||I¡}K| +| 3|K|"¡|E¡ q8W i }Lg }M|.d g}Mˆ  #t j!d| ¡|L|.d < t|ƒt|<ƒksÈt‚t|ƒt|ƒksÞt‚t|ƒt|| ƒksøt‚t|ƒt|jdd … ƒkst‚x$t@||<||| ƒD ]\}C}B}D}Nt;|Dt jAjBƒr\|Dj8t|Nƒ }nd}tj	r~t
d"|Cd#|Nd$|Dd%|ƒ xº|ND ]²}Otj	ržt
d&|Cd'|Dƒ |C|kr¼ˆ  #t j!d¡|L|O< n0ˆ  5|D¡ˆ ||Bƒ}Ft 6||Fj9|Dj8¡}P|P| |L|O< |O|Mk	r,tj		r"t
d(|Od)|ƒ t ||Od* |L|O ¡ |M 4|O¡ |d }q„W q.W t|Lƒd }Qtj(||$|Qd+d}P| +ˆ  #t j!|ƒ ¡|P¡ d}xX|MD ]P}Otj		r¢t ||Od* |L|O ¡ | +|L|O | ,|Pˆ  #t j!|¡g¡¡ |d }	q€W |=d t|?ƒ }Rtj(||$ˆ  #t j!|R¡d,d}S| +ˆ  #t j!d| |+ ¡|S¡ xÌt|=ƒD ]À}||:k
rº||: };ˆjjC||;  }Td }Ut;|Tt jAjBƒ
rp|Tj=}T|@| }Uˆ  |T¡}Iˆ  %|I¡}Vˆ  #t j!|V¡}W|Ud k
r¾x |UD ]}X| D|W|X¡}W
q¢W n|(}W| ,|Sˆ  #t j!d| ¡g¡}E| +|W|E¡ 
q(W xFtt|?ƒƒD ]6};| ,|Sˆ  #t j!d|= |; ¡g¡}E| +|?|; |E¡ 
qúW | E|(|"¡}Ytj -tj F¡ |#|&|&|"g¡}Z|jGjH||d-d.}[| 3|[|Z I¡ ¡}\tj	r”t |d/|\¡ | 0|\||P|S|Yg¡}]tj	r¾t |d0|\¡ xN|A J¡ D ]B\}^}_|_\}B}J| ,|Jˆ  #t j!d¡g¡}`| +| 2|`¡ˆ K|^¡¡ qÈW |
jL}a|
jM}bd S )1zF
    Adds the call to the gufunc function from the main function.
    r*   )ÚParallelGUFuncBuilderÚbuild_gufunc_wrapperr+   Ú_launch_threadsZmake_parallel_loopzargs = zouter_sig = zloop_ranges = Ú	expr_argsÚexpr_arg_typesr™   zparallel function = c                s*   t | tjƒrˆ | j¡S ˆ  tj| ¡S d S )N)re   r   rY   ÚloadvarrZ   Úget_constantr	   rp   )rä   )rL   r‡   r=   rC   Ú
load_range‚  s    z(call_parallel_gufunc.<locals>.load_rangez'call_parallel_gufunc loop_ranges[{}] = zloop range[{}]: %d %d (%d)
é   r   z%Parfor has potentially negative startZdims)ÚsizerZ   r   r<   Zdo_scheduling_signed)rZ   Zdo_scheduling_unsignedc                s   g | ]}ˆ   ˆ| j¡‘qS r=   )r  rZ   )rA   rá   )r‡   Ú
redarrdictr=   rC   rD   â  s    z(call_parallel_gufunc.<locals>.<listcomp>zsched[z] = z%d rí   c                s   g | ]}ˆ   |¡‘qS r=   )r  )rA   rá   )r‡   r=   rC   rD   õ  s    NZpargszvar =zgu_sig =ztype =zi =zvar = z type = z
dim_sym = z, i = z = %d
ZpshapeZpstepszparallel gufunc kernel)Úinfozbefore calling kernel %p
zafter calling kernel %p
)NrL   ÚbuilderÚlibraryrK   r  r  r+   r  r$   rQ   rR   rI   Úreturn_typeZrecvrZpysigr   Znormalize_signatureZget_functionrM   Zllvm_func_nameZ_ensure_finalizedra   rb   r]   rú   r   ZprintfÚlcZTypeÚintZpointerZget_value_typer	   rj   rp   r	  rV   Zget_abi_sizeofr†   ÚsignedZalloca_onceZsextÚsubZstoreZgepZfunctionÚmoduleZget_or_insert_functionro   r÷   ÚloadZbitcastr°   Z
make_arrayZunpack_tupleÚstridesrh   r4   Údatare   ZArrayCompatiblerd   ZbooleanZget_data_typer®   rf   rg   rN   ÚmulZinttoptrZvoidZtarget_contextZadd_dynamic_addrZ
as_pointerr¸   ZgetvarrU   r3   )cr‡   Zcresr™   Z	outer_sigr  r  rš   ZredvarsZreddictr  rT   r’   rX   r  r  r  r  r+   r  rI   r  Z	llvm_funcZsinZsoutZwrapper_ptrÚenvZwrapper_namer
  Znum_dimr   r>   r?   r@   Zbyte_tZ
byte_ptr_tZbyte_ptr_ptr_tZintp_tZuintp_tZ
intp_ptr_tZuintp_ptr_tZzeroZoneZone_typeZsizeof_intpZ
sched_nameZ	sched_typZ	sched_sigZ
sched_typeZsched_ptr_typeZ
dim_startsZ	dim_stopsZ
sched_sizer<   Z
debug_flagZscheduling_fntyZdo_schedulingrŽ   r   Zninoutsr‘   Zall_argsZnum_argsZnum_inpsZarray_stridesZ
red_shapesZrv_to_arg_dictr´   r    ZatyÚdstZaryr  Z
ary_shapesÚtypZrv_argZptrZsig_dim_dictZ
occurancesZgu_sigZdim_symZshapesZnshapesZ	num_stepsZstepsrÞ   Z
red_strideZsizeofZstepsizeZrsr  ZfntyZfnptrÚfnÚresultÚkrä   Zonly_elem_ptrrU   r3   r=   )rL   r‡   r  rC   r{   \  sò   










$

&
""
 












r{   )[Z
__future__r   r   r   ZastrO   Úcollectionsr   Ú	linecacheÚosr|   r;   ri   Zllvmlite.llvmpy.coreZllvmpyZcorer  Zllvmlite.ir.valuesr   rø   Zlivr[   ré   r   r	   r
   r   r   r   r   Znumba.ir_utilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Znumba.analysisr   r    r!   r"   rû   r#   r$   Znumba.targets.cpur%   Z	numba.sixr&   Znumba.parforr'   r(   rï   Úerrorsr)   r,   Zlower_extensionsrÊ   ry   r·   rº   rÁ   rÂ   rÇ   rÉ   rË   rÌ   rÍ   rÓ   rÔ   rÕ   rÛ   rÜ   rc   rß   rã   rw   r  r   ró   r{   r=   r=   r=   rC   Ú<module>   sd   (H  cB$	)   