U
    hâËdé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   úS/home/sam/Atlas/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__Z	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_assignsZ
find_instsr   ÚAssignÚtargetÚnameÚvaluer   ÚExprÚgetr   ÚArrayÚ_match_array_exprÚConst)	r   Zfunc_irÚblockr"   Z	calltypesZ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'   Z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   r/   r1   r0   Zexpr_opr#   Z	func_typeZfunc_keyr   r9   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   r1   r   Únargsr   r   r   rC   `   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 )Nr3   r;   z:Don't know how to find the operator for '{0}' expressions.)r<   r=   r"   r   r'   rB   Ú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.
        r5   r4   r;   z:Don't know how to find the operands for '{0}' expressions.N)r<   ÚlhsÚrhsr@   r   rG   rH   rI   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'   )r7   Zop_varr9   r   r   Ú
<listcomp>Œ   s   ÿz5RewriteArrayExprs._translate_expr.<locals>.<listcomp>)r<   r1   rO   rL   )r   rJ   rK   Zoperands_or_argsr   r9   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   )r<   Úlocr1   Útyé   N)Úsetr   Úintr#   Úvaluesr(   rL   r   r)   rR   r"   r&   r'   r%   rO   Zis_tempr@   ÚappendrQ   Úaddr$   )r   Úreplace_mapÚ	dead_varsÚ	used_varsr/   r1   Zarr_inpsZarr_exprZnew_exprZ	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_mapr/   Ú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   rT   )r^   r!   ÚcopyÚclearÚbodyr   r   r%   r`   rX   r(   r@   r'   ÚpopÚDelrW   Zinsert_before_terminator)r   rZ   r[   r\   ÚresultZ
delete_mapr/   r_   r8   Úvar_nameZinstr_valuer   r   r   Úapply¿   s@    
 ÿ


zRewriteArrayExprs.apply)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r2   r,   rC   rL   rO   rQ   r^   r`   rh   Ú__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   rT   z__ufunc_or_dufunc_{0}ú-Ú_)ÚlinenoÚ
col_offsetz1Don't know how to translate array expression '%r'N)"r   ÚtupleÚ_arr_expr_to_astrX   Úupdater
   r>   r    Ú_binopsÚastÚBinOpÚ_cmpopsÚCompareÚ	_unaryopsÚAssertionErrorÚUnaryOpr   rH   ÚhexÚhashÚreplaceÚNameÚLoadÚCallr   ZVarr'   rR   ÚlineÚcolr-   ÚNumr(   rG   )r1   r<   Zarr_expr_argsÚast_argsÚenvÚargZast_argZ	child_envÚfn_nameZfn_ast_nameZast_callr   r   r   rt   
  s`    

  ÿÿ 
 ÿÿ
ÿ
þþÿrt   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.
    )rR   ú$rp   Ú.z not uniqueN)	r   r'   ÚscopeZredefinerR   r€   r|   ÚlistrW   )Zvar_listZvar_mapr8   Zold_nameÚnew_nameZ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 )Nrq   Ú
end_lineno)r   Úgeneric_visitÚhasattrÚgetattrrq   r”   )r   r’   r   r   r   r•   M  s    
z%_EraseInvalidLineRanges.generic_visit)ri   rj   rk   rw   ÚASTr•   rm   r   r   r   r   r‘   L  s   r‘   ©Zastreec                 C   s$   t  | ¡ tƒ  | ¡ t  | ¡ dS )z)Inplace fixes invalid lineno ranges.
    N)rw   Ú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_%sro   rp   c                 S   s   | j S r   ©r'   )r8   r   r   r   Ú<lambda>j  ó    z#_lower_array_expr.<locals>.<lambda>)Úkeyc                 S   s   g | ]
}|j ‘qS r   r�   r6   r   r   r   rP   m  s     z%_lower_array_expr.<locals>.<listcomp>c                 S   s   g | ]}t  |d ¡‘qS r   )rw   r‰   )r7   Ú
param_namer   r   r   rP   q  s   ÿzdef {0}(): returnÚexecrc   rT   r   c                 3   s   | ]}ˆ   |¡V  qd S r   )Ztypeof©r7   r'   ©Úlowererr   r   r:   †  s     z$_lower_array_expr.<locals>.<genexpr>NÚnumpyF)ÚflagsZ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)r7   ÚvalZintyZouttyr9   r   r   rP   Ÿ  s   ÿzB_lower_array_expr.<locals>.ExprKernel.generate.<locals>.<listcomp>)ÚzipÚ	outer_sigr   ÚcontextZcall_internalZfndescr©   Úreturn_type)r   r   Zarg_zipZ	cast_argsrf   ©ÚbuilderÚcresÚ	inner_sigr9   r   Úgenerate�  s    
ÿ   ÿ
ÿz._lower_array_expr.<locals>.ExprKernel.generateN)ri   rj   rk   r³   r   r¯   r   r   Ú
ExprKernelœ  s   r´   )rE   Únoutri   c                    s   g | ]}ˆ   |¡‘qS r   )Zloadvarr£   r¤   r   r   rP   ª  s     )2r~   r   r€   rR   Úfilenamer@   ÚsortedrU   r�   rw   ÚparserH   r–   r    rc   r|   r   rt   r1   r(   rœ   Úcompiler¢   r­   r°   rS   r   r   ÚOptionalÚtyper+   rX   Zdtyper®   r   ZConfigStackZtop_or_noner	   ÚFlagsra   Zerror_modelZcompile_subroutineZnumba.npr¨   Z_Kernelr   rE   rµ   rF   Znumpy_ufunc_kernel)r¥   r1   Z	expr_nameZexpr_filenameZexpr_var_listZexpr_var_uniqueZ	expr_argsZexpr_paramsr‡   Z
ast_moduleZast_fnÚ	namespaceZcode_objÚimplr­   r¬   Zinner_sig_argsZargtyr§   r¨   r´   r   r   r   )r°   r±   r²   r¥   r   r   b  sf    
ÿ ÿ


ÿ     ÿr   )Mrw   Úcollectionsr   r   Ú
contextlibÚsysr   r   r¦   r   ÚoperatorZ
numba.corer   r   r   r	   Znumba.core.typingr
   Znumba.np.ufunc.dufuncr   r   Zregister_rewriteZRewriter   ÚposÚUAddÚnegÚUSubÚinvertÚInvertr{   rY   ÚAddÚsubÚSubÚmulÚMultÚtruedivÚDivÚmodÚModÚor_ÚBitOrÚrshiftÚRShiftÚxorÚBitXorÚlshiftÚLShiftÚand_ÚBitAndÚpowÚPowÚfloordivÚFloorDivrv   ÚeqÚEqÚneÚNotEqÚltÚLtÚleÚLtEÚgtÚGtÚgeÚGtEry   rt   Úcontextmanagerr�   ÚNodeTransformerr‘   r˜   rœ   r   r   r   r   r   Ú<module>   s€    X   ý            ô      ú
(
