
    J/Ph1                         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 Z G d de
          Z G d dej        e	          Zd Zd
S )    )typeof)types)GUFuncBuilder)parse_signature)	UfuncBaseUfuncLowererBase)ufunc_find_matching_loop)	serializeerrors)npydecl)	signatureAbstractTemplateNc                 h     ddl m}  G  fdd|j                  }|xj         j        z  c_        |S )Nr   npyimplc                   <     e Zd ZdZZ fdZ fdZ fdZ xZS )(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                     t                                          |||           | j                            |j                  }| j                            |          \  | _        | _        d S N)super__init__dufunc_get_ewise_dtypesargsfind_ewise_function	inner_sigcres)selfcontextbuilder	outer_sigewise_types	__class__s        U/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/numba/np/ufunc/gufunc.pyr   z1make_gufunc_kernel.<locals>.GUFuncKernel.__init__   s]    GGWgy999+77	GGK(,(G(G) )%DNDIII    c                    t          |t          j                  rBt          |t          j                  s(t                                          ||j        |          S t                                          |||          S r   )
isinstancer   Arrayr   castdtype)r   valfromtytotyr#   s       r$   r)   z-make_gufunc_kernel.<locals>.GUFuncKernel.cast   sa    &%+.. =tU[11=ww||Ct<<<77<<VT222r%   c                     | j         j        rd}t          j        |          | j                            | j         j        f            t                      j        | S )NzCCalling a guvectorize function in object mode is not supported yet.)	r   
objectmoder   NumbaRuntimeErrorr   add_linking_libslibraryr   generate)r   r   msgr#   s      r$   r3   z1make_gufunc_kernel.<locals>.GUFuncKernel.generate%   sZ    y# 4(.s333L))49+<*>???#577#T**r%   )	__name__
__module____qualname____doc__r   r   r)   r3   __classcell__)r#   _dufuncs   @r$   GUFuncKernelr      s|        	 	
 	 	 	 	 		3 	3 	3 	3 	3	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+r%   r;   )numba.npr   _Kernelr5   )r:   r   r;   s   `  r$   make_gufunc_kernelr>      sj          + + + + + + +w + + +: W--r%   c                   "     e Zd ZdZ fdZ xZS )GUFuncLowererzHCallable class responsible for lowering calls to a specific gufunc.
    c                 n    ddl m} t                                          |t          |j                   d S )Nr   r   )r<   r   r   r   r>   numpy_gufunc_kernel)r   gufuncr   r#   s      r$   r   zGUFuncLowerer.__init__4   sF    $$$$$$+ 4	6 	6 	6 	6 	6r%   )r5   r6   r7   r8   r   r9   )r#   s   @r$   r@   r@   1   sB         6 6 6 6 6 6 6 6 6r%   r@   c                       e Zd ZdZdddi dfdZd Zd Zed             Zd	 Z	dd
Z
d Zd Zd Zd ZddZd Zed             Zd Zd Zd Z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.
    NF c                 H   d | _         d| _        || _        || _        t	          ||||||          | _        | j        j        j        | _        | j        j        j        | _        | j        j	        | _
        |                     | j
                   t          j        | |           d S )NF)ufunc_frozen_is_dynamic	_identityr   gufunc_builderpy_funcr5   r8   nb_func_dispatcher_initialize	functoolsupdate_wrapper)r   rM   r   identitycache
is_dynamictargetoptionswritable_argss           r$   r   zGUFunc.__init__C   s    
%!
 ,Y%O O +3<*2:.6)*** w/////r%   c                     |                                   |                                  t          |           | _        |                                  d S r   )build_ufunc_install_typer@   	_lower_me_install_cg)r   
dispatchers     r$   rP   zGUFunc._initializeV   sM    &t,,r%   c                     | j         }t          |j        |j        | j        |j        | j        |j        |j        |j	        | j
        	  	        }|S )N)	rM   r   rS   rT   rU   rV   rW   typesigsfrozen)rL   dictrM   r   rK   rT   rJ   rV   rW   _sigsrI   )r   gbdcts      r$   _reduce_stateszGUFunc._reduce_states\   sU     Jl^('**X<

 

 

 
r%   c
           	           | |||||||          }
|D ]}|
                     |           |
                                 |	|
_        |
S )N)rM   r   rS   rT   rU   rV   rW   )addrY   rI   )clsrM   r   rS   rT   rU   rV   rW   r_   r`   r   sigs               r$   _rebuildzGUFunc._rebuildk   sm     s7i(:!.mM M M  	 	CHHSMMMMr%   c                     d| j          dS )Nz<numba._GUFunc 'z'>)r5   r   s    r$   __repr__zGUFunc.__repr__w   s    3$-3333r%   c                     || j         j        j        }t          d| j        z   t
          ft          | | j                            }|                    | |           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()).
        NGUFuncTyping_)keygeneric)	rO   targetdescrtyping_contexttyper5   r   ra   _type_meinsert_user_function)r   	typingctx_ty_clss      r$   rZ   zGUFunc._install_typez   sf     (4CI6(*dm<<<> > 	&&tW55555r%   c                 :    | j                             |           d S r   )rL   rg   )r   ftys     r$   rg   z
GUFunc.add   s    $$$$$r%   c                 B    | j                                         | _        | S r   )rL   rY   rH   rl   s    r$   rY   zGUFunc.build_ufunc   s    (4466
r%   c                     t          | j        j                  }t          t	          t
          |d                             t          t	          t
          |d                             fS Nr      )r   rL   r   tuplemaplen)r   
