
    h!                        % S SK r S SKrS SKJr  S SKJrJrJrJrJ	r	J
r
  SSKJr  SSKJrJr  SSKJrJrJrJrJr  SS	KJrJr  SS
KJr  SSKJr  SSKJr  SSKJ r   SSK!J"r"  \" SSS9r#\\\"      \$S'   \" S0 S9r%\\&   \$S'   SS0r'S\(SS4S jr)S%S jr*S%S jr+S r,S\(S\"4S jr-S r.\ R^                  S\(4S j5       r0S\"4S jr1S\"SS4S jr2S\34S jr4S  r5\Rl                  4S!\\(\4   S"\	\Rl                     4S# jjr7/ S$Qr8g)&    N)
ContextVar)AnyCallableDictOptionalTypecast   )registry)cupyhas_cupy)assert_pytorch_installedassert_tensorflow_installedget_torch_default_deviceis_cupy_arrayrequire_cpu   )cupy_pytorch_allocatorcupy_tensorflow_allocator)ParamServer)CupyOps)MPSOps)NumpyOps)Opscontext_ops)defaultcontext_poolsops	allocatorreturnc                 d    U S:X  a  [        5         gU S:X  a  [        5         g[        SU  S35      e)z~Route GPU memory allocation via PyTorch or tensorflow.
Raise an error if the given argument does not match either of the two.
pytorch
tensorflowz#Invalid 'gpu_allocator' argument: 'z4'. Available allocators are: 'pytorch', 'tensorflow'N)use_pytorch_for_gpu_memoryuse_tensorflow_for_gpu_memory
ValueErrorr   s    Q/home/james-whalen/.local/lib/python3.13/site-packages/thinc/backends/__init__.pyset_gpu_allocatorr)      s:     I"$	l	"%'1)<pq
 	
    c                     [        5         [        5       R                  S:w  a  g[        R	                  5       n SU ;  a$  [
        R                  R                  [        S9U S'   [
        R                  R                  U S   R                  5        g)a\  Route GPU memory allocation via PyTorch.

This is recommended for using PyTorch and cupy together, as otherwise
OOM errors can occur when there's available memory sitting in the other
library's pool.

We'd like to support routing Tensorflow memory allocation via PyTorch as well
(or vice versa), but do not currently have an implementation for it.
cudaNr"   r'   )r   r   typer   getr   r,   
MemoryPoolr   set_allocatormallocpoolss    r(   r$   r$   ,   sn     !&&&0E99//:P/QiIIE),334r*   c                      [        5         [        R                  5       n SU ;  a$  [        R                  R                  [        S9U S'   [        R                  R                  U S   R                  5        g)ab  Route GPU memory allocation via TensorFlow.

This is recommended for using TensorFlow and cupy together, as otherwise
OOM errors can occur when there's available memory sitting in the other
library's pool.

We'd like to support routing PyTorch memory allocation via Tensorflow as
well (or vice versa), but do not currently have an implementation for it.
r#   r'   N)	r   r   r.   r   r,   r/   r   r0   r1   r2   s    r(   r%   r%   A   sZ      !E5 "ii22=V2WlIIE,/667r*   c                  `     SSK Jn    SSKJn  g ! [         a     Nf = f! [         a     g f = f)Nr   )AppleOps)BigEndianOps)thinc_apple_opsr6   ImportErrorthinc_bigendian_opsr7   )r6   r7   s     r(   _import_extra_cpu_backendsr;   R   s9    ,4    s      

--namec                 |   [         R                  R                  5       R                  5        Vs0 s H  o"R                  U_M     nnSnU S:X  a@  [        5         UR                  S5      nUR                  SU5      nUR                  SU5      nOUR                  U 5      nUc  [        SU  35      eU" S0 UD6$ s  snf )zUGet a backend object.

The special name "cpu" returns the best available CPU backend.Ncpunumpyapple	bigendianzInvalid backend:  )r   r   get_allvaluesr<   r;   r.   r&   )r<   kwargsops_clsops_by_nameclss        r(   get_opsrI   ]   s    
 9A8L8L8N8U8U8WX8WW<<(8WKX(,Cu}"$oog&oogs+ook3/ood#
{,TF344== Ys   B9c                 J    [        U 5      (       a
  [        5       $ [        5       $ )z4Return CupyOps for a cupy array, NumpyOps otherwise.)r   r   r   )arrs    r(   get_array_opsrL   s   s    Syzr*   c              +      #    [        5       n[        [        U 40 UD65         Sv   [        U5        g! [        U5        f = f7f)z<Change the backend to execute on for the scope of the block.N)get_current_opsset_current_opsrI   )r<   rE   current_opss      r(   use_opsrQ   {   s9      "#KGD+F+,%$$s    A3 AA  Ac                      [         R                  5       c
  [        5         [        [        [         R                  5       5      $ )zGet the current backend object.)r   r.   r   r	   r   rB   r*   r(   rN   rN      s(     [__&''r*   c                 L    [         R                  U 5        U [        5       l        g)z"Change the current backend object.N)r   set_get_thread_stater   )r   s    r(   rO   rO      s    OOC!r*   c                      [         R                  5       n [        5       R                  n[	        U 5      [	        U5      :X  a  gg)NTF)r   r.   rU   r   r-   )rP   
thread_opss     r(   contextvars_eq_thread_opsrX      s4    //#K"$((JKD,,r*   c                      [         R                  " 5       n [        U S5      (       d  [        [        5      U l        U R
                  $ )zYGet a thread-specific state variable that inherits from a global
state when it's created.__local)	threadingcurrent_threadhasattr_create_thread_local_GLOBAL_STATErZ   )threads    r(   rU   rU      s5      )779F69%%-m<>>r*   attrslocal_classc                 ^    U" 5       nU R                  5        H  u  p4[        X#U5        M     U$ )N)itemssetattr)ra   rb   objr<   values        r(   r^   r^      s,     -C{{}5! %Jr*   )	rO   rN   rQ   r   r   r   r   r   r   )r    N)9
contextlibr[   contextvarsr   typingr   r   r   r   r   r	    r   compatr   r   utilr   r   r   r   r   _cupy_allocatorsr   r   _param_serverr   cupy_opsr   mps_opsr   	numpy_opsr   r   r   r   __annotations__r   dictr_   strr)   r$   r%   r;   rI   rL   contextmanagerrQ   rN   rO   boolrX   rU   localr^   __all__rB   r*   r(   <module>rz      s7     " < <  #  P &    )3M4)PZ& P",_b"Iz$ I 
 
 
5*8"# C , %# % %( (" " "4  AJS>(,Y__(=
r*   