
    AVh                     ~   d Z ddlZddl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 dd
lmZ  ej(                         Z G d de      Z G d de      Z G d de      Zd Z G d de      Z	 	 	 ddZd Z	 	 	 	 	 	 ddZd Zd Z d Z!ddZ"ddejF                  dddddfdZ$y) z/A component for running distributed TensorFlow.    N)
config_pb2)session)distribute_coordinator_context)multi_worker_util)
tf_logging)coordinator)monitored_session)
server_libc                        e Zd ZdZdZdZdZdZy)	_TaskTypepsworkerchief	evaluatorclientN)__name__
__module____qualname__PSWORKERCHIEF	EVALUATORCLIENT     c/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/distribute/distribute_coordinator.pyr   r   $   s    "&
%)&r   r   c                       e Zd ZdZdZdZy)CoordinatorModez(Specify how distribute coordinator runs.standalone_clientindependent_workerN)r   r   r   __doc__STANDALONE_CLIENTINDEPENDENT_WORKERr   r   r   r   r   .   s    0
 *
 ,r   r   c                       e Zd ZdZd Zd Zy)_Barrierz4A reusable barrier class for worker synchronization.c                     || _         d| _        d| _        t        j                         | _        t        j                         | _        t        j                         | _	        y)zInitializes the barrier object.

    Args:
      num_participants: an integer which is the expected number of calls of
        `wait` pass to through this barrier.
    r   FN)
_num_participants_counter_flag	threadinglocal_local_senseLock_lock	Condition
_condition)selfnum_participantss     r   __init__z_Barrier.__init__?   sG     .DDMDJ!)D!DJ))+DOr   c                 V   | j                    | j                  _        | j                  5  | xj                  dz  c_        | j                  | j
                  k(  r"d| _        | j                  j                  | _         ddd       | j                  5  | j                   | j                  j                  k7  r>| j                  j                          | j                   | j                  j                  k7  r>| j                  j                          ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w)z7Waits until all other callers reach the same wait call.   r   N)	r)   r,   valuer.   r(   r'   r0   wait
notify_allr1   s    r   r7   z_Barrier.waitM   s    "&**nD	 -
mmqm	$00	0&&,,
	-
 
 #JJ$++111 JJ$++111
oo  "# #- -
# #s   ADA!D0DDD(N)r   r   r   r!   r3   r7   r   r   r   r%   r%   <   s    <,#r   r%   c                     | syt        | j                         j                  t        j                  g             t        | j                         j                  t        j
                  g             z   S )z'Gets number of workers including chief.r   )lenas_dictgetr   r   r   )cluster_specs    r   _get_num_workersr?   [   s[    		\!!#''	(8(8"=	>  "5B7 
7 7r   c                      e Zd ZdZ	 	 	 ddZd Zd Zd Zd Zd Z	d	 Z
	 	 	 	 	 dd
Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zy)_WorkerContexta$  The worker context class.

  This context object provides configuration information for each task. One
  context manager with a worker context object will be created per
  invocation to the `worker_fn` where `get_current_worker_context` can be called
  to access the worker context object.
  Nc                     || _         || _        || _        || _        || _        || _        || _        | j                         | _        t        |      | _
        | j                         | _        y)ag  Initialize the worker context object.

    Args:
      strategy: a `DistributionStrategy` object.
      cluster_spec: a ClusterSpec object. It can be empty or None in the local
        training case.
      task_type: a string indicating the role of the corresponding task, such as
        "worker" or "ps". It can be None if it is local training or in-graph
        replicated training.
      task_id: an integer indicating id of the corresponding task. It can be
        None if it is local training or in-graph replicated training.
      session_config: an optional `tf.compat.v1.ConfigProto` object.
      rpc_layer: optional string specifying the RPC protocol for communication
        with worker masters. If None or empty, hosts in the `cluster_spec` will
        be used directly.
      worker_barrier: optional, the barrier object for worker synchronization.
    N)	_strategy_cluster_spec
