o
    i eT                     @   s   d Z ddlZddlmZ ddlm  mZ ddlm	Z	 e
 ZdddZG dd	 d	ejjjZG d
d dejejjjZeeej dd ZG dd dZdS )zGContains AutoCastVariable, a variable which automatically casts itself.    N)Optional)distributed_training_utilsFc                 C   s>   | j jr|rt|  nt|  }nd}d|v rd| }|S )z8Human readable representation of a tensor's numpy value.z<unprintable>
)dtypeis_numpy_compatiblerepr_numpystr)tensoris_reprtext r   Z/var/www/myenv/lib/python3.10/site-packages/keras/src/mixed_precision/autocast_variable.py
numpy_text   s   r   c                   @   sd   e Zd ZdZdd ZdefddZdd Zdd
dZdd Z	dd Z
defddZdefddZd	S )AutoCastVariableSpeczTraceType for AutoCastVariableSpec for tracing with tf.function.

    This class implements the Type for AutoCastVariable used in tracing.
    c                 C   s
   || _ d S N_valueselfvaluer   r   r   __init__0      
zAutoCastVariableSpec.__init__returnc                 C   s   | |kS )z5If the other spec is the same as `self`, return True.r   r   otherr   r   r   is_subtype_of3      z"AutoCastVariableSpec.is_subtype_ofc                    s   t  fdd|D r S dS )z;`self` is the common supertype if all input types match it.c                 3   s    | ]} |kV  qd S r   r   ).0r   r   r   r   	<genexpr>9   s    zFAutoCastVariableSpec.most_specific_common_supertype.<locals>.<genexpr>N)all)r   othersr   r   r   most_specific_common_supertype7   s   z3AutoCastVariableSpec.most_specific_common_supertypeNc                 C   s   | j S )z7Use the AutoCastVariable value itself as a placeholder.r   )r   placeholder_contextr   r   r   placeholder_value;   s   z&AutoCastVariableSpec.placeholder_valuec                 C   s   |S r   r   )r   r   _r   r   r   _cast?      zAutoCastVariableSpec._castc                 C   s   g S r   r   r   r   r   r   _to_tensorsB   r(   z AutoCastVariableSpec._to_tensorsc                 C   s   t t| jS r   )hashidr   r   r   r   r   __hash__E      zAutoCastVariableSpec.__hash__c                 C   s   | |u S r   r   r   r   r   r   __eq__H      zAutoCastVariableSpec.__eq__r   )__name__
__module____qualname____doc__r   boolr   r#   r%   r'   r)   intr,   r.   r   r   r   r   r   *   s    
r   c                   @   sB  e Zd ZdZdd Zdd Zedd Zedd	 Zed
d Z	dd Z
dd ZdddZdddZdd ZdddZ		ddeejj dee dejfddZdd  Zd!d" Zd#d$ Zed%d& Zed'd( Zed)d* Zdd+d,Zd-d. Zed/d0 Zed1d2 Z 	3dd4d5Z!d6d7 Z"dd8d9Z#dd:d;Z$dd<d=Z%dd>d?Z&dd@dAZ'ddBdCZ(ddDdEZ)ddFdGZ*ddHdIZ+ddJdKZ,ddLdMZ-ddNdOZ.ddPdQZ/ddRdSZ0ddTdUZ1edVdW Z2edXdY Z3edZd[ Z4ed\d] Z5ed^d_ Z6d`da Z7edbdc Z8eddde Z9dfdg Z:dhdi Z;djdk Z<dldm Z=ddndoZ>ddpdqZ?edrds Z@e@jAdtds Z@edudv ZBeBjAdwdv ZBdxdy ZCdzd{ ZDd|d} ZEd~d ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdddZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dS )AutoCastVariablea  Variable that casts itself to a different dtype in applicable contexts.

    This class wraps a floating-point `tf.Variable`. It emulates the variable
    interface and delegates to the wrapped variable, but it additionally will
    cast the wrapped variable under an `enable_auto_cast_variables(dtype)`
    context manager.

    For example:

    >>> v = tf.Variable(1.0, dtype=tf.float32)
    >>> v = AutoCastVariable(v)
    >>> tf.identity(v).dtype
    tf.float32
    >>> with enable_auto_cast_variables(tf.float16):
    ...   tf.identity(v).dtype
    tf.float16

    The purpose of this class is to allow Keras layers to create variables in
    float32, and automatically cast them to float16 or bfloat16 when the layer
    is called.
    c                 C   s@   t |tjstd| |jjstd|jj || _d| _dS )zCreates an AutoCastVariable instance.

        Args:
          variable: A floating-point resource variable to wrap.

        Raises:
          ValueError: If `variable` is not a floating-point resource variable
        z9variable must be of type tf.ResourceVariable, but got: %sz;variable must be a floating point variable but has type: %sdelegateN)	
