
    hg                     P   % 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JrJrJr  S SKrSSKJrJrJrJrJr  SSKJr  SSK J!r!  SS	K"J#r#  SS
K$J%r%J&r&J'r'J(r(J)r)  \" S5      r*\" S5      r+\" SSS9r,\" S0 S9r-\\.   \/S'   S$S jr0 " S S\\*\+4   5      r1\Rd                  S\	S\	S\3S\1S\44
S j5       r5\Rd                  S\	S\	S\3S\1S\	4
S j5       r6\" S\1S9r7S\7S\\3\\3\	4   4   S\74S jr8S/4S\7S\9S\74S  jjr:S\1S!\
\1/\74   S\74S" jr;/ S#Qr<g)%    N)
ContextVar)Path)AnyCallableDictGenericIterableIteratorListOptionalSequenceSetTupleTypeVarUnioncast   )CupyOpsNumpyOpsOpsParamServerget_current_ops)	Optimizer)Shim)FloatsXd)DATA_VALIDATIONconvert_recursiveis_xp_arraypartialvalidate_fwd_input_outputInTOutTSelfTModel)boundcontext_operators)defaultmodelreturnc                     U $ N )r(   argskwargss      E/home/james-whalen/.local/lib/python3.13/site-packages/thinc/model.py
empty_initr0   -   s    L    c                   J   \ rS rSr% SrSr\\S'   \R                  " 5       r
\R                  \S'   \r\\S'   \\S'   \\S'   \\S	'   \\S
'   \\S'   \\\\   4   \S'   \S    \S'   \\   \S'   \\\4   \S'   \\\\   4   \S'   / SQrS0 0 / / 0 0 SS.S\S\S
\\   S\\\\   4   S\\\\   4   S\S    S\\   S\\\4   S\\\S    4   S\\\\4      4S jjr\S\S    4S j5       r\S\\   4S j5       r \S\\\4   4S j5       r!\S\"\S 4   4S! j5       r#\S\"\S 4   4S" j5       r$\S\"\S 4   4S# j5       r%\S\"\S 4   4S$ j5       r&\'\(RR                  S%\\\4   4S& j5       5       r*S\S\\   4S' jr+S\S\4S( jr,S)S*.S\S+\S,\SS4S- jjr-S\S\\   4S. jr.S\S\\   4S/ jr/S\S\4S0 jr0S\S\\   4S1 jr1S\S+\\   SS4S2 jr2S\S\4S3 jr3S\S\4S4 jr4S\S+\SS4S5 jr5S\S\\   4S6 jr6S\S+\SS4S7 jr7S\S\\   4S8 jr8S\SS 4S9 jr9S\S\S    4S: jr:S\S+\S    SS4S; jr;S<\<S=\S\"\=\4   4S> jr>S{S<\\<   S?\\=   SS 4S@ jjr?S<\<S\"\=\\=/\<4   4   4SA jr@S<\<S\=4SB jrASC\BSS4SD jrC\(RR                  S\\"\\4   \4   4SE j5       rDSFSG.SH\S\ES    4SI jjrFS\ES    4SJ jrGS|SK\S\ES    4SL jjrHS}SM jrISSN.S\S
\\   SS4SO jjrJSPS SQS S\4SR jrKS\\"\\4   \"\\4   4   4SS jrLST\MS\M4SU jrN S~ST\MSV\\\\S \4   4      S\M4SW jjrOSX\SS4SY jrPSSZ jrQS\SS4S[ jrRS\S4S\ jrTS]\\U\4   SS4S^ jrVS\4S_ jrWS`\SSS 4Sa jrXS]\\U\4   SS 4Sb jrYSc\SS 4Sd jrZSeSf.S]\\U\4   Sg\S\4Sh jjr[SeSf.S`\SSg\S\4Si jjr\SeSf.Sc\Sg\S\4Sj jjr]Sk\SS 4Sl jr^Sk\SS 4Sm jr_Sk\SS 4Sn jr`Sk\SS 4So jraSk\SS 4Sp jrbSk\SS 4Sq jrcSk\SS 4Sr jrdSk\SS 4Ss jreSk\SS 4St jrfSk\SS 4Su jrgSk\SS 4Sv jrhSk\SS 4Sw jriSk\SS 4Sx jrjSk\SS 4Sy jrkSzrlg)r$   1   z/Class for implementing Thinc models and layers.r   	global_idglobal_id_locknameopsid_funcinit_params_dims_layers_shims_attrs_has_params)r6   r8   r7   r9   r:   r;   r<   r?   _refsr=   r>   r@   N)r:   dimsparamslayersshimsattrsrefsr7   forwardrB   rC   rD   rE   rF   rG   c                   Xl         Uc  [        [        U 5      n[        U SU5        [        U SU5        U
b  U
O	[	        5       U l        [        5       U l        [        U5      U l	        [        U5      U l
        [        U	5      U l        [        U5      U l        [        U5      U l        [        R                      [        =R"                  S-  sl        [        R"                  U l        SSS5        0 U l        UR)                  5        H*  u  pSU R&                  U'   Uc  M  U R+                  X5        M,     g! , (       d  f       NT= f)zInitialize a new model.Nr9   r:   r   )r6   r   r0   setattrr   r7   r   r;   dictr<   r?   rA   listr=   r>   r$   r5   r4   r8   r@   items	set_param)selfr6   rH   r:   rB   rC   rD   rE   rF   rG   r7   values               r/   __init__Model.__init__U   s     	<:t,Dgw'fd#/3/@"}$Z
5k$Z
F|5k !!OOq OooDG " !<<>KD%)DT" t+ *	 "!s   7/D44
Er)   c                     U R                   $ )z]A list of child layers of the model. You can append to it to add
layers but not reassign it.
)r=   rO   s    r/   rD   Model.layers|   s    
 ||r1   c                     U R                   $ r+   )r>   rT   s    r/   rE   Model.shims   s    {{r1   c                     U R                   $ )zVA dict of the model's attrs. You can write to it to update attrs but
not reassign it.
)r?   rT   s    r/   rF   Model.attrs   s    
 {{r1   .c                 H    [        U R                  R                  5       5      $ )z8Get the names of registered parameter (including unset).)tupler@   keysrT   s    r/   param_namesModel.param_names   s     T%%**,--r1   c                     [        U R                   Vs/ s H  oR                  U5      (       d  M  UPM     sn5      $ s  snf )zHGet the names of parameters with registered gradients (including unset).)r[   r]   has_gradrO   r6   s     r/   
grad_namesModel.grad_names   s2     t'7'7O'7t==;Nd'7OPPOs   >>c                 H    [        U R                  R                  5       5      $ )z9Get the names of registered dimensions (including unset).)r[   r<   r\   rT   s    r/   	dim_namesModel.dim_names        TZZ__&''r1   c                 H    [        U R                  R                  5       5      $ )z>Get the names of registered node references (including unset).)r[   rA   r\   rT   s    r/   	ref_namesModel.ref_names   rg   r1   	operatorsc              #      #    U R                   R                  [        U5      5      nSv   U R                   R                  U5        g7f)zBind arbitrary binary functions to Python operators, for use in any
`Model` instance. Can (and should) be used as a contextmanager.

EXAMPLE:
    with Model.define_operators({">>": chain}):
        model = Relu(512) >> Relu(512) >> Softmax()
N)_context_operatorssetrK   reset)clsrk   tokens      r/   define_operatorsModel.define_operators   s8      &&**4	?;$$U+s   AAc                 F    XR                   ;  a  gU R                   U   b  gg)z~Check whether the model has a dimension of a given name. If the
dimension is registered but the value is unset, returns None.
FNT)r<   ra   s     r/   has_dimModel.has_dim   &     zz!ZZ)r1   c                     XR                   ;  a  [        SU SU R                   S35      eU R                   U   nUc  SU SU R                   S3n[        U5      eU$ )z4Retrieve the value of a dimension of the given name.zCannot get dimension '' for model ''z': value unset)r<   KeyErrorr6   
ValueErrorrO   r6   rP   errs       r/   get_dimModel.get_dim   sf    zz!3D6tyykQRSTT

4 =*4&dii[WCS/!Lr1   F)forcerP   r   c                   XR                   ;  a  [        SU SU R                   S35      eU R                   U   n[        S U R                  R                  5        5       5      nUSL=(       a    XB:g  =(       a    U(       + =(       d    U=(       a    UnU(       a#  SU SU R                   SU SU 3n[        U5      eX R                   U'   g)	zSet a value for a dimension.zCannot set unknown dimension 'ry   '.c              3   <   #    U  H  u  p[        U5      v   M     g 7fr+   )bool).0xys      r/   	<genexpr> Model.set_dim.<locals>.<genexpr>   s     F-ETQa-Es   NzAttempt to change dimension 'z' from z to )r<   r{   r6   anyr@   rM   r|   )rO   r6   rP   r   	old_value
has_paramsinvalid_changer~   s           r/   set_dimModel.set_dim   s    zz!0mDII;bQ  JJt$	FT-=-=-C-C-EFF
#4/FI4F 
I--: 	 1$}TYYKwW`VaaefkelmCS/! 

4r1   c                 T    U R                  U5      (       a  U R                  U5      $ S$ )z=Retrieve the value of a dimension of the given name, or None.N)ru   r   ra   s     r/   maybe_get_dimModel.maybe_get_dim   $    %)\\$%7%7t||D!ATAr1   c                 F    XR                   ;  a  gU R                   U   b  gg)zCheck whether the model has a weights parameter of the given name.

Returns None if the parameter is registered but currently unset.
FNT)r@   ra   s     r/   	has_paramModel.has_param   s*    
 '''d#/r1   c                 2   XR                   ;  a  [        SU SU R                   S35      eU R                  R	                  U R
                  U5      (       d  [        SU SU R                   S35      eU R                  R                  U R
                  U5      $ )z%Retrieve a weights parameter by name.zUnknown param: 'ry   r   zParameter 'z' has not been allocated yet.)r@   r{   r6   r;   r   r8   	get_paramra   s     r/   r   Model.get_param   s    '''-dV=2NOO||%%dggt44dV=;XY  ||%%dggt44r1   c                 T    U R                  U5      (       a  U R                  U5      $ S$ )z.Retrieve a weights parameter by name, or None.N)r   r   ra   s     r/   maybe_get_paramModel.maybe_get_param   s$    '+~~d';';t~~d#EEr1   c                     Uc  SU R                   U'   gU R                  R                  U R                  X5        SU R                   U'   g)z Set a weights parameter's value.NT)r@   r;   rN   r8   rO   r6   rP   s      r/   rN   Model.set_param   s?    =%)DT"LL""477D8%)DT"r1   c                 N    U R                   R                  U R                  U5      $ )z@Check whether the model has a non-zero gradient for a parameter.)r;   r`   r8   ra   s     r/   r`   Model.has_grad       ||$$TWWd33r1   c                 N    U R                   R                  U R                  U5      $ )zGet a gradient from the model.)r;   get_gradr8   ra   s     r/   r   Model.get_grad   r   r1   c                 P    U R                   R                  U R                  X5        g)z#Set a gradient value for the model.N)r;   set_gradr8   r   s      r/   r   Model.set_grad      dggt3r1   c                 T    U R                  U5      (       a  U R                  U5      $ S$ )z%Retrieve a gradient by name, or None.N)r`   r   ra   s     r/   maybe_get_gradModel.maybe_get_grad  s$    &*mmD&9&9t}}T"CtCr1   c                 P    U R                   R                  U R                  X5        g)z1Increment the gradient of a parameter by a value.N)r;   inc_gradr8   r   s      r/   r   Model.inc_grad  r   r1   c                 F    XR                   ;  a  gU R                   U   b  gg)z~Check whether the model has a reference of a given name. If the
reference is registered but the value is unset, returns None.
FNT)rA   ra   s     r/   has_refModel.has_ref  rw   r1   c                     XR                   ;  a  [        SU SU R                   S35      eU R                   U   nUc  SU SU R                   S3n[        U5      eU$ )z4Retrieve the value of a reference of the given name.zCannot get reference 'ry   r   z': value unset.)rA   r{   r6   r|   r}   s       r/   get_refModel.get_ref  sf    zz!3D6tyykQSTUU

4 =*4&dii[XCS/!Lr1   c                 T    U R                  U5      (       a  U R                  U5      $ S$ )z8Retrieve the value of a reference if it exists, or None.N)r   r   ra   s     r/   maybe_get_refModel.maybe_get_ref&  r   r1   c                     Uc  X R                   U'   gX R                  5       ;   a  X R                   U'   g[        S5      e)zSet a value for a reference.Nz)Cannot add reference to node not in tree.)rA   walkr|   r   s      r/   set_refModel.set_ref*  s7    =$JJtiik!$JJtHIIr1   Xis_trainc                 "    U R                  XUS9$ )zvCall the model's `forward` function, returning the output and a
callback to compute the gradients via backpropagation.r   r9   )rO   r   r   s      r/   __call__Model.__call__3  s     zz$Hz55r1   Yc                     [         R                  " 5       (       a!  [        U R                  U R                  X5        U R
                  b  U R                  XUS9  U $ )z}Finish initialization of the model, optionally providing a batch of
example input and output data to perform shape inference.)r   r   )r   getr    r6   r9   r:   )rO   r   r   s      r/   
initializeModel.initialize8  sF       %diiQB99 IId1I%r1   c                 "    U R                  XSS9$ )aH  Run the model over a batch of data, returning the output and a
callback to complete the backward pass. A tuple (Y, finish_update),
where Y is a batch of output data, and finish_update is a callback that
takes the gradient with respect to the output and an optimizer function,
and returns the gradient with respect to the input.
Tr   r   rO   r   s     r/   begin_updateModel.begin_updateA  s     zz$Dz11r1   c                 (    U R                  XSS9S   $ )zCall the model's `forward` function with `is_train=False`, and return
only the output, instead of the `(output, callback)` tuple.
Fr   r   r   r   s     r/   predictModel.predictJ  s     zz$Ez2155r1   	optimizerc           	         U R                  5        H'  nUR                   H  nUR                  U5        M     M)     U R                  5        Hu  nUR                   Hb  nUR	                  U5      (       d  M  U" UR
                  U4UR                  U5      UR                  U5      5      u  pVUR                  XE5        Md     Mw     g)zqUpdate parameters with current gradients. The optimizer is called
