o
    0 i1                     @   s   d dl mZ d dl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mZ d dlmZ d d	lmZmZ d d
lZdd ZG dd de
ZG dd deje	Zdd Zd
S )    )typeof)types)GUFuncBuilder)parse_signature)	UfuncBaseUfuncLowererBase)ufunc_find_matching_loop)	serializeerrors)npydecl)	signatureAbstractTemplateNc                    s6   ddl m} G  fddd|j}| j j7  _|S )Nr   npyimplc                       s<   e Zd ZdZZ fddZ fddZ fddZ  ZS )z(make_gufunc_kernel.<locals>.GUFuncKernelz
        npyimpl._Kernel subclass responsible for lowering a gufunc kernel
        (element-wise function) inside a broadcast loop (which is
        generated by npyimpl.numpy_gufunc_kernel()).
        c                    s6   t  ||| | j|j}| j|\| _| _d S N)super__init__dufunc_get_ewise_dtypesargsfind_ewise_functionZ	inner_sigcres)selfcontextbuilderZ	outer_sigewise_types	__class__ a/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/numba/np/ufunc/gufunc.pyr      s
   z1make_gufunc_kernel.<locals>.GUFuncKernel.__init__c                    s:   t |tjrt |tjst ||j|S t |||S r   )
isinstancer   Arrayr   castdtype)r   valZfromtyZtotyr   r   r   r"      s
   
z-make_gufunc_kernel.<locals>.GUFuncKernel.castc                    s4   | j jrd}t|| j| j jf t j| S )NzCCalling a guvectorize function in object mode is not supported yet.)	r   Z
objectmoder
   ZNumbaRuntimeErrorr   Zadd_linking_libsZlibraryr   generate)r   r   msgr   r   r   r%   %   s
   
z1make_gufunc_kernel.<locals>.GUFuncKernel.generate)	__name__
__module____qualname____doc__r   r   r"   r%   __classcell__r   _dufuncr   r   GUFuncKernel   s    r.   )numba.npr   Z_Kernelr'   )r-   r   r.   r   r,   r   make_gufunc_kernel   s   r0   c                       s    e Zd ZdZ fddZ  ZS )GUFuncLowererzHCallable class responsible for lowering calls to a specific gufunc.
    c                    s"   ddl m} t |t|j d S )Nr   r   )r/   r   r   r   r0   Znumpy_gufunc_kernel)r   Zgufuncr   r   r   r   r   4   s
   zGUFuncLowerer.__init__)r'   r(   r)   r*   r   r+   r   r   r   r   r1   1   s    r1   c                   @   s   e Zd ZdZdddi dfddZdd Zd	d
 Zedd Zdd Z	d'ddZ
dd Zdd Zdd Zdd Zd'ddZdd Zedd Zdd  Zd!d" Zd#d$ Zd%d& ZdS )(GUFuncz
    Dynamic generalized universal function (GUFunc)
    intended to act like a normal Numpy gufunc, but capable
    of call-time (just-in-time) compilation of fast loops
    specialized to inputs.
    NFr   c                 C   sj   d | _ d| _|| _|| _t||||||| _| jjj| _| jjj| _| jj	| _
| | j
 t| | d S )NF)ufunc_frozen_is_dynamic	_identityr   gufunc_builderpy_funcr'   r*   Znb_func_dispatcher_initialize	functoolsupdate_wrapper)r   r8   r   identitycache
is_dynamictargetoptionswritable_argsr   r   r   r   C   s   
zGUFunc.__init__c                 C   s&   |    |   t| | _|   d S r   )build_ufunc_install_typer1   Z	_lower_meZ_install_cg)r   
dispatcherr   r   r   r:   V   s   
zGUFunc._initializec                 C   s6   | j }t|j|j| j|j| j|j|j|j	| j
d	}|S )N)	r8   r   r=   r>   r?   r@   rA   typesigsfrozen)r7   dictr8   r   r6   r>   r5   r@   rA   Z_sigsr4   )r   gbdctr   r   r   _reduce_states\   s   zGUFunc._reduce_statesc
              	   C   s<   | |||||||d}
|D ]}|
 | q|
  |	|
_|
S )N)r8   r   r=   r>   r?   r@   rA   )addrB   r4   )clsr8   r   r=   r>   r?   r@   rA   rE   rF   r   sigr   r   r   _rebuildk   s   zGUFunc._rebuildc                 C   s   d| j  dS )Nz<numba._GUFunc 'z'>)r'   r   r   r   r   __repr__w   s   zGUFunc.__repr__c                 C   s@   |du r	| j jj}td| j tft| | jd}|| | dS )a*  Constructs and installs a typing class for a gufunc 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GUFuncTyping_)keyZgeneric)	r9   ZtargetdescrZtyping_contexttyper'   r   rG   _type_meZinsert_user_function)r   Z	typingctxZ_ty_clsr   r   r   rC   z   s   

zGUFunc._install_typec                 C   s   | j | d S r   )r7   rK   )r   Zftyr   r   r   rK      s   z
GUFunc.addc                 C   s   | j  | _| S r   )r7   rB   r3   rO   r   r   r   rB      s   zGUFunc.build_ufuncc                 C   s0   t | jj}ttt|d ttt|d fS Nr      )r   r7   r   tuplemaplen)r   
parsed_sigr   r   r   expected_ndims   s   $zGUFunc.expected_ndimsc                 C   s  |rJ | j }| jj}|  \}}|| }t|sJ t|t|D ]F\}}	t|	tjri|	j	|| k ri|t|k r<dnd}
|t|k rF|n|t| }| j
 d|
 d| d|	j	 d| d||  d}t|q#tj|||}|\}}}}| |\}}|d	u r| jrd
