o
    ?eD*                     @   s   d 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 ddlm	Z	 ddl
mZ ddlmZ dd	lmZ g aG d
d dZejdd Zdd ZG dd deZG dd dejedZedG dd deZG dd deZdS )z7Definitions for resource-type trackable object classes.    N)context)def_function)ops)tensor)base)tf_contextlib)	tf_exportc                   @   s2   e Zd ZdZdgZdd Zedd Zdd Zd	S )
ResourceTrackerz*An object that tracks a list of resources.
_resourcesc                 C   s
   g | _ d S Nr
   self r   e/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/trackable/resource.py__init__&   s   
zResourceTracker.__init__c                 C      | j S r   r   r   r   r   r   	resources)      zResourceTracker.resourcesc                 C   s   | j | d S r   )r
   append)r   resourcer   r   r   add_resource-   s   zResourceTracker.add_resourceN)	__name__
__module____qualname____doc__	__slots__r   propertyr   r   r   r   r   r   r	   !   s    
r	   c                 c   s,    t t}t|  zdV  W |adS |aw )a  A context to manage resource trackers.

  Use this in order to collect up all resources created within a block of code.
  Example usage:

  ```python
  resource_tracker = ResourceTracker()
  with resource_tracker_scope(resource_tracker):
    resource = TrackableResource()

  assert resource_tracker.resources == [resource]

  Args:
    resource_tracker: The passed in ResourceTracker object

  Yields:
    A scope in which the resource_tracker is active.
  N)list_RESOURCE_TRACKER_STACKr   )resource_trackeroldr   r   r   resource_tracker_scope1   s   
r"   c                    s    fdd}|S )z"To avoid capturing loop variables.c                     s    g| R i |S r   r   )argskwargscaptured_gettercaptured_previousr   r   getterQ   s   z_make_getter.<locals>.getterr   )r&   r'   r(   r   r%   r   _make_getterN   s   r)   c                   @   s   e Zd ZdZdd ZdS )_ResourceMetaclassz!Metaclass for CapturableResource.c                    sL    fddfdd}t  j}|   D ]}t||}q||i |S )Nc                    s8   | d u sJ  j  g|R i |}|j|i | |S r   )__new__r   )Znext_creatorakwobjclsr   r   default_resource_creator\   s   z=_ResourceMetaclass.__call__.<locals>.default_resource_creatorc                     s    d g| R i |S r   r   )r,   r-   )r1   r   r   <lambda>b   s    z-_ResourceMetaclass.__call__.<locals>.<lambda>)r   get_default_graphZ_resource_creator_stack_resource_typer)   )r0   r#   r$   Zprevious_getterZresource_creator_stackr(   r   )r0   r1   r   __call__Z   s   
z_ResourceMetaclass.__call__N)r   r   r   r   r5   r   r   r   r   r*   W   s    r*   c                       s   e Zd ZdZdddZedd Zedd Zej	d	d Zd
d Z
edd Zej	dd Zdd Zdd Zedd Zdd Zejjf fdd	Zdd Z  ZS )CapturableResourceaz  Holds a Tensor which a tf.function can capture.

  `CapturableResource`s are discovered by traversing the graph of object
  attributes, e.g. during `tf.saved_model.save`. They are excluded from the
  scope-based tracking of `TrackableResource`; generally things that require
  initialization should inherit from `TrackableResource` instead of
  `CapturableResource` directly.
   c                 C   s0   d| _ || _t rtj| _dS t j| _dS )ad  Initialize the `CapturableResource`.

    Args:
      device: A string indicating a required placement for this resource,
        e.g. "CPU" if this resource must be created on a CPU device. A blank
        device allows the user to place resource creation, so generally this
        should be blank unless the resource only makes sense on one device.
    N)	_resource_handle_value_resource_devicer   Zexecuting_eagerlyZ
eager_moder   r3   Z
as_default_self_destruction_contextr   devicer   r   r   r   t   s   	zCapturableResource.__init__c                 C   r   r   )r   r/   r   r   r   r4      r   z!CapturableResource._resource_typec                 C   s   t | dtjS )Nr:   )getattr
contextlibsuppressr   r   r   r   _destruction_context   s   z'CapturableResource._destruction_contextc                 C   s
   || _ d S r   )r:   )r   Zdestruction_contextr   r   r   r@      s   
c                 C   s   t d)z*A function that creates a resource handle.z3TrackableResource._create_resource not implemented.)NotImplementedErrorr   r   r   r   _create_resource   s   z#CapturableResource._create_resourcec                 C   r   r   )r8   r   r   r   r   _resource_handle   r   z#CapturableResource._resource_handlec                 C   s(   t |tjtjfrt| |_|| _d S r   )	
isinstancer   ZTensorr   ZEagerTensorweakrefrefZ_parent_trackabler8   )r   valuer   r   r   rC      s   
c                 C      dS )z3A function that initializes the resource. Optional.Nr   r   r   r   r   _initialize      zCapturableResource._initializec                 C   rH   )z0A function that destroys the resource. Optional.Nr   r   r   r   r   _destroy_resource   rJ   z$CapturableResource._destroy_resourcec                 C   sJ   | j du r"t| j |  | _ W d   | j S 1 sw   Y  | j S )z:Returns the resource handle associated with this Resource.N)rC   r   r<   r9   rB   r   r   r   r   resource_handle   s   

z"CapturableResource.resource_handlec                 K   s^   t  | }t| j | }W d   n1 sw   Y  ||_||| < ||| j< | jgS )zFor implementing `Trackable`.N)copyr   r<   r9   rB   rC   rL   )r   Z
object_mapZ
tensor_mapunused_kwargsZnew_objZnew_resourcer   r   r   _export_to_saved_model_graph   s   


z/CapturableResource._export_to_saved_model_graphc                    s   t  j|fi |}|dkr>tjg dd fdd}tjg dd fdd}tjg dd fdd	}||||d
 |S )NZ
savedmodelF)Zinput_signatureZ	autographc                     s      } | S r   )rB   )r   r   r   r   _creator      z8CapturableResource._trackable_children.<locals>._creatorc                             dS N   )rI   r   r   r   r   _initializer   rQ   z<CapturableResource._trackable_children.<locals>._initializerc                      rR   rS   )rK   r   r   r   r   
_destroyer   rQ   z:CapturableResource._trackable_children.<locals>._destroyer)rB   rI   rK   )super_trackable_childrenr   functionupdate)r   	save_typer$   childrenrP   rU   rV   	__class__r   r   rX      s   z&CapturableResource._trackable_childrenc                 C   sP   z|    |   W d    W d S 1 sw   Y  W d S  ty'   Y d S w r   )r@   rK   	Exceptionr   r   r   r   __del__   s   

&zCapturableResource.__del__r7   )r   r   r   r   r   classmethodr4   r   r@   setterrB   rC   rI   rK   rL   rO   r   ZSaveType
CHECKPOINTrX   r`   __classcell__r   r   r]   r   r6   j   s*    
	





