U
    |e                     @   s0  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mZmZmZmZ d dlmZmZ d dlmZ d dl
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 d dl m!Z! d d	l"m#Z# d d
l$m%Z% dd Z&G dd de'Z(dd Z)G dd de'Z*dd Z+dd Z,dd Z-dd Z.dd Z/dS )    N)add)typesirrewritesconfigir_utils)infer_globalAbstractTemplate)	signature)utilstyping)	get_call_tablemk_unique_varcompile_to_numba_irreplace_arg_nodesguardfind_callnamerequire
find_constGuardException)NumbaValueError)OPERATORS_TO_BUILTINS)numpy_supportc                 C   s   |dkr| | S | S d S Nr    )dim_sizeindex_constr   r   Y/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/stencils/stencilparfor.py_compute_last_ind   s    r   c                   @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )StencilPassc                 C   s.   || _ || _|| _|| _|| _|| _|| _d S N)func_irtypemap	calltypesarray_analysis	typingctx	targetctxflags)selfr!   r"   r#   r$   r%   r&   r'   r   r   r   __init__"   s    zStencilPass.__init__c                    s  ddl m} t jj\}}g }i }| D ].\}}|D ] }t||r8|| |||< q8q,|sddS  jj D ]\}	}
tt	t
|
jD ]\}ttjrtjtjr̈jjdkr̈jjj|krtjj}fddttjjD }jj}t fdd|D }|D ]}t|tjrtd	q|d
}|jjj }t| j||
j|
j | j! j"\}}}|j#dd} $|	||||j%|||	}|
jd| | |
j|d d  |
_qttjrtjtjrjjdkrt&t' jjdkrt(dj _qqpdS )zP Finds all calls to StencilFuncs in the IR and converts them to parfor.
        r   )StencilFuncNcallc                    s   i | ]}| j j| qS r   )valueargs.0i)stmtr   r   
<dictcomp>I   s      z#StencilPass.run.<locals>.<dictcomp>c                 3   s   | ]} j |j V  qd S r    )r"   namer.   r(   r   r   	<genexpr>L   s     z"StencilPass.run.<locals>.<genexpr>zITuple parameters not supported for stencil kernels in parallel=True mode.outindex_offsets   )stencilnumba))numba.stencils.stencilr*   r   r!   blocksitems
isinstanceappendreversedlist	enumeratebodyr   Assignr,   Expropfuncr3   dictkwsrangelenr-   tupler   	BaseTuple
ValueErrorgetget_stencil_irr%   scopelocr"   r#   options_mk_stencil_parfortargetr   r   Const)r(   r*   
call_table_Zstencil_callsZstencil_dictZcall_varname	call_listZone_calllabelblockr0   rI   
input_dictin_argsZarg_typemaparg_typeout_arrsf
stencil_irrtarg_to_arr_dictr7   	gen_nodesr   )r(   r1   r   run,   sx    




    

    (
zStencilPass.runc              	   C   s   |  D ]\}}|j}|j}g }|jD ]x}	t|	tjr| }
t|
tjrdt|
j	tj
rd|
j	jdksht|t|
j	j	|| |t|| q&||	 q&||_qdS )z
        Find return statements in the IR and replace them with a SetItem
        call of the value "returned" by the kernel into the result array.
        Returns the block labels that contained return statements.
        castN)r=   rQ   rR   rC   r>   r   ReturnpoprD   r,   rE   rF   AssertionErrorr?   Jump)r(   r<   exit_value_varparfor_body_exit_labelrZ   r[   rQ   rR   new_bodyr1   Z	prev_stmtr   r   r   replace_return_with_setitemh   s     

z'StencilPass.replace_return_with_setitemc
           S         s	  g }
|j }tjdkr4td|||||| t| |d }j|j }t|j\}}t	|}t
|||jj tjdkrtd t| t|jj|j tjdkrtd t| j|j j |j}|j}g }t D ].}t|td|}tjj|j< || q||||||	\}}tjdkrhtd td| td	| t| g }j|}||} t|kstg }g }t D ]f}|| || |
||} || |
||}|| || |t!j"j#$|| ||d qt%|& d }t'||||< t|td
|} |j(j| j< g }! dkrd|d }"nPt|td|}"tj)*tj j|"j< tj+,||}#t-|#|"|}$|!|$ tjdkrtd t| t'||}%dkr҈j|j }td}&t||&|}'tj+.|d|}(tj)*tj|jj|&< |%j/0t-|(|'|g td})t||)|d|j1kr|j1d }*t2j33|*}+j45|+|j(st6d|(|*},n
|(d},t7|,|}-|j(j|)< |%j/0t-|-|g td}.t||.|t!j8jj9:|j(|j|j;jj< t|td|}/tj<=t>j|/j< t?dt>|}0t-|0|/|}1|%j/|1 t@A|j(jBjC}2|2dkrd}2tj+.|/|2|}3t|td|}4tjDE|j(j|4j< t-|3|4|}5|%j/|5 tFdt>jG|'|4gj4jj}6t|td|}7t-t7d||7|}8|6|8 tjHj|7j< t|td|}9t-t7d||9|}:|6|: tjj|9j< t|td|};j4ItJ}<|<j|;j< t?dtJ|}=t-|=|;|}>|6|> j4K|<tjHfd i }?tj+jL|;|7|7fd|d }@|?j|@< t|td!|}AtjMj|Aj< t-|@|A|}>|6|>  fd"d#}Bt|jD ]V}C|Ag|j }D|Ag|j }E|B|<|C|||;|6||D|9d$
 |B|<|C|||;|6||E||C d%
 q^|N| |%j/0|6 nd|j1krx|j1d }*t2j33|*}+j45|+|j(sd}FtO|Ft|td&|}Aj4ItJ}<|<j|Aj< t?dtJ|}=t-|=|A|}G|%j/|G j4K|<tjHfd i }?tj+jL|Add|d }H|?j|H< t|td'|}ItjMj|Ij< t-|H|I|}>|%j/|> t7|(|*|}Jt|td(|}K|j(j|Kj< t-|J|K|}L|%j/|L tPtJdd|I|K|}M|%j/|M tQtjHjj j|Ij jj j(}?|?j|M< R|| | tjdkrtd) t| tS|"| |}NtQtjHjj j|"j jj j(j|N< || j/0|! || j/|N tTd*d+}Ot|td(|O}Pt-tj7d|Od,|P|O}L|| j/|L || j/tU|P|O tV|}|t%|&  j/W  tjdk	rtd- t| d.||gf}Qt!j"j#X||%|||"||QjY}R|
