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

Function MaybeUpdateOpDevice

tensorflow/core/common_runtime/eager/execute.cc:821–901  ·  view source on GitHub ↗

The Op device may be updated if: - A resource touching input is specified: all resource-touching ops run in the device the resource is, regardless of anything else that has been specified. This is identical to the graph mode behavior. - All op inputs are on the CPU, small (<64 elements) and integers (int32/int64). This can be disabled by setting the environment variable "TF_EAGER_ENABLE_SMALL_TEN

Source from the content-addressed store, hash-verified

819// (int32/int64). This can be disabled by setting the environment variable
820// "TF_EAGER_ENABLE_SMALL_TENSOR_CPU_PINNING" to "0" or "false".
821Status MaybeUpdateOpDevice(EagerOperation* op) {
822 const auto& exempt_ops = InputColocationExemptionRegistry::Global()->Get();
823 if (op->is_function() || exempt_ops.find(op->Name()) != exempt_ops.end()) {
824 // Don't update the device of direct function calls.
825 // Particularly, if the user did not explicitly request any device for this
826 // function, picking a device would result in this device being the default
827 // for nodes inside the function. This is undesirable for multi-device
828 // functions since the not-explicitly-placed nodes inside the body will all
829 // end up on this default device.
830 return Status::OK();
831 }
832 EagerContext* ctx = op->EagerContext();
833 bool all_inputs_eligible_for_cpu_pinning =
834 ctx->PinSmallOpsToCPU() && !op->is_function() && IsPinnableOp(op->Name());
835 Device* op_device = op->Device() == nullptr ? ctx->HostCPU() : op->Device();
836 for (int i = 0; i < op->Inputs().size(); ++i) {
837 TensorHandle* tensor_handle = op->Inputs()[i];
838 if (tensor_handle->dtype == DT_RESOURCE) {
839 Device* resource_device = tensor_handle->resource_device();
840 VLOG(2) << "for op " << op->Name() << " input " << i << " "
841 << DataTypeString(tensor_handle->dtype)
842 << " input device = " << resource_device->name()
843 << ", op device = " << op_device->name();
844 // We check for `op->Device() == nullptr` because it can be later
845 // interpreted as unspecified device and a different device can
846 // be selected based on device priority. If any input to an op
847 // is a resource we must pin it to prevent different device selection.
848 // TODO(iga): null device can mean "unspecified" or "CPU". Clean this up.
849 if (resource_device != op_device || op->Device() == nullptr) {
850 VLOG(1) << (resource_device != op_device ? "Changing " : "Setting ")
851 << "device of operation " << op->Name() << " to "
852 << resource_device->name() << " because input #" << i
853 << " is a resource in this device.";
854 op->SetDevice(resource_device);
855 }
856 all_inputs_eligible_for_cpu_pinning = false;
857 // No point in looking at other inputs. If there are other resources,
858 // they must have the same device and we already declared the op to be
859 // ineligible for CPU pinning.
860 break;
861 } else if (all_inputs_eligible_for_cpu_pinning) {
862 Device* input_device = tensor_handle->DeviceOrHostCPU(ctx);
863 VLOG(2) << "for op " << op->Name() << " input " << i << " "
864 << DataTypeString(tensor_handle->dtype)
865 << " input device = " << input_device->name()
866 << ", op device = " << op_device->name();
867
868 // Input is on CPU.
869 if (input_device != ctx->HostCPU()) {
870 all_inputs_eligible_for_cpu_pinning = false;
871 continue;
872 }
873
874 if (tensor_handle->dtype != DataType::DT_INT32 &&
875 tensor_handle->dtype != DataType::DT_INT64) {
876 all_inputs_eligible_for_cpu_pinning = false;
877 continue;
878 }

Callers 1

EagerExecuteFunction · 0.85

Calls 15

IsPinnableOpFunction · 0.85
is_functionMethod · 0.80
PinSmallOpsToCPUMethod · 0.80
HostCPUMethod · 0.80
resource_deviceMethod · 0.80
DeviceOrHostCPUMethod · 0.80
nameMethod · 0.65
DataTypeStringFunction · 0.50
GetMethod · 0.45
findMethod · 0.45
NameMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected