U
    ¿|eì/  ã                   @   sÆ   d dl Z d dl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mZ d dl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G dd„ dejejƒZej e¡ dS )é    N)ÚjitÚtypeof)ÚcgutilsÚtypesÚ	serializeÚsigutils)Ú	is_jitted)Únpydecl)ÚAbstractTemplateÚ	signature)Ú	_internal)Úarray_analysis)Úufuncbuilder)Únumpy_supportc                    s:   ddl m} G ‡ ‡fdd„d|jƒ‰ ˆ  jˆjj7  _ˆ S )Nr   ©Únpyimplc                       s.   e Zd ZdZ”Z‡‡ fdd„Zdd„ Z‡  ZS )z(make_dufunc_kernel.<locals>.DUFuncKernelzÉ
        npyimpl._Kernel subclass responsible for lowering a DUFunc kernel
        (element-wise function) inside a broadcast loop (which is
        generated by npyimpl.numpy_ufunc_kernel()).
        c                    s.   t ˆ | ƒ |||¡ | j |j¡\| _| _d S ©N)ÚsuperÚ__init__ÚdufuncÚfind_ewise_functionÚargsÚ	inner_sigÚcres)ÚselfÚcontextÚbuilderÚ	outer_sig)ÚDUFuncKernelÚ	__class__© úR/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/np/ufunc/dufunc.pyr      s    ÿz1make_dufunc_kernel.<locals>.DUFuncKernel.__init__c           
         sÆ   ˆ j }ˆ j}‡ fdd„t||j|jƒD ƒ}ˆ jjrTˆ jj t	j
t	j
gt|jƒ ¡}nˆ jj |j|j¡}ˆ jjjj}t ||ˆ jjj¡}|j d¡ ˆ jj ˆ j||j|j|¡\}}	ˆ  |	|j|j¡S )Nc                    s    g | ]\}}}ˆ   |||¡‘qS r    )Úcast)Ú.0ÚvalZintyZoutty©r   r    r!   Ú
<listcomp>!   s   ÿzEmake_dufunc_kernel.<locals>.DUFuncKernel.generate.<locals>.<listcomp>Úalwaysinline)r   r   Úzipr   r   Ú
objectmoder   Ú	call_convÚget_function_typer   ÚpyobjectÚlenÚreturn_typer   ÚblockÚfunctionÚmoduler   Úget_or_insert_functionÚfndescÚllvm_func_nameÚ
attributesÚaddÚcall_functionr"   )
r   r   ZisigZosigZ	cast_argsÚ	func_typer1   Úentry_pointÚ_Úresr    r%   r!   Úgenerate   s:    
þ ÿ ÿ þ   þz1make_dufunc_kernel.<locals>.DUFuncKernel.generate)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r<   Ú__classcell__r    ©r   Ú_dufunc©r   r!   r      s   r   )Únumba.npr   Z_Kernelr=   Úufunc)rC   r   r    rB   r!   Úmake_dufunc_kernel   s    $rG   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚDUFuncLowererzHCallable class responsible for lowering calls to a specific DUFunc.
    c                 C   s   t |ƒ| _g | _d S r   )rG   ÚkernelÚlibs)r   r   r    r    r!   r   <   s    
zDUFuncLowerer.__init__c                 C   s(   ddl m} | ||||| jjj| j¡S )Nr   r   )rE   r   Znumpy_ufunc_kernelrI   r   rF   )r   r   r   Úsigr   r   r    r    r!   Ú__call__@   s
    þzDUFuncLowerer.__call__N)r=   r>   r?   r@   r   rL   r    r    r    r!   rH   9   s   rH   c                       sî   e Zd ZdZedƒZddi fdd„Z‡ fdd„Zd	d
„ Ze	dd„ ƒZ
dd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd „ Zd!d"„ Zd-d#d$„Zd.d%d&„Zd'd(„ Zd)d*„ Zd/d+d,„Z‡  ZS )0ÚDUFuncz¹
    Dynamic universal function (DUFunc) intended to act like a normal
    Numpy ufunc, but capable of call-time (just-in-time) compilation
    of fast loops specialized to inputs.
    )ÚidentityÚ
