
    d#                    (   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
 ddlmZmZ ddlmZmZmZmZmZ ddlZddlmZ  ed	          Zerdd
lmZmZ  ej        d          dd            ZddZddZddZ  G d deee                   Z!dS )a  
The code in this module is an experiment in going from N=1 to N=2 parallel computing frameworks in xarray.
It could later be used as the basis for a public interface allowing any N frameworks to interoperate with xarray,
but for now it is just a private experiment.
    )annotationsN)ABCabstractmethod)IterableSequence)
EntryPointentry_points)TYPE_CHECKINGAnyCallableGenericTypeVaris_chunked_arrayT_ChunkedArray)T_ChunksT_NormalizedChunks   )maxsizereturn!dict[str, ChunkManagerEntrypoint]c                     t           j        dk    rt          d          } n"t                                          dd          } t	          |           S )z
    Return a dictionary of available chunk managers and their ChunkManagerEntrypoint objects.

    Notes
    -----
    # New selection mechanism introduced with Python 3.10. See GH6514.
    )   
   zxarray.chunkmanagers)group )sysversion_infor	   getload_chunkmanagers)entrypointss    :lib/python3.11/site-packages/xarray/core/parallelcompat.pylist_chunkmanagersr#      sM     7""")?@@@"nn(()?DDk***    r!   Sequence[EntryPoint]c                Z    d | D             }d |                                 D             }|S )z9Load entrypoints and instantiate chunkmanagers only once.c                B    i | ]}|j         |                                S r   )nameload).0
entrypoints     r"   
<dictcomp>z&load_chunkmanagers.<locals>.<dictcomp>5   s3       /9
**  r$   c                8    i | ]\  }}|j         | |            S r   )	available)r*   r(   chunkmanagers      r"   r,   z&load_chunkmanagers.<locals>.<dictcomp>9   s=       D,!llnn  r$   )items)r!   loaded_entrypointsavailable_chunkmanagerss      r"   r    r    0   sT    
 =H   "4":":"<"<  
 #"r$   manager#str | ChunkManagerEntrypoint | NoneChunkManagerEntrypointc                   t                      }| Dt          |          dk    r/t          t          |                                                    } nd} t          | t                    r.| |vr"t          d|  dt          |                     ||          S t          | t                    r| S t          dt          |                      )z
    Get namespace of chunk-handling methods, guessing from what's available.

    If the name of a specific ChunkManager is given (e.g. "dask"), then use that.
    Else use whatever is installed, defaulting to dask if there are multiple options.
    Nr   daskzunrecognized chunk manager z - must be one of: zRmanager must be a string or instance of ChunkManagerEntrypoint, but received type )r#   lennextiterkeys
isinstancestr
ValueErrorlistr5   	TypeErrortype)r3   chunkmanagerss     r"   guess_chunkmanagerrC   A   s     '((M}""4 2 2 4 45566GG G'3 
-''_g__$}J]J]__   W%%	G3	4	4 
paefmananpp
 
 	
r$   c                    t           t          t          j        hfd| D             }d |D             }t	          |          dk    rt          d|           t	          |          dk    rt          d          |d         t                      }fd|                                D             }|st          dt                               t	          |          d	k    rt          d
t                               |d         S )z
    Detects which parallel backend should be used for given set of arrays.

    Also checks that all arrays are of same chunking type (i.e. not a mix of cubed and dask).
    c                T    g | ]$}t          |          rt          |          v"|%S r   )r   rA   )r*   aALLOWED_NON_CHUNKED_TYPESs     r"   
