o
    iS                  
   @   s  U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZmZmZmZ d dlZd dlmZ d dlmZ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(m)Z)m*Z*m+Z+ dd
l!m,Z- ddl!m.Z/ ddl!m0Z0 e	dddZ1e	e2 e3d< d dlm4Z4 ddl5m6Z6 ddl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< e4rddl=m>Z> dddZ?dd Z@dd ZAddeBddfddZCdede2fd d!ZDdede2fd"d#ZEdede2fd$d%ZFdede2fd&d'ZGdede2fd(d)ZHdede2fd*d+ZIdede2fd,d-ZJdede2fd.d/ZKdede2fd0d1ZLdede2fd2d3ZMdede2fd4d5ZNd6d7 ZOd8eBdd9fd:d;ZPde2fd<d=ZQdd8eBde2fd>d?ZRdd8eBde2fd@dAZSdBe8dCe8ddfdDdEZT	ddFdGdHe:dIeeB dJeUde9fdKdLZVdMdNdOee8e<e;ee8 f dPeBdeBfdQdRZWddSdTZXddUdVZYddWdXZZdYeege2f dZeegef dedefd[d\Z[dYeege2f dedefd]d^Z\		dd_e8d`e2daed ddbfdcddZ]ddedfdbdgedh de8fdidjZ^	dd_e8d`e2dke2ddlfdmdnZ_ddedodldgedh de8fdpdqZ`	dd_e8d`e2ddrfdsdtZaddedudrdgedh de8fdvdwZbedxZcdyedzecf d{ed|ededzecf fd}d~ZdG dd deeZfdegdyeeee2gef dOedHeddf
ddZhe jidddZje jidd Zke jiddegdeBfddZleG dd dZmg dZndS )    N)
ContextVar)	dataclass)AnyCallableDictListMappingOptionalSequenceTupleTypeVarUnioncast)Version)
ConfigDictValidationErrorcreate_model)table   )
cupycupy_from_dlpackhas_cupyhas_cupy_gpuhas_gpu	has_mxnethas_tensorflow	has_torchhas_torch_cuda_gpuhas_torch_mps)mxnet)
tensorflow)torchDATA_VALIDATIONF)default)TYPE_CHECKING)types)
ArgsKwargsArrayXdFloatsXdIntsXdPaddedRagged)Opsreturntorch.devicec                  C   s|   t d u rtdddlm}  ddlm} ddlm} |  }t||r/t j	
 }t d| S t||r9t dS t dS )	Nz<Cannot get default Torch device when Torch is not available.r   )get_current_ops)CupyOps)MPSOpszcuda:mpscpu)r!   
ValueErrorbackendsr/   backends.cupy_opsr0   backends.mps_opsr1   
isinstancecudacurrent_devicedevice)r/   r0   r1   ops	device_id r>   >/home/ubuntu/.local/lib/python3.10/site-packages/thinc/util.pyget_torch_default_device9   s   




