o
    i e=                     @   s   d Z ddlmZ ddlmZ eh dZi Zi Zdd Z	dd Z
d	d
 Zedg dG dd deZedgdG dd deZdS )zClass to represent a device.    )	tf_export)
pywrap_tfe>   CPUEPUGPUTPUCUSTOMc                 C      | d u rd S t | S N)strinp r   V/var/www/myenv/lib/python3.10/site-packages/tensorflow/python/framework/device_spec.py_as_str_or_none      r   c                 C   r	   r
   )intr   r   r   r   _as_int_or_none"   r   r   c                 C   s   | dv r|   S t| S )N)cpugpu)upperr   )device_typer   r   r   _as_device_str_or_none&   s   r   
DeviceSpec)v1c                   @   s   e Zd ZdZdZ					d(ddZdd Zedd	 Zd
d Z	dd Z
dd Zedd Zedd Zedd Zedd Zedd Zdd Zedd Zed)ddZed d! Zd"d# Zd$d% Zd&d' ZdS )*DeviceSpecV2a  Represents a (possibly partial) specification for a TensorFlow device.

  `DeviceSpec`s are used throughout TensorFlow to describe where state is stored
  and computations occur. Using `DeviceSpec` allows you to parse device spec
  strings to verify their validity, merge them or compose them programmatically.

  Example:

  ```python
  # Place the operations on device "GPU:0" in the "ps" job.
  device_spec = DeviceSpec(job="ps", device_type="GPU", device_index=0)
  with tf.device(device_spec.to_string()):
    # Both my_var and squared_var will be placed on /job:ps/device:GPU:0.
    my_var = tf.Variable(..., name="my_variable")
    squared_var = tf.square(my_var)
  ```

  With eager execution disabled (by default in TensorFlow 1.x and by calling
  disable_eager_execution() in TensorFlow 2.x), the following syntax
  can be used:

  ```python
  tf.compat.v1.disable_eager_execution()

  # Same as previous
  device_spec = DeviceSpec(job="ps", device_type="GPU", device_index=0)
  # No need of .to_string() method.
  with tf.device(device_spec):
    my_var = tf.Variable(..., name="my_variable")
    squared_var = tf.square(my_var)
  ```

  If a `DeviceSpec` is partially specified, it will be merged with other
  `DeviceSpec`s according to the scope in which it is defined. `DeviceSpec`
  components defined in inner scopes take precedence over those defined in
  outer scopes.

  ```python
  gpu0_spec = DeviceSpec(job="ps", device_type="GPU", device_index=0)
  with tf.device(DeviceSpec(job="train").to_string()):
    with tf.device(gpu0_spec.to_string()):
      # Nodes created here will be assigned to /job:ps/device:GPU:0.
    with tf.device(DeviceSpec(device_type="GPU", device_index=1).to_string()):
      # Nodes created here will be assigned to /job:train/device:GPU:1.
  ```

  A `DeviceSpec` consists of 5 components -- each of
  which is optionally specified:

  * Job: The job name.
  * Replica: The replica index.
  * Task: The task index.
  * Device type: The device type string (e.g. "CPU" or "GPU").
  * Device index: The device index.
  )_job_replica_task_device_type_device_index
_as_string_hashNc                 C   sd   t || _t|| _t|| _t|| _t|| _| j| j| j| j| j| jd| _	t
|  | _dS )af  Create a new `DeviceSpec` object.

    Args:
      job: string.  Optional job name.
      replica: int.  Optional replica index.
      task: int.  Optional task index.
      device_type: Optional device type string (e.g. "CPU" or "GPU")
      device_index: int.  Optional device index.  If left unspecified, device
        represents 'any' device_index.
    jobreplicataskr   device_indexN)r   r   r   r   r   r   r   r    _components_to_stringr!   hash	to_stringr"   )selfr$   r%   r&   r   r'   r   r   r   __init__k   s   




