σ
¦Υ\c           @` s=  d  d l  m Z m Z m Z d  d l m Z d  d l Z d d l 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 m Z m Z d d l m Z d d l m Z d  d l m Z e	 e
 e e f Z e	 e
 f Z d d e f e d  Z  d   Z! d   Z" d   Z# d   Z$ d   Z% d S(   i    (   t   absolute_importt   divisiont   print_function(   t   getitemNi   (   t   gettert   getter_nofancyt   getter_inlinei   (   t   optimize_blockwise(   t   zip_longest(   t   flattent   reverse_dict(   t   cullt   fuset   inline_functions(   t   ensure_dict(   t   HighLevelGraph(   t   Integralc         K` sα   t  t |   } t |  t  r6 t |  d | }  n  t |   }  | d k	 rW | } n  t |  |  \ } } t | |  }	 t	 | |	 | | p g  | d | \ }
 } | rΛ t
 |
 | d | d | } n |
 } t |  } | S(   sΏ    Optimize dask for array computation

    1.  Cull tasks not necessary to evaluate keys
    2.  Remove full slicing, e.g. x[:]
    3.  Inline fast functions like getitem and np.transpose
    t   keyst   rename_keyst   dependenciest   fast_functionsN(   t   listR	   t
   isinstanceR   R   R   t   NoneR   t	   hold_keysR   R   t   optimize_slices(   t   dskR   t	   fuse_keysR   t   inline_functions_fast_functionst   rename_fused_keyst   kwargst   dsk2R   t   holdt   dsk3t   dsk4t   dsk5(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyt   optimize   s     		c         C` s!  t  |  } d   |  j   D } t |  } xμ | D]δ } | | } xΡ | D]Ι } |  | } t |  t k rL | rL | d t k rL yg x` t | |  d k rι t t | |   }	 |  |	 }
 |
 d t k sά |
 |  k rε |	 } q Pq WWn t	 t
 f k
 rn X| j |  qL qL Wq5 W| S(   s#   Find keys to avoid fusion

    We don't want to fuse data present in the graph because it is easier to
    serialize as a raw value.

    We don't want to fuse chains after getitem/GETTERS because we want to
    move around only small pieces of data, rather than the underlying arrays.
    c         S` s4   h  |  ]* \ } } t  |  t t f k r |  q S(    (   t   typet   tuplet   str(   t   .0t   kt   v(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <setcomp>F   s   	 i    i   (   R
   t   itemsR   R%   R&   t   GETTERSt   lent   nextt   itert
   IndexErrort	   TypeErrort   append(   R   R   t
   dependentst   dataR   t   datt   depst   dept   taskt   new_dept   new_task(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyR   <   s&    	

(
		c         ` sT  t  t j f   |  j   }  x2|  j   D]$\ } } t |  t k r( | d t k r( t |  d k r( t |  d k r | \ } } } | t	 k	 } d } n | \ } } } } } xΠt |  t k r| d t k rt |  d	 k rt |  d k r | \ } }	 }
 | t	 k	 } d } n | \ } }	 }
 } } | rK| | k	 rKPn  t |  t k t |
  t k k rsPn  t |  t k rπ|
 | } t |  t |
  k rΑt d   | D  rΑPn  | t k r$t   f d   | D  r$Pq$n4 | t k r$t |    k s t |
    k r$Pn  y+ t |
 |  } | t k rHt n | } Wn t k
 rcPn X|	 | | } } } | | O} qΆ W| t k rt |  t k rΜ| j rΜ| j d k rΜ| j d k sτt |  t k rt d   | D  r| |  | <qL| t	 k s| r0| r0| | | f |  | <qL| | | | | f |  | <q( q( W|  S(
   s©    Optimize slices

    1.  Fuse repeated slices, like x[5:][2:6] -> x[7:11]
    2.  Remove full slices, like         x[:] -> x

    See also:
        fuse_slice_dict
    i    i   i   c         s` s   |  ] } | d  k Vq d  S(   N(   R   (   R(   t   i(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <genexpr>   s    c         3` s   |  ] } t  |    Vq d  S(   N(   R   (   R(   R;   (   t   fancy_ind_types(    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <genexpr>   s    c         s` sI   |  ]? } t  |  t k o@ | j o@ | j d  k o@ | j d  k Vq d  S(   N(   R%   t   slicet   startt   stopR   t   step(   R(   t   s(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <genexpr>   s   (   i   i   N(   i   i   (   R   t   npt   ndarrayt   copyR+   R%   R&   R,   R-   R   R   t   anyR   t
   fuse_sliceR   R   t   NotImplementedErrort   GETNOREMOVER=   R>   R?   R@   t   all(   R   R)   R*   t   gett   at   a_indext	   a_asarrayt   a_lockt   f2t   bt   b_indext	   b_asarrayt   b_lockt   indicest   c_index(    (   R<   s6   lib/python2.7/site-packages/dask/array/optimization.pyR   b   sb    	4	7	$
	 c         C` s   |  j  |  j |  j } } } | d k r2 d } n  | d k rG d } n  | d k  sw | d k  sw | d k	 r | d k  r t    n  t | | |  S(   ss    Replace Nones in slices with integers

    >>> normalize_slice(slice(None, None, None))
    slice(0, None, 1)
    i    i   N(   R>   R?   R@   R   RG   R=   (   RA   R>   R?   R@   (    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyt   normalize_slice­   s    		0c         C` s`   xY t  |  | d t d   D]< \ } } t |  t k	 r t | t  r t d   q q Wd  S(   Nt	   fillvalues   Can't handle normal indexing with integers and fancy indexing if the integers and fancy indices don't align with the same dimensions.(   R   R=   R   R%   R   R   R   RG   (   t   fancyt   normalt   ft   n(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyt#   check_for_nonfusible_fancy_indexing½   s    (!c         C` s­  |  d k r4 t | t  r4 | t d d  k r4 d St |  t  rR t |   }  n  t | t  rp t |  } n  t |  t  rΈ t | t  rΈ | d k  r¦ t    n  |  j | |  j St |  t  rt | t  r|  j |  j | j } | j d k	 r|  j |  j | j } n d } |  j d k	 rX| d k	 rLt	 |  j |  } qX|  j } n  |  j | j } | d k r}d } n  t | | |  St | t
  rΌg  | D] } t |  |  ^ q£St |  t
  rθt | t t f  rθ|  | St |  t  rt | t  r| f } n  t |  t  r t | t  r t d   |  D  } t d   | D  } | rx| rxt d   n, | rt |  |  n | r€t | |   n  d } t
   }	 x¬ t t |    D] }
 t |  |
 t  sρ| t |  k r|	 j |  |
  qΖn  x+ | | d k r5|	 j d  | d 7} qW|	 j t |  |
 | |   | d 7} qΖWx1 | t |  k  r|	 j | |  | d 7} qeWt |	  St    d S(   sΘ   Fuse stacked slices together

    Fuse a pair of repeated slices into a single slice:

    >>> fuse_slice(slice(1000, 2000), slice(10, 15))
    slice(1010, 1015, None)

    This also works for tuples of slices

    >>> fuse_slice((slice(100, 200), slice(100, 200, 10)),
    ...            (slice(10, 15), [5, 2]))
    (slice(110, 115, None), [150, 120])

    And a variety of other interesting cases

    >>> fuse_slice(slice(1000, 2000), 10)  # integers
    1010

    >>> fuse_slice(slice(1000, 2000, 5), slice(10, 20, 2))
    slice(1050, 1100, 10)

    >>> fuse_slice(slice(1000, 2000, 5), [1, 2, 3])  # lists
    [1005, 1010, 1015]

    >>> fuse_slice(None, slice(None, None))  # doctest: +SKIP
    None
    i    i   c         s` s   |  ] } t  | t  Vq d  S(   N(   R   R   (   R(   t   item(    (    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <genexpr>  s    c         s` s   |  ] } t  | t  Vq d  S(   N(   R   R   (   R(   R]   (    (    s6   lib/python2.7/site-packages/dask/array/optimization.pys	   <genexpr>  s    s#   Can't handle multiple list indexingN(   R   R   R=   RV   R   RG   R>   R@   R?   t   minR   RF   R&   RE   R\   t   rangeR-   R2   (   RK   RP   R>   R?   R@   t   bbt   a_has_listst   b_has_listst   jt   resultR;   (    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyRF   Λ   sl    0	 $	%
(&   t
   __future__R    R   R   t   operatorR   t   numpyRB   t   coreR   R   R   t	   blockwiseR   t   compatibilityR   R	   R
   t   optimizationR   R   R   t   utilsR   t   highlevelgraphR   t   numbersR   R,   RH   R   t   TrueR$   R   R   RV   R\   RF   (    (    (    s6   lib/python2.7/site-packages/dask/array/optimization.pyt   <module>   s&   "	&	K		