r@   c                 C   s,   t | rtS t| rtS tdt|  d)Nz4Only numpy and cupy arrays are supported, but found z` instead. If get_array_module module wasn't called directly, this might indicate a bug in Thinc.)is_numpy_arraynumpyis_cupy_arrayr   r4   type)arrr>   r>   r?   get_array_moduleK   s   rF   c                   C   s   t S N)r   r>   r>   r>   r?   gpu_is_availableY   s   rH   seedc                 C   sl   t |  tj |  trt|  tr0tj |  tr2tr4tj	
|  dtjj_dtjj_dS dS dS dS )z@Set the random seed across random, numpy.random and cupy.random.TFN)randomrI   rB   r   r!   manual_seedr   r   r   r9   manual_seed_allr5   cudnndeterministic	benchmark)rI   r>   r>   r?   fix_random_seed]   s   


rP   objc                 C      t | pt| S )z1Check whether an object is a numpy or cupy array.)rA   rC   rQ   r>   r>   r?   is_xp_arrayk      rT   c                 C      t sdS t| tjrdS dS )z(Check whether an object is a cupy array.FT)r   r8   r   ndarrayrS   r>   r>   r?   rC   p   s
   rC   c                 C   s   t | tjrdS dS )z)Check whether an object is a numpy array.TF)r8   rB   rW   rS   r>   r>   r?   rA   z   s   rA   c                 C   s    t d u rdS t| t jrdS dS NFT)r!   r8   TensorrS   r>   r>   r?   is_torch_array   s
   rZ   c                 C   s   t | o| jS rG   )rZ   is_cudarS   r>   r>   r?   is_torch_cuda_array   s   r\   c                 C   rR   rG   )r\   is_torch_mps_arrayrS   r>   r>   r?   is_torch_gpu_array   s   r^   c                 C   s   t | ot| do| jS )Nis_mps)rZ   hasattrr_   rS   r>   r>   r?   r]      s   r]   c                 C   rV   rX   )r   r8   tfrY   rS   r>   r>   r?   is_tensorflow_array   s
   rb   c                 C   s   t | od| jv S )NzGPU:)rb   r;   rS   r>   r>   r?   is_tensorflow_gpu_array   s   rc   c                 C   s   t sdS t| tjjrdS dS rX   )r   r8   mxndNDArrayrS   r>   r>   r?   is_mxnet_array   s
   rg   c                 C   s   t | o	| jjdkS )Nr3   )rg   contextdevice_typerS   r>   r>   r?   is_mxnet_gpu_array   s   rj   c                 C   s2   t | tjr| S trt | tjr|  S t| S rG   )r8   rB   rW   r   r   getarray)datar>   r>   r?   to_numpy   s
   
rn   gpu_idzcupy.cuda.Devicec                 C   s6   t stdtjj| }|  trtj	|  |S )z=Set the current GPU device for cupy and torch (if available).zNo CUDA GPU devices detected)
r   r4   r   r9   r;   Deviceuser   r!   
set_device)ro   r;   r>   r>   r?   set_active_gpu   s   rs   c                  C   s$   ddl m} m} | d}|| dS )z'Use CPU through best available backend.r   )get_opsset_current_opsr3   T)r5   rt   ru   )rt   ru   r<   r>   r>   r?   require_cpu   s   rv   c                 C   s   t rt| d t S )z?Use GPU if it's available. Returns True if so, False otherwise.ro   )r   require_gpurw   r>   r>   r?   
prefer_gpu   s   
ry   c                 C   s   ddl m}m}m} t dkrtstrtdtdt dkr(t	s(tdt
s.tdtr;||  t|  dS ||  dS )	Nr   )r0   r1   ru   Darwinz6Cannot use GPU, installed PyTorch does not support MPSz(Cannot use GPU, PyTorch is not installedz%Cannot use GPU, CuPy is not installedzNo GPU devices detectedT)r5   r0   r1   ru   platformsystemr   r   r4   r   r   r   rs   )ro   r0   r1   ru   r>   r>   r?   rx      s   

rx   dstsrcc                 C   s^   t | tjrt |tjr|| d d < d S t| r'tj|dd}t| | d S t| | d S )NF)copy)r8   rB   rW   rC   r   rl   copyto)r}   r~   r>   r>   r?   
copy_array   s   r           )label_smoothingY	n_classesr   c                C   s   |d u rt t| d }|dk rtd|dkr$|dkr!tdd}n|dks0td| d||d  }|d | }|dkrR||krRtd| d	| d
| dt| }|j||f|dd}||d|  ||  S )Nr   r   z>Label-smoothing parameter has to be greater than or equal to 0r   zn_classes should be at least 1zGn_classes should be greater than 1 when label smoothing is enabled,but z was provided.zFor z7 classes label_smoothing parameter has to be less than z, but found .float32)dtype)intrB   maxr4   rF   fullfill_diagonal)r   r   r   nongold_prob
max_smoothxplabel_distrr>   r>   r?   to_categorical   s<   r   dimXr   c                C   s   t | trt| j|dS t | trt| j|dS t| drDt| drDtt| } t| j	dkr0dS t| j	dkr?t
|  d S | j	| S t | ttfr[t| dkrSdS t| d |dS d}t|)zrInfer the 'width' of a batch of data, which could be any of: Array,
    Ragged, Padded or Sequence of Arrays.
    r   shapendimr   r   z=Cannot get width of object: has neither shape nor __getitem__)r8   r+   	get_widthrm   r*   r`   r   r'   lenr   r   r   listtupler4   )r   r   errr>   r>   r?   r      s"   



r   c                  C   s   d} t st| jdddS )z4Raise an ImportError if TensorFlow is not installed.z~TensorFlow support requires {pkg}: pip install thinc[tensorflow]

Enable TensorFlow support with thinc.api.enable_tensorflow()ztensorflow>=2.0.0,<2.6.0)pkgN)r   ImportErrorformat)templater>   r>   r?   assert_tensorflow_installed<  s   r   c                   C      t stddS )z/Raise an ImportError if MXNet is not installed.zjMXNet support requires mxnet: pip install thinc[mxnet]