|R |
t-|| |
S )/z> Converts a set of stencil kernel blocks to a parfor.
        r8   rT   r   z#stencil_blocks after copy_propagatez'stencil_blocks after removing dead codez$parfor_index_varz-stencil_blocks after replace stencil accesseszstart_lengths:zend_lengths:z$parfor_exit_valuez$parfor_index_tuple_varz.stencil_blocks after creating parfor index varNZin_arr_shapeshapeZzero_valcvalz-cval type does not match stencil return type.Zstencil_outputz	$np_g_varnpboolbool_z$np_attr_attremptyz	$none_varz$zero_index_varz$slice_func_varslice   r   rG   r-   rI   rR   $slicec
                    s  j | tjfd i }
|| }t|ttjfs4tt|t	d|}tjj
|j< t|trvtt||||}nt|||}|| tjj||	r||fn||fd|d}|
j|< t|t	d|}tjj
|j< t|||}|| |||< t|t	d|}tjtj j
|j< tj||}t|||}|| t||}ttjj
j j
|j j
j jj|< || d S )Nrv   z$border_indr   rw   rx   z$border_index_tuple_var)r%   resolve_function_typer   intpr>   intr   Varri   r   r"   r3   rD   rV   r?   rE   r+   r#   slice2_type
containersUniTuplebuild_tupleSetItemr
   nonedtype)slice_fn_tydimrQ   rR   slice_func_varstmtsZborder_indsZborder_tuple_itemsZ	other_argZother_firstsigsiZsi_varZ	si_assignslice_callexprZborder_slice_varslice_assignZborder_ind_var
tuple_calltuple_assignsetitem_callndimsr_   r(   Zzero_varr   r   handle_borderA  sZ    




 
 


z5StencilPass._mk_stencil_parfor.<locals>.handle_borderTFz	$py_g_varz$slice_instz$cval_constz%stencil_blocks after replacing returnZstencilparfor_dummy)rR   z#stencil_blocks after adding SetItemr9   )Zr<   r   DEBUG_ARRAY_OPTprintr   dump_blocksr"   r3   copy_propagateget_name_var_tableapply_copy_propagater#   remove_deadr!   	arg_namesndimrQ   rR   rJ   r   r|   r   r   rz   r?   _replace_stencil_accessesr$   get_equiv_set	get_shaperK   ri   _get_stencil_last_ind_get_stencil_start_indr:   parforsparforLoopNestmaxkeysBlockr   r~   r   rE   r   rD   getattrrC   extendrS   r   typeofr%   can_convertrN   rV   corenpytypesArraylayoutmiscModulerq   Globalr   as_dtypetype__name__	functionsNumberClassgen_np_callrt   r   resolve_value_typeru   ry   r+   r}   Zinsert_equivr   StaticSetItemr
   rn   r   Locrg   simplify_CFGrh   Parforr'   )Sr(   rZ   r]   r_   ra   r7   rU   return_typestencil_funcrc   rd   stencil_blocksin_arr
