
    bi+*                       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l
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 d d
lmZmZmZ d dl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 Z'	 	 	 	 ddZ(d Z)d Z*d Z+d Z,y)    )annotations)Callable)zip_longest)Integral)AnyN)config)AliasDataNode	GraphNodeTask_execute_subgraphconvert_legacy_graphfuse_linear_task_spec)getitem)gettergetter_inlinegetter_nofancy)
fuse_rootsoptimize_blockwise)flatten)HighLevelGraph)ensure_dictc                   t        |t        t        f      s|g}t        t        |            }t        | t              s!t	        j
                  t        |       | d      } t        | |      } t        | |      } | j                  t        |            } t        j                  d      du r| S t        |       } t        |       } t        | |      } t        |       } | S )zyOptimize dask for array computation

    1.  Cull tasks not necessary to evaluate keys
    2.  Perform linear fusion
     )dependencies)keyszoptimization.fuse.activeF)
isinstancelistsetr   r   from_collectionsidr   r   cullr   getr   r   r   _optimize_slices)dskr   kwargss      R/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/dask/array/optimization.pyoptimizer(   %   s     dT3K(vDc>*--bgsL
St
,C
St
$C
((3t9
C zz,-6

c
C
s
#C
$
/C
3
CJ    c                   t        | t              sy| j                  }|t        v r|}nyt	        | j
                        }|dk(  r'|| j
                  d   | j
                  d   |t        udfS |dk(  r|gt        | j
                        S y)zCheck if a value in a Dask graph looks like a getter.
    1. Is it a tuple with the first element a known getter.
    If a getter is found, it returns a tuple with (getter, array, index, asarray, lock).
    Otherwise it returns ``None``.
    N   r         )r   r   funcGETTERSlenargsr   r   )valuer.   r#   lengths       r'   _is_getter_taskr4   D   s     eT"::Dw_F{EJJqM5::a=#W2DdJJ	1%T%**%%%r)   c           
        t         t        j                  f| j                         } | j	                         D ]~  \  }}t        |t              r|j                  t        u s*|j                  d   }t               }|j	                         D ](  \  }}||v r|j                  |       t        |      x}s+|}|\  }	}
}}}d}|
j                  |v rt        ||
j                           x}r|j                  |
j                         |\  }}}}}t        |t              r|j                  }t        |t              r|j                  }|r||urn/t!        |      t"        u t!        |      t"        u k7  rn
t!        |      t"        u rL||z   }t%        |      t%        |      k7  rt'        d |D              rn|t(        u r8t'        fd|D              s$n|t(        u rt!        |      v st!        |      v rn	 t+        ||      }|t,        u rt.        n|}	t1        ||
j                        ||<   |
j                  }d}|||}}}
||z  }t        |
t              sn*|
j                  |v rt        ||
j                           x}r|s|	t4        u s|r|st        ||	|
|      ||<   t        ||	|
|||      ||<   +  | S # t2        $ r Y Iw xY w)a  Optimize slices
    1.  Fuse repeated slices, like x[5:][2:6] -> x[7:11]

    This is generally not very important since we are fusing those tasks anyway. There
    is one specific exception to how xarray implements opening netcdf files and subsequent
    slices. Not merging them together can cause reading the whole netcdf file before
    we drop the unnecessary data. Fusing slices avoids that pattern.

    See https://github.com/pydata/xarray/issues/9926
    r   Fc              3  $   K   | ]  }|d u  
 y wNr   ).0is     r'   	<genexpr>z#_optimize_slices.<locals>.<genexpr>   s      @*+AI@s   c              3  6   K   | ]  }t        |        y wr7   )r   )r8   r9   fancy_ind_typess     r'   r:   z#_optimize_slices.<locals>.<genexpr>   s      <?@Jq/:<s   T)r   npndarraycopyitemsr   r   r.   r   r1   r   addr4   keyr
   r2   typetupler0   anyr   