Enable MXNet support with thinc.api.enable_mxnet()N)r   r   r>   r>   r>   r?   assert_mxnet_installedC  s
   r   c                   C   r   )z1Raise an ImportError if PyTorch is not installed.z8PyTorch support requires torch: pip install thinc[torch]N)r   r   r>   r>   r>   r?   assert_pytorch_installedK  s   r   is_matchconvert_itemc                    s   |r |S t |trt t| }t|S t |tr>i }| D ]\}}t |}t |}|||< q'|S t |trM fdd|D S t |tr^t fdd|D S |S )zEither convert a single value if it matches a given function, or
    recursively walk over potentially nested lists, tuples and dicts applying
    the conversion, and returns the same type. Also supports the ArgsKwargs
    dataclass.
    c                    s   g | ]}t  |qS r>   convert_recursive.0itemr   r   r>   r?   
<listcomp>f  s    z%convert_recursive.<locals>.<listcomp>c                 3   s    | ]	}t  |V  qd S rG   r   r   r   r>   r?   	<genexpr>h  s    z$convert_recursive.<locals>.<genexpr>)r8   r&   r   r   items
from_itemsdictr   )r   r   rQ   	convertedkeyvaluer>   r   r?   r   Q  s"   





r   c                 c   s    | |r
|V  dS t |trt| t| E dH  dS t |tr=| D ]\}}t| |E dH  t| |E dH  q&dS t |tsGt |trT|D ]}t| |E dH  qIdS dS )zEither yield a single value if it matches a given function, or recursively
    walk over potentially nested lists, tuples and dicts yielding matching
    values. Also supports the ArgsKwargs dataclass.
    N)r8   r&   iterate_recursiver   r   r   r   )r   rQ   r   r   r   r>   r>   r?   r   m  s   


r   	xp_tensorrequires_gradr;   ztorch.Tensorc                 C   st   t   |du r
t }t| dr|  }tjj|}nt| dr(tjj| }nt| }|	|}|r8|
  |S )z3Convert a numpy or cupy tensor to a PyTorch tensor.NtoDlpack
__dlpack__)r   r@   r`   r   r!   utilsdlpackfrom_dlpack
from_numpytorequires_grad_)r   r   r;   dlpack_tensortorch_tensorr>   r>   r?   xp2torch  s   



r   )r<   r   r<   r,   c                C   sr   ddl m} t  t| r#t||r|    S tt	j
j| S t||s,|du r4|    S t| S )zConvert a torch tensor to a numpy or cupy tensor depending on the `ops` parameter.
    If `ops` is `None`, the type of the resultant tensor will be determined by the source tensor's device.
    r   NumpyOpsN)apir   r   r\   r8   detachr3   rB   r   r!   r   r   	to_dlpackr   asarray)r   r<   r   r>   r>   r?   torch2xp  s   

r   as_variablez	tf.Tensorc                 C   s   t   t| dr|  }tjj|}nt| dr%|  }tjj|}nt| }|rIt	|j	 tj
||d}W d   n1 sDw   Y  |du rm|du rmt	|j	 t|}W d   |S 1 shw   Y  |S )zAConvert a numpy or cupy tensor to a TensorFlow Tensor or Variabler   r   )	trainableNF)r   r`   r   ra   experimentalr   r   r   convert_to_tensorr;   Variablestop_gradient)r   r   r   r   	tf_tensorr>   r>   r?   xp2tensorflow  s&   



r   r   c                C   sj   ddl m} t  t| r!t||r|  S tjj	| }t
|S t||s*|du r.|  S t|  S )zConvert a Tensorflow tensor to numpy or cupy tensor depending on the `ops` parameter.
    If `ops` is `None`, the type of the resultant tensor will be determined by the source tensor's device.
    r   r   N)r   r   r   rc   r8   rB   ra   r   r   r   r   r   r   )r   r<   r   r   r>   r>   r?   tensorflow2xp  s   