|  d| }t|| | | |\}}|dkrd| j
 d| }t||d	usJ ttjg|R  S )z
        Implement AbstractTemplate.generic() for the typing class
        built by gufunc._install_type().

        Return the call-site signature after either validating the
        element-wise signature or compiling for it.
        ZInputOutputz: z	 operand z& does not have enough dimensions (has z, gufunc core with signature z
 requires )Nzcannot call z with types NNzFail to compile )r3   r7   r   rZ   rX   	enumerater    r   r!   ndimr'   r
   ZTypingErrorr   ZNumpy_rules_ufuncZ_handle_inputsr   r4   _compile_for_argtysnone)r   argtyskwsr3   rM   Z	inp_ndimsZ	out_ndimsZndimsidxargkindir&   Z_handle_inputs_resultr   _r   r   r   rS      sH   



zGUFunc._type_mec                 C   s   | j | }| j| d S r   )_get_function_typer7   rK   )r   rb   return_typeZfntyr   r   r   r`      s   
zGUFunc._compile_for_argtysc                 C   s   |  |j}t|t|kS r   )r   r   rV   )r   r   rM   Zdtypesr   r   r   match_signature   s   zGUFunc.match_signaturec                 C   s   | j S r   )r5   rO   r   r   r   r?      s   zGUFunc.is_dynamicc                 C   sD   t dd |}g }|D ]}t|tjr||j q|| q|S )Nc                 S   s   t | tjr| S t| S r   )r    r   Typer   )re   r   r   r   <lambda>   s    z*GUFunc._get_ewise_dtypes.<locals>.<lambda>)rW   r    r   r!   appendr#   )r   r   rb   ZtysZargtyr   r   r   r      s   zGUFunc._get_ewise_dtypesc                 G   s,   t | jj}t|t|d t|d  kS rT   )r   r7   r   rX   )r   r   rY   r   r   r   _num_args_match   s    zGUFunc._num_args_matchc                 G   s   t | jj}| |}g }t|d D ] \}}t|}|dkr'|||  q|t|| |d qt|d }t|d D ]\}}|||  }	t|pOd}
|t|	|
d q@tj	| S )Nr   ArU   )
r   r7   r   r   r^   rX   rn   r   r!   ra   )r   r   rY   r   lrd   Zsig_dimr_   offsetZrettyZret_ndimr   r   r   ri      s   

zGUFunc._get_function_typec                 O   s   | j s| js%|rt|d r|d j| dg|R i |S | j|i |S d|v r1||df7 }| j| du rCd| j d}t|| 	|}| jrQt
| j|sf| |dksb| j| }| | |   | j|i |S )Nr   __call__outFz Too few arguments for function 'z'. Note that the pattern `out = gufunc(Arg1, Arg2, ..., ArgN)` is not allowed. Use `gufunc(Arg1, Arg2, ..., ArgN, out) instead.r]   )r4   r?   _is_array_wrapper__array_ufunc__r3   popro   r'   	TypeErrorr   r   r   ri   rK   rB   )r   r   kwargsr&   ZewiserM   r   r   r   rs      s.   


zGUFunc.__call__r   )r'   r(   r)   r*   r   r:   rJ   classmethodrN   rP   rC   rK   rB   rZ   rS   r`   rk   propertyr?   r   ro   ri   rs   r   r   r   r   r2   ;   s.    



/
r2   c                 C   s    t | t ot| dot| dS )ad  Return True if obj wraps around numpy or another numpy-like library
    and is likely going to apply the ufunc to the wrapped array; False
    otherwise.

    At the moment, this returns True for

    - dask.array.Array
    - dask.dataframe.DataFrame
    - dask.dataframe.Series
    - xarray.DataArray
    - xarray.Dataset
    - xarray.Variable
    - pint.Quantity
    - other potential wrappers around dask array or dask dataframe

    We may need to add other libraries that pickle ufuncs from their
    __array_ufunc__ method in the future.

    Note that the below test is a lot more naive than
    `dask.base.is_dask_collection`
    (https://github.com/dask/dask/blob/5949e54bc04158d215814586a44d51e0eb4a964d/dask/base.py#L209-L249),  # noqa: E501
    because it doesn't need to find out if we're actually dealing with
    a dask collection, only that we're dealing with a wrapper.
    Namely, it will return True for a pint.Quantity wrapping around a plain float, a
    numpy.ndarray, or a dask.array.Array, and it's OK because in all cases
    Quantity.__array_ufunc__ is going to forward the ufunc call inwards.
    Z__dask_graph__rv   )r    rR   hasattr)objr   r   r   ru   #  s
   ru   )Znumbar   Z
numba.corer   Znumba.np.ufunc.ufuncbuilderr   Znumba.np.ufunc.sigparser   Znumba.np.ufunc.ufunc_baser   r   Znumba.np.numpy_supportr   r	   r
   Znumba.core.typingr   Znumba.core.typing.templatesr   r   r;   r0   r1   ZReduceMixinr2   ru   r   r   r   r   <module>   s    $
 i