o
    ?el#                     @   s   d 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ZG dd	 d	ZG d
d dZedgd							dddZdS )z(Device function for replicated training.    )node_def_pb2)device)
tf_logging)
server_lib)	tf_export)VariableZ
VariableV2ZAutoReloadVariableZMutableHashTableZMutableHashTableV2ZMutableHashTableOfTensorsZMutableHashTableOfTensorsV2ZMutableDenseHashTableZMutableDenseHashTableV2ZVarHandleOpZ$BoostedTreesEnsembleResourceHandleOpZ*BoostedTreesQuantileStreamResourceHandleOpZResourceConditionalAccumulatorZDecisionTreeResourcec                   @       e Zd ZdZdd Zdd ZdS )_RoundRobinStrategyzReturns the next ps task index for placement in round-robin order.

  This class is not to be used directly by users.  See instead
  `replica_device_setter()` below.
  c                 C   s   || _ d| _dS )zgCreate a new `_RoundRobinStrategy`.

    Args:
      num_tasks: Number of ps tasks to cycle among.
    r   N)
_num_tasks
_next_task)selfZ	num_tasks r   i/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/training/device_setter.py__init__)   s   
z_RoundRobinStrategy.__init__c                 C   s   | j }| j d | j | _ |S )a  Choose a ps task index for the given `Operation`.

    Args:
      unused_op: An `Operation` to be placed on ps.

    Returns:
      The next ps task index to use for the `Operation`. Returns the next
      index, in the range `[offset, offset + num_tasks)`.
       )r   r
   )r   Z	unused_optaskr   r   r   __call__2   s   
z_RoundRobinStrategy.__call__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r	   "   s    	r	   c                   @   r   )_ReplicaDeviceChooserzClass to choose devices for Ops in a replicated training setup.

  This class is not to be used directly by users.  See instead
  `replica_device_setter()` below.
  c                 C   s(   || _ || _|| _|| _|| _|| _dS )a3  Create a new `_ReplicaDeviceChooser`.

    Args:
      ps_tasks: Number of tasks in the `ps` job.
      ps_device: String.  Name of the `ps` job.
      worker_device: String.  Name of the `worker` job.
      merge_devices: Boolean. Set to True to allow merging of device specs.
      ps_ops: List of strings representing `Operation` types that need to be
        placed on `ps` devices.
      ps_strategy: A callable invoked for every ps `Operation` (i.e. matched by
        `ps_ops`), that takes the `Operation` and returns the ps task index to
        use.
    N)	_ps_tasks
_ps_device_worker_device_merge_devices_ps_ops_ps_strategy)r   ps_tasks	ps_deviceworker_devicemerge_devicesps_opsps_strategyr   r   r   r   H   s   
z_ReplicaDeviceChooser.__init__c                 C   s   | j s	|jr	|jS tj|jpd}t|tjr|n|j}| j	rQ| j
rQ|j| jv rQtj| j
}|j|j}}|rH|r?||krH|j| |d}||}| S tj| jpXd}||}| S )z~Choose a device for `op`.

    Args:
      op: an `Operation`.

    Returns:
      The device to use for the `Operation`.
     )r   )r   r   pydev
DeviceSpecfrom_string
isinstancer   ZNodeDefnode_defr   r   opr   jobreplacer   Zmake_merged_specZ	to_stringr   )r   r*   Zcurrent_devicer)   r   Zcurrent_jobZps_jobr    r   r   r   device_function^   s   

z%_ReplicaDeviceChooser.device_functionN)r   r   r   r   r   r-   r   r   r   r   r   A   s    r   ztrain.replica_device_setter)v1/job:ps/job:workerTNc           
      C   s   |dur/t |tjr| }nt| }tj|j}||vs'|| du r)dS t|| } | dkr5dS |du r=t	t
}|sDtd |du rLt| }t|sTtdt| |||||}	|	jS )a
  Return a `device function` to use when building a Graph for replicas.

  Device Functions are used in `with tf.device(device_function):` statement to
  automatically assign devices to `Operation` objects as they are constructed,
  Device constraints are added from the inner-most context first, working
  outwards. The merging behavior adds constraints to fields that are yet unset
  by a more inner context. Currently the fields are (job, task, cpu/gpu).

  If `cluster` is `None`, and `ps_tasks` is 0, the returned function is a no-op.
  Otherwise, the value of `ps_tasks` is derived from `cluster`.

  By default, only Variable ops are placed on ps tasks, and the placement
  strategy is round-robin over all ps tasks. A custom `ps_strategy` may be used
  to do more intelligent placement, such as
  `tf.contrib.training.GreedyLoadBalancingStrategy`.

  For example,

  ```python
  # To build a cluster with two ps jobs on hosts ps0 and ps1, and 3 worker
  # jobs on hosts worker0, worker1 and worker2.
  cluster_spec = {
      "ps": ["ps0:2222", "ps1:2222"],
      "worker": ["worker0:2222", "worker1:2222", "worker2:2222"]}
  with
  tf.compat.v1.device(tf.compat.v1.train.replica_device_setter(cluster=cluster_spec)):
    # Build your graph
    v1 = tf.Variable(...)  # assigned to /job:ps/task:0
    v2 = tf.Variable(...)  # assigned to /job:ps/task:1
    v3 = tf.Variable(...)  # assigned to /job:ps/task:0
  # Run compute
  ```

  Args:
    ps_tasks: Number of tasks in the `ps` job.  Ignored if `cluster` is
      provided.
    ps_device: String.  Device of the `ps` job.  If empty no `ps` job is used.
      Defaults to `ps`.
    worker_device: String.  Device of the `worker` job.  If empty no `worker`
      job is used.
    merge_devices: `Boolean`. If `True`, merges or only sets a device if the
      device constraint is completely unset. merges device specification rather
      than overriding them.
    cluster: `ClusterDef` proto or `ClusterSpec`.
    ps_ops: List of strings representing `Operation` types that need to be
      placed on `ps` devices.  If `None`, defaults to `STANDARD_PS_OPS`.
    ps_strategy: A callable invoked for every ps `Operation` (i.e. matched by
      `ps_ops`), that takes the `Operation` and returns the ps task index to
      use.  If `None`, defaults to a round-robin strategy across all `ps`
      devices.

  Returns:
    A function to pass to `tf.device()`.

  Raises:
    TypeError if `cluster` is not a dictionary or `ClusterDef` protocol buffer,
    or if `ps_strategy` is provided but not a callable.
  Nr   zQDEPRECATION: It is recommended to set merge_devices=true in replica_device_setterzps_strategy must be callable)r(   r   ZClusterSpecas_dictr%   r&   r'   r+   lenlistSTANDARD_PS_OPSloggingwarningr	   callable	TypeErrorr   r-   )
r   r   r    r!   Zclusterr"   r#   Zcluster_specZps_job_nameZchooserr   r   r   replica_device_setter   s0   B
r9   )r   r/   r0   TNNN)r   Ztensorflow.core.frameworkr   Ztensorflow.python.frameworkr   r%   Ztensorflow.python.platformr   r5   Ztensorflow.python.trainingr   Z tensorflow.python.util.tf_exportr   r4   r	   r   r9   r   r   r   r   <module>   s$   

A