
    hS              
          % S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	  S SK
Jr  S SKJrJrJrJrJrJrJrJrJrJrJr  S SKrS SKJr  S SKJrJrJr  S SKJ r   SS	K!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  SS
K!J,r-  SSK!J.r/  SSK!J0r0  \	" SSS9r1\	\2   \3S'   S SKJ4r4  SSK5J6r6  SSK6J7r7J8r8J9r9J:r:J;r;J<r<  \4(       a  SSK=J>r>  ShS jr?S r@S rASiS\BSS4S jjrCS\S\24S jrDS\S\24S jrES\S\24S jrFS\S\24S jrGS\S\24S  jrHS\S\24S! jrIS\S\24S" jrJS\S\24S# jrKS\S\24S$ jrLS\S\24S% jrMS\S\24S& jrNS' rOS(\BSS)4S* jrPS\24S+ jrQSiS(\BS\24S, jjrRSiS(\BS\24S- jjrSS.\8S/\8SS4S0 jrT SjS1S2.S3\:S4\\B   S5\US\94S6 jjjrVS7S8.S9\\8\<\;\\8   4   S:\BS\B4S; jjrWSkS< jrXSkS= jrYSkS> jrZS?\\/\24   S@\\/\4   S\S\4SA jr[S?\\/\24   S\S\4SB jr\  SlSC\8SD\2SE\S   SSF4SG jjr]SSH.SISFSJ\SK   S\84SL jjr^ SmSC\8SD\2SM\2SSN4SO jjr_SSH.SPSNSJ\SK   S\84SQ jjr` SnSC\8SD\2SSR4SS jjraSSH.STSRSJ\SK   S\84SU jjrb\" SV5      rcSW\SX\c4   SY\SZ\S\SX\c4   4S[ jrd " S\ S]\e5      rfS^\gSW\\\\2/\4   S9\S3\SS4
S_ jrh\ R                  SoS` j5       rj\ R                  Sa 5       rk\ R                  SpSb\gSc\B4Sd jj5       rl\ " Se Sf5      5       rm/ SgQrng)q    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5      eSSKJn   SSKJn  SSKJn  U " 5       n[        X15      (       a7  [         R                  R                  5       n[         R                  " SU 35      $ [        X25      (       a  [         R                  " S5      $ [         R                  " S5      $ )	Nz<Cannot get default Torch device when Torch is not available.r   )get_current_ops)CupyOps)MPSOpszcuda:mpscpu)r"   
ValueErrorbackendsr1   backends.cupy_opsr2   backends.mps_opsr3   
isinstancecudacurrent_devicedevice)r1   r2   r3   ops	device_ids        D/home/james-whalen/.local/lib/python3.13/site-packages/thinc/util.pyget_torch_default_devicerA   9   s    }WXX)*(

C#JJ--/	||eI;/00	C	 	 ||E""<<    c                     [        U 5      (       a  [        $ [        U 5      (       a  [        $ [	        S[        U 5       S35      e)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   r6   type)arrs    r@   get_array_modulerI   K   sG    c	s		9+ &<<
 	
rB   c                      [         $ N)r    rB   r@   gpu_is_availablerM   Y   s    NrB   seedc                    [         R                  " U 5        [        R                   R                  U 5        [        (       a  [        R
                  " U 5        [        (       a  [        R                   R                  U 5        [        (       aj  [        (       a^  [        R                  R                  U 5        S[        R                  R                  l        S[        R                  R                  l        gggg)z@Set the random seed across random, numpy.random and cupy.random.TFN)randomrN   rE   r   r"   manual_seedr   r   r   r;   manual_seed_allr7   cudnndeterministic	benchmark)rN   s    r@   fix_random_seedrV   ]   s    
KK	LLdy$|9++JJ&&t,15ENN  .-2ENN  * ,9 rB   objc                 <    [        U 5      =(       d    [        U 5      $ )z1Check whether an object is a numpy or cupy array.)rD   rF   rW   s    r@   is_xp_arrayrZ   k   s    #4-"44rB   c                 \    [         (       d  g[        U [        R                  5      (       a  gg)z(Check whether an object is a cupy array.FT)r   r:   r   ndarrayrY   s    r@   rF   rF   p   s!    8	C	&	&rB   c                 D    [        U [        R                  5      (       a  gg)z)Check whether an object is a numpy array.TF)r:   rE   r\   rY   s    r@   rD   rD   z   s    #u}}%%rB   c                 T    [         c  g[        U [         R                  5      (       a  ggNFT)r"   r:   TensorrY   s    r@   is_torch_arrayra      s!    }	C	&	&rB   c                 >    [        U 5      =(       a    U R                  $ rK   )ra   is_cudarY   s    r@   is_torch_cuda_arrayrd      s    #.3;;.rB   c                 <    [        U 5      =(       d    [        U 5      $ rK   )rd   is_torch_mps_arrayrY   s    r@   is_torch_gpu_arrayrg      s    s#>'9#'>>rB   c                 d    [        U 5      =(       a    [        U S5      =(       a    U R                  $ )Nis_mps)ra   hasattrri   rY   s    r@   rf   rf      s"    #H73#9HcjjHrB   c                 \    [         (       d  g[        U [        R                  5      (       a  ggr_   )r   r:   tfr`   rY   s    r@   is_tensorflow_arrayrm      s!    >	C	#	#rB   c                 D    [        U 5      =(       a    SU R                  ;   $ )NzGPU:)rm   r=   rY   s    r@   is_tensorflow_gpu_arrayro      s    s#<#**(<<rB   c                 p    [         (       d  g[        U [        R                  R                  5      (       a  ggr_   )r   r:   mxndNDArrayrY   s    r@   is_mxnet_arrayrt      s%    9	C	'	'rB   c                 X    [        U 5      =(       a    U R                  R                  S:g  $ )Nr5   )rt   contextdevice_typerY   s    r@   is_mxnet_gpu_arrayrx      s!    #C3;;#:#:e#CCrB   c                     [        U [        R                  5      (       a  U $ [        (       a/  [        U [        R                  5      (       a  U R                  5       $ [        R                  " U 5      $ rK   )r:   rE   r\   r   r   getarray)datas    r@   to_numpyr}      sH    $&&	jt||44xxz{{4  rB   gpu_idzcupy.cuda.Devicec                     [         (       d  [        S5      e[        R                  R                  R                  U 5      nUR                  5         [        (       a  [        R                  R                  U 5        U$ )z=Set the current GPU device for cupy and torch (if available).zNo CUDA GPU devices detected)
r   r6   r   r;   r=   Deviceuser   r"   
set_device)r~   r=   s     r@   set_active_gpur      sS    <788YY$$V,F
JJL

