U
    í¾|eu›  ã                   @   sþ   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mZ d dl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lmZ d dlZd dlZd d	lmZ G d
d„ deƒZedd„ ƒZ dd„ Z!G dd„ deƒZ"ddd„Z#dd„ Z$ee#ƒdd„ ƒZ%dS )é    N)Úir)ÚtypesÚtypingÚutilsr   ÚconfigÚir_utilsÚregistry)ÚCallableTemplateÚ	signatureÚinfer_globalÚAbstractTemplate)Úlower_builtin)Úregister_jitable)ÚNumbaValueError)Úliteral_unroll)Únumpy_supportc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚStencilFuncLowererzMCallable class responsible for lowering calls to a specific StencilFunc.
    c                 C   s
   || _ d S ©N)ÚstencilFunc)ÚselfÚsf© r   úS/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/stencils/stencil.pyÚ__init__   s    zStencilFuncLowerer.__init__c                 C   s:   | j  |ji |jd ¡}| ||j||¡}| |jg¡ |S r   )r   Úcompile_for_argtysÚargsÚreturn_typeZcall_internalÚfndescÚadd_linking_libsÚlibrary)r   ÚcontextÚbuilderÚsigr   ÚcresÚresr   r   r   Ú__call__   s     ÿzStencilFuncLowerer.__call__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   r   r   r   r   r      s   r   c                 G   s\   | j }t|ƒD ]H}| j|jkr&tdƒ‚|j }tt|ƒƒD ]}|| || kr8tdƒ‚q8qd S )Nz\Secondary stencil array does not have same number  of dimensions as the first stencil input.zaSecondary stencil array has some dimension smaller the same dimension in the first stencil input.)Úshaper   ÚndimÚ
ValueErrorÚrangeÚlen)Úar   ÚashapeÚargÚargshapeÚir   r   r   Ú!raise_if_incompatible_array_sizes$   s    
r4   c                 C   s   t | j| | j| ƒS )z_ Called by stencil in Python mode to add the loop index to a
        user-specified slice.
    )ÚsliceÚstartÚstop)Ú	the_sliceÚaddendr   r   r   Úslice_addition;   s    r:   c                   @   sd   e Zd Zd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d„ ZdS )ÚStencilFuncz@
    A special type to hold stencil information for the IR.
    r   c                 C   sŒ   t | ƒj| _t | ƒ jd7  _|| _|| _|| _g | _tjj	| _
tjj| _| j
 ¡  | j ¡  |  | j
¡ | j d¡| _i | _t| ƒ| _d S )Né   Úneighborhood)ÚtypeÚ
id_counterÚidÚ	kernel_irÚmodeÚoptionsÚkwsr   Ú
cpu_targetÚtyping_contextÚ
_typingctxÚtarget_contextÚ
_targetctxÚrefreshÚ_install_typeÚgetr=   Ú_type_cacher   Ú	_lower_me)r   rA   rB   rC   r   r   r   r   H   s    



zStencilFunc.__init__c              
   C   s&  g }|  ¡ D �]\}}|j}|j}g }	|jD ]ì}
t|
tjƒ�r| |¡ t|ƒdkrŽt 	|||¡}t 	||d |¡}|	 t 
|||
j|¡¡ n~g }|D ]}t 	|||¡}||g7 }q–| d|¡}tj ||¡}|	 t |||¡¡ t 	|||¡}t 
|||
j|¡}|	 |¡ q,|	 |
¡ q,|	|_q|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.
        r<   r   Ústencil_index)ÚitemsÚscopeÚlocÚbodyÚ
isinstancer   ÚReturnÚappendr.   ÚVarÚSetItemÚvalueÚredefineÚExprÚbuild_tupleÚAssign)r   ÚblocksÚ
index_varsÚout_nameÚ
ret_blocksÚlabelÚblockrQ   rR   Únew_bodyÚstmtZrvarZivarZvar_index_varsZone_varÚ	index_varÚs_index_varÚ
tuple_callÚsir   r   r   Úreplace_return_with_setitemZ   s2    

