o
    8ήcM/                     @   s   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 )    )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__ </tmp/pip-target-vg8gfxp4/lib/python/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r* 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valinty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   isigosig	cast_args	func_typer3   entry_point_resr    r'   r!   generate   s.   
z1make_dufunc_kernel.<locals>.DUFuncKernel.generate)__name__
__module____qualname____doc__r   r   rA   __classcell__r    r   _dufuncr   r!   r      s
    r   )numba.npr   _KernelrB   ufunc)rH   r   r    rG   r!   make_dufunc_kernel   s   $rM   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   )rM   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   )rJ   r   numpy_ufunc_kernelrO   r   rL   )r   r   r   sigr   r   r    r    r!   __call__>   s
   zDUFuncLowerer.__call__N)rB   rC   rD   rE   r   rS   r    r    r    r!   rN   7   s    rN   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 ).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   s6   t |r|j}tdd|d||}| || d S )Nnpyufunc)_targetcacher    )r   py_funcr   _initialize)r   r\   rU   r[   targetoptions
dispatcherr    r    r!   r   O   s   zDUFunc.__init__c                    sP   t |}tt| j||d |   t| | _|   |j	j
| _
|j	j| _d S )N)rU   )r   parse_identityr   rT   r   _install_typerN   	_lower_me_install_cgr\   rB   rE   )r   r_   rU   rI   r    r!   r]   W   s   


zDUFunc._initializec                 C   s&   t | jj }t| j| j| j|dS )4
        NOTE: part of ReduceMixin protocol
        )r_   rU   frozensiglist)list_dispatcher	overloadskeysdictrU   _frozen)r   rf   r    r    r!   _reduce_statesb   s   zDUFunc._reduce_statesc                 C   s<   t j| }||| |D ]}|| q|r|  |S )rd   )r   _DUFunc__new__r]   r8   disable_compile)clsr_   rU   re   rf   r   rR   r    r    r!   _rebuildn   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      | j jS r   )rh   r^   r'   r    r    r!   r^         zDUFunc.targetoptionsc                 C   rt   r   )rL   rW   r'   r    r    r!   rW      ru   z
DUFunc.ninc                 C   rt   r   )rL   rX   r'   r    r    r!   rX      ru   zDUFunc.noutc                 C   rt   r   )rL   nargsr'   r    r    r!   rv      ru   zDUFunc.nargsc                 C   rt   r   )rL   ntypesr'   r    r    r!   rw      ru   zDUFunc.ntypesc                 C   rt   r   )rL   r   r'   r    r    r!   r      ru   zDUFunc.typesc                 C   rt   r   )rL   rU   r'   r    r    r!   rU      ru   zDUFunc.identityc                 C   s   t | jjdks
J d| _dS )zI
        Disable the compilation of new signatures at call time.
        r   TN)r/   rh   ri   rl   r'   r    r    r!   rp      s   
zDUFunc.disable_compilec                 C   s   t |\}}| ||S )z=
        Compile the DUFunc for the given signature.
        )r   normalize_signature_compile_for_argtys)r   rR   r   r0   r    r    r!   r8      s   z
DUFunc.addc           	      O   s   | j j}|r&d|v r|d}||f7 }|r&tdddd t|D  t|}||ks8||| j j ks8J |r<J g }|d | D ]}t|}t	|t
jrT|j}nt|}|| qD| 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>)rL   rW   pop	TypeErrorjoinsortedr/   rX   r   
isinstancer   Arraydtyper   map_arrayscalar_typeappendry   tuple)	r   r   kwsrW   rz   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J |du r|}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)rl   RuntimeErrorr   r   r   _compile_element_wise_functionrh   r^   _finalize_ufunc_signature!_build_element_wise_ufunc_wrapper	_add_loopintrV   r   libraryrb   rP   )	r   r   r0   rR   r   
actual_sig	dtypenumsptrenvr    r    r!   ry      s&   


zDUFunc._compile_for_argtysc                 C   sB   |du 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()).
        NDUFuncTyping_)keygeneric)
rh   targetdescrtyping_contexttyperL   rB   r
   rk   _type_meinsert_user_function)r   	typingctx_ty_clsr    r    r!   ra      s   
zDUFunc._install_typec                 C   sj   | j rt| |}|du rdS t|j|j dt| }| jj	 D ]\}}|j
|kr2||f  S q#d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)rl   r   ufunc_find_matching_loopr   inputsoutputsr/   rh   ri   itemsr   )r   ewise_typeslooprR   r   r    r    r!   r      s   	
zDUFunc.find_ewise_functionc                 C   s  |rJ | j }tj|||}|\}}}}t|}	|	dkr)t|dt|  }
nt|}
| |
\}}|du rU| jrCtd| |f | 	|
 | |
\}}|dusUJ |	dkr^t
|}n|jdkrv|dkrqt|j||g}n	|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))rL   r	   Numpy_rules_ufunc_handle_inputsr/   r   r   rl   r   ry   rg   rX   r   r   r0   NotImplementedErrorextendr   )r   r   kwtysrL   _handle_inputs_result
base_typesexplicit_outputsndimslayoutexplicit_output_countr   rR   r   outtysr    r    r!   r     s8   




zDUFunc._type_mec                    sh   |du 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    )rb   )r#   rR   r'   r    r!   r(   @  s    z&DUFunc._install_cg.<locals>.<listcomp>)
rh   r   target_contextr   Anyr   rL   rW   rX   insert_func_defn)r   	targetctx_any_arrsig0sig1r    r'   r!   rc   0  s   
zDUFunc._install_cgr   )rB   rC   rD   rE   set_DUFunc__base_kwargsr   r]   rm   classmethodrr   rs   propertyr^   rW   rX   rv   rw   r   rU   rp   r8   r   ry   ra   r   r   rc   rF   r    r    rI   r!   rT   E   s>    









(rT   N)numbar   r   
numba.corer   r   r   r   numba.core.extendingr   numba.core.typingr	   numba.core.typing.templatesr
   r   numba.np.ufuncr   numba.parforsr   r   rJ   r   rM   objectrN   ReduceMixinrn   rT   	MAP_TYPESr   r    r    r    r!   <module>   s    + 