U
    ¿|eéA  ã                   @   s”  d dl Z d dl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mZmZmZmZmZ d dlmZ d dlmZ dd„ Ze d	¡G d
d„ dejƒƒZe
je je
je je
je jiZe
je j e
j!e j"e
j#e j$e
j%e j&e
j'e j(e
j)e j*e
j+e j,e
j-e j.e
j/e j0e
j1e j2e
j3e j4e
j5e j6iZ7e
j8e j9e
j:e j;e
j<e j=e
j>e j?e
j@e jAe
jBe jCiZDdd„ ZEejFdd„ ƒZGG dd„ de jHƒZIe jJdœdd„ZKdd„ ZLdS )é    N)ÚdefaultdictÚOrderedDict)ÚSimpleNamespace)ÚtypesÚtargetconfigÚirÚrewritesÚcompiler)Únpydecl)ÚDUFuncc                 C   s   t | tjtfƒS ©N)Ú
isinstanceÚnpÚufuncr   )Úfunc© r   úW/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/np/ufunc/array_exprs.pyÚ	_is_ufunc   s    r   zafter-inferencec                       sh   e Zd ZdZ‡ f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‡  ZS )ÚRewriteArrayExprszóThe RewriteArrayExprs class is responsible for finding array
    expressions in Numba intermediate representation code, and
    rewriting those expressions to a single operation that will expand
    into something similar to a ufunc call.
    c                    s4   t t| ƒj|f|ž|Ž |jj}d|kr0t|d< d S )NÚ	arrayexpr)Úsuperr   Ú__init__Ú	targetctxÚspecial_opsÚ_lower_array_expr)ÚselfÚstateÚargsÚkwsr   ©Ú	__class__r   r   r      s    zRewriteArrayExprs.__init__c           	      C   s¢   t |ƒdkrdS || _|| _tƒ | _i | _| tj¡}|D ]X}|j	j
}|j}t|tjƒr|t| |d¡tjƒr||  |||¡ q:t|tjƒr:|| j|< q:t | jƒdkS )z±
        Using typing and a basic block, search the basic block for array
        expressions.
        Return True when one or more matches were found, False otherwise.
        r   FN)ÚlenÚ
crnt_blockÚtypemapr   Úarray_assignsÚconst_assignsÚ
find_instsr   ÚAssignÚtargetÚnameÚvaluer   ÚExprÚgetr   ÚArrayÚ_match_array_exprÚConst)	r   Úfunc_irÚblockr#   Ú	calltypesÚassignmentsÚinstrÚtarget_nameÚexprr   r   r   Úmatch!   s"    ÿzRewriteArrayExprs.matchc                    sš   |j }ˆ j}|dkrD|jtjkrDt‡ fdd„| ¡ D ƒƒr–|||< nR|dkr–|jjˆ j	kr–ˆ j	|jj }t
|tjƒr–|j}t|ƒr–ˆ  ||¡s–|||< dS )z‘
        Find whether the given assignment (*instr*) of an expression (*expr*)
        to variable *target_name* is an array expression.
        ©ÚunaryÚbinopc                 3   s   | ]}ˆ j |j jV  qd S r   )r#   r)   Úis_internal©Ú.0Úvar©r   r   r   Ú	<genexpr>Q   s   ÿz6RewriteArrayExprs._match_array_expr.<locals>.<genexpr>ÚcallN)Úopr$   Úfnr
   Úsupported_array_operatorsÚallÚ	list_varsr   r)   r#   r   r   ÚFunctionÚ
