U
    9%e82                     @   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__ T/var/www/html/Darija-Ai-API/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>Zalwaysinline)r   r   zipr   r   Z
objectmoder   Z	call_convZget_function_typer   Zpyobjectlenreturn_typer   blockfunctionmoduler   Zget_or_insert_functionZfndescZllvm_func_name
attributesaddZcall_functionr"   )
r   r   ZisigZosigZ	cast_argsZ	func_typer,   entry_point_resr    r%   r!   generate   s:    
      z1make_dufunc_kernel.<locals>.DUFuncKernel.generate)__name__
__module____qualname____doc__r   r   r2   __classcell__r    r   _dufuncr   r!   r      s   r   )numba.npr   Z_Kernelr3   ufunc)r9   r   r    r8   r!   make_dufunc_kernel   s    $r=   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   )r=   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   )r;   r   Znumpy_ufunc_kernelr?   r   r<   )r   r   r   sigr   r   r    r    r!   __call__@   s
    zDUFuncLowerer.__call__N)r3   r4   r5   r6   r   rB   r    r    r    r!   r>   9   s   r>   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 fd!d"Zd#d$ Zd/d%d&Zd0d'd(Zd)d* Zd+d, Zd1d-d.Z  ZS )2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 )NZnpyufunc)_targetcache)r   py_funcr   Z3_suppress_deprecation_warning_nopython_not_suppliedr   _initialize	functoolsupdate_wrapper)r   rJ   rD   rI   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)rD   )r   Zparse_identityr   rC   r   _install_typer>   	_lower_me_install_cgrJ   r3   r6   )r   rO   rD   r:   r    r!   rK   [   s    


zDUFunc._initializec                 C   s&   t | jj }t| j| j| j|dS )4
        NOTE: part of ReduceMixin protocol
        )rO   rD   frozensiglist)list_dispatcher	overloadskeysdictrD   _frozen)r   rU   r    r    r!   _reduce_statesf   s    zDUFunc._reduce_statesc                 C   s<   t j| }||| |D ]}|| q|r8|  |S )rS   )r   _DUFunc__new__rK   r.   disable_compile)clsrO   rD   rT   rU   r   rA   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   )rW   rN   r%   r    r    r!   rN      s    zDUFunc.targetoptionsc                 C   s   | j jS r   )r<   rF   r%   r    r    r!   rF      s    z
DUFunc.ninc                 C   s   | j jS r   )r<   rG   r%   r    r    r!   rG      s    zDUFunc.noutc                 C   s   | j jS r   )r<   nargsr%   r    r    r!   rc      s    zDUFunc.nargsc                 C   s   | j jS r   )r<   ntypesr%   r    r    r!   rd      s    zDUFunc.ntypesc                 C   s   | j jS r   )r<   r   r%   r    r    r!   r      s    zDUFunc.typesc                 C   s   | j jS r   )r<   rD   r%   r    r    r!   rD      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(   rW   rX   AssertionErrorr[   r%   r    r    r!   r_      s    zDUFunc.disable_compilec                 C   s   t |\}}| ||S )z=
        Compile the DUFunc for the given signature.
        )r   Znormalize_signature_compile_for_argtys)r   rA   r   r)   r    r    r!   r.      s    z
DUFunc.addc                    sf   t jjj}|t|  D ]<}tt|d||k	r|j| df||}|tk	r|  S qt	 j
||S )z}
        Allow any argument that has overridden __array_ufunc__ (NEP-18)
        to take control of DUFunc.__call__.
        __array_ufunc__rB   N)r   npZndarrayrg   tuplevaluesgetattrtypeNotImplementedr   rB   )r   r   kwsdefaultargoutputr:   r    r!   rB      s    

zDUFunc.__call__c           	      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>)r<   rF   pop	TypeErrorjoinsortedr(   rG   re   r   
isinstancer   ArrayZdtyper   Zmap_arrayscalar_typeappendrf   ri   )	r   r   rn   rF   rr   Zargs_lenargtysrp   Z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)r[   RuntimeErrorrz   ri   re   r   Z_compile_element_wise_functionrW   rN   Z_finalize_ufunc_signatureZ!_build_element_wise_ufunc_wrapperZ	_add_loopintrE   r|   ZlibraryrQ   r@   )	r   r}   r)   rA   r   Z
actual_sigZ	dtypenumsZptrenvr    r    r!   rf      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_)keyZgeneric)
rW   targetdescrZtyping_contextrl   r<   r3   r
   rZ   _type_meZinsert_user_function)r   Z	typingctxZ_ty_clsr    r    r!   rP      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)r[   r   Zufunc_find_matching_loopri   inputsoutputsr(   rW   rX   itemsr   )r   ewise_typeslooprA   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rt	d| |f | 
|
 | |
\}}|dk	st |	dkrt|}n8|jdkr|dkrt|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))re   r<   r	   ZNumpy_rules_ufuncZ_handle_inputsr(   ri   r   r[   rw   rf   rV   rG   r   r{   r)   NotImplementedErrorextendr   )r   r}   Zkwtysr<   Z_handle_inputs_resultZ
base_typesZexplicit_outputsZndimsZlayoutZexplicit_output_countr   rA   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    )rQ   )r#   rA   r%   r    r!   r&   S  s     z&DUFunc._install_cg.<locals>.<listcomp>)
rW   r   Ztarget_contextr   Anyr{   r<   rF   rG   Zinsert_func_defn)r   Z	targetctxZ_anyZ_arrZsig0Zsig1r    r%   r!   rR   C  s    
zDUFunc._install_cg)N)N)N)r3   r4   r5   r6   setZ_DUFunc__base_kwargsr   rK   r\   classmethodra   rb   propertyrN   rF   rG   rc   rd   r   rD   r_   r.   rB   r~   rf   rP   r   r   rR   r7   r    r    r:   r!   rC   G   s>   










(rC   )rL   Znumbar   r   Z
numba.corer   r   r   r   Znumba.core.extendingr   Znumba.core.typingr	   Znumba.core.typing.templatesr
   r   Znumba.np.ufuncr   Znumba.parforsr   r   r;   r   r=   objectr>   ZReduceMixinr]   rC   Z	MAP_TYPESr|   r    r    r    r!   <module>   s   +  