isinstancetfVariable
ValueErrorr   is_floatingname	_variable_op)r   variabler   r   r   r   c   s   	
zAutoCastVariable.__init__c                 C   s   t tdd}|duo| j|kS )z=Returns True if this variable should be casted when accessed.r   N)getattr_autocast_dtyper   )r   autocast_dtyper   r   r   _should_cast}   s   zAutoCastVariable._should_castc                 C      | j jS )z@The dtype of the underlying variable, before any casts are done.r>   r   r   r   r   r   r         zAutoCastVariable.dtypec                 C   rE   )zDeprecated alias of `dtype`.rF   r   r   r   r   
true_dtype   rG   zAutoCastVariable.true_dtypec                 C   s   t tdd }|p| jjS Nr   )rA   rB   r>   r   r   r   r   r   r   _cast_dtype   s   zAutoCastVariable._cast_dtypec                 C   s$   | j  }|  s|S t|| jS r   )r>   r   rD   r9   castrK   r   valr   r   r   r      s   
zAutoCastVariable.valuec                 C   s   | j  }t|| jS r   )r>   
read_valuer9   rL   rK   rM   r   r   r   rO      s   
zAutoCastVariable.read_valueNc                 C      | j j||d}t|| jS )z:Reads the value of this variable sparsely, using `gather`.r=   )r>   sparse_readr9   rL   rK   r   indicesr=   rN   r   r   r   rR         zAutoCastVariable.sparse_readc                 C   rP   )z,Gather slices of the variable into a Tensor.rQ   )r>   	gather_ndr9   rL   rK   rS   r   r   r   rV      rU   zAutoCastVariable.gather_ndc                 C   s   t | j|S r   )rA   r>   )r   r=   r   r   r   __getattr__      zAutoCastVariable.__getattr__Fc                 C   st   |rt d|  stj| j||dS |dur(|| js(t d|j| jjtj| j| jj	|d}t
|| jS )z#Converts this variable to a tensor.zYCannot convert AutoCastVariable to a tensor if as_ref=True is passed to convert_to_tensorr   r=   NzeIncompatible type conversion requested to type {!r} for AutoCastVariable which is casted to type {!r})r;   rD   r9   convert_to_tensorr>   is_compatible_withrK   formatr=   r   rL   )r   r   r=   as_refrN   r   r   r   _dense_var_to_tensor   s"   
z%AutoCastVariable._dense_var_to_tensorr   r=   r   c                 C   s   | j ||dS )NrY   )r^   )r   r   r=   r   r   r   __tf_tensor__   s   zAutoCastVariable.__tf_tensor__c                 C   s   dS )z6Pass resource_variable_ops.is_resource_variable check.Nr   r   r   r   r    _should_act_as_resource_variable   s   z1AutoCastVariable._should_act_as_resource_variablec                 C   s<   t  r| jsd}|j| t|  dddS d}|j| dS )Nzy<AutoCastVariable '{v.name}' shape={v.shape} dtype={v.dtype.name} dtype_to_cast_to={v._cast_dtype.name}, numpy={np_repr}>T)r   )vnp_reprzh<AutoCastVariable '{v.name}' shape={v.shape} dtype={v.dtype.name} dtype_to_cast_to={v._cast_dtype.name}>ra   )r9   executing_eagerly_in_graph_moder\   r   rO   )r   repr_strr   r   r   __repr__   s   zAutoCastVariable.__repr__c                 C   s   | j | |S r   )r>   	set_shape)r   shaper   r   r   rh      r-   zAutoCastVariable.set_shapec                 C   rE   r   )r>   	trainabler   r   r   r   rj      r   zAutoCastVariable.trainablec                 C   rE   r   )r>   synchronizationr   r   r   r   rk      r   z AutoCastVariable.synchronizationc                 C   rE   r   )r>   aggregationr   r   r   r   rl      r   zAutoCastVariable.aggregationc                 C      | j |S r   )r>   eval)r   sessionr   r   r   rn      rX   zAutoCastVariable.evalc                 C   
   | j  S r   )r>   initialized_valuer   r   r   r   rq      r   z"AutoCastVariable.initialized_valuec                 C   rE   r   )r>   initial_valuer   r   r   r   rr      r   zAutoCastVariable.initial_valuec                 C   rE   r   )r>   
