
    i                     T   U 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mZmZmZ d dlZddlmZmZmZmZmZ ddlmZ ddl m!Z! dd	l"m#Z# dd
l$m%Z%m&Z&m'Z'm(Z(m)Z)  ed      Z* ed      Z+ edd      Z, edi       Z-ee.   e/d<   d$dZ0 G d dee*e+f         Z1ejd                  de	de	de3de1de4f
d       Z5ejd                  de	de	de3de1de	f
d       Z6 ede1      Z7de7dee3ee3e	f   f   de7fdZ8dgfde7de9de7fd Z:de1d!e
e1ge7f   de7fd"Z;g d#Z<y)%    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                     | S N )r(   argskwargss      \/var/www/vps2.regionflexible.com/Desarrollo/venv/lib/python3.12/site-packages/thinc/model.py
empty_initr0   -   s    L    c                      e Zd ZU dZdZeed<    ej                         Z	ej                  ed<   e
Zeed<   eed<   eed<   eed<   eed	<   eed
<   eeee   f   ed<   ed    ed<   ee   ed<   eeef   ed<   eeee   f   ed<   g dZdi i g g i i dddeded	ee   deeee   f   deeee   f   ded    dee   deeef   deeed    f   deeeef      fdZeded    fd       Zedee   fd       Zedeeef   fd       Z ede!edf   fd        Z"ede!edf   fd!       Z#ede!edf   fd"       Z$ede!edf   fd#       Z%e&e'jP                  d$eeef   fd%              Z)dedee   fd&Z*dedefd'Z+d(d)ded*ed+eddfd,Z,dedee   fd-Z-dedee   fd.Z.dedefd/Z/dedee   fd0Z0ded*ee   ddfd1Z1dedefd2Z2dedefd3Z3ded*eddfd4Z4dedee   fd5Z5ded*eddfd6Z6dedee   fd7Z7dedd fd8Z8deded    fd9Z9ded*ed    ddfd:Z:d;e;d<ede!e<ef   fd=Z=dyd;ee;   d>ee<   dd fd?Z>d;e;de!e<ee<ge;f   f   fd@Z?d;e;de<fdAZ@dBeAddfdCZBe'jP                  dee!eef   ef   fdD       ZCdEdFdGedeDd    fdHZEdeDd    fdIZFdzdJedeDd    fdKZGd{dLZHddMded	ee   ddfdNZIdOd dPd defdQZJdee!eef   e!eef   f   fdRZKdSeLdeLfdTZM	 d|dSeLdUeeeed ef   f      deLfdVZNdWeddfdXZOd}dYZPdeddfdZZQdeRfd[ZSd\eeTef   ddfd]ZUdefd^ZVd_eRdd fd`ZWd\eeTef   dd fdaZXdbedd fdcZYddded\eeTef   dfedefdgZZddded_eRdfedefdhZ[dddedbedfedefdiZ\djedd fdkZ]djedd fdlZ^djedd fdmZ_djedd fdnZ`djedd fdoZadjedd fdpZbdjedd fdqZcdjedd fdrZddjedd fdsZedjedd fdtZfdjedd fduZgdjedd fdvZhdjedd fdwZidjedd fdxZjy)~r$   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)r5   r7   r6   r8   r9   r:   r;   r>   _refsr<   r=   r?   N)r9   dimsparamslayersshimsattrsrefsr6   forwardrA   rB   rC   rD   rE   rF   c                z   || _         |t        t        |       }t        | d|       t        | d|       |
|
n	t	               | _        t               | _        t        |      | _	        t        |      | _
        t        |	      | _        t        |      | _        t        |      | _        t        j                   5  t        xj"                  dz  c_        t        j"                  | _        ddd       i | _        |j)                         D ])  \  }}d| j&                  |<   || j+                  ||       + y# 1 sw Y   MxY w)zInitialize a new model.Nr8   r9   r   )r5   r   r0   setattrr   r6   r   r:   dictr;   r>   r@   listr<   r=   r$   r4   r3   r7   r?   items	set_param)selfr5   rG   r9   rA   rB   rC   rD   rE   rF   r6   values               r/   __init__zModel.__init__U   s    	<:t,Dgw'fd#/3/@"}$Z
