Processes a batch of one or more BatchTask entries.
| 565 | |
| 566 | // Processes a batch of one or more BatchTask entries. |
| 567 | void ProcessBatch(std::unique_ptr<Batch> batch) const { |
| 568 | if (batch->empty()) { |
| 569 | return; |
| 570 | } |
| 571 | |
| 572 | WithContext wc(batch->task(batch->num_tasks() - 1).propagated_context); |
| 573 | |
| 574 | OpKernelContext* last_task_context = |
| 575 | batch->task(batch->num_tasks() - 1).context; |
| 576 | AsyncOpKernel::DoneCallback last_task_callback = |
| 577 | batch->task(batch->num_tasks() - 1).done_callback; |
| 578 | |
| 579 | OP_REQUIRES_OK_ASYNC(last_task_context, ValidateBatch(*batch), |
| 580 | last_task_callback); |
| 581 | |
| 582 | // All tasks should have the same number of input edges. |
| 583 | const int num_input_edges = batch->task(0).inputs.size(); |
| 584 | std::vector<Tensor> concatenated_tensors; |
| 585 | const Status concat_status = |
| 586 | ConcatInputTensors(*batch, last_task_context, &concatenated_tensors); |
| 587 | OP_REQUIRES_OK_ASYNC(last_task_context, concat_status, last_task_callback); |
| 588 | |
| 589 | // Process each input edge one at a time (the typical case has just one). |
| 590 | for (int i = 0; i < num_input_edges; ++i) { |
| 591 | last_task_context->set_output(i, concatenated_tensors.at(i)); |
| 592 | |
| 593 | // Emit batch->num_tasks() - 1 empty output tensors. |
| 594 | for (int task_idx = 0; task_idx < batch->num_tasks() - 1; ++task_idx) { |
| 595 | const BatchTask& task = batch->task(task_idx); |
| 596 | TensorShape output_shape(task.inputs.at(i).shape()); |
| 597 | output_shape.set_dim(0, 0); |
| 598 | Tensor* output = nullptr; |
| 599 | OP_REQUIRES_OK_ASYNC( |
| 600 | task.context, |
| 601 | task.context->allocate_output(i, output_shape, &output), |
| 602 | task.done_callback); |
| 603 | } |
| 604 | } |
| 605 | // Emit batch->num_tasks() - 1 empty index tensors. |
| 606 | for (int task_idx = 0; task_idx < batch->num_tasks() - 1; ++task_idx) { |
| 607 | const BatchTask& task = batch->task(task_idx); |
| 608 | TensorShape index_shape({0, 3}); |
| 609 | Tensor* output = nullptr; |
| 610 | OP_REQUIRES_OK_ASYNC( |
| 611 | task.context, |
| 612 | task.context->allocate_output(num_input_edges, index_shape, &output), |
| 613 | task.done_callback); |
| 614 | } |
| 615 | // Emit all ID tensors. |
| 616 | for (int task_idx = 0; task_idx < batch->num_tasks(); ++task_idx) { |
| 617 | const BatchTask& task = batch->task(task_idx); |
| 618 | Tensor* id; |
| 619 | OP_REQUIRES_OK_ASYNC(task.context, |
| 620 | task.context->allocate_output(num_input_edges + 1, |
| 621 | TensorShape({}), &id), |
| 622 | task.done_callback); |
| 623 | id->scalar<int64>()() = task.guid; |
| 624 | } |
nothing calls this directly
no test coverage detected