o
    i!                     @   s  U d dl 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
 ddl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mZ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!m"Z" edddZ#eee"  e$d< edi dZ%ee& e$d< ddiZ'de(ddfddZ)d1ddZ*d1ddZ+dd Z,de(de"fddZ-d d! Z.e j/de(fd"d#Z0de"fd$d%Z1de"ddfd&d'Z2de3fd(d)Z4d*d+ Z5ej6fd,ee(ef d-e	ej6 fd.d/Z7g d0Z8dS )2    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                 C   s4   | dkr	t   dS | dkrt  dS td|  d)zRoute 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    r&   K/home/ubuntu/.local/lib/python3.10/site-packages/thinc/backends/__init__.pyset_gpu_allocator   s   


r(   c                  C   sN   t   t jdkrdS t } d| vrtjjtd| d< tj	| d j
 dS )at  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poolsr&   r&   r'   r"   ,   s   
r"   c                  C   s>   t   t } d| vrtjjtd| d< tj| d j dS )az  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   r-   r.   r/   r&   r&   r'   r#   A   s
   
r#   c                  C   sL   zddl m}  W n	 ty   Y nw z	ddlm} W d S  ty%   Y d S w )Nr   )AppleOps)BigEndianOps)thinc_apple_opsr1   ImportErrorthinc_bigendian_opsr2   )r1   r2   r&   r&   r'   _import_extra_cpu_backendsR   s   r6   namec                 K   s|   dd t j  D }d}| dkr't  |d}|d|}|d|}n|| }|du r7td|  |d	i |S )
zYGet a backend object.

    The special name "cpu" returns the best available CPU backend.c                 S   s   i | ]}|j |qS r&   )r7   ).0ops_clsr&   r&   r'   
<dictcomp>b   s    zget_ops.<locals>.<dictcomp>Ncpunumpyapple	bigendianzInvalid backend: r&   )r
   r   get_allvaluesr6   r+   r$   )r7   kwargsops_by_nameclsr&   r&   r'   get_ops]   s   

rD   c                 C   s   t | rt S t S )z4Return CupyOps for a cupy array, NumpyOps otherwise.)r   r   r   )arrr&   r&   r'   get_array_opss   s   rF   c                 k   s<    t  }tt| fi | z
dV  W t| dS t| w )z<Change the backend to execute on for the scope of the block.N)get_current_opsset_current_opsrD   )r7   rA   current_opsr&   r&   r'   use_ops{   s   rJ   c                   C   s    t  du r	t  ttt  S )zGet the current backend object.N)r   r+   r   r   r   r&   r&   r&   r'   rG      s   rG   c                 C   s   t |  | t _dS )z"Change the current backend object.N)r   set_get_thread_stater   )r   r&   r&   r'   rH      s   
rH   c                  C   s(   t  } t j}t| t|krdS dS )NTF)r   r+   rL   r   r*   )rI   
thread_opsr&   r&   r'   contextvars_eq_thread_ops   s
   rN   c                  C   s"   t  } t| dstt| _| jS )z]Get a thread-specific state variable that inherits from a global
    state when it's created.__local)	threadingcurrent_threadhasattr_create_thread_local_GLOBAL_STATErO   )threadr&   r&   r'   rL      s   

rL   attrslocal_classc                 C   s(   | }|   D ]
\}}t||| q|S )N)itemssetattr)rV   rW   objr7   valuer&   r&   r'   rS      s   rS   )	rH   rG   rJ   r   r   r   r   r   r   )r   N)9
contextlibrP   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   dictrT   strr(   r"   r#   r6   rD   rF   contextmanagerrJ   rG   rH   boolrN   rL   localrS   __all__r&   r&   r&   r'   <module>   sF   
  





	