z'StencilFunc.replace_return_with_setitemc           *      C   sâ  i }g }	t jdkr*td||ƒ t |j¡ |dkr8d}
n$d}
t|ƒ|kr\tdt|ƒ|f ƒ‚t |j¡}t	ƒ }|j 
¡ D �]}|j}|j}g }|jD �]ò}t|tjƒrât|jtjƒrât jdkrÒtd|jj|jjƒ |jj||jj< t|tjƒ�r t|jtjƒ�r |jjdk�r |jjj|jk�s>t|tjƒ�rF|jj|jk�rFtd	ƒ‚t|tjƒ�r~t|jtjƒ�r~|jjd
k�r~|jjj|jk�r~|jjj|k�r~|jjdk�r¬|jj}n|jj}| |jjj¡ |
�rt|dƒ�sÚt‚|j|k�rø|	||j g7 }	n&|j|k�r|	||j g7 }	ntdƒ‚|dk�rlt ||d |¡}|  d|¡}||j }t|t!j"j#ƒ�r|  d|¡}t$ %t&¡}t!j' (|¡}|||j< t )d||¡}| *t |||¡¡ tj +|||gd|¡}| ,| j-|t!j.gi ¡||< | *t |||¡¡ | *t tj /|jj||¡|j|¡¡ nNtj 0t1j|||¡}| *t |||¡¡ | *t tj /|jj||¡|j|¡¡ �qˆg }g }|  d|¡}g }g } ||j }t2|ƒD �]–}!|  d|¡}| *t t |!|¡||¡¡ ||g7 }t |||! |¡}||g7 }|  d|¡}| |g7 } |  d|¡}"tj /|||! |¡}#| *t |#|"|¡¡ t|t!j3ƒ�rP||! }$n|dd… }$t|$t!j"j#ƒ�r|  d|¡}t$ %t&¡}t!j' (|¡}|||j< t )d||¡}| *t |||¡¡ tj +||"||! gd|¡}| ,| j-|$t!j.gi ¡||< | *t |||¡¡ n,tj 0t1j|"||! |¡}| *t |||¡¡ �qštj 4| |¡}%| *t |%||¡¡ | *t tj /|jj||¡|j|¡¡ q”| *|¡ q”||_qx|
�rÚdd„ t2|ƒD ƒ}t|	ƒdk�rÀtdƒ‚|	D �]}&t|&t5ƒ�sât|&t6ƒ�rvt2t|&ƒƒD ]|}'|&|' }(t|(tjƒ�r|(j|k�r||(j }(t|(t7ƒ�r`t8||' d |(ƒ||' d< t9||' d |(ƒ||' d< ntdƒ‚�qît|&ƒ})nNt|&t7ƒ�r¼t8|d d |&ƒ|d d< t9|d d |&ƒ|d d< d})ntdƒ‚|)|k�rÄtdƒ‚�qÄ||fS )zß
        Transforms the stencil kernel as specified by the user into one
        that includes each dimension's index variable as part of the getitem
        calls.  So, in effect array[-1] becomes array[index0-1].
        r<   Úadd_indices_to_kernelNTFúD%d dimensional neighborhood specified for %d dimensional input arrayzremembering in const_dict)ÚsetitemÚstatic_setitemz?Assignments to arrays passed to stencil kernels is not allowed.)ÚgetitemÚstatic_getitemro   ÚnamezDstencil kernel index is not constant, 'neighborhood' option requiredr   rO   r:   r   Úconst_indexZind_stencil_indexc                 S   s   g | ]}d d g‘qS )r   r   )Ú.0Ú_r   r   r   Ú
<listcomp>+  s     z5StencilFunc.add_indices_to_kernel.<locals>.<listcomp>z=Stencil kernel with no accesses to relatively indexed arrays.zCstencil kernel index is not constant,'neighborhood' option requiredz/Non-tuple or non-integer used as stencil index.z2Stencil index does not match array dimensionality.):r   ÚDEBUG_ARRAY_OPTÚprintr   Údump_blocksr^   r.   r,   Zget_tuple_tableÚsetÚvaluesrQ   rR   rS   rT   r   r]   rY   ÚConstÚtargetrq   r[   ÚopÚ	arg_namesrX   Úindexrf   ÚaddÚhasattrÚAssertionErrorr   rW   rZ   r   ÚmiscÚ	SliceTypeÚnumbaÚnjitr:   Ú	functionsÚ
DispatcherÚGlobalrV   ÚcallÚget_call_typerG   Úintpro   ÚbinopÚoperatorr-   Ú
ConstSizedr\   ÚtupleÚlistÚintÚminÚmax)*r   ÚkernelÚindex_namesr+   r=   Ústandard_indexedÚtypemapÚ	calltypesZ
const_dictZkernel_constsZneed_to_calc_kernelZtuple_tableÚrelatively_indexedrc   rQ   rR   rd   re   Zstmt_index_varrf   ZtmpvarZstmt_index_var_typZsa_varZsa_funcZsa_func_typZg_saZslice_addition_callZacc_callr_   Zsum_resultsrg   Zconst_index_varsZind_stencilsÚdimZ
getitemvarZgetitemcallZone_index_typrh   r   r3   ÚteZ	index_lenr   r   r   rk   „   sN   

ÿÿ

ÿÿ
þý
üûÿ
þýü




 þ ÿ þ

 ÿ


 ÿ


 ÿ þ

ÿ
ÿ
ÿz!StencilFunc.add_indices_to_kernelc                 C   s¦   t jdkr"td|ƒ t | jj¡ t|d tj	j
ƒs<tdƒ‚ddlm} | | j| j| j|d i ¡\}}}}t|tj	j
ƒr€tdƒ‚tj	 
||d j|d j¡}|||fS )Nr<   Úget_return_typer   zGThe first argument to a stencil kernel must be the primary input array.)Útyped_passesz:Stencil kernel must return a scalar and not a numpy array.)r   rv   rw   r   rx   rA   r^   rT   r   ÚnpytypesÚArrayr   Ú
numba.corerž   Útype_inference_stagerG   rI   r+   Úlayout)r   Úargtysrž   r˜   r   r™   rt   Úreal_retr   r   r   r�   L  s,    

úÿÿzStencilFunc.get_return_typec                 C   s2   t dt| jƒ tft| | jd�ƒ}| | |¡ dS )zmConstructs and installs a typing class for a StencilFunc object in
        the input typing context.
        ZStencilFuncTyping_)ÚkeyÚgenericN)r>   Ústrr@   r   ÚdictÚ_type_meÚinsert_user_function)r   Ú	typingctxZ_ty_clsr   r   r   rK   e  s    ÿýzStencilFunc._install_typec           
      C   s.   | j | \}}}}| j|||||f|žŽ }	|	S r   )rM   Ú_stencil_wrapper)
r   r¤   Úkwtysr   Úsigretrt   Úresultr˜   r™   Únew_funcr   r   r   r   o  s    
 ÿÿzStencilFunc.compile_for_argtysc                 C   s8  | j dk	r:t| j ƒ|d jkr:tdt| j ƒ|d jf ƒ‚|}d}d}d|krl||d f7 }|d7 }|d }d|krŠ||d f7 }|d7 }|| jkrª| j| \}}}}|S |  |¡\}}	}
t|f|žŽ }d	 d
 | j	j
¡|¡}t|ƒtƒ ktƒ f tdƒ}|jt |¡d�}| j | j| |fg¡ |||	|
f| j|< |S )z¡
        Implement AbstractTemplate.generic() for the typing class
        built by StencilFunc._install_type().
        Return the call-site signature.
        Nr   rl   Ú Úoutz
, out=Noner=   z, neighborhood=Nonez*def __numba_dummy_stencil({}{}):
    pass
ú,Z__numba_dummy_stencil)Úpysig)r=   r.   r+   r   rM   r�   r
   ÚformatÚjoinrA   r~   ÚexecÚglobalsÚlocalsÚevalÚreplacer   ÚpysignaturerI   Zinsert_func_defnrN   )r   r¤   r®   Zargtys_extraÚ	sig_extrar°   Z_sigrt   r¥   r˜   r™   r"   Z
dummy_textZ
dummy_funcr   r   r   rª   v  s>    
ÿþ
 ÿzStencilFunc._type_mec           
      C   sŠ   i }|  ¡ }i |_|j ¡ D ]d\}}t  |j| ¡}g |_|j| jD ].}t  |¡}	|j |	¡ ||krF|| ||	< qF||j|< q||fS )a  
        Create a copy of a given IR along with its calltype information.
        We need a copy of the calltypes because copy propagation applied
        to the copied IR will change the calltypes and make subsequent
        uses of the original IR invalid.
        )Úcopyr^   rP   ÚdeepcopyrS   rV   )
r   r   r™   Úcopy_calltypesÚkernel_copyZblock_labelrc   Ú	new_blockre   Úscopyr   r   r   Úcopy_ir_with_calltypesž  s    
z"StencilFunc.copy_ir_with_calltypesc           C   
      s&  |   | j|¡\}}t |j¡ |jd }	t |j|¡\}
}t |j¡}t |j|
|||¡ d|krjt	dƒ‚t 
d|¡}tjdkrŒtd||ƒ |d }tjdkrÂtd||jt|jƒ|ƒ t |j¡ dtt|ƒƒ d	d
¡| jf }g }t|jƒD ]"}t 
dt|ƒ |¡}||g7 }qît 
d|¡}t 
d|¡}d}|d k	�rF|d |¡7 }dt| jƒk�rd|d |¡7 }| j dg ¡}|	|k�r„t	dƒ‚tt|ƒt|jƒ ƒdk�r¨t	dƒ‚|  |||j| j|||¡\}}| jd k�rØ|| _tjdk�røtdƒ t |j¡ |   |j||¡}tjdk�r*td|ƒ t |j¡ d |d !|j¡|¡}g }t|jƒD ]Z}t"|| d t#ƒ�r€|| d }|| d }nd ||¡}d ||¡}| $||f¡ �qNt|ƒdk�rî|d|	 7 }|D ]}||	k�rÈ|d| 7 }�qÈ|d7 }t 
d|¡}|d ||	¡7 }dd„ } |d k�r(t% &|j¡jj'}!d |||!¡}"d| jk�r|| jd }#t(j) )|#¡}$| j* +|$|j¡�s€d }%t	|%ƒ‚nd}#|d!|" 7 }t|jƒD ]Ž}&d"g|j }'d"g|j }(d# | j|& d ¡|'|&< d$ | j|& d ¡|(|&< |d!d% |d !|'¡| |#ƒ¡ 7 }|d!d% |d !|(¡| |#ƒ¡ 7 }�q–n\d| jk�r„| jd }#t(j) )|#¡}$| j* +|$|j¡�shd }%t	|%ƒ‚d& || |#ƒ¡}"|d!|" 7 }d})t|jƒD ]P}t|)ƒD ]}*|d!7 }�qž|d' || || d |||| d ¡7 }|)d7 })�q’t|)ƒD ]}*|d!7 }�qì|d( |¡7 }|d) |¡7 }tjdk�r4td*ƒ t|ƒ t,|ƒt-ƒ kt.ƒ f t/|ƒ}+|d k	�rjt0 1|+¡},|,|_2dd+l3m4}- |- 5|+¡}.t 6|.j¡ t |.j¡}/i }0||||g|j | }1|/ 7¡ D ]B\}2}3|2|1k�rºt"|3t8j9ƒ�sÞt:‚|3j; <|3j=|3j>¡}4|4j=|0|2< �qºt ?|.j|0¡ t@|.j A¡ ƒd ‰ t B|jˆ ¡|_t@|j A¡ ƒd }5‡ fd,d-„|D ƒ}tjdk�r’td.|ˆ ƒ td/ƒ t |.j¡ td0ƒ t |j¡ |.j 7¡ D �] \}6}7tC|7jDƒD ]à\}}8t"|8t8jEƒ�r°|8jFj=|k�r°|8j>}9|7j;}:t8 G|:|9¡};|7jDd |… |;_D|7jD|d d … |7_DtH|j A¡ ƒ}<|; $t8 I|<|9¡¡ |j 7¡ D ]\}=}>|>|.j|=< �q:|7|.j|5< |;|.j|6< |D ]}?|.j|?  $t8 I|5|9¡¡ �qh �q–�q°�qœ �q �qœt J|.j¡|._t 6|.j¡ t"|tKjLƒ�sÌt:‚|}@tM|@ƒ}Atjdk�rútd1|Aƒ t |.j¡ t N|.j¡ |- O| j*| jP|.|Ad |-jQi ¡}B|BS )2Nr   r³   z6Cannot use the reserved word 'out' in stencil kernels.Z__sentinel__r<   Úname_var_tabler­   z__numba_stencil_%s_%sú-rt   r   r=   r²   z	, {}=NoneÚstandard_indexingzYThe first argument to a stencil kernel must use relative indexing, not standard indexing.z[Standard indexing requested for an array name not present in the stencil kernel definition.zAfter add_indices_to_kernelz!After replace_return_with_setitemzdef {}({}{}):
r´   z	{}[{}][0]z	{}[{}][1]z&    raise_if_incompatible_array_sizes(z)
Z
full_shapez    {} = {}.shape
c                 S   s@   t  | ¡s4t  | ¡rdS t  | ¡r<| dk r.dS dS nt| ƒS d S )Nznp.nanr   z-np.infznp.inf)ÚnpÚisfiniteÚisnanÚisinfr¨   )Úcvalr   r   r   Úcval_as_strD  s    


z1StencilFunc._stencil_wrapper.<locals>.cval_as_strz{} = np.empty({}, dtype=np.{})
rÍ   z-cval type does not match stencil return type.z    ú:z:-{}z-{}:z{}[{}] = {}
z{}[:] = {}
z.for {} in range(-min(0,{}),{}[{}]-max(0,{})):
z{} = 0
z    return {}
znew stencil func text©Úcompilerc                    s   g | ]}|ˆ  ‘qS r   r   ©rs   Úx©Zstencil_stub_last_labelr   r   ru   ¶  s     z0StencilFunc._stencil_wrapper.<locals>.<listcomp>zret_blocks w/ offsetsz"before replace sentinel stencil_irz#before replace sentinel kernel_copyÚnew_stencil_param_types)RrÅ   rA   r   Zremove_argsr^   r~   Zcopy_propagateZget_name_var_tableZapply_copy_propagater   Zget_unused_var_namer   rv   rw   Údtyper>   rx   Úhexr@   r¼   r-   r+   r¨   r¶   r©   rD   rC   rL   r.   ry   rk   r=   rj   r·   rT   r’   rV   r   Úas_dtyper&   r   ÚtypeofrG   Úcan_convertr¸   r¹   rº   r»   r   r½   rµ   r¡   rÑ   Úrun_frontendZremove_delsrP   r   rW   r‚   rQ   rZ   rq   rR   Zreplace_var_namesr”   ÚkeysZadd_offset_to_labelsÚ	enumeraterS   r]   r|   ÚBlockr“   ÚJumpZrename_labelsr   ÚTyper‘   Zfixup_var_define_in_scopeZ
compile_irrI   ZDEFAULT_FLAGS)Cr   r°   r¯   r   r˜   r™   r   rÂ   rÁ   Z	first_argZin_cpsZout_cpsrÆ   Zsentinel_nameZ	the_arrayZstencil_func_namer_   r3   Zindex_var_namer`   Zneighborhood_namer¾   r—   Zkernel_sizerš   ra   Z	func_textÚrangesÚloÚhiZother_arrayZ
shape_namerÎ   Zreturn_type_nameZout_initrÍ   Zcval_tyÚmsgr›   Zstart_itemsZ	end_itemsÚoffsetÚjZstencil_funcrµ   rÑ   Z
stencil_irZ	var_tableZnew_var_dictÚreserved_namesrq   ÚvarÚnew_varZ	new_labelrb   rc   ÚinstrR   rQ   Z
prev_blockZbody_first_labelÚlÚbZ	ret_blockÚarray_typesrÕ   r±   r   rÔ   r   r­   ¹  s¼    ÿ
û


 ÿþÿÿ

     þ ÿ

 ÿ

ÿ  ÿ

 &



ú


ÿÿÿ
 ÿ
ÿ



ÿ


ùzStencilFunc._stencil_wrapperc                 O   s   | j d k	r:t| j ƒ|d jkr:td t| j ƒ|d j¡ƒ‚d|krž|d }|j}t |¡}tj	 
||jt |¡¡}tdd„ |D ƒƒ}tdd„ |D ƒ|g ƒ}nd }tdd„ |D ƒƒ}|}tjdkrÐtd	|||ƒ |  |¡\}	}
}| j|d |	|
|f|žŽ }|d k�r|j|Ž S |j||f Ž S d S )
Nr   zD{} dimensional neighborhood specified for {} dimensional input arrayr³   c                 S   s   g | ]}t j |¡‘qS r   ©r   rÙ   rÒ   r   r   r   ru     s     z(StencilFunc.__call__.<locals>.<listcomp>c                 S   s   g | ]}t j |¡‘qS r   rî   rÒ   r   r   r   ru     s     c                 S   s   g | ]}t j |¡‘qS r   rî   rÒ   r   r   r   ru     s     r<   r%   )r=   r.   r+   r,   r¶   rÖ   r   Ú
from_dtyper   rŸ   r    Ú
map_layoutr�   r   rv   rw   r�   r­   Úentry_point)r   r   Úkwargsr°   ÚrdtypeZrttypeÚresult_typerí   Zarray_types_fullr¥   r˜   r™   r±   r   r   r   r%      s@    
ÿ þ
ÿÿ
ÿÿ

