o
    il)                     @   s   d dl Z d dlZd dlmZ d dlmZmZmZmZ d dl	Z	d dl
Z
ddlmZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ e	jddddZdd ZG dd deZdS )    N)BytesIO)AnyDictListOptional   )Opsget_current_ops)cupyh5py)
tensorflow)	Optimizer)
ArgsKwargsArrayXd)get_array_module   )ShimthinckerasT)entry_pointsc              	   C   s   z|    | W S  ttfy   Y nw dD ]}t| |s tdqt }|jdkr,d}ntj	 }| j
}t|3 | jdi | | | j | | j t| drX|   n|   W d   | S W d   | S 1 sow   Y  | S )zCall the required predict/compile/build APIs to initialize a model if it
    is a subclass of tf.keras.Model. This is required to be able to call set_weights
    on subclassed layers.)catalogue_nameeg_xeg_yeg_shapeaB  Keras subclassed models are not whole-model serializable by TensorFlow. To work around this, you must decorate your keras model subclasses with the 'keras_subclass' decorator. The decorator requires a single X/Y input of fake-data that can be used to initialize your subclass model properly when loading the saved version.cpuCPU_make_train_functionN )
get_configAttributeErrorNotImplementedErrorhasattr
ValueErrorr	   device_typetftestgpu_device_name
eg_compiledevicecompilebuildr   predictr   r   make_train_function)keras_model	prop_nameopsr(   compile_argsr   r   J/home/ubuntu/.local/lib/python3.10/site-packages/thinc/shims/tensorflow.pymaybe_handshake_model   s>   
	









r2   c                       s   e Zd ZU dZeed  ed< d(dedef fddZd	d
 Z	de
defddZde
fddZde
fddZdefddZ	d)deeeef  fddZdd Zejdd Zdd Zdd Zd ed!efd"d#Zd$d% Zd&d' Z  ZS )*TensorFlowShimzInterface between a TensorFlow model and a Thinc Model. This container is
    *not* a Thinc Model subclass itself.

    Reference for custom training:
    https://www.tensorflow.org/tutorials/customization/custom_training_walkthrough
    z	tf.Tensor	gradientsNmodel	optimizerc                    s   t  ||| d | _d S N)super__init__r4   )selfr5   configr6   	__class__r   r1   r9   I   s   
zTensorFlowShim.__init__c                    s.   g  dt f fdd}| jj|d d S )Nlinec                    s     |  d S r7   )append)r>   linesr   r1   
accumulateP   s   z*TensorFlowShim.__str__.<locals>.accumulate)print_fn
)str_modelsummaryjoin)r:   rB   r   r@   r1   __str__M   s   
zTensorFlowShim.__str__Xis_trainc                 C   s   |r|  |S | |S r7   )begin_updater+   )r:   rJ   rK   r   r   r1   __call__V   s   

zTensorFlowShim.__call__c                 C   s@   t jj }t jjd | j|ji |j}t jj| |S )Nr   )r$   r   backendlearning_phaseset_learning_phaserF   argskwargs)r:   rJ   	old_phaseYr   r   r1   r+   \   s
   zTensorFlowShim.predictc                    sX   t jjd t     j j ji  j	 fdd}|fS )Nr   c                    s    d d d  t jdkr jd g}nt jd }|jj j|| d}|d t j }|dd  }jd ur]t|tjksLJ dt	j|D ]	\}}|
| qRndd |D _tt|i dS )Nr   r   )output_gradientszgradients must matchc                 S   s   g | ]}t |qS r   )r$   Variable).0fr   r   r1   
<listcomp>   s    zATensorFlowShim.begin_update.<locals>.backprop.<locals>.<listcomp>)rQ   rR   )__exit__lenrQ   listextendrF   trainable_variablesgradientr4   zip
assign_addr   tuple)d_outputwrt_tensorsall_gradientsdX	opt_gradsvariablenew_variablerJ   outputr:   taper   r1   backpropj   s"   
z-TensorFlowShim.begin_update.<locals>.backprop)
r$   r   rN   rP   GradientTape	__enter__watchrQ   rF   rR   )r:   rJ   rm   r   rj   r1   rL   c   s   zTensorFlowShim.begin_updatec                 C   s  | j d u r	tdt| j t| jjksJ g }g }g }t| j | jjD ]#\}}| }| }||j|j	f ||
  ||
  q$t|d }|| jdf||||\}	}