typing_keyr   Ú_has_explicit_output)r   r4   r6   r5   Zexpr_opr$   Ú	func_typeÚfunc_keyr   r?   r   r.   B   s     
ÿÿ
z#RewriteArrayExprs._match_array_exprc                 C   s,   t |jƒt |jƒ }|jdk	r"dS ||jkS )zr
        Return whether the *expr* call to *func* (a ufunc) features an
        explicit output argument.
        NT)r!   r   r   ÚvarargÚnin)r   r6   r   Únargsr   r   r   rI   `   s    
z&RewriteArrayExprs._has_explicit_outputc                 C   s>   |j }|dkr|jS |dkr,| j|jj jS td |¡ƒ‚d S )Nr8   rA   z:Don't know how to find the operator for '{0}' expressions.)rB   rC   r#   r   r)   rH   ÚNotImplementedErrorÚformat©r   Úir_exprÚir_opr   r   r   Ú_get_array_operatorl   s    ÿÿz%RewriteArrayExprs._get_array_operatorc                 C   sJ   |j }|dkr|j|jfS |dkr*| ¡ S |dkr8|jS td |¡ƒ‚dS )z{Given a Numba IR expression, return the operands to the expression
        in order they appear in the expression.
        r:   r9   rA   z:Don't know how to find the operands for '{0}' expressions.N)rB   ÚlhsÚrhsrF   r   rO   rP   rQ   r   r   r   Ú_get_operandsv   s    ÿÿzRewriteArrayExprs._get_operandsc                    s:   |j }|dkr|jS ‡ fdd„ˆ  |¡D ƒ}ˆ  |¡|fS )zZTranslate the given expression from Numba IR to an array expression
        tree.
        r   c                    s   g | ]}ˆ j  |j|¡‘qS r   )r%   r,   r)   )r=   Zop_varr?   r   r   Ú
<listcomp>Œ   s   ÿz5RewriteArrayExprs._translate_expr.<locals>.<listcomp>)rB   r6   rW   rT   )r   rR   rS   Zoperands_or_argsr   r?   r   Ú_translate_expr…   s    
ÿz!RewriteArrayExprs._translate_exprc                 C   sV  i }t ƒ }ttƒ}| j ¡ D �],}|j}g }|  |¡|f}tjd|j	|| j
|jj d�}t ||j|j	¡}	|	||< |	| j|jj< |  |¡D ]¾}
|
j}|
j�r|| jk�r| j| }|j}| ¡ }|D ]}
||
j  d7  < qÄ| |  |¡¡ |jj�rH| |jj¡ d||< qŠ|| jk�r,| | j| ¡ qŠ||
j  d7  < | |
¡ qŠq|||fS )ztIterate over the matches, trying to find which instructions should
        be rewritten, deleted, or moved.
        r   )rB   Úlocr6   Útyé   N)Úsetr   Úintr$   Úvaluesr*   rT   r   r+   rZ   r#   r(   r)   r'   rW   Úis_temprF   ÚappendrY   Úaddr%   )r   Úreplace_mapÚ	dead_varsÚ	used_varsr4   r6   Zarr_inpsZarr_exprÚnew_exprÚ	new_instrÚoperandZoperand_nameZchild_assignZ
child_exprZchild_operandsr   r   r   Ú_handle_matches�   s@    ý


z!RewriteArrayExprs._handle_matchesc                 C   s   || }||kr|| }q|S )z¯Find the final replacement instruction for a given initial
        instruction by chasing instructions in a map from instructions
        to replacement instructions.
        r   )r   Zreplacement_mapr4   Úreplacementr   r   r   Ú_get_final_replacementµ   s    
z(RewriteArrayExprs._get_final_replacementc                 C   s6  |   ¡ \}}}| j ¡ }| ¡  i }| jjD ]ä}t|tjƒr¶||krª|  ||¡}|r´| 	|¡ |j
 ¡ D ]>}|j}	|	|krŠ| 	| |	¡¡ ||	 dkrh||	  d8  < qhn
| 	|¡ q,t|tjƒ�r|j
}
||
 dkrð||
  d8  < |||
< n|
|k�r| 	|¡ q,| 	|¡ q,|�r2| ¡ D ]}| |¡ �q |S )z}When we've found array expressions in a basic block, rewrite that
        block, returning a new, transformed block.
        r   r\   )ri   r"   ÚcopyÚclearÚbodyr   r   r'   rk   ra   r*   rF   r)   ÚpopÚDelr_   Úinsert_before_terminator)r   rc   rd   re   ÚresultZ
delete_mapr4   rj   r>   Úvar_nameZinstr_valuer   r   r   Úapply¿   s@    
 ÿ


zRewriteArrayExprs.apply)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r7   r.   rI   rT   rW   rY   ri   rk   rt   Ú__classcell__r   r   r   r   r      s   !
%
r   c                 C   sž  t | tƒ�r.| \}}g }i }|D ]$}t|ƒ\}}| |¡ | |¡ q |tjkrÚt|ƒdkr²|tkr„t	 
|d t| ƒ |d ¡|fS |tkrØt	 |d t| ƒ g|d g¡|fS n&|tks¾t‚t	 t| ƒ |d ¡|fS nRt|ƒ�rŒd tt|ƒƒ dd¡¡}t	 |t	 ¡ ¡}	|||< t	 |	|g ¡}
|
|fS n^t | tjƒ�rnt	j| jt	 ¡ | jj| jj�rb| jjndd�i fS t | tjƒ�rŒt	 | j ¡i fS t!d| f ƒ‚d	S )
z[Build a Python expression AST from an array expression built by
    RewriteArrayExprs.
    é   r   r\   z__ufunc_or_dufunc_{0}ú-Ú_)ÚlinenoÚ
col_offsetz1Don't know how to translate array expression '%r'N)"r   ÚtupleÚ_arr_expr_to_astra   Úupdater
   rD   r!   Ú_binopsÚastÚBinOpÚ_cmpopsÚCompareÚ	_unaryopsÚAssertionErrorÚUnaryOpr   rP   ÚhexÚhashÚreplaceÚNameÚLoadÚCallr   ÚVarr)   rZ   ÚlineÚcolr/   ÚNumr*   rO   )r6   rB   Úarr_expr_argsÚast_argsÚenvÚargZast_argZ	child_envÚfn_nameZfn_ast_nameZast_callr   r   r   r€   
  s`    

  ÿÿ 
 ÿÿ