5k$Z
F|5k !! 	&OOq OooDG	& !<<> 	,KD%%)DT" tU+	,		& 	&s   6/D11D:r)   c                     | j                   S )zmA list of child layers of the model. You can append to it to add
        layers but not reassign it.
        )r<   rN   s    r/   rC   zModel.layers|   s    
 ||r1   c                     | j                   S r+   )r=   rR   s    r/   rD   zModel.shims   s    {{r1   c                     | j                   S )zfA dict of the model's attrs. You can write to it to update attrs but
        not reassign it.
        )r>   rR   s    r/   rE   zModel.attrs   s    
 {{r1   .c                 H    t        | j                  j                               S )z8Get the names of registered parameter (including unset).)tupler?   keysrR   s    r/   param_nameszModel.param_names   s     T%%**,--r1   c                 v    t        | j                  D cg c]  }| j                  |      s| c}      S c c}w )zHGet the names of parameters with registered gradients (including unset).)rV   rX   has_gradrN   r5   s     r/   
grad_nameszModel.grad_names   s.     t'7'7Ot4==;NdOPPOs   66c                 H    t        | j                  j                               S )z9Get the names of registered dimensions (including unset).)rV   r;   rW   rR   s    r/   	dim_nameszModel.dim_names        TZZ__&''r1   c                 H    t        | j                  j                               S )z>Get the names of registered node references (including unset).)rV   r@   rW   rR   s    r/   	ref_nameszModel.ref_names   r_   r1   	operatorsc              #      K   | j                   j                  t        |            }d | j                   j                  |       yw)a  Bind 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setrJ   reset)clsrb   tokens      r/   define_operatorszModel.define_operators   s9      &&**4	?;$$U+s   AAc                 B    || j                   vry| j                   |   yy)zCheck whether the model has a dimension of a given name. If the
        dimension is registered but the value is unset, returns None.
        FNT)r;   r[   s     r/   has_dimzModel.has_dim   (     tzz!ZZ)r1   c                     || j                   vrt        d| d| j                   d      | j                   |   }|d| d| j                   d}t        |      |S )z4Retrieve the value of a dimension of the given name.zCannot get dimension '' for model ''z': value unset)r;   KeyErrorr5   
ValueErrorrN   r5   rO   errs       r/   get_dimzModel.get_dim   sh    tzz!3D6tyykQRSTT