_keepaliveÚninÚnoutNFc              	   C   sV   t |ƒr|j}t ¡ � tf d|dœ|—Ž|ƒ}W 5 Q R X |  ||¡ t | |¡ d S )NÚnpyufunc)Ú_targetÚcache)r   Úpy_funcr   Ú3_suppress_deprecation_warning_nopython_not_suppliedr   Ú_initializeÚ	functoolsÚupdate_wrapper)r   rU   rN   rT   ÚtargetoptionsÚ
dispatcherr    r    r!   r   Q   s    
ÿþþzDUFunc.__init__c                    sP   t  |¡}tt| ƒj||d� |  ¡  t| ƒ| _|  ¡  |j	j
| _
|j	j| _d S )N)rN   )r   Úparse_identityr   rM   r   Ú_install_typerH   Ú	_lower_meÚ_install_cgrU   r=   r@   )r   r[   rN   rD   r    r!   rW   [   s    


zDUFunc._initializec                 C   s&   t | jj ¡ ƒ}t| j| j| j|d�S )ú4
        NOTE: part of ReduceMixin protocol
        )r[   rN   ÚfrozenÚsiglist)ÚlistÚ_dispatcherÚ	overloadsÚkeysÚdictrN   Ú_frozen)r   rb   r    r    r!   Ú_reduce_statesf   s    üzDUFunc._reduce_statesc                 C   s<   t j | ¡}| ||¡ |D ]}| |¡ q|r8| ¡  |S )r`   )r   Ú_DUFuncÚ__new__rW   r6   Údisable_compile)Úclsr[   rN   ra   rb   r   rK   r    r    r!   Ú_rebuildr   s    zDUFunc._rebuildc                 C   s   | S )zK
        For compatibility with the various *UFuncBuilder classes.
        r    r%   r    r    r!   Úbuild_ufunc€   s    zDUFunc.build_ufuncc                 C   s   | j jS r   )rd   rZ   r%   r    r    r!   rZ   †   s    zDUFunc.targetoptionsc                 C   s   | j jS r   )rF   rP   r%   r    r    r!   rP   Š   s    z
DUFunc.ninc                 C   s   | j jS r   )rF   rQ   r%   r    r    r!   rQ   Ž   s    zDUFunc.noutc                 C   s   | j jS r   )rF   Únargsr%   r    r    r!   rp   ’   s    zDUFunc.nargsc                 C   s   | j jS r   )rF   Úntypesr%   r    r    r!   rq   –   s    zDUFunc.ntypesc                 C   s   | j jS r   )rF   r   r%   r    r    r!   r   š   s    zDUFunc.typesc                 C   s   | j jS r   )rF   rN   r%   r    r    r!   rN   ž   s    zDUFunc.identityc                 C   s   t | jjƒdkst‚d| _dS )zI
        Disable the compilation of new signatures at call time.
        r   TN)r-   rd   re   ÚAssertionErrorrh   r%   r    r    r!   rl   ¢   s    zDUFunc.disable_compilec                 C   s   t  |¡\}}|  ||¡S )z=
        Compile the DUFunc for the given signature.
        )r   Únormalize_signatureÚ_compile_for_argtys)r   rK   r   r.   r    r    r!   r6   ª   s    z
DUFunc.addc           	      O   sÌ   | j j}|rLd|kr(| d¡}||f7 }|rLtdd dd„ t|ƒD ƒ¡ ƒ‚t|ƒ}||ksp||| j j kspt‚|rxt‚g }|d |… D ]4}t	|ƒ}t
|tjƒr¨|j}n
t |¡}| |¡ qˆ|  t|ƒ¡S )NÚoutz)unexpected keyword arguments to ufunc: %sz, c                 s   s   | ]}t |ƒV  qd S r   )Úrepr)r#   Úkr    r    r!   Ú	<genexpr>¹   s     z+DUFunc._compile_for_args.<locals>.<genexpr>)rF   rP   ÚpopÚ	TypeErrorÚjoinÚsortedr-   rQ   rr   r   Ú
isinstancer   ÚArrayÚdtyper   Úmap_arrayscalar_typeÚappendrt   Útuple)	r   r   ÚkwsrP   ru   Zargs_lenÚargtysÚargÚargtyr    r    r!   Ú_compile_for_args±   s(    

ÿ

zDUFunc._compile_for_argsc           	      C   s¨   | j rtd| f ƒ‚t|tƒs"t‚|dkr0|}n||Ž }t | j| j|¡\}}}t 	|||¡}t 
||¡\}}}|  t|ƒ|¡ | j ||j|f¡ | jj |j¡ |S )a/  
        Given a tuple of argument types (these should be the array
        dtypes, and not the array types themselves), compile the
        element-wise function for those inputs, generate a UFunc loop
        wrapper, and register the loop with the Numpy ufunc object for
        this DUFunc.
        zcompilation disabled for %sN)rh   ÚRuntimeErrorr}   r‚   rr   r   Ú_compile_element_wise_functionrd   rZ   Ú_finalize_ufunc_signatureÚ!_build_element_wise_ufunc_wrapperÚ	_add_loopÚintrO   r�   Úlibraryr^   rJ   )	r   r„   r.   rK   r   Z
actual_sigÚ	dtypenumsÚptrÚenvr    r    r!   rt   Ð   s0      ÿ
  ÿ ÿ
zDUFunc._compile_for_argtysc                 C   sB   |dkr| j jj}td| jj tft| | jd�ƒ}| 	| |¡ dS )a*  Constructs and installs a typing class for a DUFunc object in the
        input typing context.  If no typing context is given, then
        _install_type() installs into the typing context of the
        dispatcher object (should be same default context used by
        jit() and njit()).
        NZDUFuncTyping_)ÚkeyÚgeneric)
rd   ÚtargetdescrÚtyping_contextÚtyperF   r=   r
   rg   Ú_type_meÚinsert_user_function)r   Ú	typingctxÚ_ty_clsr    r    r!   r]   ê   s    
þzDUFunc._install_typec                 C   sj   | j r:t | |¡}|dkrdS t|j|j ƒdt|ƒ… }| jj 	¡ D ]\}}|j
|krF||f  S qFdS )a  
        Given a tuple of element-wise argument types, find a matching
        signature in the dispatcher.

        Return a 2-tuple containing the matching signature, and
        compilation result.  Will return two None's if no matching
        signature was found.
        N)NN)rh   r   Úufunc_find_matching_loopr‚   ÚinputsÚoutputsr-   rd   re   Úitemsr   )r   Úewise_typesÚlooprK   r   r    r    r!   r   ø   s    	
zDUFunc.find_ewise_functionc                 C   s  |rt ‚| j}tj |||¡}|\}}}}t|ƒ}	|	dkrRt|dt|ƒ … ƒ}
nt|ƒ}
|  |
¡\}}|dkrª| jr†t	d| |f ƒ‚|  
|
¡ |  |
¡\}}|dk	sªt ‚|	dkr¼t|ƒ}n8|jdkrì|dkrât |j||¡g}qô|jg}ntdƒ‚| |¡ t|Ž S )zì
        Implement AbstractTemplate.generic() for the typing class
        built by DUFunc._install_type().

        Return the call-site signature after either validating the
        element-wise signature or compiling for it.
        r   Nzcannot call %s with types %sé   ztyping gufuncs (nout > 1))rr   rF   r	   ÚNumpy_rules_ufuncÚ_handle_inputsr-   r‚   r   rh   rz   rt   rc   rQ   r   r~   r.   ÚNotImplementedErrorÚextendr   )r   r„   ÚkwtysrF   Z_handle_inputs_resultÚ
base_typesÚexplicit_outputsÚndimsÚlayoutZexplicit_output_countrŸ   rK   r   Zouttysr    r    r!   r—     s<      ÿÿ




zDUFunc._type_mec                    sh   |dkrˆ j jj}tj}tj}|fˆ jj |fˆ jj  }|fˆ jj }| 	‡ fdd„||fD ƒ¡ dS )a-  
        Install an implementation function for a DUFunc object in the
        given target context.  If no target context is given, then
        _install_cg() installs into the target context of the
        dispatcher object (should be same default context used by
        jit() and njit()).
        Nc                    s   g | ]}ˆ j ˆ |f‘qS r    )r^   )r#   rK   r%   r    r!   r&   D  s     z&DUFunc._install_cg.<locals>.<listcomp>)
rd   r”   Útarget_contextr   ÚAnyr~   rF   rP   rQ   Úinsert_func_defn)r   Ú	targetctxÚ_anyÚ_arrZsig0Zsig1r    r%   r!   r_   4  s    
ÿzDUFunc._install_cg)N)N)N)r=   r>   r?   r@   ÚsetZ_DUFunc__base_kwargsr   rW   ri   Úclassmethodrn   ro   ÚpropertyrZ   rP   rQ   rp   rq   r   rN   rl   r6   r‡   rt   r]   r   r—   r_   rA   r    r    rD   r!   rM   G   s<   










(rM   )rX   Únumbar   r   Ú
numba.corer   r   r   r   Únumba.core.extendingr   Únumba.core.typingr	   Únumba.core.typing.templatesr
   r   Únumba.np.ufuncr   Únumba.parforsr   r   rE   r   rG   ÚobjectrH   ÚReduceMixinrj   rM   Ú	MAP_TYPESr�   r    r    r    r!   Ú<module>   s   +  