| 87 | } |
| 88 | |
| 89 | void FuseRecvOp::ComputeAsync(OpKernelContext* ctx, DoneCallback done) { |
| 90 | //LOG(INFO) << "FuseRecvOp::ComputeAsync"; |
| 91 | OP_REQUIRES( |
| 92 | ctx, ctx->rendezvous() != nullptr, |
| 93 | errors::Internal("Op kernel context needs to provide a rendezvous.")); |
| 94 | |
| 95 | // NOTE(rangeng.llb): recv args. |
| 96 | Rendezvous::Args args; |
| 97 | args.device_context = ctx->op_device_context(); |
| 98 | args.alloc_attrs = ctx->output_alloc_attr(0); |
| 99 | |
| 100 | using namespace std::placeholders; |
| 101 | Rendezvous::FuseDoneCallback done_cb = std::bind( |
| 102 | [ctx](DoneCallback done, |
| 103 | // Begin unbound arguments. |
| 104 | const Status& s, const std::vector<Rendezvous::Args>& send_args, |
| 105 | const Rendezvous::Args& recv_args, const std::vector<Tensor>& vals, |
| 106 | const std::vector<bool>& is_deads) { |
| 107 | ctx->SetStatus(s); |
| 108 | if (s.ok()) { |
| 109 | OpOutputList output; |
| 110 | OP_REQUIRES_OK(ctx, ctx->output_list("tensors", &output)); |
| 111 | |
| 112 | bool all_deads = true; |
| 113 | for (int i = 0; i < vals.size(); ++i) { |
| 114 | if (!is_deads[i]) { |
| 115 | output.set(i, vals[i]); |
| 116 | all_deads = false; |
| 117 | } |
| 118 | } |
| 119 | // is_output_dead means all the outputs is dead. |
| 120 | *ctx->is_output_dead() = all_deads; |
| 121 | } |
| 122 | done(); |
| 123 | }, |
| 124 | std::move(done), _1, _2, _3, _4, _5); |
| 125 | |
| 126 | FrameAndIter frame_iter = GetFrameAndIter(ctx, hostmem_sendrecv_); |
| 127 | if (!(frame_iter == FrameAndIter(0, 0))) { |
| 128 | // if frame_iter has changed, change the parsed keys. |
| 129 | for (int i = 0; i < fuse_count_; ++i) { |
| 130 | GetRendezvousKey(key_prefixs_[i], frame_iter, &parsed_keys_[i].buf_); |
| 131 | OP_REQUIRES_OK_ASYNC(ctx, |
| 132 | Rendezvous::ParseKey(parsed_keys_[i].buf_, &parsed_keys_[i]), |
| 133 | done); |
| 134 | } |
| 135 | } |
| 136 | ctx->rendezvous()->FuseRecvAsync(parsed_keys_, args, std::move(done_cb)); |
| 137 | } |
| 138 | |
| 139 | REGISTER_KERNEL_BUILDER(Name("_FuseRecv").Device(DEVICE_CPU), FuseRecvOp); |
| 140 | REGISTER_KERNEL_BUILDER(Name("_FuseRecv").Device(DEVICE_GPU), FuseRecvOp); |
nothing calls this directly
no test coverage detected