o
    e*                     @   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 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)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   TD:\Projects\ConvertPro\env\Lib\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_scope0   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   getterP   s   z_make_getter.<locals>.getterr   )r%   r&   r'   r   r$   r   _make_getterM   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,   )r0   r   r   <lambda>a   s    z-_ResourceMetaclass.__call__.<locals>.<lambda>)r   get_default_graphZ_resource_creator_stack_resource_typer(   )r/   r"   r#   Zprevious_getterZresource_creator_stackr'   r   )r/   r0   r   __call__Y   s   
z_ResourceMetaclass.__call__N)r   r   r   r   r4   r   r   r   r   r)   V   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 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   r2   Z
as_default_self_destruction_contextr   devicer   r   r   r   s   s   	zCapturableResource.__init__c                 C   r   r
   )r   r.   r   r   r   r3      r   z!CapturableResource._resource_typec                 C   s   t | dtjS )Nr9   )getattr
contextlibsuppressr   r   r   r   _destruction_context   s   z'CapturableResource._destruction_contextc                 C   s
   || _ d S r
   )r9   )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
   )r7   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TensorZEagerTensorweakrefrefZ_parent_trackabler7   )r   valuer   r   r   rB      s   
c                 C      dS )z3A function that initializes the resource. Optional.Nr   r   r   r   r   _initialize      zCapturableResource._initializec                 C   rG   )z0A function that destroys the resource. Optional.Nr   r   r   r   r   _destroy_resource   rI   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)rB   r   r;   r8   rA   r   r   r   r   resource_handle   s   

z"CapturableResource.resource_handlec                 C   s^   t  | }t| j | }W d   n1 sw   Y  ||_| |i}| j|i}||fS )zFor implementing `Trackable`.N)copyr   r;   r8   rA   rB   rK   )r   _Znew_objZnew_resourceZobj_mapZresource_mapr   r   r   _map_resources   s   


z!CapturableResource._map_resourcesc                    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
   )rA   )r   r   r   r   _creator      z8CapturableResource._trackable_children.<locals>._creatorc                             dS N   )rH   r   r   r   r   _initializer   rP   z<CapturableResource._trackable_children.<locals>._initializerc                      rQ   rR   )rJ   r   r   r   r   
_destroyer   rP   z:CapturableResource._trackable_children.<locals>._destroyer)rA   rH   rJ   )super_trackable_childrenr   functionupdate)r   	save_typer#   childrenrO   rT   rU   	__class__r   r   rW      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?   rJ   	Exceptionr   r   r   r   __del__   s   

&zCapturableResource.__del__r6   )r   r   r   r   r   classmethodr3   r   r?   setterrA   rB   rH   rJ   rK   rN   rW   r_   __classcell__r   r   r\   r   r5   i   s*    
	





r5   )	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)>
  r6   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   rV   r   )r   r;   r   r\   r   r   r     s   
zTrackableResource.__init__r`   )r   r   r   r   r   rc   r   r   r\   r   re      s    're   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.r6   c                    s   t  j|d d S )Nrf   )rV   r   r:   r\   r   r   r   #  s   zRestoredResource.__init__c                 K   s*   | |j jd}|d}|d ur||_|S )Nrf   rA   )r   r;   getrA   )r/   Zobject_protodependenciesZunused_kwargsr-   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
   )setattrrC   r   	Trackabler   FunctionZ_track_trackable)r   namerF   r   r   r   _add_trackable_child.  s   
z%RestoredResource._add_trackable_childr`   )	r   r   r   r   r   ra   rj   ro   rc   r   r   r\   r   rg      s    
rg   )r   r=   rL   rD   Ztensorflow.python.eagerr   r   Ztensorflow.python.frameworkr   Ztensorflow.python.trackabler   Ztensorflow.python.utilr   Z tensorflow.python.util.tf_exportr   r   r   contextmanagerr!   r(   typer)   rl   r5   re   rg   r   r   r   r   <module>   s(   
	~8