r6   )	metaclassz*saved_model.experimental.TrackableResourcec                       s"   e Zd ZdZd fdd	Z  ZS )TrackableResourceai  Holds a Tensor which a tf.function can capture.

  A TrackableResource is most useful for stateful Tensors that require
  initialization, such as `tf.lookup.StaticHashTable`. `TrackableResource`s
  are discovered by traversing the graph of object attributes, e.g. during
  `tf.saved_model.save`.

  A TrackableResource has three methods to override:

  * `_create_resource` should create the resource tensor handle.
  * `_initialize` should initialize the resource held at `self.resource_handle`.
  * `_destroy_resource` is called upon a `TrackableResource`'s destruction
    and should decrement the resource's ref count. For most resources, this
    should be done with a call to `tf.raw_ops.DestroyResourceOp`.

  Example usage:

  >>> class DemoResource(tf.saved_model.experimental.TrackableResource):
  ...   def __init__(self):
  ...     super().__init__()
  ...     self._initialize()
  ...   def _create_resource(self):
  ...     return tf.raw_ops.VarHandleOp(dtype=tf.float32, shape=[2])
  ...   def _initialize(self):
  ...     tf.raw_ops.AssignVariableOp(
  ...         resource=self.resource_handle, value=tf.ones([2]))
  ...   def _destroy_resource(self):
  ...     tf.raw_ops.DestroyResourceOp(resource=self.resource_handle)
  >>> class DemoModule(tf.Module):
  ...   def __init__(self):
  ...     self.resource = DemoResource()
  ...   def increment(self, tensor):
  ...     return tensor + tf.raw_ops.ReadVariableOp(
  ...         resource=self.resource.resource_handle, dtype=tf.float32)
  >>> demo = DemoModule()
  >>> demo.increment([5, 1])
  <tf.Tensor: shape=(2,), dtype=float32, numpy=array([6., 2.], dtype=float32)>
  r7   c                    s&   t D ]}||  qt j|d dS )ac  Initialize the `TrackableResource`.

    Args:
      device: A string indicating a required placement for this resource,
        e.g. "CPU" if this resource must be created on a CPU device. A blank
        device allows the user to place resource creation, so generally this
        should be blank unless the resource only makes sense on one device.
    r<   N)r   r   rW   r   )r   r<   r    r]   r   r   r     s   
zTrackableResource.__init__ra   )r   r   r   r   r   re   r   r   r]   r   rg      s    'rg   c                       s6   e Zd ZdZd	 fdd	Zedd Zdd Z  ZS )
RestoredResourcezRestored SavedResource.r7   c                    s   t  j|d d S )Nrh   )rW   r   r;   r]   r   r   r   %  s   zRestoredResource.__init__c                 K   s*   | |j jd}|d}|d ur||_|S )Nrh   rB   )r   r<   getrB   )r0   Zobject_protodependenciesrN   r.   Zresource_creatorr   r   r   _deserialize_from_proto(  s
   
z(RestoredResource._deserialize_from_protoc                 C   s<   t | || t|tjrt|tjs| || d S d S d S r   )setattrrD   r   	Trackabler   FunctionZ_track_trackable)r   namerG   r   r   r   _add_trackable_child0  s   
z%RestoredResource._add_trackable_childra   )	r   r   r   r   r   rb   rl   rq   re   r   r   r]   r   ri   "  s    
ri   )r   r>   rM   rE   Ztensorflow.python.eagerr   r   Ztensorflow.python.frameworkr   r   Ztensorflow.python.trackabler   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   r   r	   contextmanagerr"   r)   typer*   rn   r6   rg   ri   r   r   r   r   <module>   s*   
	8