_task_type_task_id_session_config_worker_barrier
_rpc_layer_get_master_target_master_targetr?   _num_workers	_is_chief_is_chief_node)r1   strategyr>   	task_typetask_idsession_config	rpc_layerworker_barriers           r   r3   z_WorkerContext.__init__l   se    2 DN%DDODM)D)DDO113D(6D..*Dr   c                 p    | j                   r*d| j                   d| j                  d| j                  dS y)Nz[cluster_spec: z, task_type: z, task_id: ]z[local])rD   rP   rQ   r9   s    r   _debug_messagez_WorkerContext._debug_message   s/    


dnndll< < r   c                     t        j                         }|rt        d| j                         z         | t         j                  _        y )Nz8You cannot run distribute coordinator in a `worker_fn`.	)r   get_current_worker_context
ValueErrorrW   _worker_contextcurrent)r1   old_contexts     r   	__enter__z_WorkerContext.__enter__   sF    0KKMK
E



 ! ! >B"22:r   c                 .    d t         j                  _        y N)r   r[   r\   )r1   unused_exception_typeunused_exception_valueunused_tracebacks       r   __exit__z_WorkerContext.__exit__   s     >B"22:r   c                 
   | j                   r| j                  t        j                  k(  ry| j                  stt        j                  | j                   j
                  v rt        j                  }d}nSt        j                  | j                   j
                  v sJ t        j                  }d}n| j                  }| j                  }d}| j                  r| j                  dz   }|| j                   j                  |      |xs d   z   S )z$Return the master target for a task. r   ://)
rD   rE   r   r   r   jobsr   rF   rI   	job_tasks)r1   rP   rQ   prefixs       r   rJ   z!_WorkerContext._get_master_target   s     I4G4G!G ??	D..33	3OO	4#5#5#:#::::$$	//igF&fD&&00;GLqIIIr   c                    | j                   r-| j                  t        j                  t        j                  dfv ryt        j                  | j                   j
                  vr-| j                  t        j                  k(  r| j                  dk(  ryy)z,Return whether the task is the chief worker.NTr   F)rD   rE   r   r   r   rh   r   rF   r9   s    r   rM   z_WorkerContext._is_chief   sh    IOOY-@-@$GG 	t116669+++0Br   c                 R    | j                   sy| j                   j                          y)zWaits for other workers to reach the same call to this method.

    Raises:
      ValueError: if `worker_barrier` is not passed to the __init__ method.
    N)rH   r7   r9   s    r   wait_for_other_workersz%_WorkerContext.wait_for_other_workers   s"     r   c                    |r1t        j                  |      }|j                  | j                         n| j                  }| j                  r | j                  j
                  j                  r:t        j                  d|       t        j                  || j                  |||      S t        j                  d|       t        j                  || j                  ||      S )a  Returns a session creator.

    The returned session creator will be configured with the correct master
    target and session configs. It will also run either init ops or ready ops
    by querying the `strategy` object when `create_session` is called on it.

    Args:
      scaffold: A `Scaffold` used for gathering or building supportive ops. If
        not specified a default one is created. It's used to finalize the graph.
      config: `ConfigProto` proto used to configure the session.
      checkpoint_dir: A string. Optional path to a directory where to restore
        variables.
      checkpoint_filename_with_path: Full file name path to the checkpoint file.
        Only one of `checkpoint_dir` or `checkpoint_filename_with_path` can be
        specified.
      max_wait_secs: Maximum time to wait for the session to become available.

    Returns:
      a descendant of SessionCreator.
    z.Creating chief session creator with config: %r)masterconfigcheckpoint_dircheckpoint_filename_with_pathz/Creating worker session creator with config: %r)ro   rp   max_wait_secs)copydeepcopy	MergeFromrG   rC   extendedexperimental_should_initlogginginfor	   ChiefSessionCreatormaster_targetWorkerSessionCreator)r1   scaffoldrp   rq   rr   rs   rR   s          r   session_creatorz_WorkerContext.session_creator   s    4 }}V,nt334++n>>T^^44MMllCVL22