in_arr_typin_cpsout_cpsname_var_tablerQ   rR   parfor_varsr0   Z
parfor_varstart_lengthsend_lengths	loopnests	equiv_setZin_arr_dim_sizesZ
start_indsZ	last_indslast_indZ	start_indrl   rk   Zfor_replacing_retZparfor_ind_varr   r   
init_block
shape_nameZ	shape_varZshape_getattrZ	zero_namerp   cval_tytemp2Z
full_constZso_nameZdtype_g_np_varZ
dtype_g_npZdtype_g_np_assignreturn_type_nameZdtype_np_attr_calldtype_attr_vardtype_attr_assignr   Znone_varZnone_assignZzero_index_varZzero_index_assignr   r   Zslice_gr   r   r   	slice_varr   r   Zstart_tuple_itemsZlast_tuple_itemsmsgZslice_assignedcallexprZslice_inst_varZcval_const_valZcval_const_varZcval_const_assignZsetitemexprr   Z	dummy_locZret_const_varpatternr   r   r   r   rT      sN   
  





    




      

  


 

















8



  


 






    
zStencilPass._mk_stencil_parforc                 C   s4  |}|dkr0t |td|}tj| j|j< t|tj	rRt 
t ||||}nt 
|||}|| t |td|}tj| j|j< t |td|}	tt}
tj|
}|| j|	j< t d|
|}t 
||	|}|| t j|	||gd|}|| jtjtjgi | j|< t 
|||}|| |S )Nr   Zstencil_const_varr   Zcompute_last_ind_varr   r   )r   r|   r   r   rz   r"   r3   r>   numbersNumberrD   rV   r?   r:   njitr   r   
Dispatcherr   rE   r+   get_call_typer%   r#   )r(   r   Z
end_lengthrd   rQ   rR   r   r   const_assignZg_varZ
check_funcfunc_typZg_objZg_assign
index_callindex_assignr   r   r   r     s>    
 


 
 

z!StencilPass._get_stencil_last_indc           	      C   s   t |trtt|dS dd }t|i | j| jtjf| j	| j
}t|jdksRt|j d }t||g ||jd d 7 }|jd jj}|S )Nr   c                 S   s   t t| dS r   )absmin)Zs_lengthr   r   r   get_start_ind  s    z9StencilPass._get_stencil_start_ind.<locals>.get_start_indr8   )r>   r{   r   r   r   r%   r&   r   rz   r"   r#   rK   r<   ri   popitemr   rC   r,   )	r(   Zstart_lengthrd   rQ   rR   r   f_irr[   Zret_varr   r   r   r     s    

  z"StencilPass._get_stencil_start_indc              	      s  j }|d }dd |D }	d|jkr`|jd D ]}
|
 kr0tdq0 fdd|jd D }ng }|j|krvtdj|j j}|j}|j}|jdk}|r|dg }|dg }n d	d |jD }d