zStencilFunc.__call__N)r&   r'   r(   r)   r?   r   rj   rk   r�   rK   r   rª   rÅ   r­   r%   r   r   r   r   r;   A   s   * I
(  Ir;   Úconstantc                 K   sX   t | tƒsd}| }n| }d }|D ]}|dkr td| ƒ‚q t||ƒ}|d k	rT||ƒS |S )Nrõ   )rÍ   rÈ   r=   zUnknown stencil option )rT   r¨   r,   Ú_stencil)Zfunc_or_moderC   rB   ÚfuncÚoptionÚwrapperr   r   r   Ústencil!  s    

rú   c                    s&   ˆ dkrt dˆ  ƒ‚‡ ‡fdd„}|S )Nrõ   zUnsupported mode style c                    s"   ddl m} | | ¡}t|ˆ ˆƒS )Nr   rÐ   )r¡   rÑ   rÛ   r;   )r÷   rÑ   rA   ©rB   rC   r   r   Ú	decorated7  s    
z_stencil.<locals>.decorated)r,   )rB   rC   rü   r   rû   r   rö   3  s    rö   c                 C   s   t  t  tjj¡d¡S )z lowering for dummy stencil callsr   )ÚlirÚConstantÚIntTyper   rŒ   Úbitwidth)r    r!   r"   r   r   r   r   Ústencil_dummy_lower>  s    r  )rõ   )&r¿   ÚnumpyrÉ   Úllvmliter   rý   r¡   r   r   r   r   r   r   Únumba.core.typing.templatesr	   r
   r   r   Znumba.core.imputilsr   Znumba.core.extendingr   Únumba.core.errorsr   Únumba.misc.specialr   r…   rŽ   Únumba.npr   Úobjectr   r4   r:   r;   rú   rö   r  r   r   r   r   Ú<module>   s2   $
     e
