1c8b59c046895fa5b6d79f73e0b5817330fcfbfc1A. Unique TensorFlower/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
200986d48bb646daab659503ad3a713919865f32dDerek Murray
300986d48bb646daab659503ad3a713919865f32dDerek MurrayLicensed under the Apache License, Version 2.0 (the "License");
400986d48bb646daab659503ad3a713919865f32dDerek Murrayyou may not use this file except in compliance with the License.
500986d48bb646daab659503ad3a713919865f32dDerek MurrayYou may obtain a copy of the License at
600986d48bb646daab659503ad3a713919865f32dDerek Murray
700986d48bb646daab659503ad3a713919865f32dDerek Murray    http://www.apache.org/licenses/LICENSE-2.0
800986d48bb646daab659503ad3a713919865f32dDerek Murray
900986d48bb646daab659503ad3a713919865f32dDerek MurrayUnless required by applicable law or agreed to in writing, software
1000986d48bb646daab659503ad3a713919865f32dDerek Murraydistributed under the License is distributed on an "AS IS" BASIS,
1100986d48bb646daab659503ad3a713919865f32dDerek MurrayWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1200986d48bb646daab659503ad3a713919865f32dDerek MurraySee the License for the specific language governing permissions and
1300986d48bb646daab659503ad3a713919865f32dDerek Murraylimitations under the License.
1400986d48bb646daab659503ad3a713919865f32dDerek Murray==============================================================================*/
1500986d48bb646daab659503ad3a713919865f32dDerek Murray
1600986d48bb646daab659503ad3a713919865f32dDerek Murray#ifndef TENSORFLOW_CORE_DISTRIBUTED_RUNTIME_BASE_RENDEZVOUS_MGR_H_
1700986d48bb646daab659503ad3a713919865f32dDerek Murray#define TENSORFLOW_CORE_DISTRIBUTED_RUNTIME_BASE_RENDEZVOUS_MGR_H_
1800986d48bb646daab659503ad3a713919865f32dDerek Murray
1900986d48bb646daab659503ad3a713919865f32dDerek Murray#include <string>
2000986d48bb646daab659503ad3a713919865f32dDerek Murray#include <unordered_set>
2100986d48bb646daab659503ad3a713919865f32dDerek Murray
2200986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/distributed_runtime/rendezvous_mgr_interface.h"
2300986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/distributed_runtime/worker_env.h"
24396b6bd1af7bd5a9295b13f30c5ed34e7de42daaBrennan Saeta#include "tensorflow/core/distributed_runtime/worker_session.h"
2500986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/framework/control_flow.h"
2600986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/framework/rendezvous.h"
2700986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/lib/core/status.h"
2812629a0a754d274cf1262f09db0290c6782e0adbA. Unique TensorFlower#include "tensorflow/core/lib/gtl/flatmap.h"
2912629a0a754d274cf1262f09db0290c6782e0adbA. Unique TensorFlower#include "tensorflow/core/lib/gtl/flatset.h"
3012629a0a754d274cf1262f09db0290c6782e0adbA. Unique TensorFlower#include "tensorflow/core/lib/hash/hash.h"
3100986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/platform/macros.h"
3200986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/platform/mutex.h"
3300986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/platform/thread_annotations.h"
3400986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/platform/types.h"
3500986d48bb646daab659503ad3a713919865f32dDerek Murray#include "tensorflow/core/util/device_name_utils.h"
3600986d48bb646daab659503ad3a713919865f32dDerek Murray
3700986d48bb646daab659503ad3a713919865f32dDerek Murraynamespace tensorflow {
3800986d48bb646daab659503ad3a713919865f32dDerek Murray
3900986d48bb646daab659503ad3a713919865f32dDerek Murrayclass BaseRemoteRendezvous;
4000986d48bb646daab659503ad3a713919865f32dDerek Murrayclass BaseRecvTensorCall;
4100986d48bb646daab659503ad3a713919865f32dDerek Murray
4200986d48bb646daab659503ad3a713919865f32dDerek Murray// RendezvousMgr keeps track of a set of local rendezvous instances.
4300986d48bb646daab659503ad3a713919865f32dDerek Murray// All tensors sent by this worker are buffered in a RendezvousMgr
4400986d48bb646daab659503ad3a713919865f32dDerek Murray// until the tensor is received.  Each global unique "step_id"
4500986d48bb646daab659503ad3a713919865f32dDerek Murray// corresponds to one local rendezvous instance managed by a
4600986d48bb646daab659503ad3a713919865f32dDerek Murray// RendezvousMgr.
4700986d48bb646daab659503ad3a713919865f32dDerek Murray//
4800986d48bb646daab659503ad3a713919865f32dDerek Murray// E.g.,
4900986d48bb646daab659503ad3a713919865f32dDerek Murray//   Rendezvous* rendez = worker_env->rendezvous_mgr->Find(0x8935);
5000986d48bb646daab659503ad3a713919865f32dDerek Murray//   fork execution of a graph executor using "rendez" on thread 1;
5100986d48bb646daab659503ad3a713919865f32dDerek Murray//   fork execution of another graph executor using "rendez" on thread 2;
5200986d48bb646daab659503ad3a713919865f32dDerek Murray//   ...
5300986d48bb646daab659503ad3a713919865f32dDerek Murray//   join threads 1 and 2;
5400986d48bb646daab659503ad3a713919865f32dDerek Murray//
5500986d48bb646daab659503ad3a713919865f32dDerek Murray// In the example above, execution in thread 1 and 2 communicates with
5600986d48bb646daab659503ad3a713919865f32dDerek Murray// each other by send/recv operations through `rendez`.
5700986d48bb646daab659503ad3a713919865f32dDerek Murray//
5800986d48bb646daab659503ad3a713919865f32dDerek Murray// Tensors sent and received through a rendezvous managed by this
5900986d48bb646daab659503ad3a713919865f32dDerek Murray// RendezvousMgr must have keys generated by Rendezvous::CreateKey().
6000986d48bb646daab659503ad3a713919865f32dDerek Murrayclass BaseRendezvousMgr : public RendezvousMgrInterface {
6100986d48bb646daab659503ad3a713919865f32dDerek Murray public:
62f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  explicit BaseRendezvousMgr(const WorkerEnv* worker_env);
63396b6bd1af7bd5a9295b13f30c5ed34e7de42daaBrennan Saeta
6400986d48bb646daab659503ad3a713919865f32dDerek Murray  ~BaseRendezvousMgr() override;
6500986d48bb646daab659503ad3a713919865f32dDerek Murray
6600986d48bb646daab659503ad3a713919865f32dDerek Murray  // Returns Rendezvous supporting send and recv among workers in the
6700986d48bb646daab659503ad3a713919865f32dDerek Murray  // "step_id".  The caller takes ownership of one reference on the
6800986d48bb646daab659503ad3a713919865f32dDerek Murray  // returned Rendezvous instance.
69f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  //
70f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  // Note: the caller must guarantee to eventually call Initialize on the
71f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  // returned RemoteRendezvous
72f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  RemoteRendezvous* Find(int64 step_id) override;
7300986d48bb646daab659503ad3a713919865f32dDerek Murray
7400986d48bb646daab659503ad3a713919865f32dDerek Murray  // Finds the local rendezvous instance for the "step_id".  Runs
7500986d48bb646daab659503ad3a713919865f32dDerek Murray  // "done" when the tensor for "key" is produced or an error occurs.
7600986d48bb646daab659503ad3a713919865f32dDerek Murray  //
7700986d48bb646daab659503ad3a713919865f32dDerek Murray  // This method is used by the rpc handler of RecvTensor.
78a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  void RecvLocalAsync(int64 step_id, const Rendezvous::ParsedKey& parsed,
7900986d48bb646daab659503ad3a713919865f32dDerek Murray                      Rendezvous::DoneCallback done) override;
8000986d48bb646daab659503ad3a713919865f32dDerek Murray
8100986d48bb646daab659503ad3a713919865f32dDerek Murray  // Synchronous wrapper for RecvLocalAsync.
82a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  Status RecvLocal(int64 step_id, const Rendezvous::ParsedKey& parsed,
83a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower                   Tensor* val, bool* is_dead) override;
8400986d48bb646daab659503ad3a713919865f32dDerek Murray
8500986d48bb646daab659503ad3a713919865f32dDerek Murray  // Removes rendezvous for "step_id".
8600986d48bb646daab659503ad3a713919865f32dDerek Murray  //
8700986d48bb646daab659503ad3a713919865f32dDerek Murray  // TODO(zhifengc): Have a background thread in worker that
8800986d48bb646daab659503ad3a713919865f32dDerek Murray  // periodically calls CleanupAll().
8900986d48bb646daab659503ad3a713919865f32dDerek Murray  void Cleanup(int64 step_id) override;
9000986d48bb646daab659503ad3a713919865f32dDerek Murray
9100986d48bb646daab659503ad3a713919865f32dDerek Murray  // Removed all rendezvous.
9200986d48bb646daab659503ad3a713919865f32dDerek Murray  void CleanupAll() override;
9300986d48bb646daab659503ad3a713919865f32dDerek Murray
9400986d48bb646daab659503ad3a713919865f32dDerek Murray protected:
9500986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual BaseRemoteRendezvous* Create(int64 step_id,
96f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta                                       const WorkerEnv* worker_env) = 0;
9700986d48bb646daab659503ad3a713919865f32dDerek Murray
9800986d48bb646daab659503ad3a713919865f32dDerek Murray private:
9900986d48bb646daab659503ad3a713919865f32dDerek Murray  // Maps step_id to rendezvous.
10012629a0a754d274cf1262f09db0290c6782e0adbA. Unique TensorFlower  typedef gtl::FlatMap<int64, BaseRemoteRendezvous*> Table;
10100986d48bb646daab659503ad3a713919865f32dDerek Murray
10200986d48bb646daab659503ad3a713919865f32dDerek Murray  // Not owned.
10300986d48bb646daab659503ad3a713919865f32dDerek Murray  const WorkerEnv* const worker_env_;
10400986d48bb646daab659503ad3a713919865f32dDerek Murray
10500986d48bb646daab659503ad3a713919865f32dDerek Murray  mutex mu_;
10600986d48bb646daab659503ad3a713919865f32dDerek Murray  Table table_ GUARDED_BY(mu_);
10700986d48bb646daab659503ad3a713919865f32dDerek Murray
10800986d48bb646daab659503ad3a713919865f32dDerek Murray  BaseRemoteRendezvous* FindOrCreate(int64 step_id);
10900986d48bb646daab659503ad3a713919865f32dDerek Murray
11000986d48bb646daab659503ad3a713919865f32dDerek Murray  TF_DISALLOW_COPY_AND_ASSIGN(BaseRendezvousMgr);
11100986d48bb646daab659503ad3a713919865f32dDerek Murray};
11200986d48bb646daab659503ad3a713919865f32dDerek Murray
11300986d48bb646daab659503ad3a713919865f32dDerek Murray// RemoteRendezvous is a Rendezvous which can handle either
11400986d48bb646daab659503ad3a713919865f32dDerek Murray// the producer or consumer being in a remote process.
11500986d48bb646daab659503ad3a713919865f32dDerek Murray//
11600986d48bb646daab659503ad3a713919865f32dDerek Murray// Buffering of Tensor values is delegated to a "local" Rendezvous
11700986d48bb646daab659503ad3a713919865f32dDerek Murray// obtained from NewLocalRendezvous().  This class just adds
11800986d48bb646daab659503ad3a713919865f32dDerek Murray// functionality to coordinate with remote workers.
119f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saetaclass BaseRemoteRendezvous : public RemoteRendezvous {
12000986d48bb646daab659503ad3a713919865f32dDerek Murray public:
121cbfd50ff0f01e1825922230a8bc6e5766da98dd7A. Unique TensorFlower  BaseRemoteRendezvous(const WorkerEnv* env, int64 step_id);
122f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
123f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  // Upgrades the BaseRemoteRendezvous to full initialization.
124f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  Status Initialize(WorkerSession* session) override;
12500986d48bb646daab659503ad3a713919865f32dDerek Murray
12600986d48bb646daab659503ad3a713919865f32dDerek Murray  // Forwards to local_, where the Tensor "val" will be buffered and
12700986d48bb646daab659503ad3a713919865f32dDerek Murray  // any waiting callback stored.
128a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  Status Send(const ParsedKey& key, const Rendezvous::Args& args,
12900986d48bb646daab659503ad3a713919865f32dDerek Murray              const Tensor& val, const bool is_dead) override;
13000986d48bb646daab659503ad3a713919865f32dDerek Murray
13100986d48bb646daab659503ad3a713919865f32dDerek Murray  // This method is called only by the RecvOp.  It tests to see
13200986d48bb646daab659503ad3a713919865f32dDerek Murray  // whether the value will be produced by a local or remote device
13300986d48bb646daab659503ad3a713919865f32dDerek Murray  // and handles accordingly.  In the local case it forwards to
13400986d48bb646daab659503ad3a713919865f32dDerek Murray  // local_, in the remote case it initiates an RPC request.
135a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  void RecvAsync(const ParsedKey& key, const Rendezvous::Args& args,
13600986d48bb646daab659503ad3a713919865f32dDerek Murray                 DoneCallback done) override;
13700986d48bb646daab659503ad3a713919865f32dDerek Murray
13800986d48bb646daab659503ad3a713919865f32dDerek Murray  void StartAbort(const Status& status) override;
13900986d48bb646daab659503ad3a713919865f32dDerek Murray
14000986d48bb646daab659503ad3a713919865f32dDerek Murray  // This method is called only by the local Worker, forwarded through
14100986d48bb646daab659503ad3a713919865f32dDerek Murray  // the same method on RendezvousMgr.  This occurs when the Worker
14200986d48bb646daab659503ad3a713919865f32dDerek Murray  // has received a RecvTensor request, either locally or over the
14300986d48bb646daab659503ad3a713919865f32dDerek Murray  // network.  In either case it needs to retrieve a locally buffered
14400986d48bb646daab659503ad3a713919865f32dDerek Murray  // value from local_, and give it to its caller.
14500986d48bb646daab659503ad3a713919865f32dDerek Murray  //
146a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  // Runs "done" as soon as the tensor for "parsed" is available or an error
14700986d48bb646daab659503ad3a713919865f32dDerek Murray  // is detected.
14800986d48bb646daab659503ad3a713919865f32dDerek Murray  //
149a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  // REQUIRES: "parsed" is one that will be Saved into the local rendezvous.
150a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  void RecvLocalAsync(const ParsedKey& parsed, DoneCallback done);
15100986d48bb646daab659503ad3a713919865f32dDerek Murray
15200986d48bb646daab659503ad3a713919865f32dDerek Murray protected:
153a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  virtual void RecvFromRemoteAsync(const Rendezvous::ParsedKey& parsed,
15400986d48bb646daab659503ad3a713919865f32dDerek Murray                                   const Rendezvous::Args& args,
15500986d48bb646daab659503ad3a713919865f32dDerek Murray                                   DoneCallback done) = 0;
15600986d48bb646daab659503ad3a713919865f32dDerek Murray
15700986d48bb646daab659503ad3a713919865f32dDerek Murray  // Returns true if "src" and "dst" are located in the same worker,
15800986d48bb646daab659503ad3a713919865f32dDerek Murray  // and hence may use a local rendezvous.
15900986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual bool IsSameWorker(DeviceNameUtils::ParsedName src,
16000986d48bb646daab659503ad3a713919865f32dDerek Murray                            DeviceNameUtils::ParsedName dst);
16100986d48bb646daab659503ad3a713919865f32dDerek Murray
16200986d48bb646daab659503ad3a713919865f32dDerek Murray  // If aborted, aborts "call". Otherwise, adds "call" into active_.
16300986d48bb646daab659503ad3a713919865f32dDerek Murray  void RegisterCall(BaseRecvTensorCall* call);
16400986d48bb646daab659503ad3a713919865f32dDerek Murray
16500986d48bb646daab659503ad3a713919865f32dDerek Murray  // Removes "call" from active_ if "call" is in active_.
16600986d48bb646daab659503ad3a713919865f32dDerek Murray  void DeregisterCall(BaseRecvTensorCall* call);
16700986d48bb646daab659503ad3a713919865f32dDerek Murray
168f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  WorkerSession* session();
169f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
170f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  bool is_initialized();
171f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
17200986d48bb646daab659503ad3a713919865f32dDerek Murray  ~BaseRemoteRendezvous() override;
17300986d48bb646daab659503ad3a713919865f32dDerek Murray
17400986d48bb646daab659503ad3a713919865f32dDerek Murray  const WorkerEnv* const env_;  // Not owned.
17500986d48bb646daab659503ad3a713919865f32dDerek Murray  const int64 step_id_;
17600986d48bb646daab659503ad3a713919865f32dDerek Murray
17700986d48bb646daab659503ad3a713919865f32dDerek Murray private:
17800986d48bb646daab659503ad3a713919865f32dDerek Murray  Rendezvous* local_;  // Owns a Ref on this object.
17900986d48bb646daab659503ad3a713919865f32dDerek Murray
18000986d48bb646daab659503ad3a713919865f32dDerek Murray  mutable mutex mu_;
18100986d48bb646daab659503ad3a713919865f32dDerek Murray
18200986d48bb646daab659503ad3a713919865f32dDerek Murray  // Status given by StartAbort() if any.
18300986d48bb646daab659503ad3a713919865f32dDerek Murray  Status status_ GUARDED_BY(mu_);
184f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  WorkerSession* session_ GUARDED_BY(mu_);  // Not owned.
185f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
186f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  // Data structures to handle calls when partially initialized.
187f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  struct DeferredCall {
188f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta    const ParsedKey parsed;
189f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta    DoneCallback done;
190f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
191f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta    DeferredCall(const ParsedKey& parsed, DoneCallback done);
192f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  };
193f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  std::vector<DeferredCall> deferred_calls_ GUARDED_BY(mu_);
19400986d48bb646daab659503ad3a713919865f32dDerek Murray
19500986d48bb646daab659503ad3a713919865f32dDerek Murray  // Active outstanding RecvTensor calls.
19612629a0a754d274cf1262f09db0290c6782e0adbA. Unique TensorFlower  gtl::FlatSet<BaseRecvTensorCall*> active_ GUARDED_BY(mu_);
19700986d48bb646daab659503ad3a713919865f32dDerek Murray
198f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  bool is_initialized_locked() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
199f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta    return session_ != nullptr;
200f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  }
201f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
202a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  // If "is_src" is true, checks that the rendezvous key "parsed"'s
203a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  // source is in this process. If "is_src" is false, checks that the
204a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  // rendezvous key "parsed"'s destination is in this process.
205a120b0bec12d47d4769a604b1cfafa3988a19a0cA. Unique TensorFlower  Status ValidateDevices(const Rendezvous::ParsedKey& parsed, bool is_src);
20600986d48bb646daab659503ad3a713919865f32dDerek Murray
20700986d48bb646daab659503ad3a713919865f32dDerek Murray  // Callback handling the case when a rendezvous has been
20800986d48bb646daab659503ad3a713919865f32dDerek Murray  // accomplished in local_ and the consumer is local to this process.
20900986d48bb646daab659503ad3a713919865f32dDerek Murray  // Tensor "in" will be copied into "out". The key "parsed" encodes
21000986d48bb646daab659503ad3a713919865f32dDerek Murray  // the src and dst devices.
21100986d48bb646daab659503ad3a713919865f32dDerek Murray  void SameWorkerRecvDone(const Rendezvous::ParsedKey& parsed,
21200986d48bb646daab659503ad3a713919865f32dDerek Murray                          const Rendezvous::Args& in_args,
21300986d48bb646daab659503ad3a713919865f32dDerek Murray                          const Rendezvous::Args& out_args, const Tensor& in,
21400986d48bb646daab659503ad3a713919865f32dDerek Murray                          Tensor* out, StatusCallback done);
21500986d48bb646daab659503ad3a713919865f32dDerek Murray
216f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  // Must be called only if fully initialized.
217f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta  void RecvLocalAsyncInternal(const ParsedKey& parsed, DoneCallback done);
218f28935a7d280b6ba75fe93fe35783d87b9cc2ec9Brennan Saeta
21900986d48bb646daab659503ad3a713919865f32dDerek Murray  TF_DISALLOW_COPY_AND_ASSIGN(BaseRemoteRendezvous);
22000986d48bb646daab659503ad3a713919865f32dDerek Murray};
22100986d48bb646daab659503ad3a713919865f32dDerek Murray
22200986d48bb646daab659503ad3a713919865f32dDerek Murrayclass BaseRecvTensorCall {
22300986d48bb646daab659503ad3a713919865f32dDerek Murray public:
22400986d48bb646daab659503ad3a713919865f32dDerek Murray  BaseRecvTensorCall() {}
22500986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual ~BaseRecvTensorCall() {}
22600986d48bb646daab659503ad3a713919865f32dDerek Murray
22700986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual void Start(std::function<void()> recv_done) = 0;
22800986d48bb646daab659503ad3a713919865f32dDerek Murray
22900986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual void StartAbort(const Status& s) = 0;
23000986d48bb646daab659503ad3a713919865f32dDerek Murray
23100986d48bb646daab659503ad3a713919865f32dDerek Murray  virtual Status status() const = 0;
23200986d48bb646daab659503ad3a713919865f32dDerek Murray
23300986d48bb646daab659503ad3a713919865f32dDerek Murray private:
23400986d48bb646daab659503ad3a713919865f32dDerek Murray  TF_DISALLOW_COPY_AND_ASSIGN(BaseRecvTensorCall);
23500986d48bb646daab659503ad3a713919865f32dDerek Murray};
23600986d48bb646daab659503ad3a713919865f32dDerek Murray
23700986d48bb646daab659503ad3a713919865f32dDerek Murray}  // end namespace tensorflow
23800986d48bb646daab659503ad3a713919865f32dDerek Murray
23900986d48bb646daab659503ad3a713919865f32dDerek Murray#endif  // TENSORFLOW_CORE_DISTRIBUTED_RUNTIME_BASE_RENDEZVOUS_MGR_H_
240