##'(EG G llDfM33
##%	' 'r   c                 @    t        j                  | j                        S r`   )rt   ru   rG   r9   s    r   rR   z_WorkerContext.session_config  s    ==--..r   c                     | j                   duS )z"Whether the barrier is set or not.N)rH   r9   s    r   has_barrierz_WorkerContext.has_barrier
  s     t++r   c                 j    t        | j                        xr | j                  t        j                  k7  S )z*Whether it is distributed training or not.)boolrD   rE   r   r   r9   s    r   distributed_modez_WorkerContext.distributed_mode  s)     ""#N9;N;N(NNr   c                 @    t        j                  | j                        S )z*Returns a copy of the cluster_spec object.)rt   ru   rD   r9   s    r   r>   z_WorkerContext.cluster_spec  s     ==++,,r   c                     | j                   S )z+Returns the role of the corresponding task.)rE   r9   s    r   rP   z_WorkerContext.task_type  s     ??r   c                     | j                   S )z2Returns the id or index of the corresponding task.)rF   r9   s    r   rQ   z_WorkerContext.task_id  s     ==r   c                     | j                   S )zDReturns the session master for the corresponding task to connect to.)rK   r9   s    r   r|   z_WorkerContext.master_target#       r   c                     | j                   S )z)Returns whether the task is a chief node.)rN   r9   s    r   is_chiefz_WorkerContext.is_chief(  r   r   c                     | j                   S )z:Returns number of workers in the cluster, including chief.)rL   r9   s    r   num_workersz_WorkerContext.num_workers-  s     r   c                 B    | j                   j                  j                  S )zWhether to run init ops.)rC   rw   rx   r9   s    r   rx   z'_WorkerContext.experimental_should_init2  s     >>"";;;r   c                 B    | j                   j                  j                  S )zWhether to save checkpoint.)rC   rw   should_checkpointr9   s    r   r   z _WorkerContext.should_checkpoint7  s     >>""444r   c                 B    | j                   j                  j                  S )zWhether to save summaries.)rC   rw   should_save_summaryr9   s    r   r   z"_WorkerContext.should_save_summary<  s     >>""666r   )NgrpcN)NNNNi   )r   r   r   r!   r3   rW   r^   rd   rJ   rM   rm   r   propertyrR   r   r   r>   rP   rQ   r|   r   r   rx   r   r   r   r   r   rA   rA   c   sB    #""+HBB
