U
    /e9-                     @   s  d dl Z d dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZ eeejfej eeejfej eeejfej e	eejfej e	ejjejj eeejfe eejje eejd3d	d
Z eejjd4ddZ!eejjd5ddZ"e#de#de
#de#ddd Z$e#de#ddd Z%e#de#de
#de#ddd Z&e#de#ddd Z'dd Z(eejjdd Z)eeejfd d! Z*d"d# Z+e,d$d%d&Z-e
eejfd'd( Z.d)d* Z/G d+d, d,eZ0G d-d. d.e0Z1ed/d0e0d1d2Z2e23d0e1  dS )6    N)chunk)concatenate_lookupdivide_lookupeinsum_lookupempty_lookupnannumel_lookupnumel_lookuppercentile_lookuptensordot_lookup)divide)	ma_divide_percentile)CreationDispatchDaskBackendEntrypointlinearc                 C   s   t | ||S Nr   )aqmethod r   7/tmp/pip-unpacked-wheel-dbjnr7gq/dask/array/backends.py
percentile   s    r   c                 C   s`   t jj| |d}dd | D }tdd |D r8td|r\t |}t|dkr\|d |_|S )	N)axisc                 S   s   g | ]}t |d r|jqS )
fill_value)hasattrr   ).0ir   r   r   
<listcomp>&   s     
 z _concatenate.<locals>.<listcomp>c                 s   s   | ]}t |tjV  qd S r   )
isinstancenpndarray)r   fr   r   r   	<genexpr>'   s     z_concatenate.<locals>.<genexpr>zADask doesn't support masked array's with non-scalar `fill_value`s   r   )r    maconcatenateany
ValueErroruniquelenr   )Zarraysr   outZfill_valuesr   r   r   _concatenate#   s    

r,      c                    s8  zt | W n2 tk
r>   tt| dttd|Y n
X |\zt}tW n tk
rz   gd}Y nX zt}tW n tk
r   gd}Y nX | j | j}|j|j}d}||krd}nlt|D ]b} |  |  kr
d} qF| dk r(|  |7  < | dk r|  |7  < q|sTtdfddt|D }	|	 }
d}D ]}| | 9 }qzd|f} fd	d|	D }fd
dt|D }	|	 }d}D ]}|| 9 }q|df}fdd|	D }| |
	|}||	|}t
j||}|	|| S )Nr   r$   TFzshape-mismatch for sumc                    s   g | ]}| kr|qS r   r   r   k)axes_ar   r   r   a   s      z_tensordot.<locals>.<listcomp>c                    s   g | ]} | qS r   r   r   r   )as_r   r   r   g   s     c                    s   g | ]}| kr|qS r   r   r.   )axes_br   r   r   i   s      c                    s   g | ]} | qS r   r   r2   )bsr   r   r   o   s     )iter	TypeErrorlistranger*   shapendimr(   Z	transposeZreshaper    r%   dot)r   baxesnanbZndaZndbequalr/   notinZ	newaxes_aZN2r   Z
newshape_aZoldaZ	newaxes_bZ
newshape_bZoldbatZbtresr   )r3   r0   r4   r5   r   
_tensordot3   sj    

rE   cupyc                     sz   dd l  ddlm}  t j j t j j |  jt	 t
 jt t jt t j fdd}d S )Nr   )r	   c                     s$   | dd  | dd   j| |S )NZcastingorder)popeinsum)argskwargsrF   r   r   _cupy_einsum   s    z#register_cupy.<locals>._cupy_einsum)rF   dask.array.dispatchr	   r   registerr!   r&   r
   	tensordotr   r   _numel_arrayliker   	_nannumelr   )r	   rM   r   rL   r   register_cupyw   s    
rS   Zcupyxc               
      sz   ddl m}  zddl m m W n, tk
rL } ztd|W 5 d }~X Y nX d fdd	}t| | t| t d S )Nr   )spmatrixhstackvstackz>Stacking of sparse arrays requires at least CuPy version 8.0.0c                    s4   |dkr| S |dkr  | S d| }t |d S )Nr   r$   zECan only concatenate cupy sparse matrices for axis in {0, 1}.  Got %s)r(   Lr   msgrU   r   r   _concat_cupy_sparse   s    z+register_cupyx.<locals>._concat_cupy_sparse)r   )	Zcupyx.scipy.sparserT   rV   rW   ImportErrorr   rO   r
   _tensordot_scipy_sparse)rT   er[   r   rU   r   register_cupyx   s    r_   sparsec                  C   sH   dd l } t| j| j t| j| j t| jt t	| jt
 d S )Nr   )r`   r   rO   ZCOOr&   r
   rP   r   _numel_ndarrayr   _nannumel_sparse)r`   r   r   r   register_sparse   s
    rc   scipyc                     s:   dd l  d fdd	} t jj|  t jjt d S )Nr   c                    s<   |dkr j | S |dkr( j | S d| }t|d S )Nr   r$   zFCan only concatenate scipy sparse matrices for axis in {0, 1}.  Got %s)r`   rW   rV   r(   rX   rd   r   r   r,      s    z+register_scipy_sparse.<locals>._concatenate)r   )Zscipy.sparser   rO   r`   rT   r
   r]   )r,   r   re   r   register_scipy_sparse   s    rf   c                 C   s   | j |j   krdksn tt|d t|d   krBdksHn t|d \}|d \}|dkrl|dkspt| j| |j| kst|dkr|dkr| j| S |dkr|dkr| j|j S |dkr|dkr| | S |dkr|dkr| |j S d S )Nr-   r   r$   )r   r$   )r;   AssertionErrorr*   r:   T)r   r=   r>   Za_axisZb_axisr   r   r   r]      s    *


r]   c                 K   s   t jt| f|S )z'Numel implementation for masked arrays.)r   sumr    Z	ones_likexrK   r   r   r   _numel_masked   s    rl   c                 K   s   t | fddi|S )zJNumel implementation for arrays that want to return numel of type ndarray.coerce_np_ndarrayT_numelrj   r   r   r   ra      s    ra   c                 K   s   t | fddi|S )zKNumel implementation for arrays that want to return numel of the same type.rm   Frn   rj   r   r   r   rQ      s    rQ   )rm   c                    s,  | j |dd}|dd |dtj} dkrtj|d}|dkrN|S |rjtjdt ||dS tj| |dt |d	S t t	t
fs g tfd
d D }|dkrt	 fddttD }n t	 fddttD }|rttj||d|S tj| |||d	S dS )a	  
    A reduction to count the number of elements.

    This has an additional kwarg in coerce_np_ndarray, which determines
    whether to ensure that the resulting array is a numpy.ndarray, or whether
    we allow it to be other array types via `np.full_like`.
    keepdimsFr   Ndtype)rq   )r$   )r:   r   rq   )r:   rq   c                 3   s   | ]} | V  qd S r   r   r   Zdim)r:   r   r   r#     s     z_numel.<locals>.<genexpr>Tc                 3   s"   | ]}| kr| nd V  qdS )r$   Nr   rr   r   r:   r   r   r#     s    c                 3   s   | ]}| kr| V  qd S r   r   rr   rs   r   r   r#     s      )r:   getr    Zfloat64prodfullr*   Z	full_liker   tupler8   mathr9   Zbroadcast_toarray)rk   rm   rK   rp   rq   ru   Z	new_shaper   rs   r   ro      s,    

 ro   c                 K   s   t jt|  f|S )z;A reduction to count the number of elements, excluding nans)r   ri   r    isnanrj   r   r   r   rR     s    rR   c                 K   s"   t | f|}t|dr| S |S )a  
    A reduction to count the number of elements in a sparse array, excluding nans.
    This will in general result in a dense matrix with an unpredictable fill value.
    So make it official and convert it to dense.

    https://github.com/dask/dask/issues/7169
    todense)rR   r   r{   )rk   rK   nr   r   r   rb      s    rb   c                   @   s   e Zd ZdZedd ZedddddZeddddd	Zedddd
dZ	edddddZ
eddddddZdS )ArrayBackendEntrypointzjDask-Array version of ``DaskBackendEntrypoint``

    See Also
    --------
    NumpyBackendEntrypoint
    c                 C   s   t dS )zReturn the backend-specific RandomState class

        For example, the 'numpy' backend simply returns
        ``numpy.random.RandomState``.
        NNotImplementedErrorselfr   r   r   RandomState6  s    z"ArrayBackendEntrypoint.RandomStateN)rq   metac                K   s   t dS )ztCreate an array of ones

        Returns a new array having a specified shape and filled
        with ones.
        Nr~   r:   rq   r   rK   r   r   r   ones?  s    zArrayBackendEntrypoint.onesc                K   s   t dS )zvCreate an array of zeros

        Returns a new array having a specified shape and filled
        with zeros.
        Nr~   r   r   r   r   zerosH  s    zArrayBackendEntrypoint.zerosc                K   s   t dS )z`Create an empty array

        Returns an uninitialized array having a specified shape.
        Nr~   r   r   r   r   emptyQ  s    zArrayBackendEntrypoint.emptyc                K   s   t dS )zCreate a uniformly filled array

        Returns a new array having a specified shape and filled
        with fill_value.
        Nr~   )r:   r   rq   r   rK   r   r   r   rv   Y  s    zArrayBackendEntrypoint.fullr$   c               K   s   t dS )zCreate an ascending or descending array

        Returns evenly spaced values within the half-open interval
        ``[start, stop)`` as a one-dimensional array.
        Nr~   )startstopsteprq   r   rK   r   r   r   arangeb  s    zArrayBackendEntrypoint.arange)Nr$   )__name__
__module____qualname____doc__propertyr   staticmethodr   r   r   rv   r   r   r   r   r   r}   .  s   
r}   c                   @   s   e Zd Zedd ZdS )NumpyBackendEntrypointc                 C   s   t jjS r   )r    randomr   r   r   r   r   r   m  s    z"NumpyBackendEntrypoint.RandomStateN)r   r   r   r   r   r   r   r   r   r   l  s   r   ry   numpyarray_creation_dispatch)module_namedefaultZentrypoint_classname)r   )r   )r-   )4rx   r   r    Z
dask.arrayr   rN   r   r   r   r   r   r   r	   r
   Zdask.array.numpy_compatr   Z	np_divider   Zdask.array.percentiler   Zdask.backendsr   r   rO   objectr!   r&   rP   rI   r   r%   Zmasked_arrayr   r,   rE   Zregister_lazyrS   r_   rc   rf   r]   rl   ra   rQ   boolro   rR   rb   r}   r   r   Zregister_backendr   r   r   r   <module>   sn   (

C

(
>