| 161 | } // namespace |
| 162 | |
| 163 | void RecvOp::ComputeAsync(OpKernelContext* ctx, DoneCallback done) { |
| 164 | OP_REQUIRES_ASYNC( |
| 165 | ctx, ctx->rendezvous() != nullptr, |
| 166 | errors::Internal("Op kernel context needs to provide a rendezvous."), |
| 167 | done); |
| 168 | |
| 169 | Rendezvous::Args args; |
| 170 | args.device_context = ctx->op_device_context(); |
| 171 | args.alloc_attrs = ctx->output_alloc_attr(0); |
| 172 | if (ctx->is_eager()) { |
| 173 | // NOTE(fishx): Only set cancellation_manager in eager mode. Because in |
| 174 | // Tensorflow 1.x, session (or graph_mgr) will abort the underlying |
| 175 | // rendezvous if it encounters any error. |
| 176 | args.cancellation_manager = ctx->cancellation_manager(); |
| 177 | } |
| 178 | |
| 179 | FrameAndIter frame_iter = GetFrameAndIter(ctx, hostmem_sendrecv_); |
| 180 | if (frame_iter == FrameAndIter(0, 0)) { |
| 181 | VLOG(2) << "Recv " << parsed_key_.buf_; |
| 182 | ctx->rendezvous()->RecvAsync(parsed_key_, args, |
| 183 | make_recv_callback(ctx, std::move(done))); |
| 184 | } else { |
| 185 | Rendezvous::ParsedKey in_loop_parsed; |
| 186 | GetRendezvousKey(key_prefix_, frame_iter, &in_loop_parsed.buf_); |
| 187 | VLOG(2) << "Recv " << in_loop_parsed.buf_; |
| 188 | OP_REQUIRES_OK_ASYNC( |
| 189 | ctx, Rendezvous::ParseKey(in_loop_parsed.buf_, &in_loop_parsed), done); |
| 190 | ctx->rendezvous()->RecvAsync(in_loop_parsed, args, |
| 191 | make_recv_callback(ctx, std::move(done))); |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | REGISTER_KERNEL_BUILDER(Name("_Recv").Device(DEVICE_CPU), RecvOp); |
| 196 | REGISTER_KERNEL_BUILDER(Name("_Recv").Device(DEVICE_DEFAULT), RecvOp); |
nothing calls this directly
no test coverage detected