ÿ
þþÿr€   c              	   c   s˜   t ƒ }| D ]Z}|j}|jj||jd�j}| dd¡ dd¡}||krRt|›d�ƒ‚||f||< ||_q
t|ƒ}z
|V  W 5 | ¡ D ]\}}||_q‚X dS )za
    Legalize names in the variable list for use as a Python function's
    parameter names.
    )rZ   ú$r|   Ú.z not uniqueN)	r   r)   ÚscopeÚredefinerZ   rŒ   rˆ   Úlistr_   )Zvar_listÚvar_mapr>   Úold_nameÚnew_nameÚparam_namesr   r   r   Ú_legalize_parameter_names2  s    
r¢   c                       s(   e Zd Zejejdœ‡ fdd„Z‡  ZS )Ú_EraseInvalidLineRanges)ÚnodeÚreturnc                    s>   t ƒ  |¡}t|dƒr:t|dd ƒd k	r:|j|jkr:|`|`|S )Nr}   Ú
end_lineno)r   Úgeneric_visitÚhasattrÚgetattrr}   r¦   )r   r¤   r   r   r   r§   M  s    
z%_EraseInvalidLineRanges.generic_visit)ru   rv   rw   rƒ   ÚASTr§   ry   r   r   r   r   r£   L  s   r£   ©Zastreec                 C   s$   t  | ¡ tƒ  | ¡ t  | ¡ dS )z)Inplace fixes invalid lineno ranges.
    N)rƒ   Úfix_missing_locationsr£   Úvisitr«   r   r   r   Ú_fix_invalid_lineno_rangesW  s    
r®   c              	      s  dt t|ƒƒ dd¡ }|jj}| ¡ }tt|ƒdd„ d�}dd„ |D ƒ}t|ƒ�t}d	d„ |D ƒ}t	 
d
 |¡|d¡}	t|	dƒrŽt|	jƒdks’t‚|	jd }
