| 230 | } |
| 231 | |
| 232 | Status RemoteCopyNode::StartRecv() { |
| 233 | // TODO(gjn): We should consider just using the low-level RecvOp::Compute() |
| 234 | // functionality here instead of constructing an Op. |
| 235 | const AttrTypeMap* types; |
| 236 | bool is_function = false; |
| 237 | Status status = AttrTypeMapForOp("_Recv", &types, &is_function); |
| 238 | if (!status.ok()) { |
| 239 | captured_state_->dst()->Poison(status); |
| 240 | return status; |
| 241 | } |
| 242 | DCHECK(!is_function); |
| 243 | EagerOperation op(ctx_, "_Recv", /*is_function=*/false, types); |
| 244 | |
| 245 | op.SetDevice(recv_device_); |
| 246 | |
| 247 | op.MutableAttrs()->Set("tensor_name", wire_id_); |
| 248 | op.MutableAttrs()->Set("send_device", send_device_->name()); |
| 249 | op.MutableAttrs()->Set( |
| 250 | "send_device_incarnation", |
| 251 | static_cast<int64>(send_device_->attributes().incarnation())); |
| 252 | op.MutableAttrs()->Set("recv_device", recv_device_->name()); |
| 253 | op.MutableAttrs()->Set("client_terminated", false); |
| 254 | |
| 255 | op.MutableAttrs()->Set("tensor_type", src_->dtype); |
| 256 | |
| 257 | if (recv_device_->IsLocal()) { |
| 258 | std::vector<Tensor> outputs(1); |
| 259 | status = RunLocalRecv(&op, &outputs); |
| 260 | if (!status.ok()) { |
| 261 | captured_state_->dst()->Poison(status); |
| 262 | return status; |
| 263 | } |
| 264 | return captured_state_->dst()->SetTensor(outputs[0]); |
| 265 | } else { |
| 266 | // Handles captured_state_->dst_ internally. |
| 267 | return RunRemoteRecv(&op); |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | Status RemoteCopyNode::StartRemoteSendTensor() { |
| 272 | EnqueueRequest request; |
nothing calls this directly
no test coverage detected