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