4 =*4&dii[WCS/!Lr1   F)forcerO   ru   c                b   || j                   vrt        d| d| j                   d      | j                   |   }t        d | j                  j                         D              }|duxr ||k7  xr | xs |xr |}|r#d| d| j                   d| d| }t        |      || j                   |<   y)	zSet a value for a dimension.zCannot set unknown dimension 'rn   '.c              3   8   K   | ]  \  }}t        |        y wr+   )bool).0xys      r/   	<genexpr>z Model.set_dim.<locals>.<genexpr>   s     FTQaFs   NzAttempt to change dimension 'z' from z to )r;   rp   r5   anyr?   rL   rq   )rN   r5   rO   ru   	old_value
has_paramsinvalid_changers   s           r/   set_dimzModel.set_dim   s    tzz!0mDII;bQ  JJt$	FT-=-=-C-C-EFF
#4/FI4F 
I--: 	 1$}TYYKwW`VaaefkelmCS/! 

4r1   c                 J    | j                  |      r| j                  |      S dS )z=Retrieve the value of a dimension of the given name, or None.N)rk   rt   r[   s     r/   maybe_get_dimzModel.maybe_get_dim   !    %)\\$%7t||D!ATAr1   c                 B    || j                   vry| j                   |   yy)zCheck whether the model has a weights parameter of the given name.

        Returns None if the parameter is registered but currently unset.
        FNT)r?   r[   s     r/   	has_paramzModel.has_param   s,    
 t'''d#/r1   c                 &   || j                   vrt        d| d| j                   d      | j                  j	                  | j
                  |      st        d| d| j                   d      | j                  j                  | j
                  |      S )z%Retrieve a weights parameter by name.zUnknown param: 'rn   rw   zParameter 'z' has not been allocated yet.)r?   rp   r5   r:   r   r7   	get_paramr[   s     r/   r   zModel.get_param   s    t'''-dV=2NOO||%%dggt4dV=;XY  ||%%dggt44r1   c                 J    | j                  |      r| j                  |      S dS )z.Retrieve a weights parameter by name, or None.N)r   r   r[   s     r/   maybe_get_paramzModel.maybe_get_param   s!    '+~~d';t~~d#EEr1   c                     |d| j                   |<   y| j                  j                  | j                  ||       d| j                   |<   y)z Set a weights parameter's value.NT)r?   r:   rM   r7   rN   r5   rO   s      r/   rM   zModel.set_param   sA    =%)DT"LL""477D%8%)DT"r1   c                 N    | j                   j                  | j                  |      S )z@Check whether the model has a non-zero gradient for a parameter.)r:   rZ   r7   r[   s     r/   rZ   zModel.has_grad       ||$$TWWd33r1   c                 N    | j                   j                  | j                  |      S )zGet a gradient from the model.)r:   get_gradr7   r[   s     r/   r   zModel.get_grad   r   r1   c                 R    | j                   j                  | j                  ||       y)z#Set a gradient value for the model.N)r:   set_gradr7   r   s      r/   r   zModel.set_grad      dggtU3r1   c                 J    | j                  |      r| j                  |      S dS )z%Retrieve a gradient by name, or None.N)rZ   r   r[   s     r/   maybe_get_gradzModel.maybe_get_grad  s!    &*mmD&9t}}T"CtCr1   c                 R    | j                   j                  | j                  ||       y)z1Increment the gradient of a parameter by a value.N)r:   inc_gradr7   r   s      r/   r   zModel.inc_grad  r   r1   c                 B    || j                   vry| j                   |   yy)zCheck whether the model has a reference of a given name. If the
        reference is registered but the value is unset, returns None.
        FNT)r@   r[   s     r/   has_refzModel.has_ref  rl   r1   c                     || j                   vrt        d| d| j                   d      | j                   |   }|d| d| j                   d}t        |      |S )z4Retrieve the value of a reference of the given name.zCannot get reference 'rn   rw   z': value unset.)r@   rp   r5   rq   rr   s       r/   get_refzModel.get_ref  sh    tzz!3D6tyykQSTUU

4 =*4&dii[XCS/!Lr1   c                 J    | j                  |      r| j                  |      S dS )z8Retrieve the value of a reference if it exists, or None.N)r   r   r[   s     r/   maybe_get_refzModel.maybe_get_ref&  r   r1   c                     ||| j                   |<   y|| j                         v r|| j                   |<   yt        d      )zSet a value for a reference.Nz)Cannot add reference to node not in tree.)r@   walkrq   r   s      r/   set_refzModel.set_ref*  s=    =$DJJtdiik!$DJJtHIIr1   Xis_trainc                 *    | j                  | ||      S )z~Call the model's `forward` function, returning the output and a
        callback to compute the gradients via backpropagation.r   r8   )rN   r   r   s      r/   __call__zModel.__call__3  s     zz$Hz55r1   Yc                     t        j                         r"t        | j                  | j                  ||       | j
                  | j                  | ||       | S )zFinish initialization of the model, optionally providing a batch of
        example input and output data to perform shape inference.)r   r   )r   getr    r5   r8   r9   )rN   r   r   s      r/   
initializezModel.initialize8  sG      %diiQB99 IIda1I%r1   c                 *    | j                  | |d      S )ap  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   rN   r   s     r/   begin_updatezModel.begin_updateA  s     zz$Dz11r1   c                 0    | j                  | |d      d   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/   predictzModel.predictJ  s     zz$Ez2155r1   	optimizerc           	      t   | j                         D ]$  }|j                  D ]  }|j                  |        & | j                         D ]n  }|j                  D ]]  }|j	                  |      s ||j
                  |f|j                  |      |j                  |            \  }}|j                  ||       _ p y)zUpdate parameters with current gradients. The optimizer is called
        with each parameter and gradient of the model.
        N)	r   rD   finish_updaterX   rZ   r7   r   r   rM   )rN   r   nodeshimr5   paramgrads          r/   r   zModel.finish_updateP  s     IIK 	.D

 .""9-.	. IIK 	0D(( 0==&"+$)=t}}T?R#KE4 NN4/0	0r1   c              #   "  K   i }| j                   D ]>  }| j                  |f}||v s| j                  |      ||<   | j                  |||          @ t	        j
                         5 }| j                  D ]"  }|j                  |j                  |             $ | j                  D ]"  }|j                  |j                  |             $ d ddd       |r+|j                         D ]  \  }}| j                  ||        yy# 1 sw Y   7xY ww)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)rX   r7   r   rM   
contextlib	ExitStackrC   enter_context
use_paramsrD   rL   )	rN   rB   backupr5   keystacklayerr   r   s	            r/   r   zModel.use_params_  s     $$ 	2D77D/Cf}#~~d3ttVC[1		2 !!# 	u >##E$4$4V$<=>

 =##DOOF$;<=	 %||~ ,etU+, 	 	s#   $D?D&A'D6DDDbfsorderr   c                    |dk(  r| j                         S |dk(  r| j                  d      S |dk(  r| j                  d      S t        d      )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_dfsrq   )rN   r   s     r/   r   z
Model.walkv  sV     E>>>##i>>U>33j >>T>22TUUr1   c              #      K   | g}t               }|D ]I  }t        |      |v r|j                  t        |             | |j                  |j                         K yw)z/Iterate out layers of the model, breadth-first.N)re   r7   addextendrC   )rN   queueseenr   s       r/   r   zModel._walk_bfs  sW      	&D$x4HHRXJLL%	&s   AAr   c              #     K   t               }| g}t        | j                        |t        |       <   |s|  |rd	 t	        |t        |d                  }t        |      |vr8|s| |j                  |       t        |j                        |t        |      <   |rcyy# t        $ r |r|d    |j                          Y )w xY ww)z-Iterate out layers of the model, depth-first.N)rJ   iterrC   r7   nextappendStopIterationpop)rN   r   r   r   
next_childs        r/   r   zModel._walk_dfs  s     -1Vdkk*RXJ!$r%)}"56
*~-%((LL,+/
0A0A+BDJ(  ! )O		s/   7CAB CC"C CCCc                 j   t        | j                               D ];  }||j                  v s|j                  j                  |       ||j                  v r*= t	        | j                               }|D ]>  }|j
                  D ]-  }|j                  |      }|||vs|j                  |d       / @ y)a]  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)rK   r   rC   removere   ra   r   r   )rN   r   childtreer5   refs         r/   remove_nodezModel.remove_node  s     $))+& 	*E%,,&##D) %,,&	* 499; 	-D -ll4(?s$LLt,-	-r1   )r9   c                8    t        | d|       t        | d|       y )Nr8   r9   )rI   )rN   rG   r9   s      r/   replace_callbackszModel.replace_callbacks  s     	gw'fd#r1   oldnewc                    d}t        | j                  d            D ]e  }||u rd}
|j                  D cg c]
  }||u r|n| c}|_        |j                  D ](  }|j	                  |      |u s|j                  ||       * g |S c c}w )zzReplace a node anywhere it occurs within the model. Returns a boolean
        indicating whether the replacement was made.Fr   r   T)rK   r   r<   ra   r   r   )rN   r   r   r   r   r   r5   s          r/   replace_nodezModel.replace_node  s     
 45 		0Ds{ AE 7<5C<CU2  !NN 0D||D)S0T3/0		0  s   Bc                     i }| j                         D ]H  }|j                  D ]7  }|j                  |      }|j                  |      }||f||j                  |f<   9 J |S )zGet non-zero gradients of the model's parameters, as a dictionary
        keyed by the parameter ID. The values are (weights, gradients) tuples.
        )r   r\   r   r   r7   )rN   	gradientsr   r5   r   r   s         r/   get_gradientszModel.get_gradients  sk     	IIK 	;D ;t,}}T*.3T]	477D/*;	;
 r1   rN   c                 "    | j                         S )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.
        )_copyrR   s    r/   copyz
Model.copy  s     zz|r1   r   c           
         |i }i }| j                   D ])  }| j                  |      r| j                  |      nd ||<   + g }| j                  D ]k  }t	        |      |v r,|j                  t        t        |t	        |                      <|j                  |      }||t	        |      <   |j                  |       m g }| j                  D ]j  }t	        |      |v r,|j                  t        t        |t	        |                      <|j                         }	|	|t	        |      <   |j                  |	       l t        | j                  | j                  | j                  t        j                  |      t        j                  | j                         t        j                  | j"                        ||      }
| j$                  D ]1  }|
j'                  || j)                  |      j                                3 t        t*        |
      S )N)r9   rB   rA   rE   rC   rD   )rX   r   r   rC   r7   r   r   r$   r   rD   r   r   r5   r8   r9   deepcopyr;   r>   r\   r   r   r#   )rN   r   rB   r5   copied_layersr   copied_layercopied_shimsr   copied_shimcopieds              r/   r   zModel._copy  s    <D$$ 	RD37>>$3G4>>$/TF4L	R &([[ 	3E%yD $$T%bi%AB${{40".RY$$\2	3 JJ 	1D$x4##DtBtH~$>?"iik!,RX##K0	1 $)IIJJ==(tzz*--, 	$
 OO 	>DOOD$--"5":":"<=	>E6""r1   gpu_idc                     ddl }|j                  j                  j                  |      5  | j	                  t                      ddd       y# 1 sw Y   yxY w)z)Transfer the model to a given GPU device.r   N)cupy.cuda.devicecudadeviceDevice_to_opsr   )rN   r   cupys      r/   to_gpuzModel.to_gpu  s@    YY$$V, 	$LL#	$ 	$ 	$s   AAc                 6    | j                  t                      y)zTransfer the model to CPU.N)r   r   rR   s    r/   to_cpuzModel.to_cpu  s    XZ r1   c           
         | j                         D ]  }||_        |j                  D ]  }|j                  |      r0|j	                  ||j                  |j                  |                   |j                  |      sV|j                  ||j                  |j                  |                    |j                  D ](  }|j                  |j                  |j                         *  y)z Common method for to_cpu/to_gpu.N)r   r6   rX   r   rM   	asarray_fr   rZ   r   r   rD   	to_devicedevice_type	device_id)rN   r6   r   r5   r   s        r/   r   zModel._to_ops  s    IIK 	?DDH(( L>>$'NN4t~~d7K)LM==&MM$dmmD6I(JK	L
 

 ?s>?	?r1   c                     | j                         }t        | j                  j                  d      }t	        t
        ||      }t        j                  |      S )aa  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   r6   to_numpyr   r   srslymsgpack_dumps)rN   msgto_numpy_les      r/   to_byteszModel.to_bytes&  sD     llndhh//C@[#>""3''r1   pathc                     t        |t              rt        |      n|}|j                  d      5 }|j	                  | j                                ddd       y# 1 sw Y   yxY w)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writer	  )rN   r
  file_s      r/   to_diskzModel.to_disk3  sL     (c2tDzYYt_ 	)KK(	) 	) 	)s    AA!c                    g g g g d}t        | j                               }t        |      D ci c]  \  }}|j                  | }}}t        |      D ]  \  }}i }g }|j                  D ]\  }|j                  |      sd||<   |j                  |      }	|	j                  |v r||	j                     ||<   L|j                  |       ^ |rt        d|       i }
|j                  D ])  }|j                  |      r|j                  |      nd|
|<   + |d   j                  ||j                  |
|d        |D ]L  }i }|j                  j                         D ]  \  }}	 t        ||||      ||<    |d   j                  |       N |D ]<  }|d   j                  |j"                  D cg c]  }|j%                          c}       > |D ]i  }i }|j&                  D ]B  }|j)                  |      r*t+        t,        t.           |j1                  |            ||<   >d||<   D |d   j                  |       k |S c c}}w # t         $ r Y w xY wc c}w )	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.
        )nodesrE   rB   rD   NzCannot get references: r  )indexr5   rA   rF   rE   rD   rB   )rK   r   	enumerater7   ra   r   r   r   rq   r^   rk   rt   r5   rE   rL   serialize_attr	TypeErrorrD   r	  rX   r   r   r   r   r   )rN   r  r  ir   	node_to_irF   invalid_refsr5   r   rA   dimrE   rO   r   rB   s                   r/   r  zModel.to_dict;  st    *,bBQSTTYY[!
 09/?@GAtTWWaZ@	@ ' 	GAt-/D&(L 2||D)!%DJ,,t,Cvv*%.svv%6T
$++D12  #:<.!IJJD~~ M15c1BDLL-S	MLTYYdK#	(  	'DE#zz//1 e"0tT"JE$K
 L&	'  	JDLTZZ HT HI	J 	)D46F(( (>>$'#'(:DNN4<P#QF4L#'F4L	(
 M  (	) 
O A4 !  !Is   H: I *I
 	II
bytes_datac                     t        j                  |      }t        t        | j                  j
                  |      }| j                  |      S )ae  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.
        )r  msgpack_loadsr   r   r6   asarray	from_dict)rN   r  r  s      r/   
from_byteszModel.from_bytest  s;     !!*-TXX-=-=sC~~c""r1   c                     t        |t              rt        |      n|}|j                  d      5 }|j	                         }ddd       | j                        S # 1 sw Y   xY w)a  Deserialize the model from disk. Most models will serialize to a single
        file, which should just be the bytes contents of model.to_bytes().

        The model instance must have the same architecture (layers, dimensions)
        as the model that was serialized. For example, if a chain(Relu(10),
        Relu(1), Logistic()) model was saved, load it into a model created with
        the same chain(...) call, not a bare Model().
        rbN)r  r  r   r  readr"  )rN   r
  r  r  s       r/   	from_diskzModel.from_disk  sT     (c2tDzYYt_ 	&J	&z**	& 	&s   AA"r  c                    d|j                         vrd}t        |      t        | j                               }t	        |d         t	        |      k7  rt        d      t        |      D ]u  \  }}|d   |   }|d   |_        |d   j                         D ]  \  }}|	|j                  ||        |d   j                         D ]/  \  }	}
|
|j                  |	d        |j                  |	||
          1 |d   |   j                         D ]=  \  }}|j                  j                  |      }t        ||||      }||j                  |<   ? |d   |   j                         D ]B  \  }}|)|j                  j                  |      j                         }|j!                  ||       D t        |d	   |         D ]#  \  }}|j"                  |   j%                  |       % x | S )
Nr  zMTrying to read a Model that was created with an incompatible version of Thincz.Cannot deserialize model: mismatched structurer5   rA   rF   rE   rB   rD   )rW   rq   rK   r   lenr  r5   rL   r   r   rE   r   deserialize_attrr6   r   r   rM   rD   r"  )rN   r  rs   r  r  r   infor  rO   r   	ref_indexattrdefault_valueloaded_value
param_name
shim_bytess                   r/   r!  zModel.from_dict  s   #((*$aCS/!TYY[!s7|E
*MNN ' 	5GAtw<?DVDI"6l002 -
U$LLe,- #'v,"4"4"6 8Y$LLd+LLeI&67	8
  #7|A446 0e $

t 4/udDQ#/

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

1((45'	5* r1   Tstrictr2  c                   t        |t              rt        |      n|}|j                         s|j	                         sy|j                  d      5 }|j                         }ddd       | j                  |      S # 1 sw Y   xY w)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.
        Fr$  Nr1  )r  r  r   is_direxistsr  r%  can_from_bytes)rN   r
  r2  r  r  s        r/   can_from_diskzModel.can_from_disk  so    
 (c2tDz;;=YYt_ 	&J	&"":f"==	& 	&s   A<<Bc                r    	 t        j                  |      }| j                  ||      S # t        $ r Y yw xY w)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.
        Fr1  )r  r  rq   can_from_dict)rN   r  r2  r  s       r/   r6  zModel.can_from_bytes  sC    
	%%j1C !!#f!55  		s   * 	66c                   d|j                         vryt        | j                               }t        |d         t        |      k7  ryt	        |      D ]e  \  }}|d   |   }|r|d   |j
                  k7  r yt        |d   |         t        |j                        k7  r y|d   j                         D ]7  \  }}|j                  |      }	|	du r  y|	s!|j                  |      |k7  s6  y |d   |   j                         D ]P  \  }
}|j                  |
      }|du r  y|s!|$|j                  |
      }|j                  |j                  k7  sO  y |s|d   |   j                         D ]E  \  }}||j                  v s	 t        |j                  |   |j                  |   ||      }||k7  sD  y h y# t        $ r Y Ww xY w)	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.
        r  Fr5   rD   rA   rB   rE   T)rW   rK   r   r(  r  r5   rD   rL   rk   rt   r   r   shaperE   r  r  )rN   r  r2  r  r  r   r*  r  rO   rk   r/  r   r   r,  
serializeds                  r/   r9  zModel.can_from_dict  s   
 #((*$TYY[!s7|E
* ' !	)GAtw<?D$v,$))33w<?#s4::6 "6l002 !
U,,s+e# c!2e!; ! &)]1%5%;%;%= %!
E NN:6	% 5#4 NN:6E{{ekk1$% #&w<?#8#8#: 
)KD%tzz)%)7 $

4 0$**T2BD$*J
 &.#(
)/!	)D 	  ) %$%s   (F==	G	G	otherc                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '+' operator.+zUndefined operator: +rd   r   r  rN   r=  s     r/   __add__zModel.__add__  H    d--11333441t&&**,S1$>>r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '-' operator.-zUndefined operator: -r@  rA  s     r/   __sub__zModel.__sub__  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '*' operator.*zUndefined operator: *r@  rA  s     r/   __mul__zModel.__mul__  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '@' operator.@zUndefined operator: @r@  rA  s     r/   
__matmul__zModel.__matmul__  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S z-Apply the function bound to the '/' operator./zUndefined operator: /r@  rA  s     r/   __div__zModel.__div__
  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S rN  r@  rA  s     r/   __truediv__zModel.__truediv__  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z.Apply the function bound to the '//' operator.z//zUndefined operator: //r@  rA  s     r/   __floordiv__zModel.__floordiv__  H    t..22444552t&&**,T24??r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '%' operator.%zUndefined operator: %r@  rA  s     r/   __mod__zModel.__mod__  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z.Apply the function bound to the '**' operator.z**zUndefined operator: **r@  )rN   r=  r.   s      r/   __pow__zModel.__pow__"  rU  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z.Apply the function bound to the '<<' operator.z<<zUndefined operator: <<r@  rA  s     r/   
__lshift__zModel.__lshift__(  rU  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z.Apply the function bound to the '>>' operator.z>>zUndefined operator: >>r@  rA  s     r/   
__rshift__zModel.__rshift__.  rU  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '&' operator.&zUndefined operator: &r@  rA  s     r/   __and__zModel.__and__4  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '^' operator.^zUndefined operator: ^r@  rA  s     r/   __xor__zModel.__xor__:  rC  r1   c                     d| j                   j                         vrt        d       | j                   j                         d   | |      S )z-Apply the function bound to the '|' operator.|zUndefined operator: |r@  rA  s     r/   __or__zModel.__or__@  rC  r1   )NN)F)r   r$   r)   Nr+   )r)   N)k__name__
__module____qualname____doc__r3   int__annotations__	threadingLockr4   r&   rd   r  r   r   r   r   r   r   r   r   ry   	__slots__r   r   r   r   r   rP   propertyrC   rD   rE   r   rX   r\   r^   ra   classmethodr   contextmanagerri   rk   rt   r   r   r   r   r   rM   rZ   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   bytesr	  r   r  r  r"  r&  r!  r7  r6  r9  rB  rF  rI  rL  rP  rR  rT  rX  rZ  r\  r^  ra  rd  rg  r,   r1   r/   r$   r$   1   s/   9Is%3Y^^%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   _rO   r5   c                 ,    t        j                  |      S )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).
    )r  r  ru  rO   r5   r(   s       r/   r  r  G       u%%r1   c                 ,    t        j                  |      S )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).
    )r  r  rw  s       r/   r)  r)  P  rx  r1   _ModelTmappingc                     | j                         D ]V  }|j                  |v s||j                     }|j                         D ]#  \  }}||j                  v s||j                  |<   % X | S )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   r5   rL   rE   )r(   r{  r   rE   r,  rO   s         r/   change_attr_valuesr}  \  sm     

 -99DII&E${{} -e4::%',DJJt$-- Lr1   dropout_ratedropc                 z    | j                         D ]'  }|D ]   }||j                  v s||j                  |<   " ) | S )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   rE   )r(   r  rE   r   r,  s        r/   set_dropout_rater  i  sI     

 ( 	(Dtzz!#'

4 	(( Lr1   wrapperc                 ~    t        | j                               D ]  }| j                  | ||               ||       S )zORecursively wrap a model and its submodules. The model is updated
    in-place.)rK   r   r   )r(   r  r   s      r/   wrap_model_recursiver  t  s>     UZZ\" 04/0 5>r1   )r$   r  r)  r}  r  r  )r(   r$   r)   r$   )=r   r   	functoolsrn  contextvarsr   pathlibr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r  backendsr   r   r   r   r   
optimizersr   rD   r   typesr   utilr   r   r   r   r    r!   r"   r#   r&   rJ   rm  r0   r$   singledispatchr  rt  r  r)  rz  r}  floatr  r  __all__r,   r1   r/   <module>r     s       "    "  J J !    envw'&01Db&Q :d# QS?GCI S?l &c &# &S & &5 & & & &C &s &5 &S & & )5
)
g 
S$sCx.5H0I 
g 
 :H8H G 5 W  %'9I0J w r1   