||
j_t|jƒ\|
jd _}t|	ƒ W 5 Q R X t|	|dƒ}t||ƒ || }ˆj}ˆj‰ |j‡fdd„|D ƒŽ }g }|jD ]@}t|tjƒ�r0|j}t|tjƒ�rL| |j ¡ n
| |¡ �q|j!j |Ž ‰t" #¡  $¡ }|dk�r„t% &¡ n| '¡ }d|_(|j)ˆ |ˆ|dd�‰ddl*m+} G ‡ ‡‡fdd„d|j,ƒ}t-t|ƒd|d�}|j.|j/ |_0‡fdd„|D ƒ}| 1|ˆ ||||¡S )z:Lower an array expression built by RewriteArrayExprs.
    z__numba_array_expr_%sr{   r|   c                 S   s   | j S r   ©r)   )r>   r   r   r   Ú<lambda>j  ó    z#_lower_array_expr.<locals>.<lambda>)Úkeyc                 S   s   g | ]
}|j ‘qS r   r¯   r<   r   r   r   rX   m  s     z%_lower_array_expr.<locals>.<listcomp>c                 S   s   g | ]}t  |d ¡‘qS r   )rƒ   r—   )r=   Ú
param_namer   r   r   rX   q  s   ÿzdef {0}(): returnÚexecrn   r\   r   c                 3   s   | ]}ˆ   |¡V  qd S r   )Útypeof©r=   r)   ©Úlowererr   r   r@   †  s     z$_lower_array_expr.<locals>.<genexpr>NÚnumpyF)ÚflagsÚcaching)Únpyimplc                       s   e Zd Z‡ ‡‡fdd„ZdS )z%_lower_array_expr.<locals>.ExprKernelc                    sL   t |ˆ jjˆjƒ}‡ fdd„|D ƒ}ˆ j ˆˆjˆ|¡}ˆ  |ˆjˆ jj¡S )Nc                    s    g | ]\}}}ˆ   |||¡‘qS r   )Úcast)r=   ÚvalÚintyÚouttyr?   r   r   rX   Ÿ  s   ÿzB_lower_array_expr.<locals>.ExprKernel.generate.<locals>.<listcomp>)ÚzipÚ	outer_sigr   ÚcontextÚcall_internalÚfndescr½   Úreturn_type)r   r   Zarg_zipÚ	cast_argsrr   ©ÚbuilderÚcresÚ	inner_sigr?   r   Úgenerate�  s    
ÿ   ÿ
ÿz._lower_array_expr.<locals>.ExprKernel.generateN)ru   rv   rw   rÌ   r   rÈ   r   r   Ú
ExprKernelœ  s   rÍ   )rM   Únoutru   c                    s   g | ]}ˆ   |¡‘qS r   )Úloadvarr¶   r·   r   r   rX   ª  s     )2rŠ   r‹   rŒ   rZ   ÚfilenamerF   Úsortedr]   r¢   rƒ   ÚparserP   r¨   r!   rn   rˆ   r   r€   r6   r*   r®   Úcompiler´   rÃ   rÉ   r[   r   r   ÚOptionalÚtyper-   ra   ÚdtyperÆ   r   ÚConfigStackÚtop_or_noner	   ÚFlagsrl   Úerror_modelÚcompile_subroutineÚnumba.npr¼   Ú_Kernelr   rM   rÎ   rN   Únumpy_ufunc_kernel)r¸   r6   Z	expr_nameZexpr_filenameZexpr_var_listZexpr_var_uniqueÚ	expr_argsZexpr_paramsr•   Z
ast_moduleZast_fnÚ	namespaceÚcode_objÚimplrÃ   rÂ   Zinner_sig_argsÚargtyrº   r¼   rÍ   r   r   r   )rÉ   rÊ   rË   r¸   r   r   b  sf    
ÿ ÿ


ÿ     ÿr   )Mrƒ   Úcollectionsr   r   Ú
contextlibÚsysr   r   r¹   r   ÚoperatorÚ
numba.corer   r   r   r	   Únumba.core.typingr
   Znumba.np.ufunc.dufuncr   r   Úregister_rewriteÚRewriter   ÚposÚUAddÚnegÚUSubÚinvertÚInvertr‡   rb   ÚAddÚsubÚSubÚmulÚMultÚtruedivÚDivÚmodÚModÚor_ÚBitOrÚrshiftÚRShiftÚxorÚBitXorÚlshiftÚLShiftÚand_ÚBitAndÚpowÚPowÚfloordivÚFloorDivr‚   ÚeqÚEqÚneÚNotEqÚltÚLtÚleÚLtEÚgtÚGtÚgeÚGtEr…   r€   Úcontextmanagerr¢   ÚNodeTransformerr£   rª   r®   r   r   r   r   r   Ú<module>   s€    X   ý            ô      ú
(