constraintr   r   r   r   rs     r   zAutoCastVariable.constraintTc           	      C   sb   t jj r||||d}|rt| j}||_|S |S |||||}|r/t jj	|r/t|S |S )NF)
r9   compatv1#executing_eagerly_outside_functionscreate_autocast_variabler>   r?   __internal__opsis_resource_variable)	r   	update_fnr   use_lockingr=   rO   	assign_opvar
assign_varr   r   r   _apply_assign_update  s   
z%AutoCastVariable._apply_assign_updatec                 O   s8   ||i |}t jj r| S t jj|rt|S |S r   )r9   rt   ru   rv   rx   ry   rz   rw   )r   r{   argskwargs
update_varr   r   r   _apply_update  s   zAutoCastVariable._apply_updatec                 C      |  | jj||||S r   )r   r>   assign)r   r   r|   r=   rO   r   r   r   r   (     zAutoCastVariable.assignc                 C   r   r   )r   r>   
assign_addr   deltar|   r=   rO   r   r   r   r   -  r   zAutoCastVariable.assign_addc                 C   r   r   )r   r>   
assign_subr   r   r   r   r   2  r   zAutoCastVariable.assign_subc                 C      |  | jj|||S r   )r   r>   scatter_subr   sparse_deltar|   r=   r   r   r   r   7     zAutoCastVariable.scatter_subc                 C   r   r   )r   r>   scatter_addr   r   r   r   r   <  r   zAutoCastVariable.scatter_addc                 C   r   r   )r   r>   scatter_maxr   r   r   r   r   A  r   zAutoCastVariable.scatter_maxc                 C   r   r   )r   r>   scatter_minr   r   r   r   r   F  r   zAutoCastVariable.scatter_minc                 C   r   r   )r   r>   scatter_mulr   r   r   r   r   K  r   zAutoCastVariable.scatter_mulc                 C   r   r   )r   r>   scatter_divr   r   r   r   r   P  r   zAutoCastVariable.scatter_divc                 C   r   r   )r   r>   scatter_updater   r   r   r   r   U  r   zAutoCastVariable.scatter_updatec                 C   r   r   )r   r>   batch_scatter_updater   r   r   r   r   Z  r   z%AutoCastVariable.batch_scatter_updatec                 C   r   r   )r   r>   scatter_nd_subr   rT   updatesr=   r   r   r   r   _  r   zAutoCastVariable.scatter_nd_subc                 C   r   r   )r   r>   scatter_nd_addr   r   r   r   r   d  r   zAutoCastVariable.scatter_nd_addc                 C   r   r   )r   r>   scatter_nd_updater   r   r   r   r   i  r   z"AutoCastVariable.scatter_nd_updatec                 C      | j ||S r   )r>   load)r   r   ro   r   r   r   r   n  r-   zAutoCastVariable.loadc                 C   rE   r   )r>   r=   r   r   r   r   r=   q  r   zAutoCastVariable.namec                 C   rE   r   )r>   _shared_namer   r   r   r   r   u  r   zAutoCastVariable._shared_namec                 C   rE   r   )r>   initializerr   r   r   r   r   y  r   zAutoCastVariable.initializerc                 C   rE   r   )r>   devicer   r   r   r   r   }  r   zAutoCastVariable.devicec                 C   s   | j dkr	| jjS | j S )Nr7   )r?   r>   opr   r   r   r   r     s   
zAutoCastVariable.opc                 C   s   | j  }|d u r| jS |S r   )r>   _as_graph_elementr?   )r   graph_elementr   r   r   r     s   
z"AutoCastVariable._as_graph_elementc                 C   rE   r   )r>   graphr   r   r   r   r     r   zAutoCastVariable.graphc                 C   rE   r   )r>   ri   r   r   r   r   ri     r   zAutoCastVariable.shapec                 C   rp   r   )r>   	get_shaper   r   r   r   r     r   zAutoCastVariable.get_shapec                 C   s   t | S r   )r   )r   contextr   r   r   __tf_tracing_type__  r/   z$AutoCastVariable.__tf_tracing_type__c                 C   rp   r   )r>    _gather_saveables_for_checkpointr   r   r   r   r     s   
z1AutoCastVariable._gather_saveables_for_checkpointc                 K   s*   | j j|||fi |}|| j  || < |S r   )r>   _export_to_saved_model_graph)r   
object_map
tensor_mapoptionsr   resource_listr   r   r   r     s   z-AutoCastVariable._export_to_saved_model_graphc                 C   rm   r   )r>   to_proto)r   export_scoper   r   r   r     rX   zAutoCastVariable.to_protoc                 C   r   r   )r>   
from_proto)r   variable_defimport_scoper   r   r   r     r-   zAutoCastVariable.from_protoc                 C   rE   r   r>   _handle_namer   r   r   r   r     r   zAutoCastVariable._handle_namec                 C      || j _d S r   r   )r   handle_namer   r   r   r        c                 C   rE   r   r>   _initializer_opr   r   r   r   r     r   z AutoCastVariable._initializer_opc                 C   r   r   r   )r   initializer_opr   r   r   r     r   c                 C   s   |   | S r   rO   r   or   r   r   __add__  rX   zAutoCastVariable.__add__c                 C   s   ||    S r   r   r   r   r   r   __radd__  rX   zAutoCastVariable.__radd__c                 C   s   |   | S r   r   r   r   r   r   __sub__  rX   zAutoCastVariable.__sub__c                 C   s   ||    S r   r   r   r   r   r   __rsub__  rX   zAutoCastVariable.__rsub__c                 C   s   |   | S r   r   r   r   r   r   __mul__  rX   zAutoCastVariable.__mul__c                 C   s   ||    S r   r   r   r   r   r   __rmul__  rX   zAutoCastVariable.__rmul__c                 C   s   |   | S r   r   r   r   r   r   __truediv__  rX   zAutoCastVariable.__truediv__c                 C   s   ||    S r   r   r   r   r   r   __rtruediv__  rX   zAutoCastVariable.__rtruediv__c                 C   s   |   | S r   r   r   r   r   r   __floordiv__  rX   zAutoCastVariable.__floordiv__c                 C   s   ||    S r   r   r   r   r   r   __rfloordiv__  rX   zAutoCastVariable.__rfloordiv__c                 C   s   |   | S r   r   r   r   r   r   __mod__  rX   zAutoCastVariable.__mod__c                 C   s   ||    S r   r   r   r   r   r   __rmod__  rX   zAutoCastVariable.__rmod__c                 C   s   |   |k S r   r   r   r   r   r   __lt__  rX   zAutoCastVariable.__lt__c                 C   s   |   |kS r   r   r   r   r   r   __le__  rX   zAutoCastVariable.__le__c                 C   s   |   |kS r   r   r   r   r   r   __gt__  rX   zAutoCastVariable.__gt__c                 C   s   |   |kS r   r   r   r   r   r   __ge__   rX   zAutoCastVariable.__ge__c                 C   s   |   | S r   r   r   r   r   r   __getitem__  rX   zAutoCastVariable.__getitem__c                 C   s   t |  ||S r   powrO   )r   r   modulor   r   r   __pow__  s   zAutoCastVariable.__pow__c                 C   s   t ||  S r   r   r   r   r   r   __rpow__	  r-   zAutoCastVariable.__rpow__c                 C   s
   |    S r   r   r   r   r   r   __neg__  r   zAutoCastVariable.__neg__c                 C   s   t |  S r   )absrO   r   r   r   r   __abs__  rX   zAutoCastVariable.__abs__c                 C   (   z|   |W S  ty   t Y S w r   )rO   __div__AttributeErrorNotImplementedr   r   r   r   r     
   zAutoCastVariable.__div__c                 C   r   r   )rO   __rdiv__r   r   r   r   r   r   r     r   zAutoCastVariable.__rdiv__c                 C   r   r   )rO   