fuse_slicer   r   r	   NotImplementedErrorr   )r%   _vinner_graphseen	inner_keyinner_valuea_tasktemp_keyr#   aa_index	a_asarraya_lockfusedb_taskf2bb_index	b_asarrayb_lockindicesc_indexr<   s                          @r'   r$   r$   ^   s    RZZ(O
((*C		 N11d#2C(CFF1Iu&1&7&7&9 F	"I{D #(55v5$5;2QFee{*-k!%%.@AAFAHHQUUO8>5B7Iv!'84")--!'84")--&"6W.DMU4JKG}-")G"3w<3w<7C @/6@ = "/ <DK< 9 "~-W8=O;",Wg"> )+m(;f05h0FH-#$55 $ *+GVwA*I%a.] ee{*-k!%%.@AAFA^ G^	&
 -137,KK),0 #q'9f-K)IF	N` J+ / s   5AJ<<	KKc                    | j                   | j                  | j                  }}}|d}|d}|dk  s|dk  s||dk  r
t               t	        |||      S )zrReplace Nones in slices with integers

    >>> normalize_slice(slice(None, None, None))
    slice(0, None, 1)
    r   r,   )startstopsteprG   slice)sr^   r_   r`   s       r'   normalize_slicerc      sa     4E}|qyD1H 0TAX!##d##r)   c                    t        | |t        d             D ]2  \  }}t        |      t        ust	        |t
              s)t        d       y )N)	fillvaluezCan't handle normal indexing with integers and fancy indexing if the integers and fancy indices don't align with the same dimensions.)r   ra   rC   r   r   r   rG   )fancynormalfns       r'   #check_for_nonfusible_fancy_indexingrj      sK     E6U4[A 17$:a#:%2 r)   c                   |  t        |t              r|t        dd      k(  ryt        | t              rt        |       } t        |t              rt        |      }t        | t              r;t        |t              r+|dk  r
t	               | j
                  || j                  z  z   S t        | t              rt        |t              r| j
                  | j                  |j
                  z  z   }|j                  '| j
                  | j                  |j                  z  z   }nd}| j                  %|t        | j                  |      }n| j                  }| j                  |j                  z  }|dk(  rd}t        |||      S t        |t              r|D cg c]  }t        | |       c}S t        | t              rt        |t        t        f      r| |   S t        | t              rt        |t              s|f}t        | t              rDt        |t              r3t        d | D              }t        d |D              }|r|rt	        d      |rt        | |       n|rt        ||        d}t               }	t        t        |             D ]  }
t        | |
   t              s|t        |      k(  r|	j!                  | |
          9||   |	j!                  d       |dz  }||   |	j!                  t        | |
   ||                |dz  } |t        |      k  r(|	j!                  ||          |dz  }|t        |      k  r(t        |	      S t	               c c}w )a  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
    Nr   r,   c              3  <   K   | ]  }t        |t                y wr7   r   r   r8   items     r'   r:   zfuse_slice.<locals>.<genexpr>%       ?T*T40?   c              3  <   K   | ]  }t        |t                y wr7   rm   rn   s     r'   r:   zfuse_slice.<locals>.<genexpr>&  rp   rq   z#Can't handle multiple list indexing)r   ra   rc   r   rG   r^   r`   r_   minr   rF   rD   rE   rj   ranger0   append)rP   rW   r^   r_   r`   bba_has_listsb_has_listsjresultr9   s              r'   rF   rF      s   : 	yZ5)a5t3D.D !UA!UA!U
1h 7q5%''wwQVV##!U
1e 4!&&177**6677QVVaff_,DD661664(vvvv19DUD$''!T,-.b
1b!..!Tz!h->?t!UJq%$8D !U
1e 4?Q???Q??;%&KLL/15/15s1v 		A!A$)Q#a&[ad#A$,d#Q A$, MM*QqT1Q401FA		 #a&jMM!A$FA #a&j V}

I /s   M)r2   r   returnz3tuple[Callable, Any, Any, bool, bool | None] | None)-
__future__r   collections.abcr   	itertoolsr   numbersr   typingr   numpyr=   daskr   dask._task_specr	   r
   r   r   r   r   r   dask.array.chunkr   dask.array.corer   r   r   dask.blockwiser   r   	dask.corer   dask.highlevelgraphr   
dask.utilsr   r/   GETNOREMOVEr(   r4   r$   rc   rj   rF   r   r)   r'   <module>r      s    " $ !       % A A 9  . "
 >='
: ~&>84]@$  ` r)   