parsed_sigs     r$   expected_ndimszGUFunc.expected_ndims   sL    $T%8%BCC
c#z!}--..c#z!}6M6M0N0NOOr%   c                    |rJ | j         }| j        j        }|                                 \  }}||z   }t	          |          sJ t	          |                      t          |          D ]\  }}	t          |	t          j                  r|	j	        ||         k     rv|t	          |          k     rdnd}
|t	          |          k     r|n|t	          |          z
  }| j
         d|
 d| d|	j	         d| d||          d}t          j        |          t          j                            |||          }|\  }}}}|                     |          \  }}|{| j        rd
|  d| }t          j        |          |                     |           |                     |          \  }}|dk    r!d| j
         d| }t          j        |          |J 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.
        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 )rH   rL   r   r   r   	enumerater'   r   r(   ndimr5   r   TypingErrorr   Numpy_rules_ufunc_handle_inputsr   rI   _compile_for_argtysnone)r   argtyskwsrH   ri   	inp_ndims	out_ndimsndimsidxargkindir4   _handle_inputs_resultr"   _s                   r$   ru   zGUFunc._type_me   sH    
!+#2244	9I%6{{&&CJJ&&&!&)) 	. 	.HC#u{++ .5:0E0E"%I"6"6wwHY//CCS3y>>5I} > > > >q > >.1h> >!$> >05c
> > >  (--- ' 9 H H63!  ! 4Q1))+66Q; | .?T??v??(---$$[111--k::FCl""LLLFLL(---???-f----r%   c                 N     | j         | }| j                            |           d S r   )_get_function_typerL   rg   )r   r   return_typefntys       r$   r   zGUFunc._compile_for_argtys   s0     't&/%%%%%r%   c                 v    |                      |j                  }t          |          t          |          k    S r   )r   r   r   )r   r"   ri   dtypess       r$   match_signaturezGUFunc.match_signature   s0    ''11V}}k 2 222r%   c                     | j         S r   )rJ   rl   s    r$   rU   zGUFunc.is_dynamic   s    r%   c                     t          d |          }g }|D ]L}t          |t          j                  r|                    |j                   7|                    |           M|S )Nc                 X    t          | t          j                  r| nt          |           S r   )r'   r   Typer   )r   s    r$   <lambda>z*GUFunc._get_ewise_dtypes.<locals>.<lambda>   s'    
3
(C(C "!C[[ r%   )r   r'   r   r(   appendr*   )r   r   r   tysargtys        r$   r   zGUFunc._get_ewise_dtypes   sw     ! !"&( ( 	" 	"E%-- "

5;''''

5!!!!
r%   c                     t          | j        j                  }t          |          t          |d                   t          |d                   z   k    S r}   )r   rL   r   r   )r   r   r   s      r$   _num_args_matchzGUFunc._num_args_match   sC    $T%8%BCC
4yyC
1..Z]1C1CCCCr%   c                 ^   t          | j        j                  }|                     |          }g }t	          |d                   D ]e\  }}t          |          }|dk    r|                    ||                    6|                    t          j        ||         |d                     ft          |d                   }t	          |d                   D ]J\  }}|||z            }	t          |          pd}
|                    t          j        |	|
d                     Kt          j	        | S )Nr   Ar~   )
r   rL   r   r   r   r   r   r   r(   r   )r   r   r   r"   lr   sig_dimr   offsetrettyret_ndims              r$   r   zGUFunc._get_function_type   s#   $T%8%BCC
,,T22 %jm44 	C 	CLCw<<DqyyS)****[%5tSAABBBBZ]##%jm44 	8 	8LCf-E7||(qHHHU[#667777z1~r%   c                 0   | j         s| j        s<|r-t          |d                   r |d         j        | dg|R i |S  | j        |i |S d|v r||                    d          fz  } | j        | du rd| j         d}t          |          | 	                    |          }| j        rt          | j        |          sL|                     |          dk    s | 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   )rI   rU   _is_array_wrapper__array_ufunc__rH   popr   r5   	TypeErrorr   r	   r   r   rg   rY   )r   r   kwargsr4   ewiseri   s         r$   r   zGUFunc.__call__   s    < 	)t 	)
  3)$q'22 3.tAw.*'+  /5   "tz426222f__VZZ&&((D4&%//
4=    
 C..  &&t,,
 	7
EJJ 	 ++E22lBB-d-t4tz4*6***r%   r   )r5   r6   r7   r8   r   rP   re   classmethodrj   rm   rZ   rg   rY   r   ru   r   r   propertyrU   r   r   r   r   rF   r%   r$   rE   rE   ;   sY         59!20 0 0 0&     	 	 [	4 4 46 6 6 6% % %  P P P-. -. -.^& & & &3 3 3     X 	 	 	D D D  0(+ (+ (+ (+ (+r%   rE   c                 n    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.
    __dask_graph__r   )r'   rt   hasattr)objs    r$   r   r   #  s?    : sD!!! 	,C)**	,C*++r%   )numbar   
numba.corer   numba.np.ufunc.ufuncbuilderr   numba.np.ufunc.sigparser   numba.np.ufunc.ufunc_baser   r   numba.np.numpy_supportr	   r
   r   numba.core.typingr   numba.core.typing.templatesr   r   rQ   r>   r@   ReduceMixinrE   r   rF   r%   r$   <module>r      sQ               5 5 5 5 5 5 3 3 3 3 3 3 A A A A A A A A ; ; ; ; ; ; ( ( ( ( ( ( ( ( % % % % % % C C C C C C C C    ! ! !H6 6 6 6 6$ 6 6 6e+ e+ e+ e+ e+Y"I e+ e+ e+P         r%   