zDeviceSpecV2.__init__c                 C      | j S )zReturn a string representation of this `DeviceSpec`.

    Returns:
      a string of the form
      /job:<name>/replica:<id>/task:<id>/device:<device_type>:<id>.
    )r!   r+   r   r   r   r*      s   zDeviceSpecV2.to_stringc                 C   s   | |  | S )a;  Construct a `DeviceSpec` from a string.

    Args:
      spec: a string of the form
       /job:<name>/replica:<id>/task:<id>/device:CPU:<id> or
       /job:<name>/replica:<id>/task:<id>/device:GPU:<id> as cpu and gpu are
         mutually exclusive. All entries are optional.

    Returns:
      A DeviceSpec.
    )_string_to_components)clsspecr   r   r   from_string   s   zDeviceSpecV2.from_stringc                 C   s
   |  |S )a  Parse a `DeviceSpec` name into its components.

    **2.x behavior change**:

    In TensorFlow 1.x, this function mutates its own state and returns itself.
    In 2.x, DeviceSpecs are immutable, and this function will return a
      DeviceSpec which contains the spec.

    * Recommended:

      ```
      # my_spec and my_updated_spec are unrelated.
      my_spec = tf.DeviceSpec.from_string("/CPU:0")
      my_updated_spec = tf.DeviceSpec.from_string("/GPU:0")
      with tf.device(my_updated_spec):
        ...
      ```

    * Will work in 1.x and 2.x (though deprecated in 2.x):

      ```
      my_spec = tf.DeviceSpec.from_string("/CPU:0")
      my_updated_spec = my_spec.parse_from_string("/GPU:0")
      with tf.device(my_updated_spec):
        ...
      ```

    * Will NOT work in 2.x:

      ```
      my_spec = tf.DeviceSpec.from_string("/CPU:0")
      my_spec.parse_from_string("/GPU:0")  # <== Will not update my_spec
      with tf.device(my_spec):
        ...
      ```

    In general, `DeviceSpec.from_string` should completely replace
    `DeviceSpec.parse_from_string`, and `DeviceSpec.replace` should
    completely replace setting attributes directly.

    Args:
      spec: an optional string of the form
       /job:<name>/replica:<id>/task:<id>/device:CPU:<id> or
       /job:<name>/replica:<id>/task:<id>/device:GPU:<id> as cpu and gpu are
         mutually exclusive. All entries are optional.

    Returns:
      The `DeviceSpec`.

    Raises:
      ValueError: if the spec was not valid.
    )r2   r+   r1   r   r   r   parse_from_string   s   
5zDeviceSpecV2.parse_from_stringc                 C   s   | j | | S )a!  Returns a new DeviceSpec which incorporates `dev`.

    When combining specs, `dev` will take precedence over the current spec.
    So for instance:
    ```
    first_spec = tf.DeviceSpec(job=0, device_type="CPU")
    second_spec = tf.DeviceSpec(device_type="GPU")
    combined_spec = first_spec.make_merged_spec(second_spec)
    ```

    is equivalent to:
    ```
    combined_spec = tf.DeviceSpec(job=0, device_type="GPU")
    ```

    Args:
      dev: a `DeviceSpec`

    Returns:
      A new `DeviceSpec` which combines `self` and `dev`
    )	__class___get_combined_propertiesr+   devr   r   r   make_merged_spec   s   zDeviceSpecV2.make_merged_specc                 K   s6   t | j| j| j| j| jd}|| | jdi |S )a  Convenience method for making a new DeviceSpec by overriding fields.

    For instance:
    ```
    my_spec = DeviceSpec=(job="my_job", device="CPU")
    my_updated_spec = my_spec.replace(device="GPU")
    my_other_spec = my_spec.replace(device=None)
    ```

    Args:
      **kwargs: This method takes the same args as the DeviceSpec constructor

    Returns:
      A DeviceSpec with the fields specified in kwargs overridden.
    r#   Nr   )dictr$   r%   r&   r   r'   updater5   )r+   kwargsinit_kwargsr   r   r   replace   s   
zDeviceSpecV2.replacec                 C   r-   r
   )r   r.   r   r   r   r$   
     zDeviceSpecV2.jobc                 C   r-   r
   )r   r.   r   r   r   r%     r?   zDeviceSpecV2.replicac                 C   r-   r
   )r   r.   r   r   r   r&     r?   zDeviceSpecV2.taskc                 C   r-   r
   )r   r.   r   r   r   r     r?   zDeviceSpecV2.device_typec                 C   r-   r
   )r    r.   r   r   r   r'     r?   zDeviceSpecV2.device_indexc                 C   sj   |j dur|j n| j |jdur|jn| j|jdur|jn| j|jdur&|jn| j|jdur1|jfS | jfS )a*  Combine the current DeviceSpec with another DeviceSpec.

    The combination of DeviceSpecs is will give priority to dev.

    Args:
      dev: a `DeviceSpec`

    Returns:
      A tuple of (job, replica, task, device_type, device_index) which
      represents the combination of self and dev.
    Nr#   r7   r   r   r   r6     s   z%DeviceSpecV2._get_combined_propertiesc                  C   s>   t i } t }|D ]}| | dd  q
| tB } | S )N:   )setr   TF_ListPluggablePhysicalDevicesadddecodesplit_VALID_DEVICE_TYPES)valid_device_typesphysical_devicesdevicer   r   r   _get_valid_device_types2  s   z$DeviceSpecV2._get_valid_device_typesc                 C   s  t | }|dur|S | }d\}}}}}| pd} dd | dD }t }	|D ]}
t|
}|
r|dkr?|
d d	kr?|
d
 }q(|dkrN|
d dkrN|
d
 }q(|dkr]|
d dkr]|
d
 }q(|d
kse|dkr|
d  |	v r|durytd|  d|
d  }|dkr|
d
 dkrt|
d
 }q(|dkr|
d dkr|durtd|  d|
d
 }|
