| 541 | } |
| 542 | |
| 543 | void GraphMgr::StartParallelExecutors( |
| 544 | const string& handle, int64 step_id, Item* item, Rendezvous* rendezvous, |
| 545 | Rendezvous* global_rendezvous, |
| 546 | CollectiveExecutor::Handle* ce_handle, StepStatsCollector* collector, |
| 547 | CostGraphDef* cost_graph, CancellationManager* cancellation_manager, |
| 548 | WorkerSession* session, const ExecutorOpts& opts, StatusCallback done) { |
| 549 | const int num_units = item->units.size(); |
| 550 | CHECK_GE(num_units, 1); |
| 551 | ScopedStepContainer* step_container = new ScopedStepContainer( |
| 552 | step_id, |
| 553 | [this](const string& name) { device_mgr_->ClearContainers({name}); }); |
| 554 | #ifdef TENSORFLOW_USE_STAR |
| 555 | int32 cpu_id = 0; |
| 556 | if (worker_env_->lockless) { |
| 557 | cpu_id = seastar::engine().cpu_id(); |
| 558 | } |
| 559 | #endif // TENSORFLOW_USE_STAR |
| 560 | // NOTE: Transfer one ref of rendezvous and item. |
| 561 | ExecutorBarrier* barrier = |
| 562 | new ExecutorBarrier(num_units, rendezvous, |
| 563 | [this, item, collector, cost_graph, step_container, |
| 564 | #ifdef TENSORFLOW_USE_STAR |
| 565 | done, cpu_id](const Status& s) { |
| 566 | BuildCostModel(item, collector, cost_graph); |
| 567 | if (worker_env_->lockless) { |
| 568 | seastar::alien::submit_to(cpu_id, [s, done] { |
| 569 | done(s); |
| 570 | return seastar::make_ready_future(); |
| 571 | }); |
| 572 | } else { |
| 573 | done(s); |
| 574 | } |
| 575 | #else |
| 576 | done](const Status& s) { |
| 577 | BuildCostModel(item, collector, cost_graph); |
| 578 | done(s); |
| 579 | #endif // TENSORFLOW_USE_STAR |
| 580 | delete step_container; |
| 581 | }); |
| 582 | Executor::Args args; |
| 583 | args.step_id = step_id; |
| 584 | args.round_step_id = step_id; |
| 585 | args.rendezvous = rendezvous; |
| 586 | args.global_rendezvous = global_rendezvous; |
| 587 | args.collective_executor = ce_handle ? ce_handle->get() : nullptr; |
| 588 | args.cancellation_manager = cancellation_manager; |
| 589 | args.stats_collector = collector; |
| 590 | args.step_container = step_container; |
| 591 | args.sync_on_finish = sync_on_finish_; |
| 592 | if (LogMemory::IsEnabled()) { |
| 593 | LogMemory::RecordStep(args.step_id, handle); |
| 594 | } |
| 595 | args.executor_policy = opts.executor_policy(); |
| 596 | thread::ThreadPool* pool = worker_env_->compute_pool; |
| 597 | using std::placeholders::_1; |
| 598 | using std::placeholders::_2; |
| 599 | // Line below is equivalent to this code, but does one less indirect call: |
| 600 | // args.runner = [pool](std::function<void()> fn) { pool->Schedule(fn); }; |
nothing calls this directly
no test coverage detected