__matmul__r   r   r   r   r   r   r   "  r   zAutoCastVariable.__matmul__c                 C   r   r   )rO   __rmatmul__r   r   r   r   r   r   r   *  r   zAutoCastVariable.__rmatmul__r   )NNF)NN)NNT)FN)\r0   r1   r2   r3   r   rD   propertyr   rH   rK   r   rO   rR   rV   rW   r^   r   r9   dtypesDTyper	   Tensorr_   r`   rg   rh   rj   rk   rl   rn   rq   rr   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r=   r   r   r   r   r   r   ri   r   r   r   r   r   r   r   setterr   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   r6   L   s    











































	
r6   c                 C   s.   t | s	t| S G dd dt| j}|| S )av  Creates an AutoCastVariable that wraps another variable.

    This typically just returns `AutoCastVariable(variable)`. But, if the
    variable is a DistributedVariable or one of its subclasses, we instead
    dynamically create a class that subclasses from both AutoCastVariable and
    variable.__class__. This is so the returned variable will still pass
    `isinstance(variable, variable.__class__)`, which is required for
    DistributedVariables and its subclasses to work properly.

    Args:
      variable: A floating-point resource variable to wrap.

    Returns:
      An AutoCastVariable that wraps the variable.
    c                   @   s   e Zd ZdZdd ZdS )z=create_autocast_variable.<locals>.AutoCastDistributedVariablezAn AutoCastVariable that also subclasses from variable.__class__.

        variable.__class__ is either a DistributedVariable or an
        AggregatingVariable.
        c                 S   s   dj | dS )Nzu<AutoCastDistributedVariable dtype={v.dtype.name} dtype_to_cast_to={v._cast_dtype.name} inner_variable={v._variable}>rc   )r\   r   r   r   r   rg   R  s   zFcreate_autocast_variable.<locals>.AutoCastDistributedVariable.__repr__N)r0   r1   r2   r3   rg   r   r   r   r   AutoCastDistributedVariableK  s    r   )r   is_distributed_variabler6   	__class__)r@   r   r   r   r   rw   8  s   