f%MrB   c                  4    SSK Jn Jn  U " S5      nU" U5        g)z'Use CPU through best available backend.r   )get_opsset_current_opsr5   T)r7   r   r   )r   r   r>   s      r@   require_cpur      s    2
%.CCrB   c                 6    [         (       a	  [        U S9  [         $ )z?Use GPU if it's available. Returns True if so, False otherwise.r~   )r   require_gpur   s    r@   
prefer_gpur      s    w6"NrB   c                    SSK JnJnJn  [        R
                  " 5       S:X  a,  [        (       d!  [        (       a  [        S5      e[        S5      e[        R
                  " 5       S:w  a  [        (       d  [        S5      e[        (       d  [        S5      e[        (       a  U" U" 5       5        [        U 5        gU" U" 5       5        g)	Nr   )r2   r3   r   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)r7   r2   r3   r   platformsystemr   r   r6   r   r   r   r   )r~   r2   r3   r   s       r@   r   r      s    ::H$]]9UVVCDD		h	&xx@AAW233|	"v  	!rB   dstsrcc                 .   [        U [        R                  5      (       a$  [        U[        R                  5      (       a  XS S & g [        U 5      (       a,  [        R
                  " USS9n[        R                  " X5        g [        R                  " X5        g )NF)copy)r:   rE   r\   rF   r   r{   copyto)r   r   s     r@   
copy_arrayr      s]    #u}}%%*S%--*H*HA	s		jj5)CSrB           )label_smoothingY	n_classesr   c          	         Uc"  [        [        R                  " U 5      S-   5      nUS:  a  [        S5      eUS:X  a  US:X  a  [        S5      eSnOUS:  d  [        SU S35      eX!S-
  -  nUS-
  U-  nUS:  a  X$:  a  [        SU S	U S
U S35      e[	        U 5      nUR                  X4USS9nUR                  USU-
  5        X`   $ )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)intrE   maxr6   rI   fullfill_diagonal)r   r   r   nongold_prob
max_smoothxplabel_distrs          r@   to_categoricalr      s    		!q()	L
 	
 #>=>>1} k1  'a-8a-9,J1}69+ =l,&7q:
 	
 
!	B''90,i'PK[!o"56>rB   dimXr   c                P   [        U [        5      (       a  [        U R                  US9$ [        U [        5      (       a  [        U R                  US9$ [        U S5      (       a  [        U S5      (       an  [        [        U 5      n [        U R                  5      S:X  a  g[        U R                  5      S:X  a  [        U R                  5       5      S-   $ U R                  U   $ [        U [        [        45      (       a  [        U 5      S:X  a  g[        U S   US9$ Sn[        U5      e)zjInfer 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__)r:   r,   	get_widthr|   r+   rj   r   r(   lenr   r   r   listtupler6   )r   r   errs      r@   r   r      s     !VS))	Av		S))	G		F!3!3!qww<1\Qquuw<!##773<	Ae}	%	%q6Q;QqTs++MorB   c                  N    Sn [         (       d  [        U R                  SS95      eg)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)templates    r@   assert_tensorflow_installedr   <  s+     RH>(//.H/IJJ rB   c                  0    [         (       d  [        S5      eg)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   rL   rB   r@   assert_mxnet_installedr   C  s    9z
 	
 rB   c                  0    [         (       d  [        S5      eg)z1Raise an ImportError if PyTorch is not installed.z8PyTorch support requires torch: pip install thinc[torch]N)r   r   rL   rB   r@   assert_pytorch_installedr   K  s    9TUU rB   is_matchconvert_itemc                 8  ^ ^ T " U5      (       a  T" U5      $ [        U[        5      (       a:  [        T T[        UR	                  5       5      5      n[        R
                  " U5      $ [        U[        5      (       a;  0 nUR	                  5        H#  u  pE[        T TU5      n[        T TU5      nXSU'   M%     U$ [        U[        5      (       a  U Vs/ s H  n[        T TU5      PM     sn$ [        U[        5      (       a  [        UU 4S jU 5       5      $ U$ s  snf )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              3   >   >#    U  H  n[        TTU5      v   M     g 7frK   )convert_recursive).0itemr   r   s     r@   	<genexpr>$convert_recursive.<locals>.<genexpr>h  s      UQT&xtDDQTs   )r:   r'   r   r   items
from_itemsdictr   )r   r   rW   	convertedkeyvaluer   s   ``     r@   r   r   Q  s     }}C  	C	$	$%hd399;>OP	$$Y//	C			))+JC#HlC@C%heDE"cN & 	C		LOPCD!(L$?CPP	C		UQTUUU
	 Qs   Dc              #     #    U " U5      (       a  Uv   g[        U[        5      (       a,  [        U [        UR	                  5       5      5       Sh  vN   g[        U[
        5      (       a@  UR	                  5        H+  u  p#[        X5       Sh  vN   [        X5       Sh  vN   M-     g[        U[        5      (       d  [        U[        5      (       a  U H  n[        X5       Sh  vN   M     gg N Nf NU N7f)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)r:   r'   iterate_recursiver   r   r   r   )r   rW   r   r   r   s        r@   r   r   m  s     
 }}		C	$	$$XtCIIK/@AAA	C		))+JC(777(999 & 
C		*S%"8"8D(888  #9 	B 89 9sI   AC;C3=C;C5C;!C7"AC;(C9)C;5C;7C;9C;	xp_tensorrequires_gradr=   ztorch.Tensorc                    [        5         Uc
  [        5       n[        U S5      (       a:  U R                  5       n[        R
                  R                  R                  U5      nOQ[        U S5      (       a*  [        R
                  R                  R                  U 5      nO[        R                  " U 5      nUR                  U5      nU(       a  UR                  5         U$ )z3Convert a numpy or cupy tensor to a PyTorch tensor.toDlpack
__dlpack__)r   rA   rj   r   r"   utilsdlpackfrom_dlpack
from_numpytorequires_grad_)r   r   r=   dlpack_tensortorch_tensors        r@   xp2torchr     s     ~)+y*%%!**,{{))55mD	L	)	){{))55i@''	2??6*L##%rB   )r>   r   r>   r-   c                   SSK Jn  [        5         [        U 5      (       an  [	        X5      (       a,  U R                  5       R                  5       R                  5       $ [        [        R                  R                  R                  U 5      5      $ [	        X5      (       d  Uc,  U R                  5       R                  5       R                  5       $ [        R                  " U 5      $ )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   NumpyOps)apir   r   rd   r:   detachr5   rE   r   r"   r   r   	to_dlpackr   asarray)r   r>   r   s      r@   torch2xpr     s     <((c$$&&(,,.4466#EKK$6$6$@$@$NOOc$$&&(,,.4466<<--rB   as_variablez	tf.Tensorc                    [        5         [        U S5      (       a:  U R                  5       n[        R                  R
                  R                  U5      nOa[        U S5      (       a:  U R                  5       n[        R                  R
                  R                  U5      nO[        R                  " U 5      nU(       a=  [        R                  " UR                  5         [        R                  " XAS9nSSS5        USL aF  USL aA  [        R                  " UR                  5         [        R                  " U5      nSSS5        U$ U$ ! , (       d  f       N[= f! , (       d  f       U$ = f)zAConvert a numpy or cupy tensor to a TensorFlow Tensor or Variabler   r   )	trainableNF)r   rj   r   rl   experimentalr   r   r   convert_to_tensorr=   Variablestop_gradient)r   r   r   r   	tf_tensors        r@   xp2tensorflowr     s	     !y*%%!**,OO**66}E		L	)	)!,,.OO**66}E	((3	 YYy''(IGI )+"6 YYy''(((3I )9 )(
 )(s   E%E
E
E(r   c                x   SSK Jn  [        5         [        U 5      (       aT  [	        X5      (       a  U R                  5       $ [        R                  R                  R                  U 5      n[        U5      $ [	        X5      (       d  Uc  U R                  5       $ [        R                  " U R                  5       5      $ )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   )r   r   r   ro   r:   rE   rl   r   r   r   r   r   r   )r   r>   r   r   s       r@   tensorflow2xpr     s     !y))c$$??$$OO22<<YGM#M22c$$??$$<<	 122rB   zmx.nd.NDArrayc                    [        5         [        U S5      (       a0  U R                  5       n[        R                  R                  U5      nO[        R                  R                  U 5      nU(       a  UR                  5         U$ )z1Convert a numpy or cupy tensor to a MXNet tensor.r   )r   rj   r   rq   rr   r   r   attach_grad)r   r   r   	mx_tensors       r@   xp2mxnetr     sb     y*%%!**,EE%%m4	EE$$Y/	rB   r   c                z   SSK Jn  [        5         [        U 5      (       aG  [	        X5      (       a  U R                  5       R                  5       $ [        U R                  5       5      $ [	        X5      (       d  Uc  U R                  5       R                  5       $ [        R                  " U R                  5       5      $ )z1Convert a MXNet tensor to a numpy or cupy tensor.r   r   )r   r   r   rx   r:   r   asnumpyr   to_dlpack_for_writer   r   )r   r>   r   s      r@   mxnet2xpr     s     )$$c$$##%--//#I$A$A$CDDc$$##%--//<<	 1 1 344rB   PartialTfunc.argskwargsc                 \    [         R                  " U /UQ70 UD6nU R                  Ul        U$ )zfWrapper around functools.partial that retains docstrings and can include
other workarounds if needed.
)	functoolspartial__doc__)r   r   r   partial_funcs       r@   r   r     s0     $$T;D;F;L<<LrB   c                   b    \ rS rSr/ 4S\S\S\S\\\\\4      \	\
\\4      4   SS4
S jjrS	rg)
DataValidationErrori  namer   r   errorsr.   Nc           	         SU S3nS[        U5       S[        U5       3n/ nU H_  nSR                  UR                  S/ 5       V	s/ s H  n	[        U	5      PM     sn	5      n
UR	                  XR                  S5      45        Ma     XV[        U5      /n[        R                  U SS	R                  U5      -   5        g
s  sn	f )z8Custom error for validating inputs / outputs at runtime.zData validation error in ''zX: z Y: z -> locmsgz


N)rG   joinrz   strappendr   r6   __init__)selfr  r   r   r  message	type_infor|   errorperr_locresults               r@   r  DataValidationError.__init__  s     /tfA6$q'$tAwi0	Ekk599UB3G"H3Ga3q63G"HIGKK))E"234  eDk2D&499V+<"<= #Is   B>
rL   )__name__
__module____qualname____firstlineno__r
  r   r   r   r	   r   r   r  __static_attributes__rL   rB   r@   r  r    sh     LN>> > 	>
 hwsCx014S#X3GGH> 
> >rB   r  r  c                 p   [         R                  " U5      n[         R                  R                  n[	        UR
                  R                  5       5      n[        U5      S:w  aO  [        U5       SSR                  U Vs/ s H  owR                  PM     sn5       S3nSU 3n	[        XUSU	0/5      egs  snf )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, )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   r   sigr   paramsr  
bad_paramsr   s
             r@   validate_fwd_input_outputr&  #  s     

D
!C##E#..'')*F
6{aF}Btyy&1I&Q&&&1I'J&K1M
Z[eZfg!$1s|n==8 = 2Js   >B3c              #      #    [         R                  " U SS9nUv   UR                  5         [        R                  " UR
                  5        g 7f)NF)modedelete)tempfileNamedTemporaryFilecloseosremover  )r(  fs     r@   make_tempfiler0  O  s5     ##e<A
GGGIIIaffs   AAc              #      #    [         R                  " 5          [        R                  5       n[        R	                  U 5        S v   [        R	                  U5        S S S 5        g ! , (       d  f       g = f7frK   )	threadingLockr#   rz   set)
validationprevs     r@   data_validationr7  W  sG     		""$J'D!	 
		s   A5AA$	A5$
A2.A5r  id_colorc              #      #    [         (       aV  [        R                  R                  R	                  X5        Sv   [        R                  R                  R                  5         gSv   g7f)ztContext manager to register the executed code as an NVTX range. The
ranges can be used as markers in CUDA profiling.N)r   r   r;   nvtx	RangePushRangePop)r  r8  s     r@   use_nvtx_ranger=  `  s<      x		  3		!s   A'A)c                   |    \ rS rSr% Sr\R                  \S'   \R                  \S'   \	S\
4S j5       rS\
4S jrSrg	)
	ArrayInfoil  z4Container for info for checking array compatibility.r   r   rH   c                 8    U " UR                   UR                  S9$ )Nr   r   rA  )clsrH   s     r@   
from_arrayArrayInfo.from_arrays  s    #))44rB   c                     UR                   U R                   :w  a%  [        SU R                    SUR                    35      eUR                  U R                  :w  a%  [        SU R                   SUR                   35      eg )NzShape mismatch in backprop. Y: z, dY: zType mismatch in backprop. Y: )r   r6   r   )r  rH   s     r@   check_consistencyArrayInfo.check_consistencyw  ss    99

"1$**VCII;O  99

"0F399+N  #rB   rL   N)r  r  r  r  r   r&   Shape__annotations__DTypesclassmethodr(   rC  rF  r  rL   rB   r@   r?  r?  l  s>    >;;<<5W 5 5W rB   r?  )rI   rA   rV   rF   rD   r   r   r   r   r   r   r   r   r   r   r&  r  r0  r=  r?  r   r   )r.   r/   )r   rK   )r.   N)FN)FF)F)r)r   )o
contextlibr   r  r-  r   rP   r*  r2  contextvarsr   dataclassesr   typingr   r   r   r   r	   r
   r   r   r   r   r   rE   packaging.versionr   pydanticr   r   r   wasabir   compatr   r   r   r   r   r   r   r   r   r   r    rq   r!   rl   r"   r#   boolrI  r%    r&   r'   r(   r)   r*   r+   r,   r   r-   rA   rI   rM   r   rV   rZ   rF   rD   ra   rd   rg   rf   rm   ro   rt   rx   r}   r   r   r   r   r   floatr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r6   r  r
  r&  contextmanagerr0  r7  r=  r?  __all__rL   rB   r@   <module>rZ     s      	     " !     % > >      $ $./@%$PD! P    H H$
3# 3d 35S 5T 5
s t     /S /T /?C ?D ?IC ID IS T = = =  DC DD D!3 #5 T s 4  D *G ' d   $% !	%%}% 	%
 %R IKWffhw&778BE8K
Vud{#3;SE3J3GNQ89# 5 9C 9C 9(  '+ ^$ 	8 =A. .*25/.., JO'+BF6 7;33$,UO33. /4'+  ;?55(055( :
3=
!*-9<c8m>* >&)
)sC.34)9<)AD)	)X   " " C 3     ,rB   