| 182 | } |
| 183 | |
| 184 | Status SliceSendOp::SendStringSlice(OpKernelContext* ctx, |
| 185 | const FrameAndIter& frame_iter, |
| 186 | const std::string& elem, int64 index) { |
| 187 | Rendezvous::Args args; |
| 188 | args.device_context = ctx->op_device_context(); |
| 189 | args.alloc_attrs = ctx->input_alloc_attr(0); |
| 190 | Rendezvous::ParsedKey parsed_key; |
| 191 | |
| 192 | int64 slice_num = elem.size() / slice_size_; |
| 193 | if (elem.size() % slice_size_ != 0) { |
| 194 | slice_num += 1; |
| 195 | } |
| 196 | Tensor data_t; |
| 197 | for (int64 i = 0; i < slice_num; i++) { |
| 198 | TF_RETURN_IF_ERROR(ctx->allocate_temp(DT_STRING, TensorShape({}), &data_t)); |
| 199 | size_t start = i * slice_size_; |
| 200 | size_t copy_size = slice_size_; |
| 201 | if (start > elem.size() - slice_size_) { |
| 202 | copy_size = elem.size() - start; |
| 203 | } |
| 204 | data_t.scalar<tstring>()() = elem.substr(start, copy_size); |
| 205 | std::string tensor_name_suffix = \ |
| 206 | strings::StrCat("_slice_transfer_data_", std::to_string(index), "_", |
| 207 | std::to_string(i)); |
| 208 | slice_sendrecv::GetSliceRendezvousKey(key_prefix_, tensor_name_suffix, |
| 209 | frame_iter, &parsed_key.buf_); |
| 210 | VLOG(2) << "SliceSend " << parsed_key.buf_; |
| 211 | TF_RETURN_IF_ERROR(Rendezvous::ParseKey(parsed_key.buf_, &parsed_key)); |
| 212 | TF_RETURN_IF_ERROR( |
| 213 | ctx->rendezvous()->FlowControlSend(tensor_name_, parsed_key, args, data_t, |
| 214 | ctx->is_input_dead())); |
| 215 | } |
| 216 | |
| 217 | return Status::OK(); |
| 218 | } |
| 219 | |
| 220 | Status SliceSendOp::SendBasicType(OpKernelContext* ctx, |
| 221 | const FrameAndIter& frame_iter, |
nothing calls this directly
no test coverage detected