with each parameter and gradient of the model.
N)	r   rE   finish_updater]   r`   r8   r   r   rN   )rO   r   nodeshimr6   paramgrads          r/   r   Model.finish_updateP  s     IIKD

""9- #   IIKD((==&&"+$)=t}}T?R#KE NN4/ )  r1   c              #   D  #    0 nU R                    H?  nU R                  U4nXA;   d  M  U R                  U5      X#'   U R                  X1U   5        MA     [        R
                  " 5        nU R                   H#  nUR                  UR                  U5      5        M%     U R                   H#  nUR                  UR                  U5      5        M%     Sv   SSS5        U(       a+  UR                  5        H  u  p8U R                  X85        M     gg! , (       d  f       NA= f7f)zContext manager to temporarily set the model's parameters to
specified values. The params are a dictionary keyed by model IDs, whose
values are arrays of weight values.
N)r]   r8   r   rN   
contextlib	ExitStackrD   enter_context
use_paramsrE   rM   )	rO   rC   backupr6   keystacklayerr   r   s	            r/   r   Model.use_params_  s      $$D77D/C}#~~d3tC[1	 % !!#u##E$4$4V$<= %

##DOOF$;< # $ %||~t+  .  $#s$   #D A D )A+D;D 
DD bfsorderr   c                    US:X  a  U R                  5       $ US:X  a  U R                  SS9$ US:X  a  U R                  SS9$ [        S5      e)zIterate out layers of the model.

Nodes are returned in breadth-first order by default. Other possible
orders are "dfs_pre" (depth-first search in preorder) and "dfs_post"
(depth-first search in postorder).r   dfs_preF)
post_orderdfs_postTz5Invalid order, must be one of: bfs, dfs_pre, dfs_post)	_walk_bfs	_walk_dfsr|   )rO   r   s     r/   r   
Model.walkv  sV     E>>>##i>>U>33j >>T>22TUUr1   c              #      #    U /n[        5       nU HM  n[        U5      U;   a  M  UR                  [        U5      5        Uv   UR                  UR                  5        MO     g7f)z/Iterate out layers of the model, breadth-first.N)rn   r8   addextendrD   )rO   queueseenr   s       r/   r   Model._walk_bfs  sQ     D$x4HHRXJLL% s   A"A$r   c              #     #    [        5       nU /n[        U R                  5      U[        U 5      '   U(       d  U v   U(       aq   [	        U[        US   5         5      n[        U5      U;  a=  U(       d  Uv   UR                  U5        [        UR                  5      U[        U5      '   U(       a  Mp  gg! [         a!    U(       a  US   v   UR                  5          N5f = f7f)z-Iterate out layers of the model, depth-first.N)rK   iterrD   r8   nextappendStopIterationpop)rO   r   r   r   
next_childs        r/   r   Model._walk_dfs  s     -1Vdkk*RXJ!$r%)}"56
*~-%((LL,+/
0A0A+BDJ( e ! )O		s1   AC#A&B5 *C#3C#5(C C#C  C#c                    [        U R                  5       5       H@  nXR                  ;   d  M  UR                  R                  U5        XR                  ;   a  M,  MB     [	        U R                  5       5      nU HE  nUR
                   H2  nUR                  U5      nUc  M  XS;  d  M   UR                  US5        M4     MG     g)a5  Remove a node from all layers lists, and then update references.
References that no longer point to a node within the tree will be set
to `None`. For instance, let's say a node has its grandchild as a reference.
If the child is removed, the grandchild reference will be left dangling,
so will be set to None.
N)rL   r   rD   removern   ri   r   r   )rO   r   childtreer6   refs         r/   remove_nodeModel.remove_node  s     $))+&E,,&##D) ,,& ' 499;Dll4(?sLLt, ' r1   )r:   c                8    [        U SU5        [        U SU5        g )Nr9   r:   )rJ   )rO   rH   r:   s      r/   replace_callbacksModel.replace_callbacks  s     	gw'fd#r1   oldnewc                 &   Sn[        U R                  SS95       Hm  nXAL a  SnM  UR                   Vs/ s H  oUUL a  UOUPM     snUl        UR                   H*  nUR	                  U5      UL d  M  UR                  Xb5        M,     Mo     U$ s  snf )zrReplace a node anywhere it occurs within the model. Returns a boolean
indicating whether the replacement was made.Fr   r   T)rL   r   r=   ri   r   r   )rO   r  r  r   r   r   r6   s          r/   replace_nodeModel.replace_node  s     
 45D{ AE @LuC<CU2  !NND||D)S0T/ + 6  s   Bc                     0 nU R                  5        HI  nUR                   H6  nUR                  U5      nUR                  U5      nXE4XR                  U4'   M8     MK     U$ )zGet non-zero gradients of the model's parameters, as a dictionary
keyed by the parameter ID. The values are (weights, gradients) tuples.
)r   rb   r   r   r8   )rO   	gradientsr   r6   r   r   s         r/   get_gradientsModel.get_gradients  s]     	IIKDt,}}T*.3]	77D/* (  
 r1   rO   c                 "    U R                  5       $ )z
Create a copy of the model, its attributes, and its parameters. Any child
layers will also be deep-copied. The copy will receive a distinct `model.id`
value.
)_copyrT   s    r/   copy
Model.copy  s     zz|r1   r   c                 (   Uc  0 n0 nU R                    H.  nU R                  U5      (       a  U R                  U5      OS X#'   M0     / nU R                   Hn  n[	        U5      U;   a-  UR                  [        [        U[	        U5         5      5        M?  UR                  U5      nXa[	        U5      '   UR                  U5        Mp     / nU R                   Hm  n[	        U5      U;   a-  UR                  [        [        U[	        U5         5      5        M?  UR                  5       n	X[	        U5      '   UR                  U	5        Mo     [        U R                  U R                  U R                  [        R                  " U5      [        R                  " U R                   5      [        R                  " U R"                  5      UUS9n
U R$                   H1  nU
R'                  X0R)                  U5      R                  5       5        M3     [        [*        U
5      $ )N)r:   rC   rB   rF   rD   rE   )r]   r   r   rD   r8   r   r   r$   r  rE   r   r  r6   r9   r:   deepcopyr<   r?   rb   r   r   r#   )rO   r   rC   r6   copied_layersr   copied_layercopied_shimsr   copied_shimcopieds              r/   r  Model._copy  s    <D$$D37>>$3G3G4>>$/TFL % &([[E%yD $$T%bi%AB${{40".RY$$\2 ! JJD$x4##DtBtH~$>?"iik!,RX##K0  $)IIJJ==(tzz*--, 	$
 OODOOD--"5":":"<= $E6""r1   gpu_idc                     SSK nUR                  R                  R                  U5         U R	                  [        5       5        SSS5        g! , (       d  f       g= f)z)Transfer the model to a given GPU device.r   N)cupy.cuda.devicecudadeviceDevice_to_opsr   )rO   r  cupys      r/   to_gpuModel.to_gpu  s7    YY$$V,LL# -,,s   A
Ac                 6    U R                  [        5       5        g)zTransfer the model to CPU.N)r!  r   rT   s    r/   to_cpuModel.to_cpu  s    XZ r1   c           
         U R                  5        H  nXl        UR                   H  nUR                  U5      (       a/  UR	                  X1R                  UR                  U5      5      5        UR                  U5      (       d  M`  UR                  X1R                  UR                  U5      5      5        M     UR                   H)  nUR                  UR                  UR                  5        M+     M     g)z Common method for to_cpu/to_gpu.N)r   r7   r]   r   rN   	asarray_fr   r`   r   r   rE   	to_devicedevice_type	device_id)rO   r7   r   r6   r   s        r/   r!  Model._to_ops  s    IIKDH((>>$''NN4t~~d7K)LM==&&MM$dmmD6I(JK	 )
 

s> #  r1   c                     U R                  5       n[        U R                  R                  SS9n[	        [
        X!5      n[        R                  " U5      $ )a9  Serialize the model to a bytes representation. Models are usually
serialized using msgpack, so you should be able to call msgpack.loads()
on the data and get back a dictionary with the contents.

Serialization should round-trip identically, i.e. the same bytes should
result from loading and serializing a model.
<)
byte_order)to_dictr   r7   to_numpyr   r   srslymsgpack_dumps)rO   msgto_numpy_les      r/   to_bytesModel.to_bytes&  sB     llndhh//C@[>""3''r1   pathc                     [        U[        5      (       a  [        U5      OUnUR                  S5       nUR	                  U R                  5       5        SSS5        g! , (       d  f       g= f)zSerialize the model to disk. Most models will serialize to a single
file, which should just be the bytes contents of model.to_bytes().
wbN)
isinstancestrr   openwriter7  )rO   r9  file_s      r/   to_diskModel.to_disk3  sD     (c22tDzYYt_KK( __s    A
A+c                    / / / / S.n[        U R                  5       5      n[        U5       VVs0 s H  u  p4UR                  U_M     nnn[        U5       H  u  p40 n/ nUR                   Hc  nUR                  U5      (       d  SXh'   M  UR                  U5      n	U	R                  U;   a  XYR                     Xh'   MR  UR                  U5        Me     U(       a  [        SU 35      e0 n
UR                   H.  nUR                  U5      (       a  UR                  U5      OSX'   M0     US   R                  X4R                  XS.5        M     U HK  n0 nUR                  R                  5        H  u  p [        XX5      X'   M     US   R                  U5        MM     U H?  nUS   R                  UR"                   Vs/ s H  oR%                  5       PM     sn5        MA     U Hp  n0 nUR&                   HG  nUR)                  U5      (       a*  [+        [,        [.           UR1                  U5      5      X'   MC  SX'   MI     US   R                  U5        Mr     U$ s  snnf ! [          a     GM  f = fs  snf )	zSerialize the model to a dict representation.

Serialization should round-trip identically, i.e. the same dict should
result from loading and serializing a model.
)nodesrF   rC   rE   NzCannot get references: rD  )indexr6   rB   rG   rF   rE   rC   )rL   r   	enumerater8   ri   r   r   r   r|   re   ru   r   r6   rF   rM   serialize_attr	TypeErrorrE   r7  r]   r   r   r   r   r   )rO   r5  rD  ir   	node_to_irG   invalid_refsr6   r   rB   dimrF   rP   r   rC   s                   r/   r1  Model.to_dict;  s:    *,bBQSTTYY[!
 09/?@/?GATWWaZ/?	@ 'GA-/D&(L||D))!%DJ,,t,Cvv*%.vv%6
$++D1 '  #:<.!IJJD~~15c1B1BDLL-	 &LYYK# (( DE#zz//1"0t"JEK  2
 L&  DLTZZ HZTZ HI D46F((>>$''#'(:DNN4<P#QFL#'FL	 )
 M  (  
O A4 !  !Is   I3I >I2
 
I/.I/
bytes_datac                     [         R                  " U5      n[        [        U R                  R
                  U5      nU R                  U5      $ )a=  Deserialize the model from a bytes representation. Models are usually
serialized using msgpack, so you should be able to call msgpack.loads()
on the data and get back a dictionary with the contents.

Serialization should round-trip identically, i.e. the same bytes should
result from loading and serializing a model.
)r3  msgpack_loadsr   r   r7   asarray	from_dict)rO   rN  r5  s      r/   
from_bytesModel.from_bytest  s;     !!*-TXX-=-=sC~~c""r1   c                     [        U[        5      (       a  [        U5      OUnUR                  S5       nUR	                  5       nSSS5        U R                  W5      $ ! , (       d  f       N= f)zDeserialize the model from disk. Most models will serialize to a single
file, which should just be the bytes contents of model.to_bytes().
rbN)r<  r=  r   r>  readrS  )rO   r9  r@  rN  s       r/   	from_diskModel.from_disk  sO     (c22tDzYYt_J z** _s   A
A,r5  c                    SUR                  5       ;  a  Sn[        U5      e[        U R                  5       5      n[	        US   5      [	        U5      :w  a  [        S5      e[        U5       GHy  u  pEUS   U   nUS   Ul        US   R                  5        H  u  pxUc  M
  UR                  Xx5        M     US   R                  5        H0  u  pU
c  UR                  U	S 5        M  UR                  XU
   5        M2     US   U   R                  5        H:  u  pUR                  R                  U5      n[        XX5      nXR                  U'   M<     US   U   R                  5        HB  u  pUb)  UR                  R                  U5      R                  5       nUR!                  X5        MD     [        US	   U   5       H#  u  pOUR"                  U   R%                  U5        M%     GM|     U $ )
NrD  zMTrying to read a Model that was created with an incompatible version of Thincz.Cannot deserialize model: mismatched structurer6   rB   rG   rF   rC   rE   )r\   r|   rL   r   lenrF  r6   rM   r   r   rF   r   deserialize_attrr7   rQ  r  rN   rE   rS  )rO   r5  r~   rD  rI  r   inforL  rP   r   	ref_indexattrdefault_valueloaded_value
param_name
shim_bytess                   r/   rR  Model.from_dict  s   #((*$aCS/!TYY[!s7|E
*MNN 'GAw<?DVDI"6l002
$LL, 3 #'v,"4"4"6$LLd+LLI&67	 #7
  #7|A446 $

t 4/dQ#/

4   7 &)]1%5%;%;%=!
$ HH,,U388:Ez1 &> "+3w<?!;

1((4 "<' (* r1   Tstrictrf  c                2   [        U[        5      (       a  [        U5      OUnUR                  5       (       d  UR	                  5       (       d  gUR                  S5       nUR                  5       nSSS5        U R                  WUS9$ ! , (       d  f       N= f)zCheck whether serialized data on disk is compatible with the model.
If 'strict', the function returns False if the model has an attribute
already loaded that would be changed.
FrV  Nre  )r<  r=  r   is_direxistsr>  rW  can_from_bytes)rO   r9  rf  r@  rN  s        r/   can_from_diskModel.can_from_disk  sn    
 (c22tDz;;==YYt_J "":f"== _s   B
Bc                n     [         R                  " U5      nU R                  X2S9$ ! [         a     gf = f)zCheck whether the bytes data is compatible with the model. If 'strict',
the function returns False if the model has an attribute already loaded
that would be changed.
Fre  )r3  rP  r|   can_from_dict)rO   rN  rf  r5  s       r/   rj  Model.can_from_bytes  sA    
	%%j1C !!#!55  		s   ' 
44c                   SUR                  5       ;  a  g[        U R                  5       5      n[        US   5      [        U5      :w  a  g[	        U5       GH  u  pEUS   U   nU(       a  US   UR
                  :w  a    g[        US   U   5      [        UR                  5      :w  a    gUS   R                  5        H?  u  pxUR                  U5      n	U	SL a      gU	(       d  M'  UR                  U5      U:w  d  M>      g   US   U   R                  5        HZ  u  pUR                  U
5      nUSL a      gU(       d  M'  Uc  M,  UR                  U
5      nUR                  UR                  :w  d  MY      g   U(       d  GM(  US   U   R                  5        HF  u  pXR                  ;   d  M   [        UR                  U   UR                  U   X5      nX:w  d  ME      g   GM     g! [         a     M]  f = f)	zCheck whether a dictionary is compatible with the model.
If 'strict', the function returns False if the model has an attribute
already loaded that would be changed.
rD  Fr6   rE   rB   rC   rF   T)r\   rL   r   r[  rF  r6   rE   rM   ru   r   r   r   shaperF   rG  rH  )rO   r5  rf  rD  rI  r   r]  rL  rP   ru   rb  r   r   r_  
serializeds                  r/   rn  Model.can_from_dict  s   
 #((*$TYY[!s7|E
* 'GAw<?D$v,$))33w<?#s4::6 "6l002
,,s+e# Wc!2e!;  3 &)]1%5%;%;%=!
 NN:6	% Y5#4 NN:6E{{ekk1$ &> v#&w<?#8#8#:KDzz)%)7 $

4 0$**T2BD*J
 &.#( $;/ (D 	  ) %$%s   +'G$$
G21G2otherc                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '+' operator.+zUndefined operator: +rm   r   rH  rO   rt  s     r/   __add__Model.__add__  D    d--1133344&&**,S1$>>r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '-' operator.-zUndefined operator: -rw  rx  s     r/   __sub__Model.__sub__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '*' operator.*zUndefined operator: *rw  rx  s     r/   __mul__Model.__mul__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '@' operator.@zUndefined operator: @rw  rx  s     r/   
__matmul__Model.__matmul__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ z-Apply the function bound to the '/' operator./zUndefined operator: /rw  rx  s     r/   __div__Model.__div__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ r  rw  rx  s     r/   __truediv__Model.__truediv__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z.Apply the function bound to the '//' operator.z//zUndefined operator: //rw  rx  s     r/   __floordiv__Model.__floordiv__  D    t..2244455&&**,T24??r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '%' operator.%zUndefined operator: %rw  rx  s     r/   __mod__Model.__mod__  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z.Apply the function bound to the '**' operator.z**zUndefined operator: **rw  )rO   rt  r.   s      r/   __pow__Model.__pow__  r  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z.Apply the function bound to the '<<' operator.z<<zUndefined operator: <<rw  rx  s     r/   
__lshift__Model.__lshift__#  r  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z.Apply the function bound to the '>>' operator.z>>zUndefined operator: >>rw  rx  s     r/   
__rshift__Model.__rshift__)  r  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '&' operator.&zUndefined operator: &rw  rx  s     r/   __and__Model.__and__/  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '^' operator.^zUndefined operator: ^rw  rx  s     r/   __xor__Model.__xor__5  r{  r1   c                     SU R                   R                  5       ;  a  [        S5      eU R                   R                  5       S   " X5      $ )z-Apply the function bound to the '|' operator.|zUndefined operator: |rw  rx  s     r/   __or__Model.__or__;  r{  r1   )
r?   r<   r@   r=   r;   rA   r>   r8   r6   r7   )NN)F)r   r$   r)   Nr+   )r)   N)m__name__
__module____qualname____firstlineno____doc__r4   int__annotations__	threadingLockr5   r&   rm   r=  r   r   r   r   r   r   r   r   r   	__slots__r   r   r   r   r   rQ   propertyrD   rE   rF   r   r]   rb   re   ri   classmethodr   contextmanagerrr   ru   r   r   r   r   r   r   rN   r`   r   r   r   r   r   r   r   r   r!   r"   r   r   r   r   r   r   r   r	   r   r   r   r  r  r	  r  r#   r  r  r#  r&  r!  bytesr7  r   rA  r1  rS  rX  rR  rk  rj  rn  ry  r~  r  r  r  r  r  r  r  r  r  r  r  r  __static_attributes__r,   r1   r/   r$   r$   1   s-   9Is%.^^%5NINN5*
I	HGO
NXc]"##']JcNc8D>)**I( $()+02$& "-/26%,%, %,
 x %, 3%&%, S(8,,-%, !%, Dz%, CH~%, 3))*%, eHg-./%,N W   tDz   tCH~   .U38_ . . QE#s(O Q Q (5c? ( ( (5c? ( ( 
