MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / Finish

Method Finish

tensorflow/core/common_runtime/executor.cc:1449–1534  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1447
1448template <class PropagatorStateType>
1449void ExecutorState<PropagatorStateType>::Finish() {
1450 mu_.lock();
1451 auto status = status_;
1452 auto done_cb = std::move(done_cb_);
1453 auto runner = std::move(runner_);
1454 mu_.unlock();
1455 int64_t step_id = step_id_;
1456 CHECK(done_cb != nullptr);
1457 Device* device = immutable_state_.params().device;
1458
1459 if (vlog_ && !status.ok() && VLOG_IS_ON(1)) {
1460 // Logs verbose information about the current state of active and pending
1461 // nodes in the propagator.
1462 propagator_.DumpState();
1463 }
1464
1465 // There are several potential race conditions below. To name a few:
1466 // 1. Even if the device's status is OK at the precise moment when
1467 // num_deferred_ops_ reaches 0, it could go bad before device->RefreshStatus()
1468 // is called below, caused by work enqueued onto the same device by other
1469 // concurrent ExecutorState objects.
1470 // 2. Some implementations of Device::RefreshStatus, such as
1471 // XlaDevice::RefreshStatus, may be inherently racy because it releases the
1472 // device mutex after a stream pointer is acquired and before the stream is
1473 // queried for status.
1474 // 3. It's the same for some implementations of Device::Sync, such as
1475 // XlaDevice::Sync.
1476 //
1477 // However, these race conditions are acceptable because a stream (and
1478 // therefore an XlaDevice) can only go from OK to not-OK, never the opposite,
1479 // which means we will at worst report errors when there isn't any, never the
1480 // opposite.
1481
1482 // An early exit for devices don't allow sync on completion. Ops that run on
1483 // these devices should have used num_deferred_ops correctly to ensure the
1484 // device has finished all relevant work at this point.
1485 if (!device->AllowsSyncOnCompletion()) {
1486 status.Update(device->RefreshStatus());
1487 if (!status.ok()) {
1488 // In device async execution mode, it's possible for device execution to
1489 // lag behind ExecutorState scheduling so much that this is the first
1490 // place a device execution error surfaces.
1491 // If so, all ExecutorState::NodeDone calls have already happened with OK
1492 // status. This is the last defense where StartCancel must be called to
1493 // abort all computation still running on any device.
1494 // TODO(b/124523000): Always call Finish in a separate thread, so even if
1495 // StartCancel blocks the current thread's execution, we won't encounter
1496 // deadlocks caused by inter-op thread exhaustion.
1497 if (rendezvous_) {
1498 rendezvous_->StartAbort(status);
1499 }
1500 if (cancellation_manager_) {
1501 cancellation_manager_->StartCancel();
1502 } else if (collective_executor_) {
1503 // If there's cancellation_manager_, collective ops aborts
1504 // collective_executor_ upon cancellation; otherwise we need to abort
1505 // here.
1506 collective_executor_->StartAbort(status);

Callers

nothing calls this directly

Calls 11

paramsMethod · 0.80
lockMethod · 0.45
unlockMethod · 0.45
okMethod · 0.45
DumpStateMethod · 0.45
UpdateMethod · 0.45
RefreshStatusMethod · 0.45
StartAbortMethod · 0.45
StartCancelMethod · 0.45
SyncMethod · 0.45

Tested by

no test coverage detected