rw   c                   @   s0   e Zd ZdZddgZdd Zdd Zdd	 Zd
S )enable_auto_cast_variableszContext manager which enables the autocasting of `AutoCastVariable`s.

    Under this context manager, `AutoCastVariable`s will be cast to `dtype` if
    `dtype` is floating-point. Otherwise, `AutoCastVariable`s will not be cast.
    _dtype_prev_dtypec                 C   s   |r|j sd }|| _d S r   )r<   r   rJ   r   r   r   r   f  s   

z#enable_auto_cast_variables.__init__c                 C   s   t tdd | _| jt_d S rI   )rA   rB   r   r   r   r   r   r   r   	__enter__k  s   z$enable_auto_cast_variables.__enter__c                 C   s   | j t_d S r   )r   rB   r   )r   type_arg	value_argtraceback_argr   r   r   __exit__o  rX   z#enable_auto_cast_variables.__exit__N)r0   r1   r2   r3   	__slots__r   r   r   r   r   r   r   r   ]  s    r   )F)r3   	threadingtypingr   tensorflow.compat.v2rt   v2r9   keras.src.distributer   localrB   r   typesexperimental	TraceTyper   r:   rx   r   r6   #register_tensor_conversion_functionr^   rw   r   r   r   r   r   <module>   s"   
"   j%