,c8m)< 
,  
,	C 	HTN 		C 	C 	 ?D !C ! !t ! ! B# B(3- B
c 
htn 
5c 5h 5FC FHX,> F*c *(8*< * *4S 4T 44S 4X 44S 4 4d 4D3 D8H+= D4S 4 4d 4	C 	HTN 		C 	G 	B# B(7*; BJC J(9 Jd J6# 6 6%h2G 6
HSM Xd^ w 2c 2eD(D63;2G,G&H 26 6 60y 0T 0 ,eCHox&?!@ , ,, $) VS VXg-> V	&8G, 	&D Xg5F ,-$ @D$$*28*<$	$ g $ *
tE#s(OU8X;M5N$NO 
5 U  HL'#'##DeGTM.B)B$CD'#	'#R$S $T $!
?3 
?4 
?(% ()E$), ) )7 7r
#U 
#w 
#+eD#I. +7 +T g < GK 
>%c	"2 
>t 
>t 
> CG 	6 	64 	64 	6 :> - -$ -$ -^?S ?W ??S ?W ??S ?W ?? ? ??S ?W ?? ? ?@# @' @?S ?W ?@S @w @@ @ @@ @ @?S ?W ??S ?W ??C ?G ?r1   _rP   r6   c                 .    [         R                  " U5      $ )zSerialize an attribute value (defaults to msgpack). You can register
custom serializers using the @serialize_attr.register decorator with the
type to serialize, e.g.: @serialize_attr.register(MyCustomObject).
)r3  r4  r  rP   r6   r(   s       r/   rG  rG  B       u%%r1   c                 .    [         R                  " U5      $ )zDeserialize an attribute value (defaults to msgpack). You can register
custom deserializers using the @deserialize_attr.register decorator with the
type to deserialize, e.g.: @deserialize_attr.register(MyCustomObject).
)r3  rP  r  s       r/   r\  r\  K  r  r1   _ModelTmappingc                     U R                  5        H[  nUR                  U;   d  M  XR                     nUR                  5        H$  u  pEXBR                  ;   d  M  XRR                  U'   M&     M]     U $ )zWalk over the model's nodes, changing the value of attributes using the
provided mapping, which maps node names to attr names to attr values.
)r   r6   rM   rF   )r(   r  r   rF   r_  rP   s         r/   change_attr_valuesr  W  s[     

99II&E${{}::%',JJt$  -  Lr1   dropout_ratedropc                     U R                  5        H+  nU H"  nXCR                  ;   d  M  XR                  U'   M$     M-     U $ )zWalk over the model's nodes, setting the dropout rate. You can specify
one or more attribute names, by default it looks for ["dropout_rate"].
)r   rF   )r(   r  rF   r   r_  s        r/   set_dropout_rater  d  s;     

Dzz!#'

4    Lr1   wrapperc                     [        U R                  5       5       H  nU R                  X!" U5      5        M     U" U 5      $ )zKRecursively wrap a model and its submodules. The model is updated
in-place.)rL   r   r	  )r(   r  r   s      r/   wrap_model_recursiver  o  s9     UZZ\"4/ # 5>r1   )r$   rG  r\  r  r  r  )r(   r$   r)   r$   )=r   r  	functoolsr  contextvarsr   pathlibr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r3  backendsr   r   r   r   r   
optimizersr   rE   r   typesr   utilr   r   r   r   r    r!   r"   r#   r&   rK   r  r0   r$   singledispatchr=  r  rG  r\  r  r  floatr  r  __all__r,   r1   r/   <module>r     s       "    "  J J !    envw'&01Db&Q :d# QN?GCI N?b &c &# &S & &5 & & & &C &s &5 &S & & )5
)
g 
S$sCx.5H0I 
g 
 :H8H G 5 W  %'9I0J w r1   