r   zmx.nd.NDArrayc                 C   sB   t   t| dr|  }tj|}ntj| }|r|  |S )z1Convert a numpy or cupy tensor to a MXNet tensor.r   )r   r`   r   rd   re   r   r   attach_grad)r   r   r   	mx_tensorr>   r>   r?   xp2mxnet  s   
r   r   c                C   sh   ddl m} t  t| rt||r|   S t|  S t||s'|du r-|   S t	
|  S )z1Convert a MXNet tensor to a numpy or cupy tensor.r   r   N)r   r   r   rj   r8   r   asnumpyr   to_dlpack_for_writer   r   )r   r<   r   r>   r>   r?   mxnet2xp  s   
r   PartialTfunc.argskwargsc                 O   s$   t j| g|R i |}| j|_|S )znWrapper around functools.partial that retains docstrings and can include
    other workarounds if needed.
    )	functoolspartial__doc__)r   r   r   partial_funcr>   r>   r?   r     s   r   c                   @   sN   e Zd Zg fdedededeeeeef  ee	eef  f ddf
ddZ
dS )	DataValidationErrornamer   r   errorsr-   Nc                 C   s   d| d}dt | dt | }g }|D ]}ddd |dg D }	||	|d	f q||t|g}
t| d
d|
  dS )z8Custom error for validating inputs / outputs at runtime.zData validation error in ''zX: z Y: z -> c                 S   s   g | ]}t |qS r>   )strr   pr>   r>   r?   r     s    z0DataValidationError.__init__.<locals>.<listcomp>locmsgz


N)rD   joinrk   appendr   r4   __init__)selfr   r   r   r   message	type_inform   errorerr_locresultr>   r>   r?   r     s   zDataValidationError.__init__)__name__
__module____qualname__r   r   r   r
   r   r   r   r   r>   r>   r>   r?   r     s    "r   r   c           	      C   sr   t |}t jj}t|j }t|dkr7t| dddd |D  d}d| }t	| ||d|igd	S )
zValidate the input and output of a forward function against the type
    annotations, if available. Used in Model.initialize with the input and
    output samples as they pass through the network.
       z (z, c                 S   s   g | ]}|j qS r>   )r   r   r>   r>   r?   r   .  s    z-validate_fwd_input_output.<locals>.<listcomp>)zJInvalid forward function. Expected 3 arguments (model, X , is_train), got r   N)
inspect	signature	Signatureemptyr   
parametersvaluesr   r   r   )	r   r   r   r   sigr   params
bad_paramsr   r>   r>   r?   validate_fwd_input_output#  s   
$
r  rc                 c   s.    t j| dd}|V  |  t|j d S )NF)modedelete)tempfileNamedTemporaryFilecloseosremover   )r  fr>   r>   r?   make_tempfileO  s
   r  c                 c   sR    t   t }t|  d V  t| W d    d S 1 s"w   Y  d S rG   )	threadingLockr"   rk   set)
validationprevr>   r>   r?   data_validationW  s   

"r  r   id_colorc                 c   s6    t rtjj| | dV  tjj  dS dV  dS )zxContext manager to register the executed code as an NVTX range. The
    ranges can be used as markers in CUDA profiling.N)r   r   r9   nvtx	RangePushRangePop)r   r  r>   r>   r?   use_nvtx_range`  s   
r  c                   @   sF   e Zd ZU dZejed< ejed< ede	fddZ
de	fddZd	S )
	ArrayInfoz4Container for info for checking array compatibility.r   r   rE   c                 C   s   | |j |jdS )Nr   r   r  )clsrE   r>   r>   r?   
from_arrays  rU   zArrayInfo.from_arrayc                 C   sL   |j | j krtd| j  d|j  |j| jkr$td| j d|j d S )NzShape mismatch in backprop. Y: z, dY: zType mismatch in backprop. Y: )r   r4   r   )r   rE   r>   r>   r?   check_consistencyw  s   zArrayInfo.check_consistencyN)r   r   r   r   r%   Shape__annotations__DTypesclassmethodr'   r  r  r>   r>   r>   r?   r  l  s   
 

r  )rF   r@   rP   rC   rA   rs   ry   rx   r   r   r   r   r   r   r   r  r   r  r  r  r   r   )r-   r.   )r   rG   )r-   N)FN)FF)F)r  )r   )o
contextlibr   r   r	  r{   rJ   r  r  contextvarsr   dataclassesr   typingr   r   r   r   r   r	   r
   r   r   r   r   rB   packaging.versionr   pydanticr   r   r   wasabir   compatr   r   r   r   r   r   r   r   r   r   r   rd   r    ra   r!   r"   boolr  r$    r%   r&   r'   r(   r)   r*   r+   r   r,   r@   rF   rH   r   rP   rT   rC   rA   rZ   r\   r^   r]   rb   rc   rg   rj   rn   rs   rv   ry   rx   r   floatr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   r   r   r  contextmanagerr  r  r  r  __all__r>   r>   r>   r?   <module>   sF  
 40 

				

)




 









,