d |jD }t	
|}d}| D ]\}}g }|jD ]}t|tjr@t|jtjr@|jjdkr@|jjj|	ksjt|tjs\t|tjrr|jj|	krrtdt|tjrt|jtjr|jjdkr|jjj|	kr|jjj|kr|jj}|dkr|g}n"t|dr|j|kr||j }t	|_fdd|D }|r6|t||||}|rt|tjs^tdd |D rftdttt||}ttt ||}d}|t||||}|dkr|d }nPt|t!d|}t"j#$t"j%|j|j< tj&||}t|||}|'| t(fdd|D r0j|jjj j)}nj|jjj }tj*|jj||}t+|j|jjj j|j j,|< ||_|'| q||_q|r|std||fS )z Convert relative indexing in the stencil kernel to standard indexing
            by adding the loop index variables to the corresponding dimensions
            of the array index tuples.
        r   c                 S   s   g | ]
}|j qS r   )r3   r/   xr   r   r   
<listcomp>+  s     z9StencilPass._replace_stencil_accesses.<locals>.<listcomp>standard_indexingz[Standard indexing requested for an array name not present in the stencil kernel definition.c                    s   g | ]} | qS r   r   r   )rc   r   r   r   2  s     zYThe first argument to a stencil kernel must use relative indexing, not standard indexing.Nc                 S   s   g | ]}|d  qS )r   r   r   r   r   r   r   I  s     c                 S   s   g | ]}|d  qS )r8   r   r   r   r   r   r   J  s     F)setitemstatic_setitemz?Assignments to arrays passed to stencil kernels is not allowed.)static_getitemgetitemr8   r3   c                    s   g | ]}t  j|qS r   )_get_const_index_exprr!   r/   v)r(   ra   r   r   r   t  s     c                 S   s   g | ]}t |t qS r   r>   r{   r   r   r   r   r     s     z<Variable stencil index only possible with known neighborhoodTz$parfor_index_ind_varc                    s   g | ]} j |j tjkqS r   )r"   r3   r   rz   r   r4   r   r   r     s   z=Stencil kernel with no accesses to relatively indexed arrays.)-r<   rS   rN   r3   r"   r   rQ   rR   neighborhoodr   get_tuple_tabler=   rC   r>   r   rD   r,   rE   rF   r   r   rU   indexhasattrbuild_definitions_definitions_add_index_offsetsrA   r|   anymapr   r   r   r   r~   r   rz   r   r?   allr   r   r
   r#   )r(   ra   r   r]   r7   r   rc   r   r   Zin_arg_namesr   standard_indexedr   rQ   rR   need_to_calc_kernelr   r   tuple_tableZfound_relative_indexrZ   r[   rm   r1   
index_list
index_varsind_varr   r   Zgetitem_return_typgetitem_callr   )rc   r(   ra   r   r   #  s    













      

 



z%StencilPass._replace_stencil_accessesc                 C   s<  t |t |ksttdd || D r:ttt||S g }g }tt |D ]}|| }	t|	trt	
|td|}	tj| j|	j< t	t	|| ||	|}
||
 || }t|trt	
|td|}tj| j|j< t	t	|| |||}
||
 t|	ts&t| j|	j tjjr\| j|j tjks>t| |	||||}|| qNt|tst| j|j tjjr| j|	j tjkst| ||	|||}|| qNt	
|td|}tj| j|j< t	jtj|	||}| jtjtjtjfi | j|< t	|||}|| || qN|| |S )zw Does the actual work of adding loop index variables to the
            relative index constants or variables.
        c                 S   s   g | ]}t |tqS r   r   r   r   r   r   r     s     z2StencilPass._add_index_offsets.<locals>.<listcomp>old_index_var
offset_varZoffset_stencil_index)rK   ri   r   rA   r   r   rJ   r>   r{   r   r|   r   r   rz   r"   r3   rD   rV   r?   ru   r   	SliceType_add_offset_to_slicerE   binopoperatorr%   ry   r#   r   )r(   r   r7   rm   rQ   rR   	out_nodesr   r0   r  r   r  	index_varr   r   r   r   r   r     s    
  
  
  
  
   
 


zStencilPass._add_index_offsetsc                 C   s   t |trBd|j|j}i }t|i | |d }|g}tjf}	n&dd }||g}| j|j	 }
|
tjf}	| j
jjj}t||| j| j|	| j| j}|j \}}t|| |jd jj}||jd d  |S )NzRdef f(offset):
                return slice({} + offset, {} + offset)
            fc                 S   s   t | j| | j| S r    )ru   startstop)Z	old_sliceoffsetr   r   r   r
     s    z+StencilPass._add_offset_to_slice.<locals>.fr   )r>   ru   formatr  r  execr   rz   r"   r3   r!   func_idrG   __globals__r   r%   r&   r#   r<   r   r   rC   r,   r   )r(   r   r  r  rQ   rR   Zf_textr
  r-   arg_typsZ
slice_type_globalsr   rX   r[   	new_indexr   r   r   r    s2    
 

  
z StencilPass._add_offset_to_sliceN)r   
__module____qualname__r)   re   rn   rT   r   r   r   r   r  r   r   r   r   r   !   s   
<  s" Dr   c                 C   s  ddl m} ddlm}	 ddlm}
 ddlm} | j	 }t	