d}t| j | jjD ]\}}|d\}}|	|||  |}|| ||7 }qid | _ d S )NzcThere are no gradients for optimization. Be sure to call begin_update before calling finish_update.r   ztensorflow-shim)r4   r"   r[   rF   r^   r`   numpyr?   sizeshaperavelr   idconcatenatepopreshapeassign)r:   r6   paramsgradsshapesgradrh   paramxpflat_params
flat_gradsstartrr   rs   r   r   r1   finish_update   s2   



zTensorFlowShim.finish_update
state_dictc                 C   sL   |d u r|   }| jjD ]}g }|jD ]
}|||j  q|| qd S r7   )_create_state_dictrF   layersweightsr?   nameset_weights)r:   r   layercurrent_layer_weightsweightr   r   r1   _load_weights_from_state_dict   s   
z,TensorFlowShim._load_weights_from_state_dictc                 C   s0   i }| j jD ]}|jD ]	}| ||j< qq|S r7   )rF   r   r   rq   r   )r:   r   r   r   r   r   r1   r      s   
z!TensorFlowShim._create_state_dictc                 c   s    d| j  d}i }| D ]8\}}t|drF||rFtd u r)t|tjs(J nt|tjjjr6t	|}t|tjs>J |||
|d< q|r\|  }| | d V  | | d S d V  d S )Ntensorflow__
startswith )ru   itemsr!   r   r
   
isinstancerq   ndarraycoreasnumpyreplacer   r   )r:   rz   
key_prefixr   kvbackupr   r   r1   
use_params   s$   


zTensorFlowShim.use_paramsc                 C   s2   | j  }tjj  tjj|| _ |   dS )zsimilar to tf.keras.models.clone_model()
        But the tf.keras.models.clone_model changes the names of tf.Variables.
        This method even preserves that
        N)	rF   to_jsonr$   r   rN   clear_sessionmodelsmodel_from_jsonr   )r:   model_json_configr   r   r1   _clone_model   s   
zTensorFlowShim._clone_modelc                 C   sB   | j  }d | _ tjj  t| }tjj	||_ |
  |S r7   )rF   r   r$   r   rN   r   copydeepcopyr   r   r   )r:   r   copiedr   r   r1   r      s   

zTensorFlowShim.copyr#   	device_idc                 C   s   |dkr t d |   W d    d S 1 sw   Y  d S |dkrCt d| |   W d    d S 1 s<w   Y  d S d S )Nr   z/CPUgpuz/GPU:{})r$   r(   r   format)r:   r#   r   r   r   r1   	to_device   s   
"
"zTensorFlowShim.to_devicec                 C   s   t  }z#t|d}| jj|dd W d    n1 sw   Y  | W S  ty9   t| jds7tdY nw t	
| jj | jj| j fS )Nwh5)save_formatr   zXCouldn't serialize to h5, and model has no factory function for component serialization.)r   r   FilerF   savegetvaluer    r!   r"   keras_model_fnsgetr   get_weights)r:   filelikerX   r   r   r1   to_bytes   s   
zTensorFlowShim.to_bytesc              	   C   sP  t  }|jdkrd}ntj }t|ttfr[tjj	
  t|}|d t|d'}t| tjj|| _W d    n1 sEw   Y  	 W d    d S 1 sVw   Y  |\}}| jd u rt|}tjj	
  t| t| jdr| jj}	||	ji |	j}
n| }
W d    n1 sw   Y  t|
| _| j| d S )Nr   r   r   reg_args)r	   r#   r$   r%   r&   r   rE   bytesr   rN   r   r   seekr   r   r(   r   
load_modelrF   r   r   r!   r   rQ   rR   r2   _model_initializedr   )r:   datar/   r(   r   rX   r   model_weightsmodel_fnak	new_modelr   r   r1   
from_bytes   s6   


 


zTensorFlowShim.from_bytes)NNr7   ) __name__
__module____qualname____doc__r   r   __annotations__r   r9   rI   r   boolrM   r+   rL   r   r   r   rE   r   r   r   
contextlibcontextmanagerr   r   r   intr   r   r   __classcell__r   r   r<   r1   r3   ?   s*   
 	" 


	r3   ) r   r   ior   typingr   r   r   r   	cataloguerq   backendsr   r	   compatr
   r   r   r$   
optimizersr   typesr   r   utilr   shimr   creater   r2   r3   r   r   r   r1   <module>   s    *