ó
¦–Õ\c        	   @` sŽ  d  d l  m Z m Z m Z d  d l Z d  d l 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 m Z m Z m Z m Z m Z d d l m Z m Z d	 „  Z d
 „  Z e e e d „ Z d „  Z e e e d „ Z e e e d „ Z d „  Z  d „  Z! d „  Z" d „  Z# d „  Z$ e e e e e e e e d „ Z% d „  Z& e j' d ƒ Z( d „  Z) d e* f d „  ƒ  YZ+ d S(   i    (   t   absolute_importt   divisiont   print_functionN(   t   getitemi   (   t   configt   core(   t   unicode(   t   istaskt   get_dependenciest   subst   toposortt   flattent   reverse_dictt
   ishashable(   t   addt   incc         ` s   t  | t t f ƒ s! | g } n  g  } t ƒ  } t ƒ  } t t t | ƒ ƒ ƒ } x¬ | rÿ g  } | | 7} g  | D]! } | t ˆ  | d t ƒf ^ qq } | j | ƒ xN | D]F \ }	 }
 x7 |
 D]/ } | | k r¿ | j | ƒ | j	 | ƒ q¿ q¿ Wq¬ W| } qT W‡  f d †  | Dƒ } | | f S(   s   Return new dask with only the tasks required to calculate keys.

    In other words, remove unnecessary tasks from dask.
    ``keys`` may be a single key or list of keys.

    Examples
    --------
    >>> d = {'x': 1, 'y': (inc, 'x'), 'out': (add, 'x', 10)}
    >>> dsk, dependencies = cull(d, 'out')  # doctest: +SKIP
    >>> dsk  # doctest: +SKIP
    {'x': 1, 'out': (add, 'x', 10)}
    >>> dependencies  # doctest: +SKIP
    {'x': set(), 'out': set(['x'])}

    Returns
    -------
    dsk: culled dask graph
    dependencies: Dict mapping {key: [deps]}.  Useful side effect to accelerate
        other optimizations, notably fuse.
    t   as_listc         ` s   i  |  ] } ˆ  | | “ q S(    (    (   t   .0t   k(   t   dsk(    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>7   s   	 (
   t
   isinstancet   listt   sett   dictR   R   t   Truet   updateR   t   append(   R   t   keyst   out_keyst   seent   dependenciest   workt   new_workR   t   depst   _t   deplistt   dt   out(    (   R   s0   lib/python2.7/site-packages/dask/optimization.pyt   cull   s(    			
+
c         C` s  t  |  d ƒ } | t k s( | t k rr g  |  d d d … D] } t | ƒ ^ q< } | j |  d ƒ d j | ƒ S| t k rt |  d ƒ d k rt |  d d t t f ƒ rg  |  d d d … D] } t | ƒ ^ qÅ } | j |  d d ƒ d j | ƒ f |  d d Sd Sd S(   s   Create new keys for fused tasksi    Niÿÿÿÿt   -i   (
   t   typet   strR   t	   key_splitR   t   joint   tuplet   lenR   t   None(   R   t   typt   xt   names(    (    s0   lib/python2.7/site-packages/dask/optimization.pyt!   default_fused_linear_keys_renamer<   s    ,",c         ` s…  | d k	 rL t | t ƒ rL t | t ƒ s7 | g } n  t t | ƒ ƒ } n  | d k rq ‡  f d †  ˆ  Dƒ } n  i  } t ƒ  } xµ ˆ  D]­ } | | } t | ƒ d k } xˆ | D]€ }	 | d k	 rÞ |	 | k rÞ | j |	 ƒ q° |	 | k r| |	 =| j |	 ƒ q° | r| j |	 ƒ q° |	 | k r° | | |	 <q° q° Wq‡ Wg  }
 t t t	 | j
 ƒ  ƒ ƒ } x« | r| j ƒ  \ }	 } |	 | g } x3 | | k rµ| j | ƒ } | | =| j | ƒ qƒW| j ƒ  x3 |	 | k rõ| j |	 ƒ }	 | |	 =| j |	 ƒ qÃW|
 j | ƒ q\Wd „  | j
 ƒ  Dƒ } | t k r2t } n | t k rGd } n | } i  } t ƒ  } t ƒ  } t } x,|
 D]$} | d k	 r·| | ƒ } | d k	 o±| ˆ  k o±| | k } n  | j ƒ  }	 ˆ  |	 } xj | r9| j ƒ  } | | j | j |	 ƒ ƒ | | j |	 ƒ t ˆ  | |	 | ƒ } | j |	 ƒ | }	 qÐW| j |	 ƒ | rŒ| | | <| | |	 <| |	 | | <| h | |	 <| j |	 ƒ qr| | |	 <qrWx3 ˆ  j
 ƒ  D]% \ } } | | k r§| | | <q§q§W| r{xm | j
 ƒ  D]_ \ } } xP | | @D]D } | | } | j | ƒ | j | ƒ t | | | | ƒ | | <qúWqãW| d k	 r{x# | | D] } | | =| | =q]Wq{n  | | f S(   s3   Return new dask graph with linear sequence of tasks fused together.

    If specified, the keys in ``keys`` keyword argument are *not* fused.
    Supply ``dependencies`` from output of ``cull`` if available to avoid
    recomputing dependencies.

    **This function is mostly superseded by ``fuse``**

    Parameters
    ----------
    dsk: dict
    keys: list
    dependencies: dict, optional
        {key: [list-of-keys]}.  Must be a list to provide count of each key
        This optional input often comes from ``cull``
    rename_keys: bool or func, optional
        Whether to rename fused keys with ``default_fused_linear_keys_renamer``
        or not.  Renaming fused keys can keep the graph more understandable
        and comprehensive, but it comes at the cost of additional processing.
        If False, then the top-most key will be used.  For advanced usage, a
        func is also accepted, ``new_key = rename_keys(fused_key_list)``.

    Examples
    --------
    >>> d = {'a': 1, 'b': (inc, 'a'), 'c': (inc, 'b')}
    >>> dsk, dependencies = fuse(d)
    >>> dsk # doctest: +SKIP
    {'a-b-c': (inc, (inc, 1)), 'c': 'a-b-c'}
    >>> dsk, dependencies = fuse(d, rename_keys=False)
    >>> dsk # doctest: +SKIP
    {'c': (inc, (inc, 1))}
    >>> dsk, dependencies = fuse(d, keys=['b'], rename_keys=False)
    >>> dsk  # doctest: +SKIP
    {'b': (inc, 1), 'c': (inc, 'b')}

    Returns
    -------
    dsk: output graph with keys fused
    dependencies: dict mapping dependencies after fusion.  Useful side effect
        to accelerate other downstream optimizations.
    c         ` s(   i  |  ] } t  ˆ  | d  t ƒ| “ q S(   R   (   R   R   (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>|   s   	i   c         S` s%   i  |  ] \ } } t  | ƒ | “ q S(    (   R   (   R   R   t   v(    (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>¡   s   	 N(   R.   R   R   R   R   R-   R   R   t   mapt   reversedt   itemst   popitemt   popR   t   reverseR   R2   t   FalseR   t   removeR	   (   R   R   R   t   rename_keyst   child2parentt	   unfusiblet   parentR!   t   has_many_childrent   childt   chainst   parent2childt   chaint   key_renamert   rvt   fusedt   aliasest
   is_renamedt   new_keyt   valt   keyt   old_key(    (   R   s0   lib/python2.7/site-packages/dask/optimization.pyt   fuse_linearL   s¨    *	
	
				
	



"c         C` sQ   |  d  k r t ƒ  St |  t ƒ r& |  St |  t t f ƒ sG |  g }  n  t |  ƒ S(   N(   R.   R   R   R   (   R0   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt	   _flat_set×   s    c         ` s¶  ˆ  r@ t  t t ˆ  j ƒ  ƒ ƒ t ƒ r@ d „  ˆ  j ƒ  Dƒ ‰  n  t | ƒ } ˆ  d k rq ‡ f d †  ˆ Dƒ ‰  n  | r  | j ‡  ‡ f d †  ˆ j ƒ  Dƒ ƒ n  t	 t
 ‡ f d †  | Dƒ ƒ d ˆ  ƒ} i  } xp | D]h } ˆ | } xK | ˆ  | @D]; } | | k r| | }	 n
 ˆ | }	 t | | |	 ƒ } qô W| | | <qÕ W| j ƒ  }
 xb ˆ j ƒ  D]T \ } } | |
 k rZx, | ˆ  | @D] } t | | | | ƒ } qW| |
 | <qZqZW|
 S(   s…   Return new dask with the given keys inlined with their values.

    Inlines all constants if ``inline_constants`` keyword is True. Note that
    the constant keys will remain in the graph, to remove them follow
    ``inline`` with ``cull``.

    Examples
    --------
    >>> d = {'x': 1, 'y': (inc, 'x'), 'z': (add, 'x', 'y')}
    >>> inline(d)  # doctest: +SKIP
    {'x': 1, 'y': (inc, 1), 'z': (add, 1, 'y')}

    >>> inline(d, keys='y')  # doctest: +SKIP
    {'x': 1, 'y': (inc, 1), 'z': (add, 1, (inc, 1))}

    >>> inline(d, keys='y', inline_constants=False)  # doctest: +SKIP
    {'x': 1, 'y': (inc, 1), 'z': (add, 'x', (inc, 'x'))}
    c         S` s%   i  |  ] \ } } t  | ƒ | “ q S(    (   R   (   R   R   R3   (    (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>õ   s   	 c         ` s"   i  |  ] } t  ˆ  | ƒ | “ q S(    (   R   (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>ú   s   	c         3` sK   |  ]A \ } } t  | ƒ r' | ˆ k s? ˆ  | r t | ƒ r | Vq d  S(   N(   R   R   (   R   R   R3   (   R   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <genexpr>þ   s    	c         3` s+   |  ]! } | ˆ  k r | ˆ  | f Vq d  S(   N(    (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <genexpr>  s    R   N(   R   t   nextt   itert   valuesR   R6   RO   R.   R   R
   R   R	   t   copy(   R   R   t   inline_constantsR   t   replaceordert   keysubsRL   RK   t   dept   replacet   dsk2t   item(    (   R   R   s0   lib/python2.7/site-packages/dask/optimization.pyt   inlineá   s4    ')	

c   
      ` sõ   ˆ s
 ˆ  St  | ƒ } t  ˆ ƒ ‰ | d k rG ‡  f d †  ˆ  Dƒ } n  t | ƒ } ‡ f d †  } g  ˆ  j ƒ  D]@ \ } } t | ƒ ro | | ro | | k ro | | ƒ ro | ^ qo }	 |	 rñ t ˆ  |	 d | d | ƒ‰  x |	 D] } ˆ  | =qÝ Wn  ˆ  S(   s†   Inline cheap functions into larger operations

    Examples
    --------
    >>> dsk = {'out': (add, 'i', 'd'),  # doctest: +SKIP
    ...        'i': (inc, 'x'),
    ...        'd': (double, 'y'),
    ...        'x': 1, 'y': 1}
    >>> inline_functions(dsk, [], [inc])  # doctest: +SKIP
    {'out': (add, (inc, 'x'), 'd'),
     'd': (double, 'y'),
     'x': 1, 'y': 1}

    Protect output keys.  In the example below ``i`` is not inlined because it
    is marked as an output key.

    >>> inline_functions(dsk, ['i', 'out'], [inc, double])  # doctest: +SKIP
    {'out': (add, 'i', (double, 'y')),
     'i': (inc, 'x'),
     'x': 1, 'y': 1}
    c         ` s"   i  |  ] } t  ˆ  | ƒ | “ q S(    (   R   (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>:  s   	c         ` s0   y t  |  ƒ j ˆ  ƒ SWn t k
 r+ t SXd  S(   N(   t   functions_oft   issubsett	   TypeErrorR:   (   R3   (   t   fast_functions(    s0   lib/python2.7/site-packages/dask/optimization.pyt	   inlinable>  s    RT   R   N(   R   R.   R   R6   R   R[   (
   R   t   outputR_   RT   R   t
   dependentsR`   R   R3   R   (    (   R   R_   s0   lib/python2.7/site-packages/dask/optimization.pyt   inline_functions  s"    :	c         C` s#   x t  |  d ƒ r |  j }  q W|  S(   Nt   func(   t   hasattrRd   (   Rd   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   unwrap_partialO  s    c         C` sŸ   t  ƒ  } |  g } t t h } xz | rš g  } xa | D]Y }  t |  ƒ | k r4 t |  ƒ r€ | j t |  d ƒ ƒ | |  d 7} q | |  7} q4 q4 W| } q! W| S(   sÒ    Set of functions contained within nested task

    Examples
    --------
    >>> task = (add, (mul, 1, 2), (inc, 3))  # doctest: +SKIP
    >>> functions_of(task)  # doctest: +SKIP
    set([add, mul, inc])
    i    i   (   R   R   R,   R(   R   R   Rf   (   t   taskt   funcsR   t   sequence_typesR    (    (    s0   lib/python2.7/site-packages/dask/optimization.pyR\   U  s    				
c         C` sÌ   t  ƒ  } x¼ |  j ƒ  D]® \ } } y„ t | ƒ r› | d | k r› | d |  k r› t |  | d ƒ r› |  | d d | k r› | | |  | d ƒ | | <n
 | | | <Wq t k
 rÃ | | | <q Xq W| S(   s+  Fuse selections with lower operation.

    Handles graphs of the form:
    ``{key1: (head1, key2, ...), key2: (head2, ...)}``

    Parameters
    ----------
    dsk : dict
        dask graph
    head1 : function
        The first element of task1
    head2 : function
        The first element of task2
    merge : function
        Takes ``task1`` and ``task2`` and returns a merged task to
        replace ``task1``.

    Examples
    --------
    >>> def load(store, partition, columns):
    ...     pass
    >>> dsk = {'x': (load, 'store', 'part', ['a', 'b']),
    ...        'y': (getitem, 'x', 'a')}
    >>> merge = lambda t1, t2: (load, t2[1], t2[2], t1[2])
    >>> dsk2 = fuse_selections(dsk, getitem, load, merge)
    >>> cull(dsk2, 'y')[0]
    {'y': (<function load at ...>, 'store', 'part', 'a')}
    i    i   (   R   R6   R   R^   (   R   t   head1t   head2t   mergeRY   R   R3   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   fuse_selectionsq  s    	,,c         ` s   t  |  t | ‡  f d †  ƒ S(   s6   Fuse getitem with lower operation

    Parameters
    ----------
    dsk: dict
        dask graph
    func: function
        A function in a task to merge
    place: int
        Location in task to insert the getitem key

    Examples
    --------
    >>> def load(store, partition, columns):
    ...     pass
    >>> dsk = {'x': (load, 'store', 'part', ['a', 'b']),
    ...        'y': (getitem, 'x', 'a')}
    >>> dsk2 = fuse_getitem(dsk, load, 3)  # columns in arg place 3
    >>> cull(dsk2, 'y')[0]
    {'y': (<function load at ...>, 'store', 'part', 'a')}
    c         ` s+   t  | ˆ   ƒ |  d f t  | ˆ  d ƒ S(   Ni   i   (   R,   (   t   at   b(   t   place(    s0   lib/python2.7/site-packages/dask/optimization.pyt   <lambda>²  t    (   Rm   R   (   R   Rd   Rp   (    (   Rp   s0   lib/python2.7/site-packages/dask/optimization.pyt   fuse_getitem›  s    c         C` s$  t  |  ƒ } t | ƒ } t | ƒ } | t k s< | t k r‹ t | ƒ } d „  | Dƒ } | j | ƒ t | ƒ } | j | ƒ d j	 | ƒ S| t
 k r t | ƒ d k r t | d t t f ƒ r t | ƒ } d „  | Dƒ } | j | ƒ t | ƒ } | j | d ƒ d j	 | ƒ f | d Sd S(   s"   Create new keys for ``fuse`` tasksc         S` s   h  |  ] } t  | ƒ ’ q S(    (   R*   (   R   R   (    (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <setcomp>¼  s   	 R'   i    c         S` s   h  |  ] } t  | ƒ ’ q S(    (   R*   (   R   R   (    (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <setcomp>Ä  s   	 i   N(   R5   RP   R(   R)   R   R*   t   discardt   sortedR   R+   R,   R-   R   (   R   t   itt	   first_keyR/   t
   first_nameR1   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   default_fused_keys_renamerµ  s$    c	   @   
   ` s¬
  | d k	 rL t | t ƒ rL t | t ƒ s7 | g } n  t t | ƒ ƒ } n  | d k rŽ t j d d ƒ d k ry d } qŽ t j d d ƒ } n  | d k rÖ t j d d ƒ d k rÁ t ˆ  ƒ } qÖ t j d d ƒ } n  | põ t j d d ƒ põ | d } | p(t j d d ƒ p(d | t j	 | d ƒ } | d k rLt j d t
 ƒ } n  | sZ| rdˆ  | f S| d k r…t j d t ƒ } n  | t k ršt }	 n | t
 k r¯d }	 n | }	 |	 d k	 } | d k ræ‡  f d	 †  ˆ  Dƒ }
 n t | ƒ }
 i  } xh |
 j ƒ  D]Z \ } } x; | D]3 } | | k r:| g | | <q| | j | ƒ qWt | ƒ |
 | <qWd
 „  | j ƒ  Dƒ } | rŒ| | 8} n  | rÀ| s¶t d „  | j ƒ  Dƒ ƒ rÀˆ  |
 f Sˆ  j ƒ  } i  } g  } g  } |
 j } | j } | j } | j } | j } | j } | j } | j } | j } | j } xÈ| r
| ƒ  } | | ƒ x | | k rt| | d } qWW| | ƒ | | |
 | @ƒ xkt rþ	| d } | | k r:| |
 | @}  x2 |  rò| |  ƒ | } | d } | |
 | @}  qÁW| ƒ  | | | | | r| g n d d d d d |
 | | f ƒ q”| ƒ  |
 | }! |! | }" |! |" }  t |  ƒ }# |# d k r‚| ƒ  \ }$ }% }& }' }( }) }* }+ t |+ ƒ }, |* |, d k o¿d k n rÑ|, d }* n  |" |+ O}" t |" ƒ |, k }- |- s |* d 7}* n  |) |* |' | k r|- s&|' | k  rt ˆ  | |$ |% ƒ }. |! j |$ ƒ |! | |$ ƒ O}! | |$ =| |$ ƒ | r—|& j | ƒ |& | | <| |$ d ƒ n  | rõ|- rÈ| | |. |& |' |( |) |* |" f ƒ q | | |. |& |' d |( |) d |* |" f ƒ q|. | | <Pqí	|% | |$ <| |$ ƒ | r~|* t | d ƒ k rFt | d ƒ }* n  | | | | | rb| g n d d |( d |* |" f ƒ qí	Pnkg  }& d }' d }( d }/ d }) d }* t ƒ  }+ d }0 | |# }1 | |# 3x |1 D]• \ }2 }3 }4 }5 }6 }7 }8 }9 |5 d k r|/ d 7}/ n |5 |' k r|5 }' n  |( |6 7}( |) |7 7}) |* |8 7}* t |9 ƒ |0 k rZt |9 ƒ }0 n  |+ |9 O}+ qÏWt |+ ƒ }, |* t |# d t d |, |0 ƒ ƒ 7}* |* |, d k o³d k n rÅ|, d }* n  |" |+ O}" t |" ƒ |, k }- |- sô|* d 7}* n  |) |* |' | k r?	|/ | k r?	|( | k r?	|' | k r?	|- s>|' | k  r?	ˆ  | }. t ƒ  }: xv |1 D]n }; |; d }< t |. |< |; d ƒ }. | |< =|: | |< ƒ O}: | |< ƒ | rX| |< d ƒ |& j |; d ƒ qXqXW|! |  8}! |! |: O}! | rþ|& j | ƒ |& | | <n  | r1	| | |. |& |' d |( |) d |* |" f ƒ qí	|. | | <Pn® x. |1 D]& }; |; d | |; d <| |; d ƒ qF	W| rì	|( | k r‹	| }( n  |* t | d ƒ k r´	t | d ƒ }* n  | | | | | rÐ	| g n d d |( d |* |" f ƒ n P| | d } q”Wq;W| r"
t | | |
 | | ƒ n  | r¢
xw | j ƒ  D]f \ }= }> |	 |> ƒ }? |? d k	 r5
|? | k r5
| |= | |? <|? | |= <|
 |= |
 |? <|? h |
 |= <q5
q5
Wn  | |
 f S(   s[   Fuse tasks that form reductions; more advanced than ``fuse_linear``

    This trades parallelism opportunities for faster scheduling by making tasks
    less granular.  It can replace ``fuse_linear`` in optimization passes.

    This optimization applies to all reductions--tasks that have at most one
    dependent--so it may be viewed as fusing "multiple input, single output"
    groups of tasks into a single task.  There are many parameters to fine
    tune the behavior, which are described below.  ``ave_width`` is the
    natural parameter with which to compare parallelism to granularity, so
    it should always be specified.  Reasonable values for other parameters
    with be determined using ``ave_width`` if necessary.

    Parameters
    ----------
    dsk: dict
        dask graph
    keys: list or set, optional
        Keys that must remain in the returned dask graph
    dependencies: dict, optional
        {key: [list-of-keys]}.  Must be a list to provide count of each key
        This optional input often comes from ``cull``
    ave_width: float (default 2)
        Upper limit for ``width = num_nodes / height``, a good measure of
        parallelizability
    max_width: int
        Don't fuse if total width is greater than this
    max_height: int
        Don't fuse more than this many levels
    max_depth_new_edges: int
        Don't fuse if new dependencies are added after this many levels
    rename_keys: bool or func, optional
        Whether to rename the fused keys with ``default_fused_keys_renamer``
        or not.  Renaming fused keys can keep the graph more understandable
        and comprehensive, but it comes at the cost of additional processing.
        If False, then the top-most key will be used.  For advanced usage, a
        function to create the new name is also accepted.
    fuse_subgraphs : bool, optional
        Whether to fuse multiple tasks into ``SubgraphCallable`` objects.

    Returns
    -------
    dsk: output graph with keys fused
    dependencies: dict mapping dependencies after fusion.  Useful side effect
        to accelerate other downstream optimizations.
    t   fuse_ave_widthi   t   fuse_max_heightt   fuse_max_depth_new_edgesg      ø?t   fuse_max_widtht   fuse_subgraphst   fuse_rename_keysc         ` s(   i  |  ] } t  ˆ  | d  t ƒ| “ q S(   R   (   R   R   (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>*  s   	 c         S` s.   h  |  ]$ \ } } t  | ƒ d  k r | ’ q S(   i   (   R-   (   R   R   t   vals(    (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <setcomp>7  s   	 c         s` s'   |  ] } t  t | ƒ ƒ d  k Vq d S(   i   N(   R-   R   (   R   R3   (    (    s0   lib/python2.7/site-packages/dask/optimization.pys	   <genexpr>;  s    i    iÿÿÿÿi   N(   R.   R   R   R   R   R   t   getR-   t   matht   logR:   R   Ry   R   R6   R   t   allRR   RS   R8   R   R;   t   extendR	   t   intt   mint   maxt   _inplace_fuse_subgraphs(@   R   R   R   t	   ave_widtht	   max_widtht
   max_heightt   max_depth_new_edgesR<   R~   RE   R!   t   rdepsR   R€   R3   t	   reducibleRF   t   fused_treest
   info_stackt   children_stackt   deps_popt   reducible_addt   reducible_popt   reducible_removet   fused_trees_popt   info_stack_appendt   info_stack_popt   children_stack_appendt   children_stack_extendt   children_stack_popR?   RA   t   childrent   deps_parentt   edgest   num_childrent	   child_keyt
   child_taskt
   child_keyst   heightt   widtht	   num_nodest   fudget   children_edgest   num_children_edgest   no_new_edgesRK   t   num_single_nodest   max_num_edgest   children_infot   cur_keyt   cur_taskt   cur_keyst
   cur_heightt	   cur_widtht   cur_num_nodest	   cur_fudget	   cur_edgest   children_depst
   child_infot	   cur_childt   root_keyt
   fused_keyst   alias(    (   R   s0   lib/python2.7/site-packages/dask/optimization.pyt   fuseË  sŠ   1	

		#
												

	
	

!


! 


% 


	"	


$ 

	



-
	
c         ` sÂ  i  } t  ƒ  } xµ ˆ  D]­ } | | } t | ƒ d k }	 xˆ | D]€ }
 | d k	 rm |
 | k rm | j |
 ƒ q? |
 | k r | |
 =| j |
 ƒ q? |	 r¦ | j |
 ƒ q? |
 | k r? | | |
 <q? q? Wq Wg  } d „  | j ƒ  Dƒ } xæ | rË| j ƒ  \ }
 } |
 | g } x3 | | k r?| j | ƒ } | | =| j | ƒ qW| j ƒ  x3 |
 | k r| j |
 ƒ }
 | |
 =| j |
 ƒ qMWd } x? | D]7 } | t	 ˆ  | ƒ 7} | d k r| j | ƒ PqqWqæ Wxï | D]ç } ‡  f d †  | Dƒ } | d } | | d } | | <x  | d D] } | | =ˆ  | =qWt
 | ƒ } t | | | ƒ f | ˆ  | <| rÓg  } xC | D]; } | j | t ƒ } | rœ| j | ƒ qn| j | ƒ qnW| | | <qÓqÓWd S(   sJ   Subroutine of fuse.

    Mutates dsk, depenencies, and fused_trees inplacei   c         S` s   i  |  ] \ } } | | “ q S(    (    (   R   R   R3   (    (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>  s   	 i    c         ` s   i  |  ] } ˆ  | | “ q S(    (    (   R   R   (   R   (    s0   lib/python2.7/site-packages/dask/optimization.pys
   <dictcomp>3  s   	 iÿÿÿÿN(   R   R-   R.   R   R6   R7   R8   R   R9   R   R,   t   SubgraphCallableR:   R…   (   R   R   R   R   R<   R=   R>   R?   R!   R@   RA   RB   RC   RD   t   ntasksRL   t   subgrapht   outkeyt
   inkeys_setR   t   inkeyst   chain2t   subchain(    (   R   s0   lib/python2.7/site-packages/dask/optimization.pyR‰     sh    	
	

s   [a-f]+c         C` s`  t  |  ƒ t k r! |  j ƒ  }  n  t  |  ƒ t k r@ |  d }  n  y|  j d ƒ } | d d j ƒ  s| | d j d ƒ } n
 | d } xX | d D]L } | j ƒ  rÜ t | ƒ d k oÇ t j	 | ƒ d k	 rÜ | d | 7} q‘ Pq‘ Wt | ƒ d k r	t j	 d | ƒ r	d S| d d	 k rB| j d
 ƒ j ƒ  d j d ƒ d } n  | SWn t k
 r[d SXd S(   sQ  
    >>> key_split('x')
    'x'
    >>> key_split('x-1')
    'x'
    >>> key_split('x-1-2-3')
    'x'
    >>> key_split(('x-2', 1))
    'x'
    >>> key_split("('x-2', 1)")
    'x'
    >>> key_split('hello-world-1')
    'hello-world'
    >>> key_split(b'hello-world-1')
    'hello-world'
    >>> key_split('ae05086432ca935f6eba409a8ecd4896')
    'data'
    >>> key_split('<module.submodule.myclass object at 0xdaf372')
    'myclass'
    >>> key_split(None)
    'Other'
    >>> key_split('x-abcdefab')  # ignores hex
    'x'
    >>> key_split('_(x)')  # strips unpleasant characters
    'x'
    i    R'   s   _'()"i   i   i    s   [a-f0-9]{32}t   datat   <s   <>t   .iÿÿÿÿt   OtherN(   R(   t   bytest   decodeR,   t   splitt   isalphat   stripR-   t   hex_patternt   matchR.   t   ret	   Exception(   t   st   wordst   resultt   word(    (    s0   lib/python2.7/site-packages/dask/optimization.pyR*   Q  s*    
$)R½   c           B` sM   e  Z d  Z d Z d d „ Z d „  Z d „  Z d	 „  Z d
 „  Z d „  Z	 RS(   sD  Create a callable object from a dask graph.

    Parameters
    ----------
    dsk : dict
        A dask graph
    outkey : hashable
        The output key from the graph
    inkeys : list
        A list of keys to be used as arguments to the callable.
    name : str, optional
        The name to use for the function.
    R   RÀ   RÂ   t   namet   subgraph_callablec         C` s(   | |  _  | |  _ | |  _ | |  _ d  S(   N(   R   RÀ   RÂ   RÖ   (   t   selfR   RÀ   RÂ   RÖ   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   __init__–  s    			c         C` s   |  j  S(   N(   RÖ   (   RØ   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   __repr__œ  s    c         C` sj   t  |  ƒ t  | ƒ k oi |  j | j k oi |  j | j k oi t |  j ƒ t | j ƒ k oi |  j | j k S(   N(   R(   R   RÀ   R   RÂ   RÖ   (   RØ   t   other(    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   __eq__Ÿ  s
    c         C` s   |  | k S(   N(    (   RØ   RÛ   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   __ne__¦  s    c         G` sn   t  | ƒ t  |  j ƒ k sC t d t  |  j ƒ t  | ƒ f ƒ ‚ n  t j |  j |  j t t |  j | ƒ ƒ ƒ S(   Ns   Expected %d args, got %d(	   R-   RÂ   t
   ValueErrorR   R   R   RÀ   R   t   zip(   RØ   t   args(    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   __call__©  s
    "c         C` s"   t  |  j |  j |  j |  j f f S(   N(   R½   R   RÀ   RÂ   RÖ   (   RØ   (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt
   __reduce__°  s    (   R   RÀ   RÂ   RÖ   (
   t   __name__t
   __module__t   __doc__t	   __slots__RÙ   RÚ   RÜ   RÝ   Rá   Râ   (    (    (    s0   lib/python2.7/site-packages/dask/optimization.pyR½   †  s   				(,   t
   __future__R    R   R   R‚   RÐ   t   operatorR   Rr   R   R   t   compatibilityR   R   R   R	   R
   R   R   R   t
   utils_testR   R   R&   R2   R.   R   RN   RO   R[   R:   Rc   Rf   R\   Rm   Rs   Ry   R¼   R‰   t   compileRÎ   R*   t   objectR½   (    (    (    s0   lib/python2.7/site-packages/dask/optimization.pyt   <module>   s6   4	.	‹	
:3			*			ÿ 9	I	5