<listcomp>z*get_chunked_array_type.<locals>.<listcomp>o   sG       A $(772K#K#K 	
#K#K#Kr$   c                ,    h | ]}t          |          S r   )rA   )r*   rF   s     r"   	<setcomp>z)get_chunked_array_type.<locals>.<setcomp>v   s    ;;;q477;;;r$   r   zJMixing chunked array types is not supported, but received multiple types: r   z,Expected a chunked array but none were foundc                >    g | ]}|                               |S r   r   )r*   r/   chunked_arrs     r"   rH   z*get_chunked_array_type.<locals>.<listcomp>   s=       ((55  r$   z5Could not find a Chunk Manager which recognises type    z&Multiple ChunkManagers recognise type )	intfloatnpndarrayr8   r@   r#   valuesrA   )argschunked_arrayschunked_array_typesrB   selectedrG   rL   s        @@r"   get_chunked_array_typerW   e   s`    "%eRZ 8     N <;N;;;
!##nYlnn
 
 	
 
 	!	!Q	&	&FGGG !#K&((M   )0022  H
  WDDUDUWW
 
 	
 
X!		TkARARTTUUU{r$   c                  D   e Zd ZU dZded<   dZded<   edPd	            ZdQdZedRd            Z	e	 	 	 	 dSdTd            Z
edUd            ZdVd ZedWd"            ZedXd#            Z	 	 	 	 	 dYdZd.Zedd$ddd/d[d9            Zddddd:d\d>Zdddd?d]dGZd^dIZd_dOZdS )`r5   aJ  
    Adapter between a particular parallel computing framework and xarray.

    Attributes
    ----------
    array_cls
        Type of the array class this parallel computing framework provides.

        Parallel frameworks need to provide an array class that supports the array API standard.
        Used for type checking.
    ztype[T_ChunkedArray]	array_clsTboolr.   r   Nonec                    t                      NNotImplementedErrorselfs    r"   __init__zChunkManagerEntrypoint.__init__       !###r$   datar   c                ,    t          || j                  S r]   )r<   rY   ra   rd   s     r"   r   z'ChunkManagerEntrypoint.is_chunked_array   s    $///r$   r   r   c                    t                      r]   r^   rf   s     r"   chunkszChunkManagerEntrypoint.chunks   rc   r$   Nrh   T_Chunks | T_NormalizedChunksshapetuple[int, ...] | Nonelimit
int | Nonedtypenp.dtype | Noneprevious_chunksT_NormalizedChunks | Nonec                    t                      )zCalled by open_datasetr^   )ra   rh   rj   rl   rn   rp   s         r"   normalize_chunksz'ChunkManagerEntrypoint.normalize_chunks   s     "###r$   
np.ndarrayr   c                    t                      )zMCalled when .chunk is called on an xarray object that is not already chunked.r^   ra   rd   rh   kwargss       r"   
from_arrayz!ChunkManagerEntrypoint.from_array   s    
 "###r$   /T_NormalizedChunks | tuple[int, ...] | T_Chunksc                     |j         |fi |S )zICalled when .chunk is called on an xarray object that is already chunked.)rechunkrv   s       r"   r{   zChunkManagerEntrypoint.rechunk   s     t|F--f---r$   tuple[np.ndarray, ...]c                    t                      )zLUsed anytime something needs to computed, including multiple arrays at once.r^   )ra   rd   rw   s      r"   computezChunkManagerEntrypoint.compute        "###r$   c                    t                      )zGReturn the array_api namespace following the python array API standard.r^   r`   s    r"   	array_apiz ChunkManagerEntrypoint.array_api   r   r$   Farrfuncr   combine_funcCallable | Noneaggregate_funcaxisint | Sequence[int] | Nonekeepdimsc                    t                      )zEUsed in some reductions like nanfirst, which is used by groupby.firstr^   )ra   r   r   r   r   r   rn   r   s           r"   	reductionz ChunkManagerEntrypoint.reduction        "###r$   )axesr   output_dtypes	vectorize	signaturer=   rS   r    Sequence[tuple[int, ...]] | Noner   $Sequence[np.typing.DTypeLike] | Noner   bool | Nonec                   t                      )z
        Called inside xarray.apply_ufunc, so must be supplied for vast majority of xarray computations to be supported.
        r^   )	ra   r   r   r   r   r   r   rS   rw   s	            r"   apply_gufuncz#ChunkManagerEntrypoint.apply_gufunc   s     "###r$   )rn   rh   	drop_axisnew_axisnp.typing.DTypeLike | Noner   r   c                   t                      )zNCalled in elementwise operations, but notably not called in xarray.map_blocks.r^   )ra   r   rn   rh   r   r   rS   rw   s           r"   
map_blocksz!ChunkManagerEntrypoint.map_blocks   r   r$   )adjust_chunksnew_axesalign_arraysout_indr   r   dict[Any, Callable] | Noner   dict[Any, int] | Noner   c                   t                      )z)Called by some niche functions in xarray.r^   )ra   r   r   r   r   r   rS   rw   s           r"   	blockwisez ChunkManagerEntrypoint.blockwise   r   r$   :tuple[dict[str, T_NormalizedChunks], list[T_ChunkedArray]]c                    t                      )zCalled by xr.unify_chunks.r^   )ra   rS   rw   s      r"   unify_chunksz#ChunkManagerEntrypoint.unify_chunks	  s     "###r$   sources)T_ChunkedArray | Sequence[T_ChunkedArray]targetsrw   dict[str, Any]c                    t                      )z!Used when writing to any backend.r^   )ra   r   r   rw   s       r"   storezChunkManagerEntrypoint.store  s     "###r$   )r   r[   )rd   r   r   rZ   )rd   r   r   r   )NNNN)rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   r   r   )rd   rt   rh   r   r   r   )rd   r   rh   ry   r   r   )rd   r   r   r|   )r   r   )NNNNF)r   r   r   r   r   r   r   r   r   r   rn   ro   r   rZ   r   r   )r   r   r   r=   rS   r   r   r   r   rZ   r   r   r   r   )r   r   rS   r   rn   r   rh   rk   r   r   r   r   )r   r   r   r   rS   r   r   r   r   r   r   rZ   )rS   r   r   r   )r   r   r   r   rw   r   )__name__
__module____qualname____doc____annotations__r.   r   rb   r   rh   rs   rx   r{   r~   propertyr   r   r   r   r   r   r   r   r$   r"   r5   r5      s        
 
 $###I$ $ $ ^$0 0 0 0 $ $ $ ^$  )- !%59	$ 	$ 	$ 	$ ^	$ $ $ $ ^$. . . . $ $ $ ^$ $ $ $ X$ )-*.+/!%$ $ $ $ $  26>B!%$ $ $ $ $ ^$( -1)-04/3$ $ $ $ $ $$ 59*.!$ $ $ $ $ $$ $ $ $$ $ $ $ $ $r$   )r   r   )r!   r%   r   r   )r3   r4   r   r5   )r   r5   )"r   
__future__r   	functoolsr   abcr   r   collections.abcr   r   importlib.metadatar   r	   typingr
   r   r   r   r   numpyrP   xarray.core.pycompatr   r   xarray.core.typesr   r   	lru_cacher#   r    rC   rW   r5   r   r$   r"   <module>r      s   
 # " " " " "     



 # # # # # # # # . . . . . . . . 7 7 7 7 7 7 7 7                  1 1 1 1 1 1)** ?>>>>>>>> Q+ + +  + # # # #"!
 !
 !
 !
H( ( ( (VH$ H$ H$ H$ H$S'."9 H$ H$ H$ H$ H$r$   