U
    /e                     @   s  d dl mZ d dlmZ d dl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lmZ dd Zdd Zdd Zed)ddZeeZed*ddZdd Ze	jdddeeej ddZ!e	jdddeeej"ddZ#e	jdddeeej$ddZ%eeZ&e&ej%ej$d Z$e	jdd!deeej'Z(e&ej)ej'd Z*e(j+dk	re(j+,d"d#e(_+e(j+,d$d%e(_+d&d! Z)d'd( Z'e(j+e)_+e*j+e'_+dS )+    partial)productN)curry)array_creation_dispatch)Arraynormalize_chunks)meta_from_array)tokenize)	blockwise)ArrayChunkShapeDep)funcnamec                 C   s   t |tjr| }t |ttfs(|f}|dd }|dd}|dd }|d krf| |f||j}t|}t|||d}|pt	| d t
| ||||| }|||||dS )Nnamechunksautodtyper   -)shaper   kwargsr   r   )
isinstancenpZndarraytolisttuplelistpopr   r   r   r
   )funcargsr   r   r   r   r    r   3/tmp/pip-unpacked-wheel-dbjnr7gq/dask/array/wrap.py_parse_wrap_args   s2    
     r    c              	   O   s   d|kr |d |dd  }}n
| d}t|tr<tdt| |||}|d }|d }|d }|d }|d	 }t| fd|i|} ttt| }}	t	| ||t
||	i d
}
t|
||||dddS )=
    Transform np creation function into blocked version
    r   r      NzTDask array input not supported. Please use tuple, list, or a 1D numpy array instead.r   r   r   r   )Z	numblocksmeta)r   r#   )r   r   r   	TypeErrorr    r   r   rangelencore_blockwiser   get)r   r   r   r   parsedr   r   r   Zout_indZdep_indgraphr   r   r   wrap_func_shape_as_first_arg.   s0    

	r+   c                    s    d }t |}d|j}t |}|d }|d |d }|d }|d t|gfdd |D  }	t| }
t|
}
fd	d|
D }tt|
D ]\}}||| d< q fd
dt||
D }tt|	|}t	||||
dS )r!   r   r   r   r   r   r   c                 S   s   g | ]}t t|qS r   )r%   r&   ).0Zbdr   r   r   
<listcomp>a   s     z"wrap_func_like.<locals>.<listcomp>c                    s   g | ]} qS r   r   )r,   _)r   r   r   r-   d   s     c                 3   s,   | ]$\}}t fd i|f  V  qdS )r   Nr   )r,   ks)r   r   r   r   r   	<genexpr>g   s     z!wrap_func_like.<locals>.<genexpr>)r#   )r	   r(   r   r    r   r   	enumeratezipdictr   Zastype)r   r   r   xr#   r   r)   r   r   keysZshapeskwir0   valsZdskr   )r   r   r   r   r   wrap_func_likeR   s$    r:   c                 K   sZ   |d krt | |f|}nt | |f|}d}|jd k	rV|d|ji |j |_d|j |_|S )Nz
    Blocked variant of %(name)s

    Follows the signature of %(name)s exactly except that it also features
    optional keyword arguments ``chunks: int, tuple, or dict`` and ``name: str``.

    Original signature follows below.
    r   Zblocked_)r   __doc____name__)Z	wrap_funcr   	func_liker   ftemplater   r   r   wrapn   s    
r@   r   c                 O   s0   |dkrdnd}t | |f|d|i||S )Nr   r"   r   )r   Zbroadcast_to)r   r   r#   r   r   Z
null_shaper   r   r   _broadcast_trick_inner   s    rA   c                 C   s   t | }| j|_| j|_|S )a  
    Provide a decorator to wrap common numpy function with a broadcast trick.

    Dask arrays are currently immutable; thus when we know an array is uniform,
    we can replace the actual data by a single value and have all elements point
    to it, thus reducing the size.

    >>> x = np.broadcast_to(1, (100,100,100))
    >>> x.base.nbytes
    8

    Those array are not only more efficient locally, but dask serialisation is
    aware of the _real_ size of those array and thus can send them around
    efficiently and schedule accordingly.

    Note that those array are read-only and numpy will refuse to assign to them,
    so should be safe.
    )rA   r;   r<   )r   innerr   r   r   broadcast_trick   s    rC   numpyones)backendr   Zf8r   zerosempty)r=   fullz*array([0.1,  0.1,  0.1,  0.1,  0.1,  0.1])z%array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1])z >>> np.full_like(y, [0, 0, 255])zB>>> np.full_like(y, [0, 0, 255])  # doctest: +NORMALIZE_WHITESPACEc                 O   sj   t |dkr$tdt|j d|dd d krVt|drJ|j|d< nt||d< t|| |d|S )Nr   $fill_value must be scalar. Received 	 instead.r   )r   
fill_value)	r   ndim
ValueErrortyper<   r(   hasattrr   _full)r   rL   r   r   r   r   r   rI      s    
c                 O   s8   t |dkr$tdt|j dt|| |d|S )Nr   rJ   rK   )arL   )r   rM   rN   rO   r<   
_full_like)rR   rL   r   r   r   r   r   	full_like   s    rT   )N)r   )-	functoolsr   	itertoolsr   rD   r   Ztlzr   Zdask.array.backendsr   Zdask.array.corer   r   Zdask.array.utilsr	   Z	dask.baser
   Zdask.blockwiser   r'   Zdask.layersr   Z
dask.utilsr   r    r+   r:   r@   wrA   rC   Zregister_inplaceZ	ones_likerE   Z
zeros_likerG   Z
empty_likerH   Zw_likerT   rQ   rI   rS   r;   replacer   r   r   r   <module>   sv   $