|j}||_t|j}d|krhtdddlm}	 |	j}|	|| t||||}tjd|j ||jj|jj|jj|jjd	\|j_|j_|j_}|
j|jj|jj|jjd
d	|jj|jjtjd W 5 Q R X t |t! }t"|# }t$|# }tj%&| tj'dkrft(d t)| i }|jj* D ].\}}t+,|t-||}|||< |||j.< qvt/|| tj'dkrt(d t)| |jj* D ]\}}|||< qi }|0 D ]}|j1D ]t}t2|t+j3rt2|j4t+j5rtj'dkrTt(d||j4j6|j4j.|j4j6|k ||j4j6 j.||j4j.< ||j4j6 |_4qqtj'dkrt(d| t(d t)| t7| ||_|| 8|d |fS )z'get typed IR from stencil bytecode
    r   )
CPUContext)
cpu_target)type_annotations)type_inference_stager6   z6Cannot use the reserved word 'out' in stencil kernels.zbefore-inferenceNr   )r!   r"   r#   liftedlifted_fromr-   r   html_outputr8   zInitial stencil_blockszAfter replace_varsr\   rc   zAfter replace arg with arr)9Znumba.core.cpur  numba.core.registryr  Znumba.core.annotationsr  numba.core.typed_passesr  	kernel_ircopydeepcopyr<   r   r   rN   target_contextnested_contextDummyPipeliner   rewrite_registryapplystater%   r&   r!   r-   r"   r   r#   ZTypeAnnotationr   HTMLadd_offset_to_labels
next_labelr   r   r   _the_max_labelupdater   r   r   r=   r   r|   r   r3   replace_varsvaluesrC   r>   rD   r,   Argr   remove_delsget_return_type)r`   r%   r-   rQ   rR   r\   r"   r#   r  r  r  r  Zstencil_func_irr   r   r&   tprX   Z	min_label	max_labelvar_dictr   typnew_varr+   call_typrc   r[   r1   r   r   r   rP     s    
   


 



rP   c                   @   s   e Zd Zdd ZdS )r%  c                 C   sP   ddl m} | | _|| j_|| j_|| j_|| j_d | j_d | j_d | j_	d S )Nr   )	StateDict)
Znumba.core.compilerr9  r(  r%   r&   r-   r!   r"   r   r#   )r(   r%   r&   r-   r   r9  r   r   r   r)   g  s    zDummyPipeline.__init__N)r   r  r  r)   r   r   r   r   r%  f  s   r%  c                 C   s   t t| ||}|dk	r|S |S )z
    infer index_var as constant if it is of a expression form like c-1 where c
    is a constant in the outer function.
    index_var is assumed to be inside stencil kernel
    N)r   _get_const_index_expr_inner)ra   r!   r	  	const_valr   r   r   r   s  s       r   c                 C   sr   t t|tj tt| ||}|dk	r*|S t| |}tt| ||}|dk	rP|S tt	| ||}|dk	rj|S t
dS )zWinner constant inference function that calls constant, unary and binary
    cases.
    N)r   r>   r   r|   r   _get_const_two_irsr   get_definition_get_const_unary_expr_get_const_binary_exprr   )ra   r!   r	  	var_const	index_defr   r   r   r:    s,          r:  c                 C   s8   t t| |}|dk	r|S t t||}|dk	r0|S tdS )zWget constant in either of two IRs if available
    otherwise, throw GuardException
    N)r   r   r   )Zir1Zir2varr@  r   r   r   r<    s    r<  c                 C   sF   t t|tjo|jdk |j}t| ||}t|j }t	d
||S )zQevaluate constant unary expr if possible
    otherwise, raise GuardException
    unaryz{}{})r   r>   r   rE   rF   r,   r:  r   fnevalr  )ra   r!   rA  Z	inner_varr;  rF   r   r   r   r>    s
    
r>  c                 C   sR   t t|tjo|jdk t| ||j}t| ||j}t|j	 }t
d|||S )zRevaluate constant binary expr if possible
    otherwise, raise GuardException
    r  z{}{}{})r   r>   r   rE   rF   r:  lhsrhsr   rD  rE  r  )ra   r!   rA  arg1arg2rF   r   r   r   r?    s
    
r?  )0r   r!  r   pytypesr  r   numpyrq   numba.parfors.parforr:   
numba.corer   r   r   r   numba.core.typing.templatesr   r	   numba.core.typingr
   r   r   numba.core.ir_utilsr   r   r   r   r   r   r   r   r   numba.core.errorsr   Znumba.core.utilsr   numba.npr   r   objectr   rP   r%  r   r:  r<  r>  r?  r   r   r   r   <module>   s8   ,     rX