d dkrt|
d }q(|r|
d dkrtd|
d  d|  dq(|||||f}|t |< |S )aE  Stateless portion of device spec string parsing.

    Args:
      spec: An optional string specifying a device specification.

    Returns:
      The parsed components of `spec`. Note that the result of this function
      must go through attribute setters of DeviceSpec, and should therefore NOT
      be used directly.
    NNNNNN c                 S   s   g | ]}| d qS )r@   )rF   ).0xr   r   r   
<listcomp>O  s    z6DeviceSpecV2._string_to_components.<locals>.<listcomp>/   r   r$   rA   r%   r&   zEMultiple device types are not allowed while parsing the device spec: .*   rJ   zUnknown attribute 'z1' is encountered while parsing the device spec: 'z'.)	_STRING_TO_COMPONENTS_CACHEgetrF   r   rK   lenr   
ValueErrorr   )r1   cached_resultraw_specr$   r%   r&   r   r'   splitsrH   ylyoutputr   r   r   r/   ;  sV   



 


z"DeviceSpecV2._string_to_componentsc           	      C   s   | ||||f}t |}|dur|S g }| dur|d|   |dur,|dt|  |dur9|dt|  |durPd}|durGt|}|d||f  d|}|t |< |S )z>Stateless portion of `to_string` (separated to allow caching).Nz/job:z	/replica:z/task:rT   z/device:%s:%srM   )_COMPONENTS_TO_STRING_CACHErW   appendr   join)	r$   r%   r&   r   r'   keyrZ   r_   device_index_stringr   r   r   r(   q  s&   

z"DeviceSpecV2._components_to_stringc                 C   s   t || jo|  | kS )aF  Checks if the `other` DeviceSpec is same as the current instance, eg have

       same value for all the internal fields.

    Args:
      other: Another DeviceSpec

    Returns:
      Return `True` if `other` is also a DeviceSpec instance and has same value
      as the current instance.
      Return `False` otherwise.
    )
isinstancer5   r*   )r+   otherr   r   r   __eq__  s   zDeviceSpecV2.__eq__c                 C   r-   r
   )r"   r.   r   r   r   __hash__  s   zDeviceSpecV2.__hash__c                 C   s.   d| j  d| j d| j d| j d| j dS )Nz<DeviceSpec(job=z
, replica=z, task=z, device_type=z, device_index=z)>r#   r.   r   r   r   __repr__  s   zDeviceSpecV2.__repr__rL   r
   )__name__
__module____qualname____doc__	__slots__r,   r*   classmethodr2   r4   r9   r>   propertyr$   r%   r&   r   r'   r6   staticmethodrK   r/   r(   rg   rh   ri   r   r   r   r   r   .   sF    8
	
7





5
r   c                   @   s   e Zd ZejZejZejjdd Zejjdd Zej	jdd Z	ej
jdd Z
ejjd	d
 Zdd Zdd Zdd Zdd Zejje_ejje_dS )DeviceSpecV1c                 C      t || _d\| _| _d S N)NN)r   r   r!   r"   )r+   r$   r   r   r   r$        
zDeviceSpecV1.jobc                 C   rs   rt   )r   r   r!   r"   )r+   r%   r   r   r   r%     ru   zDeviceSpecV1.replicac                 C   rs   rt   )r   r   r!   r"   )r+   r&   r   r   r   r&     ru   zDeviceSpecV1.taskc                 C   rs   rt   )r   r   r!   r"   )r+   r   r   r   r   r     ru   zDeviceSpecV1.device_typec                 C   rs   rt   )r   r    r!   r"   )r+   r'   r   r   r   r'     ru   zDeviceSpecV1.device_indexc                 C   s   | j d u rt|  | _ | j S r
   )r"   r)   r*   r.   r   r   r   rh     s   
zDeviceSpecV1.__hash__c                 C   s0   | j d u r| j| j| j| j| j| jd| _ | j S )Nr#   )r!   r(   r$   r%   r&   r   r'   r.   r   r   r   r*     s   
zDeviceSpecV1.to_stringc                 C   s"   |  |\| _| _| _| _| _| S r
   )r/   r$   r%   r&   r   r'   r3   r   r   r   r4     s   zDeviceSpecV1.parse_from_stringc                 C   s"   |  |\| _| _| _| _| _dS )zMerge the properties of "dev" into this `DeviceSpec`.

    Note: Will be removed in TensorFlow 2.x since DeviceSpecs will become
          immutable.

    Args:
      dev: a `DeviceSpec`.
    N)r6   r$   r%   r&   r   r'   r7   r   r   r   
merge_from  s   
zDeviceSpecV1.merge_fromN)rj   rk   rl   r   rm   rn   r$   setterr%   r&   r   r'   rh   r*   r4   rv   r   r   r   r   rr     s&    






rr   N)rm    tensorflow.python.util.tf_exportr   tensorflow.pythonr   	frozensetrG   rV   r`   r   r   r   objectr   rr   r   r   r   r   <module>   s   
  
w