J2	   $!%)48$(.'` / / , , O O - -           < < 5 5 7 7r   rA   c	           	         t        j                  |      }t        j                  |      }|t        j                  k(  r|r*|j	                  |       n|sJ |j	                  ||||       t        |||||||      }	|	5  |r+|j                         5   | |      cddd       cddd       S  | |      cddd       S # 1 sw Y   nxY w	 ddd       y# 1 sw Y   yxY w)z:Runs a single worker by calling `worker_fn` under context.)rR   rS   rT   N)rt   ru   r   r   	configurerA   stop_on_exception)
	worker_fnrO   r>   rP   rQ   rR   rS   rT   coordcontexts
             r   _run_single_workerr   B  s     ==0.]]8$()%%%(O8~|YH##%'  !""$ #"# #! !
 x ! !# # #! ! !s*   >CB=	C,C=C	CCc                 H   t        j                  |       j                         }|t        j                  k(  r8t        j                  |v sJ t        j                  |t        j                     i}n |j                  t        j                  d       t        j                  |      S )zESplit the cluster for evaluator since it needn't talk to other tasks.N)r   normalize_cluster_specr<   r   r   pop)r>   rP   new_cluster_specs      r   _split_cluster_for_evaluatorr   g  s     '==GI )%%%"2222-i.A.AB ,,d3		1	12B	CCr   c                 f   t        t        dd      t        j                  | k(  sJ t        j                  |k(  sJ t        j                  |k(  sJ t        j
                  t              k(  sJ t        j                  |k(  sJ t        j                  |k(  sJ t        j                  S dt        _
        | t        _        |t        _        |t        _        t              t        _        |t        _        |t        _        | sJ | j                  ||      |r|dz   z    G fddt              }|dk(  r |       }nVrt        j                  d       nt        j                  d	       t        | |      } t!        j"                  | |||
      }|j%                          |t        _	        |S )zRuns a standard server.serverNTrg   c                   $    e Zd ZdZ fdZd Zy)$_run_std_server.<locals>._FakeServerz)A fake server that runs a master session.c                 b    t        j                  d       t        j                         y )NzVCreating a remote session to start a TensorFlow server, target = %r, session_config=%r)targetrp   )ry   rz   r   Session)r1   rR   r   s    r   startz*_run_std_server.<locals>._FakeServer.start  s*    ll+,2ND ooVN;r   c                 0    	 t        j                  d       )N   )timesleepr9   s    r   joinz)_run_std_server.<locals>._FakeServer.join  s    

1 r   N)r   r   r   r!   r   r   )rR   r   s   r   _FakeServerr     s    3<r   r   googlezDStarting standard TensorFlow server, target = %r, session_config= %rz0Starting standard TensorFlow server, target = %r)job_name
task_indexrp   protocol)getattr_thread_localr>   rP   rQ   session_config_strreprrS   environmentr   server_startedtask_addressobjectry   rz   r   r
   Serverr   )	r>   rP   rQ   rR   rS   r   r   r   r   s	      `    @r   _run_std_serverr   }  s    ]Hd+7%%555""i///  G+++++tN/CCCC""i///$$333 $(M !-M'M#M'+N';M$'M +M	$$Y8&'FF  H]Fll( llEvN/iHLF 	,,.-	-r   c                    t        j                         }d}t        j                  |j                  v rCt        j                  t        |||t        j                  d|f||d      }|j                          g }	t        t        |            }
t        j                  t        j                  fD ]  }t        t        |j                         j!                  |g                   D ]I  }t        j                  t        | |||||f||
|d      }|j                          |	j#                  |       K  |r|	|gz   }n|	}|j%                  |       y)z7Runs a standalone client for between-graph replication.Nr   rS   r   r   argskwargs)rS   rT   r   )r   Coordinatorr   r   rh   r*   Threadr   r   r%   r?   r   r   ranger;   r<   r=   appendr   )r   rO   eval_fneval_strategyr>   rR   rS   r   eval_threadthreadsrT   rP   rQ   tthreads_to_joins                  r   _run_between_graph_clientr     sH    
!
!
#%+L---""!}lI4G4G #
	K ',\:;.OOY%5%56 i\11377	2FGH 


#8\9g  % .	a gginnQ -OO**_ 
r   c           
      >   t        j                         }d}t        j                  |j                  v rCt        j                  t        |||t        j                  d|f||d      }|j                          t        | ||dd|||      }	|r|j                  |g       |	S )z2Runs a standalone client for in-graph replication.Nr   r   r   )
r   r   r   r   rh   r*   r   r   r   r   )
r   rO   r   r   r>   rR   rS   r   r   worker_results
             r   _run_in_graph_clientr     s     
!
!
#%+L---""!}lI4G4G #
	K $

- 	JJ}	r   c                     |t         j                  k(  r|r=|j                  |       n*t        j                  |       } | j                  ||||       |j
                  dd= y)a  Call strategy's `configure` to mutate the session_config.

  The session_config is currently needed as default config for a TensorFlow
  server. In the future, we should be able to remove this method and only pass
  the session config to a client session.
  )rR   )rR   r>   rP   rQ   N)r   r   r   rt   ru   device_filters)rO   r   rR   r>   rP   rQ   s         r   )_configure_session_config_for_std_serversr     se     )%%%^< }}X&H%!	   ##A&r   c                 h   t        j                  t        j                  j	                  dd            }d|vrt        d      t        j                  |d         }d|vrt        d      |d   }d|vrt        d      |d   }t        |j	                  d	d
            }|j	                  dd      }| xs t        j                         } d|j                  v rd| j                  _        n*d|j                  vrt        d      d| j                  _        t        |||| |      }|j                          |S )a  Starts a standard TensorFlow server.

  This method parses configurations from "TF_CONFIG" environment variable and
  starts a TensorFlow server. The "TF_CONFIG" is typically a json string and
  must have information of the cluster and the role of the server in the
  cluster. One example is:

  TF_CONFIG='{
      "cluster": {
          "worker": ["host1:2222", "host2:2222", "host3:2222"],
          "ps": ["host4:2222", "host5:2222"]
      },
      "task": {"type": "worker", "index": 1}
  }'

  This "TF_CONFIG" specifies there are 3 workers and 2 ps tasks in the cluster
  and the current role is worker 1.

  Valid task types are "chief", "worker", "ps" and "evaluator" and you can have
  at most one "chief" and at most one "evaluator".

  An optional key-value can be specified is "rpc_layer". The default value is
  "grpc".

  Args:
    session_config: an optional `tf.compat.v1.ConfigProto` object. Users can
      pass in the session config object to configure server-local devices.

  Returns:
    a `tf.distribute.Server` object which has already been started.

  Raises:
    ValueError: if the "TF_CONFIG" environment is not complete.
  	TF_CONFIG{}clusterz$"cluster" is not found in TF_CONFIG.taskz!"task" is not found in TF_CONFIG.typez9"task_type" is not found in the `task` part of TF_CONFIG.indexr   rS   r   r   z/job:chief/replica:0/task:0r   z=You must have `chief` or `worker` jobs in the `cluster_spec`.z/job:worker/replica:0/task:0)r>   rP   rQ   rR   rS   )jsonloadsosenvironr=   rZ   r   r   intr   ConfigProtorh   experimentalcollective_group_leaderr   r   )rR   	tf_configr>   task_envrP   rQ   rS   r   s           r   run_standard_tensorflow_serverr   '  sF   F jjT:;)i
=
>>"99)I:NO,9
:
;;v(8
EG Gv)Wa()'mmK0)!=Z%;%;%=. !!!% 7 |(((
IK K 	' 7 #& 	,,.	-r   r   c
           	         t        j                  t        j                  j	                  dd            }
|
j	                  d|	      }	|
j	                  dd      }|sS|
j	                  di       }|
j	                  di       }|r-|j	                  d|      }t        |j	                  d	|            }|rt        j                  |      }npt        |j                  d
      rZ|j                  j                  }|j                  }|j                  }|j                  xs |	}	|j                  }|j                         }|xs t!        j"                  d      }|r)t%        j&                  d||j)                         ||||	       |sPt%        j&                  d       t+        | |ddd||	       |rt+        ||ddd||	       yt%        j,                  d       y|t.        j0                  k(  r|st%        j,                  d       |xs | }|st%        j,                  d       |t2        j4                  dfv r8|j                  j6                  rt9        | ||||||	      S t;        | ||||||	      S t=        ||||||       t?        |||||	|      }|jA                          y|t.        jB                  k7  rtE        d|z        |st%        j,                  d       |xs | }|st%        j,                  d       t=        ||||||       |t2        jF                  k7  r(tI        |j                  dd      st?        |||||	|      }|t2        jJ                  t2        jL                  fv rc|j                  j6                  rt+        | ||||||	      S tO        ||||      }|jP                  rt+        | ||dd||	      S jA                          y|t2        jF                  k(  rt+        |||||||	      S |t2        jR                  k7  rtE        d|z        jA                          y)a  Runs the coordinator for distributed TensorFlow.

  This function runs a split coordinator for distributed TensorFlow in its
  default mode, i.e the STANDALONE_CLIENT mode. Given a `cluster_spec`
  specifying server addresses and their roles in a cluster, this coordinator
  will figure out how to set them up, give the underlying function the right
  targets for master sessions via a scope object and coordinate their training.
  The cluster consisting of standard servers needs to be brought up either with
  the standard server binary or with a binary running distribute coordinator
  with `task_type` set to non-client type which will then turn into standard
  servers.

  In addition to be the distribute coordinator, this is also the source of
  configurations for each job in the distributed training. As there are multiple
  ways to configure a distributed TensorFlow cluster, its context object
  provides these configurations so that users or higher-level APIs don't have to
  figure out the configuration for each job by themselves.

  In the between-graph replicated training, this coordinator will create
  multiple threads and each calls the `worker_fn` which is supposed to create
  its own graph and connect to one worker master given by its context object. In
  the in-graph replicated training, it has only one thread calling this
  `worker_fn`.

  Another mode is the INDEPENDENT_WORKER mode where each server runs a
  distribute coordinator which will start a standard server and optionally runs
  `worker_fn` depending whether it is between-graph training or in-graph
  replicated training.

  The `strategy` object is expected to be a DistributionStrategy object which
  has implemented methods needed by distributed coordinator such as
  `configure(session_config, cluster_spec, task_type, task_id)` which configures
  the strategy object for a specific task and `experimental_should_init`
  property which instructs the distribute coordinator whether to run init ops
  for a task. The distribute coordinator will make a copy of the `strategy`
  object, call its `configure` method and pass it to `worker_fn` as an argument.

  The `worker_fn` defines the training logic and is called under its own
  worker context which can be accessed to via `get_current_worker_context`. A
  worker context provides access to configurations for each task, e.g. the
  task_type, task_id, master target and so on. Since `worker_fn` will be called
  in a thread and possibly multiple times, caller should be careful when it
  accesses global data. For example, it is unsafe to define flags in a
  `worker_fn` or to define different environment variables for different
  `worker_fn`s.

  The `worker_fn` for the between-graph replication is defined as if there is
  only one worker corresponding to the `worker_fn` and possibly ps jobs. For
  example, when training with parameter servers, it assigns variables to
  parameter servers and all other operations to that worker. In the in-graph
  replication case, the `worker_fn` has to define operations for all worker
  jobs. Using a distribution strategy can simplify the `worker_fn` by not having
  to worry about the replication and device assignment of variables and
  operations.

  This method is intended to be invoked by high-level APIs so that users don't
  have to explicitly call it to run this coordinator. For those who don't use
  high-level APIs, to change a program to use this coordinator, wrap everything
  in a the program after global data definitions such as commandline flag
  definition into the `worker_fn` and get task-specific configurations from
  the worker context.

  The `cluster_spec` can be either passed by the argument or parsed from the
  "TF_CONFIG" environment variable. Example of a TF_CONFIG:
  ```
    cluster = {'chief': ['host0:2222'],
               'ps': ['host1:2222', 'host2:2222'],
               'worker': ['host3:2222', 'host4:2222', 'host5:2222']}
    os.environ['TF_CONFIG'] = json.dumps({'cluster': cluster})
  ```

  If `cluster_spec` is not given in any format, it becomes local training and
  this coordinator will connect to a local session.

  For evaluation, if "evaluator" exists in the cluster_spec, a separate thread
  will be created to call `eval_fn` with its `task_type` set to "evaluator". If
  `eval_fn` is not defined, fall back to `worker_fn`. This implies that
  evaluation will be done on a single machine if there is an "evaluator" task.
  If "evaluator" doesn't exist in the cluster_spec, it entirely depends on the
  `worker_fn` for how to do evaluation.

  Args:
    worker_fn: the function to be called. The function should accept a
      `strategy` object and will be given access to a context object via a
      context manager scope.
    strategy: a DistributionStrategy object specifying whether it should
      run between-graph replicated training or not, whether to run init ops,
      etc. This object will also be configured given `session_config`,
      `cluster_spec`, `task_type` and `task_id`.
    eval_fn: optional function for "evaluator" task. If `eval_fn` is not passed
      in but a "evaluator" task is found in the `cluster_spec`, the `worker_fn`
      will be used for this task.
    eval_strategy: optional DistributionStrategy object for "evaluator" task.
    mode: in which mode this distribute coordinator runs.
    cluster_spec: a dict, ClusterDef or ClusterSpec specifying servers and roles
      in a cluster. If not set or empty, fall back to local training.
    task_type: the current task type, optional if this is a client.
    task_id: the current task id, optional if this is a client.
    session_config: an optional `tf.compat.v1.ConfigProto` object which will be
      passed to `strategy`'s `configure` method and used to create a session.
    rpc_layer: optional string, the protocol for RPC, e.g. "grpc".

  Raises:
    ValueError: if `cluster_spec` is supplied but not a dict or a ClusterDef or
      a ClusterSpec.

  Returns:
    In the client job, return the value returned by `worker_fn` if
    it is in-graph replication or INDEPENDENT_WORKER mode; return None
    otherwise.
  r   r   rS   r   Nr   r   r   r   _cluster_resolverT)allow_soft_placementzRunning Distribute Coordinator with mode = %r, cluster_spec = %r, task_type = %r, task_id = %r, environment = %r, rpc_layer = %rz%Running local Distribute Coordinator.z4Skipped evaluation since `eval_fn` is not passed in.zf`eval_fn` is not passed in. The `worker_fn` will be used if an "evaluator" task exists in the cluster.zW`eval_strategy` is not passed in. No distribution strategy will be used for evaluation.)r>   rP   rQ   rR   rS   r   zUnexpected coordinator mode: %r_std_server_startedFzUnexpected task_type: %r)*r   r   r   r   r=   r   r   r   hasattrrw   r   rP   rQ   rS   r   r>   r   r   ry   rz   r<   r   warningr   r"   r   r   experimental_between_graphr   r   r   r   r   r#   rZ   r   r   r   r   rA   r   r   )r   rO   r   r   moder>   rP   rQ   rR   rS   r   r   r   cluster_resolverr   r   s                   r   run_distribute_coordinatorr   s  s   r jjT:;)mmK3)mT2+	==B/L}}VR(H,,vy1iHLL'23g$;;LILx  "56((:: **I&&G **7iI"..K#002L " !Z%;%;&!. LL	IJN	7KL
 
LL89y(D$n "-tT'4 ooLM000oo M N"Goo > ?
 Y%%t,,				5	5(Hg)6)7D 	D $Ix-$0.)M 	M 0-0>097D #'!#f kkm11184?@@oo M N"Goo > ?
 .h.<l.7B 	Y(((H%%'<eD #'!#f Y__i&6&677				5	5!)X|Y")>9F 	F !<GL#Ixt$(.)E E ++-	i))	)i 'D D 
ill	"3i?@@kkmr   )rf   NN)NNNNNNr`   )%r!   rt   r   r   r*   r   tensorflow.core.protobufr   tensorflow.python.clientr   tensorflow.python.distributer   r   tensorflow.python.platformr   ry   tensorflow.python.trainingr   r	   r
   r+   r   r   r   r   r%   r?   rA   r   r   r   r   r   r   r   r"   r   r   r   r   <module>r      s    6   	   / , G : < 2 8 1  	! ,f ,#v #>7\7V \7J "$&*!"!JD, "&" #'" $BJ(V@'4F\ (,-1$3$E$E,0)-'+.2)/ur   