aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/common_runtime
diff options
context:
space:
mode:
authorGravatar Vijay Vasudevan <vrv@google.com>2017-01-05 16:30:18 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-01-05 16:47:19 -0800
commitb7a6a82c35330c1e32f4a3051a2332515fdceaeb (patch)
tree791c0ec16e1aa8422c365dbf0ce727480bcfb049 /tensorflow/core/common_runtime
parent128578ccce4483764a294d3abc8282832b164124 (diff)
Use 'priority' field in device registration to allow
external devices to register custom priority orderings. By default, external devices are prioritized below CPU and GPU (maintaining existing behavior as of recently), but can choose to register a higher number if desired. The default priority is set to 50, and our existing CPU and GPU devices have registrations that have higher values. A custom device registration can choose an even higher value than any of ours, if they want to be preferred by the simple_placer. Note that in the future, better placement algorithms may decide to just ignore this field, so it's not a particularly good ordering to rely on. Changed the test to not rely on device registrations of existing devices, registering dummy factories instead. This maintains the existing within-DeviceType priority ordering, and also maintains the previously existing DeviceSet ordering, with one exception that SYCL is preferred below GPU but still above CPU. There were no guarantees about SYCL vs. GPU ordering before (it was pointer ordering before), so this is more deterministic and not harmful. Change: 143723649
Diffstat (limited to 'tensorflow/core/common_runtime')
-rw-r--r--tensorflow/core/common_runtime/device_factory.cc14
-rw-r--r--tensorflow/core/common_runtime/device_factory.h47
-rw-r--r--tensorflow/core/common_runtime/device_set.cc26
-rw-r--r--tensorflow/core/common_runtime/device_set.h8
-rw-r--r--tensorflow/core/common_runtime/device_set_test.cc63
-rw-r--r--tensorflow/core/common_runtime/gpu/gpu_device_factory.cc4
-rw-r--r--tensorflow/core/common_runtime/simple_placer.cc15
-rw-r--r--tensorflow/core/common_runtime/simple_placer_test.cc281
-rw-r--r--tensorflow/core/common_runtime/sycl/sycl_device_factory.cc2
-rw-r--r--tensorflow/core/common_runtime/threadpool_device_factory.cc3
10 files changed, 273 insertions, 190 deletions
diff --git a/tensorflow/core/common_runtime/device_factory.cc b/tensorflow/core/common_runtime/device_factory.cc
index efbdf6bbb1..108a9c0d91 100644
--- a/tensorflow/core/common_runtime/device_factory.cc
+++ b/tensorflow/core/common_runtime/device_factory.cc
@@ -46,8 +46,22 @@ std::unordered_map<string, FactoryItem>& device_factories() {
new std::unordered_map<string, FactoryItem>;
return *factories;
}
+
} // namespace
+// static
+int32 DeviceFactory::DevicePriority(const string& device_type) {
+ mutex_lock l(*get_device_factory_lock());
+ std::unordered_map<string, FactoryItem>& factories = device_factories();
+ auto iter = factories.find(device_type);
+ if (iter != factories.end()) {
+ return iter->second.priority;
+ }
+
+ return -1;
+}
+
+// static
void DeviceFactory::Register(const string& device_type, DeviceFactory* factory,
int priority) {
mutex_lock l(*get_device_factory_lock());
diff --git a/tensorflow/core/common_runtime/device_factory.h b/tensorflow/core/common_runtime/device_factory.h
index 3852dd2223..10eb62afa8 100644
--- a/tensorflow/core/common_runtime/device_factory.h
+++ b/tensorflow/core/common_runtime/device_factory.h
@@ -52,6 +52,20 @@ class DeviceFactory {
virtual Status CreateDevices(const SessionOptions& options,
const string& name_prefix,
std::vector<Device*>* devices) = 0;
+
+ // Return the device priority number for a "device_type" string.
+ //
+ // Higher number implies higher priority.
+ //
+ // In standard TensorFlow distributions, GPU device types are
+ // preferred over CPU, and by default, custom devices that don't set
+ // a custom priority during registration will be prioritized lower
+ // than CPU. Custom devices that want a higher priority can set the
+ // 'priority' field when registering their device to something
+ // higher than the packaged devices. See calls to
+ // REGISTER_LOCAL_DEVICE_FACTORY to see the existing priorities used
+ // for built-in devices.
+ static int32 DevicePriority(const string& device_type);
};
namespace dfactory {
@@ -60,8 +74,37 @@ template <class Factory>
class Registrar {
public:
// Multiple registrations for the same device type with different priorities
- // are allowed. The registration with the highest priority will be used.
- explicit Registrar(const string& device_type, int priority = 0) {
+ // are allowed. Priorities are used in two different ways:
+ //
+ // 1) When choosing which factory (that is, which device
+ // implementation) to use for a specific 'device_type', the
+ // factory registered with the highest priority will be chosen.
+ // For example, if there are two registrations:
+ //
+ // Registrar<CPUFactory1>("CPU", 125);
+ // Registrar<CPUFactory2>("CPU", 150);
+ //
+ // then CPUFactory2 will be chosen when
+ // DeviceFactory::GetFactory("CPU") is called.
+ //
+ // 2) When choosing which 'device_type' is preferred over other
+ // DeviceTypes in a DeviceSet, the ordering is determined
+ // by the 'priority' set during registration. For example, if there
+ // are two registrations:
+ //
+ // Registrar<CPUFactory>("CPU", 100);
+ // Registrar<GPUFactory>("GPU", 200);
+ //
+ // then DeviceType("GPU") will be prioritized higher than
+ // DeviceType("CPU").
+ //
+ // The default priority values for built-in devices is:
+ // GPU: 210
+ // SYCL: 200
+ // GPUCompatibleCPU: 70
+ // ThreadPoolDevice: 60
+ // Default: 50
+ explicit Registrar(const string& device_type, int priority = 50) {
DeviceFactory::Register(device_type, new Factory(), priority);
}
};
diff --git a/tensorflow/core/common_runtime/device_set.cc b/tensorflow/core/common_runtime/device_set.cc
index 84f435b022..0ed9470655 100644
--- a/tensorflow/core/common_runtime/device_set.cc
+++ b/tensorflow/core/common_runtime/device_set.cc
@@ -20,6 +20,7 @@ limitations under the License.
#include <vector>
#include "tensorflow/core/common_runtime/device.h"
+#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/lib/core/stringpiece.h"
#include "tensorflow/core/lib/gtl/map_util.h"
@@ -52,24 +53,19 @@ Device* DeviceSet::FindDeviceByName(const string& name) const {
// static
int DeviceSet::DeviceTypeOrder(const DeviceType& d) {
- if (StringPiece(d.type()) == DEVICE_CPU) {
- return 3;
- } else if (StringPiece(d.type()) == DEVICE_GPU ||
- StringPiece(d.type()) == DEVICE_SYCL) {
- return 2;
- } else {
- // Non-CPU/GPU devices are never prioritized over CPU and GPU, and
- // must be explicitly selected. This is to prevent surprising
- // placements that cause a lot of cross-device communication
- // between the host CPU device and other devices.
- return 10;
- }
+ return DeviceFactory::DevicePriority(d.type());
}
static bool DeviceTypeComparator(const DeviceType& a, const DeviceType& b) {
- // Order by "order number"; break ties lexicographically.
- return std::make_pair(DeviceSet::DeviceTypeOrder(a), StringPiece(a.type())) <
- std::make_pair(DeviceSet::DeviceTypeOrder(b), StringPiece(b.type()));
+ // First sort by prioritized device type (higher is preferred) and
+ // then by device name (lexicographically).
+ auto a_priority = DeviceSet::DeviceTypeOrder(a);
+ auto b_priority = DeviceSet::DeviceTypeOrder(b);
+ if (a_priority != b_priority) {
+ return a_priority > b_priority;
+ }
+
+ return StringPiece(a.type()) < StringPiece(b.type());
}
std::vector<DeviceType> DeviceSet::PrioritizedDeviceTypeList() const {
diff --git a/tensorflow/core/common_runtime/device_set.h b/tensorflow/core/common_runtime/device_set.h
index 1c2312e724..b0540dfa95 100644
--- a/tensorflow/core/common_runtime/device_set.h
+++ b/tensorflow/core/common_runtime/device_set.h
@@ -61,12 +61,10 @@ class DeviceSet {
// with more preferable devices earlier.
std::vector<DeviceType> PrioritizedDeviceTypeList() const;
- // A comparator to sort by device types according to
- // system-determined priority.
+ // An order to sort by device types according to system-determined
+ // priority.
//
- // For internal-use only.
- //
- // Higher result implies lower priority.
+ // Higher result implies higher priority.
static int DeviceTypeOrder(const DeviceType& d);
private:
diff --git a/tensorflow/core/common_runtime/device_set_test.cc b/tensorflow/core/common_runtime/device_set_test.cc
index 7c59b43489..ff20ee94a7 100644
--- a/tensorflow/core/common_runtime/device_set_test.cc
+++ b/tensorflow/core/common_runtime/device_set_test.cc
@@ -14,6 +14,7 @@ limitations under the License.
==============================================================================*/
#include "tensorflow/core/common_runtime/device_set.h"
+#include "tensorflow/core/common_runtime/device_factory.h"
#include <vector>
#include "tensorflow/core/lib/core/status.h"
@@ -54,37 +55,43 @@ class DeviceSetTest : public ::testing::Test {
std::vector<std::unique_ptr<Device>> owned_;
};
+class DummyFactory : public DeviceFactory {
+ public:
+ Status CreateDevices(const SessionOptions& options, const string& name_prefix,
+ std::vector<Device*>* devices) override {
+ return Status::OK();
+ }
+};
+
+// Assumes the default priority is '50'.
+REGISTER_LOCAL_DEVICE_FACTORY("d1", DummyFactory);
+REGISTER_LOCAL_DEVICE_FACTORY("d2", DummyFactory, 51);
+REGISTER_LOCAL_DEVICE_FACTORY("d3", DummyFactory, 49);
+
TEST_F(DeviceSetTest, PrioritizedDeviceTypeList) {
+ EXPECT_EQ(50, DeviceSet::DeviceTypeOrder(DeviceType("d1")));
+ EXPECT_EQ(51, DeviceSet::DeviceTypeOrder(DeviceType("d2")));
+ EXPECT_EQ(49, DeviceSet::DeviceTypeOrder(DeviceType("d3")));
+
EXPECT_EQ(std::vector<DeviceType>{}, types());
- AddDevice("CPU", "/job:a/replica:0/task:0/cpu:0");
- EXPECT_EQ(std::vector<DeviceType>{DeviceType(DEVICE_CPU)}, types());
-
- AddDevice("CPU", "/job:a/replica:0/task:0/cpu:1");
- EXPECT_EQ(std::vector<DeviceType>{DeviceType(DEVICE_CPU)}, types());
-
- AddDevice("GPU", "/job:a/replica:0/task:0/gpu:0");
- EXPECT_EQ(
- (std::vector<DeviceType>{DeviceType(DEVICE_GPU), DeviceType(DEVICE_CPU)}),
- types());
-
- AddDevice("SYCL", "/job:a/replica:0/task:0/device:sycl:0");
- EXPECT_TRUE((types()[0] == DeviceType(DEVICE_SYCL) ||
- types()[0] == DeviceType(DEVICE_GPU)));
- EXPECT_TRUE((types()[1] == DeviceType(DEVICE_SYCL) ||
- types()[1] == DeviceType(DEVICE_GPU)));
- EXPECT_TRUE(types()[2] == DeviceType(DEVICE_CPU));
-
- AddDevice("T1", "/job:a/replica:0/task:0/device:T1:0");
- AddDevice("T1", "/job:a/replica:0/task:0/device:T1:1");
- AddDevice("T2", "/job:a/replica:0/task:0/device:T2:0");
- EXPECT_TRUE((types()[0] == DeviceType(DEVICE_SYCL) ||
- types()[0] == DeviceType(DEVICE_GPU)));
- EXPECT_TRUE((types()[1] == DeviceType(DEVICE_SYCL) ||
- types()[1] == DeviceType(DEVICE_GPU)));
- EXPECT_TRUE(types()[2] == DeviceType(DEVICE_CPU));
- EXPECT_TRUE(types()[3] == DeviceType("T1"));
- EXPECT_TRUE(types()[4] == DeviceType("T2"));
+ AddDevice("d1", "/job:a/replica:0/task:0/device:d1:0");
+ EXPECT_EQ(std::vector<DeviceType>{DeviceType("d1")}, types());
+
+ AddDevice("d1", "/job:a/replica:0/task:0/device:d1:1");
+ EXPECT_EQ(std::vector<DeviceType>{DeviceType("d1")}, types());
+
+ // D2 is prioritized higher than D1.
+ AddDevice("d2", "/job:a/replica:0/task:0/device:d2:0");
+ EXPECT_EQ((std::vector<DeviceType>{DeviceType("d2"), DeviceType("d1")}),
+ types());
+
+ // D3 is prioritized below D1.
+ AddDevice("d3", "/job:a/replica:0/task:0/device:d3:0");
+ EXPECT_EQ((std::vector<DeviceType>{
+ DeviceType("d2"), DeviceType("d1"), DeviceType("d3"),
+ }),
+ types());
}
} // namespace
diff --git a/tensorflow/core/common_runtime/gpu/gpu_device_factory.cc b/tensorflow/core/common_runtime/gpu/gpu_device_factory.cc
index 878256d5d7..94143a55d5 100644
--- a/tensorflow/core/common_runtime/gpu/gpu_device_factory.cc
+++ b/tensorflow/core/common_runtime/gpu/gpu_device_factory.cc
@@ -60,7 +60,7 @@ class GPUDeviceFactory : public BaseGPUDeviceFactory {
}
};
-REGISTER_LOCAL_DEVICE_FACTORY("GPU", GPUDeviceFactory);
+REGISTER_LOCAL_DEVICE_FACTORY("GPU", GPUDeviceFactory, 210);
//------------------------------------------------------------------------------
// A CPUDevice that optimizes for interaction with GPUs in the
@@ -104,7 +104,7 @@ class GPUCompatibleCPUDeviceFactory : public DeviceFactory {
return Status::OK();
}
};
-REGISTER_LOCAL_DEVICE_FACTORY("CPU", GPUCompatibleCPUDeviceFactory, 50);
+REGISTER_LOCAL_DEVICE_FACTORY("CPU", GPUCompatibleCPUDeviceFactory, 70);
} // namespace tensorflow
diff --git a/tensorflow/core/common_runtime/simple_placer.cc b/tensorflow/core/common_runtime/simple_placer.cc
index 48ce6af33f..99c74ce038 100644
--- a/tensorflow/core/common_runtime/simple_placer.cc
+++ b/tensorflow/core/common_runtime/simple_placer.cc
@@ -51,13 +51,14 @@ std::vector<Device*> FilterSupportedDevices(
}
auto device_sort = [](const Device* a, const Device* b) {
- // First sort by prioritized device type and then by device name.
- return std::make_pair(
- DeviceSet::DeviceTypeOrder(DeviceType(a->device_type())),
- StringPiece(a->name())) <
- std::make_pair(
- DeviceSet::DeviceTypeOrder(DeviceType(b->device_type())),
- StringPiece(b->name()));
+ auto a_priority = DeviceSet::DeviceTypeOrder(DeviceType(a->device_type()));
+ auto b_priority = DeviceSet::DeviceTypeOrder(DeviceType(b->device_type()));
+ // First sort by prioritized device type (higher is preferred) and
+ // then by device name (lexicographically).
+ if (a_priority != b_priority) {
+ return a_priority > b_priority;
+ }
+ return StringPiece(a->name()) < StringPiece(b->name());
};
std::sort(filtered_devices.begin(), filtered_devices.end(), device_sort);
return filtered_devices;
diff --git a/tensorflow/core/common_runtime/simple_placer_test.cc b/tensorflow/core/common_runtime/simple_placer_test.cc
index 0c4edc28ec..bb13281cdb 100644
--- a/tensorflow/core/common_runtime/simple_placer_test.cc
+++ b/tensorflow/core/common_runtime/simple_placer_test.cc
@@ -21,6 +21,7 @@ limitations under the License.
#include <vector>
#include "tensorflow/core/common_runtime/device.h"
+#include "tensorflow/core/common_runtime/device_factory.h"
#include "tensorflow/core/common_runtime/device_set.h"
#include "tensorflow/core/framework/device_attributes.pb.h"
#include "tensorflow/core/framework/graph.pb.h"
@@ -75,73 +76,89 @@ class FakeDevice : public Device {
static std::unique_ptr<Device> MakeCPU(const string& name) {
DeviceAttributes device_attributes;
device_attributes.set_name(name);
- device_attributes.set_device_type(DeviceType(DEVICE_CPU).type());
+ device_attributes.set_device_type(DeviceType("FakeCPU").type());
return std::unique_ptr<Device>(new FakeDevice(device_attributes));
}
static std::unique_ptr<Device> MakeGPU(const string& name) {
DeviceAttributes device_attributes;
device_attributes.set_name(name);
- device_attributes.set_device_type(DeviceType(DEVICE_GPU).type());
+ device_attributes.set_device_type(DeviceType("FakeGPU").type());
return std::unique_ptr<Device>(new FakeDevice(device_attributes));
}
};
+class DummyFactory : public DeviceFactory {
+ public:
+ Status CreateDevices(const SessionOptions& options, const string& name_prefix,
+ std::vector<Device*>* devices) override {
+ return Status::OK();
+ }
+};
+
+// Device order now depends on the registration of devices, not a fixed
+// value in device_set.cc. To avoid the need to link in the real CPU and GPU
+// devices into this test, we create fake devices and registrations that
+// can stand-in for the real devices for the purposes of testing placement
+// and ordering.
+REGISTER_LOCAL_DEVICE_FACTORY("FakeCPU", DummyFactory);
+REGISTER_LOCAL_DEVICE_FACTORY("FakeGPU", DummyFactory, 51);
+
// Register the following ops so they can be added to a Graph, and
// kernels so that they can be placed on particular device types.
REGISTER_OP("TestVariable").Output("o: Ref(float)");
-REGISTER_KERNEL_BUILDER(Name("TestVariable").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestVariable").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestVariable").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestVariable").Device("FakeGPU"), DummyOp);
REGISTER_OP("VariableCPU").Output("o: Ref(float)");
-REGISTER_KERNEL_BUILDER(Name("VariableCPU").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("VariableCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("VariableGPU").Output("o: Ref(float)");
-REGISTER_KERNEL_BUILDER(Name("VariableGPU").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("VariableGPU").Device("FakeGPU"), DummyOp);
REGISTER_OP("VariableNoKernels").Output("o: Ref(float)");
REGISTER_OP("TestAdd").Input("a: float").Input("b: float").Output("o: float");
-REGISTER_KERNEL_BUILDER(Name("TestAdd").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestAdd").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestAdd").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestAdd").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestRelu").Input("i: float").Output("o: float");
-REGISTER_KERNEL_BUILDER(Name("TestRelu").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestRelu").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestRelu").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestRelu").Device("FakeGPU"), DummyOp);
REGISTER_OP("ReluCPU").Input("i: float").Output("o: float");
-REGISTER_KERNEL_BUILDER(Name("ReluCPU").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("ReluCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("ReluGPU").Input("i: float").Output("o: float");
-REGISTER_KERNEL_BUILDER(Name("ReluGPU").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("ReluGPU").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestAssign").Input("i: Ref(float)").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("TestAssign").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestAssign").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestAssign").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestAssign").Device("FakeGPU"), DummyOp);
REGISTER_OP("AssignCPU").Input("i: Ref(float)").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("AssignCPU").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("AssignCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("AssignGPU").Input("i: Ref(float)").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("AssignGPU").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("AssignGPU").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestInput").Output("a: float").Output("b: float");
-REGISTER_KERNEL_BUILDER(Name("TestInput").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestInput").Device("FakeCPU"), DummyOp);
// Op producing an output that can be placed on CPU or GPU.
REGISTER_OP("TestCPUGPUOutput").Output("a: float");
-REGISTER_KERNEL_BUILDER(Name("TestCPUGPUOutput").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestCPUGPUOutput").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestCPUGPUOutput").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestCPUGPUOutput").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestDevice").Output("a: float").Output("b: float");
-REGISTER_KERNEL_BUILDER(Name("TestDevice").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestDevice").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestDeviceEnforce").Input("a: Ref(float)").Output("b: float");
-REGISTER_KERNEL_BUILDER(Name("TestDeviceEnforce").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestDeviceEnforce").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestDeviceEnforce").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestDeviceEnforce").Device("FakeGPU"), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("Shape").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("Shape").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("Shape").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("Shape").Device("FakeGPU"), DummyOp);
////////////////////////////////////////////////////////////////////////////////
//
@@ -162,11 +179,11 @@ class SimplePlacerTest : public ::testing::Test {
// objects.
for (int i = 0; i < 10; ++i) {
local_devices_.emplace_back(FakeDevice::MakeCPU(
- strings::StrCat("/job:a/replica:0/task:0/cpu:", i)));
+ strings::StrCat("/job:a/replica:0/task:0/device:fakecpu:", i)));
devices_.AddDevice(local_devices_.back().get());
// Insert the GPUs in reverse order.
local_devices_.emplace_back(FakeDevice::MakeGPU(
- strings::StrCat("/job:a/replica:0/task:0/gpu:", 9 - i)));
+ strings::StrCat("/job:a/replica:0/task:0/device:fakegpu:", 9 - i)));
devices_.AddDevice(local_devices_.back().get());
}
}
@@ -258,9 +275,9 @@ TEST_F(SimplePlacerTest, TestNoConstraints) {
}
TF_EXPECT_OK(Place(&g));
- EXPECT_DEVICE_TYPE(g, "in", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "n1", DEVICE_GPU);
- EXPECT_DEVICE_TYPE(g, "n2", DEVICE_GPU);
+ EXPECT_DEVICE_TYPE(g, "in", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "n1", "FakeGPU");
+ EXPECT_DEVICE_TYPE(g, "n2", "FakeGPU");
}
// Test that a graph with device type and reference constraints on
@@ -279,12 +296,12 @@ TEST_F(SimplePlacerTest, TestDeviceTypeConstraints) {
}
TF_EXPECT_OK(Place(&g));
- EXPECT_DEVICE_TYPE(g, "in", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "var_cpu", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "assign_cpu", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "in", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "var_cpu", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "assign_cpu", "FakeCPU");
EXPECT_COLOCATED(g, "var_cpu", "assign_cpu");
- EXPECT_DEVICE_TYPE(g, "var_gpu", DEVICE_GPU);
- EXPECT_DEVICE_TYPE(g, "assign_gpu", DEVICE_GPU);
+ EXPECT_DEVICE_TYPE(g, "var_gpu", "FakeGPU");
+ EXPECT_DEVICE_TYPE(g, "assign_gpu", "FakeGPU");
EXPECT_COLOCATED(g, "var_gpu", "assign_gpu");
}
@@ -302,8 +319,8 @@ TEST_F(SimplePlacerTest, TestMetadataColocatedWithInput) {
}
TF_EXPECT_OK(Place(&g));
- EXPECT_DEVICE_TYPE(g, "var_cpu", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "shape_op", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "var_cpu", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "shape_op", "FakeCPU");
EXPECT_COLOCATED(g, "var_cpu", "shape_op");
}
@@ -348,9 +365,9 @@ TEST_F(SimplePlacerTest, TestPartialSpec) {
}
TF_EXPECT_OK(Place(&g));
- EXPECT_DEVICE_TYPE(g, "in", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "in", "FakeCPU");
EXPECT_DEVICE_CONTAINS(g, "in", "/job:a");
- EXPECT_DEVICE_TYPE(g, "var", DEVICE_GPU);
+ EXPECT_DEVICE_TYPE(g, "var", "FakeGPU");
EXPECT_DEVICE_CONTAINS(g, "var", "/job:a");
}
@@ -363,11 +380,11 @@ TEST_F(SimplePlacerTest, TestAssignedDevicePreserved) {
TF_EXPECT_OK(BuildGraph(b, &g));
}
- GetNodeByName(g, "in")
- ->set_assigned_device_name("/job:a/replica:0/task:0/cpu:7");
+ GetNodeByName(g, "in")->set_assigned_device_name(
+ "/job:a/replica:0/task:0/device:fakecpu:7");
TF_EXPECT_OK(Place(&g));
- EXPECT_EQ("/job:a/replica:0/task:0/cpu:7",
+ EXPECT_EQ("/job:a/replica:0/task:0/device:fakecpu:7",
GetNodeByName(g, "in")->assigned_device_name());
}
@@ -377,19 +394,20 @@ TEST_F(SimplePlacerTest, TestPartialSpecGpuToCpu) {
Graph g(OpRegistry::Global());
{ // Scope for temporary variables used to construct g.
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
- ops::SourceOp("TestInput", b.opts().WithName("in").WithDevice("/gpu:0"));
+ ops::SourceOp("TestInput",
+ b.opts().WithName("in").WithDevice("/device:fakegpu:0"));
ops::SourceOp("TestVariable",
- b.opts().WithName("var").WithDevice("/gpu:0"));
+ b.opts().WithName("var").WithDevice("/device:fakegpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
options.config.set_allow_soft_placement(true);
TF_EXPECT_OK(Place(&g, &options));
- EXPECT_DEVICE_TYPE(g, "in", DEVICE_CPU);
- EXPECT_DEVICE_CONTAINS(g, "in", "/cpu");
- EXPECT_DEVICE_TYPE(g, "var", DEVICE_GPU);
- EXPECT_DEVICE_CONTAINS(g, "var", "/gpu:0");
+ EXPECT_DEVICE_TYPE(g, "in", "FakeCPU");
+ EXPECT_DEVICE_CONTAINS(g, "in", "/device:fakecpu");
+ EXPECT_DEVICE_TYPE(g, "var", "FakeGPU");
+ EXPECT_DEVICE_CONTAINS(g, "var", "/device:fakegpu:0");
}
// Test that a node with an assigned GPU device but has not registered
@@ -402,15 +420,16 @@ TEST_F(SimplePlacerTest, TestAssignedGpuDeviceToCpuDevice) {
TF_EXPECT_OK(BuildGraph(b, &g));
}
- GetNodeByName(g, "in")
- ->set_assigned_device_name("/job:a/replica:0/task:0/gpu:0");
+ GetNodeByName(g, "in")->set_assigned_device_name(
+ "/job:a/replica:0/task:0/device:fakegpu:0");
Status s = Place(&g);
EXPECT_EQ(error::INTERNAL, s.code());
EXPECT_TRUE(
StringPiece(s.error_message())
- .contains("Assigned device '/job:a/replica:0/task:0/gpu:0' "
- "does not have registered OpKernel support for TestInput"));
+ .contains(
+ "Assigned device '/job:a/replica:0/task:0/device:fakegpu:0' "
+ "does not have registered OpKernel support for TestInput"));
}
// Test that graphs with reference connections are correctly placed.
@@ -451,47 +470,47 @@ Status SimplePlacerTest::ReferenceTestHelper(const string& variable_op_type,
// (unconstrained, CPU-only, and GPU-only).
TEST_F(SimplePlacerTest, TestReferenceConnection) {
Status s;
- TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "TestAssign", DEVICE_GPU));
- TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "AssignCPU", DEVICE_CPU));
- TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "AssignGPU", DEVICE_GPU));
- TF_EXPECT_OK(ReferenceTestHelper("VariableCPU", "TestAssign", DEVICE_CPU));
- TF_EXPECT_OK(ReferenceTestHelper("VariableCPU", "AssignCPU", DEVICE_CPU));
+ TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "TestAssign", "FakeGPU"));
+ TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "AssignCPU", "FakeCPU"));
+ TF_EXPECT_OK(ReferenceTestHelper("TestVariable", "AssignGPU", "FakeGPU"));
+ TF_EXPECT_OK(ReferenceTestHelper("VariableCPU", "TestAssign", "FakeCPU"));
+ TF_EXPECT_OK(ReferenceTestHelper("VariableCPU", "AssignCPU", "FakeCPU"));
{
- Status s = ReferenceTestHelper("VariableCPU", "AssignGPU", DEVICE_CPU);
+ Status s = ReferenceTestHelper("VariableCPU", "AssignGPU", "FakeCPU");
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
EXPECT_TRUE(StringPiece(s.error_message())
.contains("no device type supports both of those nodes"));
}
- TF_EXPECT_OK(ReferenceTestHelper("VariableGPU", "TestAssign", DEVICE_GPU));
+ TF_EXPECT_OK(ReferenceTestHelper("VariableGPU", "TestAssign", "FakeGPU"));
{
- Status s = ReferenceTestHelper("VariableGPU", "AssignCPU", DEVICE_CPU);
+ Status s = ReferenceTestHelper("VariableGPU", "AssignCPU", "FakeCPU");
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
EXPECT_TRUE(StringPiece(s.error_message())
.contains("no device type supports both of those nodes"));
}
- TF_EXPECT_OK(ReferenceTestHelper("VariableGPU", "AssignGPU", DEVICE_GPU));
+ TF_EXPECT_OK(ReferenceTestHelper("VariableGPU", "AssignGPU", "FakeGPU"));
}
// Handle-using dummy variable ops.
REGISTER_OP("TestHandleVariable").Output("o: resource");
-REGISTER_KERNEL_BUILDER(Name("TestHandleVariable").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestHandleVariable").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestHandleVariable").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestHandleVariable").Device("FakeGPU"), DummyOp);
REGISTER_OP("HandleVariableCPU").Output("o: resource");
-REGISTER_KERNEL_BUILDER(Name("HandleVariableCPU").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("HandleVariableCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("HandleVariableGPU").Output("o: resource");
-REGISTER_KERNEL_BUILDER(Name("HandleVariableGPU").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("HandleVariableGPU").Device("FakeGPU"), DummyOp);
REGISTER_OP("TestHandleAssign").Input("i: resource").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("TestHandleAssign").Device(DEVICE_CPU), DummyOp);
-REGISTER_KERNEL_BUILDER(Name("TestHandleAssign").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestHandleAssign").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestHandleAssign").Device("FakeGPU"), DummyOp);
REGISTER_OP("HandleAssignCPU").Input("i: resource").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("HandleAssignCPU").Device(DEVICE_CPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("HandleAssignCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("HandleAssignGPU").Input("i: resource").Input("v: float");
-REGISTER_KERNEL_BUILDER(Name("HandleAssignGPU").Device(DEVICE_GPU), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("HandleAssignGPU").Device("FakeGPU"), DummyOp);
// Tests all combinations of resource handles and ops using them.
TEST_F(SimplePlacerTest, TestResourceHandle) {
@@ -514,21 +533,17 @@ TEST_F(SimplePlacerTest, TestResourceHandle) {
return Status::OK();
};
TF_EXPECT_OK(
- handle_test("TestHandleVariable", "TestHandleAssign", DEVICE_GPU));
- TF_EXPECT_OK(
- handle_test("TestHandleVariable", "HandleAssignCPU", DEVICE_CPU));
- TF_EXPECT_OK(
- handle_test("TestHandleVariable", "HandleAssignGPU", DEVICE_GPU));
- TF_EXPECT_OK(
- handle_test("HandleVariableCPU", "TestHandleAssign", DEVICE_CPU));
- TF_EXPECT_OK(handle_test("HandleVariableCPU", "HandleAssignCPU", DEVICE_CPU));
- TF_EXPECT_OK(handle_test("HandleVariableGPU", "HandleAssignGPU", DEVICE_GPU));
- TF_EXPECT_OK(
- handle_test("HandleVariableGPU", "TestHandleAssign", DEVICE_GPU));
+ handle_test("TestHandleVariable", "TestHandleAssign", "FakeGPU"));
+ TF_EXPECT_OK(handle_test("TestHandleVariable", "HandleAssignCPU", "FakeCPU"));
+ TF_EXPECT_OK(handle_test("TestHandleVariable", "HandleAssignGPU", "FakeGPU"));
+ TF_EXPECT_OK(handle_test("HandleVariableCPU", "TestHandleAssign", "FakeCPU"));
+ TF_EXPECT_OK(handle_test("HandleVariableCPU", "HandleAssignCPU", "FakeCPU"));
+ TF_EXPECT_OK(handle_test("HandleVariableGPU", "HandleAssignGPU", "FakeGPU"));
+ TF_EXPECT_OK(handle_test("HandleVariableGPU", "TestHandleAssign", "FakeGPU"));
EXPECT_FALSE(
- handle_test("HandleVariableGPU", "HandleAssignCPU", DEVICE_CPU).ok());
+ handle_test("HandleVariableGPU", "HandleAssignCPU", "FakeCPU").ok());
EXPECT_FALSE(
- handle_test("HandleVariableCPU", "HandleAssignGPU", DEVICE_CPU).ok());
+ handle_test("HandleVariableCPU", "HandleAssignGPU", "FakeCPU").ok());
}
// Test that an assignment of an operator to the wrong device
@@ -541,24 +556,24 @@ TEST_F(SimplePlacerTest, TestReferenceConnectionIgnoreInfeasible) {
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
Node* input = ops::SourceOp(
"TestDevice",
- b.opts().WithName("in").WithDevice("/job:a/task:0/device:GPU:0"));
- Node* var = ops::SourceOp(
- "TestVariable",
- b.opts().WithName("var_0").WithDevice("/job:a/task:0/device:GPU:0"));
+ b.opts().WithName("in").WithDevice("/job:a/task:0/device:fakegpu:0"));
+ Node* var = ops::SourceOp("TestVariable",
+ b.opts().WithName("var_0").WithDevice(
+ "/job:a/task:0/device:fakegpu:0"));
// This op is specified on CPU, but in practice will be ignored,
// because the reference edges forces it on GPU.
- ops::BinaryOp(
- "TestAssign", var, input,
- b.opts().WithName("assign").WithDevice("/job:a/task:0/device:CPU:0"));
+ ops::BinaryOp("TestAssign", var, input,
+ b.opts().WithName("assign").WithDevice(
+ "/job:a/task:0/device:fakecpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
s = Place(&g, &options);
TF_EXPECT_OK(s);
- EXPECT_DEVICE_TYPE(g, "var_0", DEVICE_GPU);
- EXPECT_DEVICE_TYPE(g, "assign", DEVICE_GPU);
+ EXPECT_DEVICE_TYPE(g, "var_0", "FakeGPU");
+ EXPECT_DEVICE_TYPE(g, "assign", "FakeGPU");
}
// Test that an assignment of an operator to the a more specified device
@@ -581,17 +596,17 @@ TEST_F(SimplePlacerTest,
// This op is specified on CPU and is more specific than the variable.
// Because the variable is less specified, the variable will be
// assigned to CPU.
- ops::BinaryOp(
- "TestAssign", var, input,
- b.opts().WithName("assign").WithDevice("/job:a/task:0/device:CPU:0"));
+ ops::BinaryOp("TestAssign", var, input,
+ b.opts().WithName("assign").WithDevice(
+ "/job:a/task:0/device:fakecpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
s = Place(&g, &options);
TF_EXPECT_OK(s);
- EXPECT_DEVICE_TYPE(g, "var_0", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "assign", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "var_0", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "assign", "FakeCPU");
}
// A reference connection exists between a variable and an assign,
@@ -605,19 +620,19 @@ TEST_F(SimplePlacerTest, TestReferenceConnectionNoSourceDevice) {
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
Node* input = ops::SourceOp(
"TestDevice",
- b.opts().WithName("in").WithDevice("/job:a/task:0/device:GPU:0"));
+ b.opts().WithName("in").WithDevice("/job:a/task:0/device:fakegpu:0"));
Node* var = ops::SourceOp("TestVariable", b.opts().WithName("var_0"));
- ops::BinaryOp(
- "TestAssign", var, input,
- b.opts().WithName("assign").WithDevice("/job:a/task:0/device:CPU:0"));
+ ops::BinaryOp("TestAssign", var, input,
+ b.opts().WithName("assign").WithDevice(
+ "/job:a/task:0/device:fakecpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
s = Place(&g, &options);
TF_EXPECT_OK(s);
- EXPECT_DEVICE_TYPE(g, "var_0", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "assign", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "var_0", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "assign", "FakeCPU");
}
TEST_F(SimplePlacerTest, TestColocationGroup) {
@@ -828,10 +843,10 @@ TEST_F(SimplePlacerTest, TestHeterogeneousDeviceSetFailure) {
DeviceSet heterogeneous;
std::unique_ptr<Device> gpu(
- FakeDevice::MakeGPU("/job:b/replica:0/task:0/gpu:0"));
+ FakeDevice::MakeGPU("/job:b/replica:0/task:0/device:fakegpu:0"));
heterogeneous.AddDevice(gpu.get());
std::unique_ptr<Device> cpu(
- FakeDevice::MakeCPU("/job:b/replica:0/task:1/cpu:0"));
+ FakeDevice::MakeCPU("/job:b/replica:0/task:1/device:fakecpu:0"));
heterogeneous.AddDevice(cpu.get());
Status s = Place(&g, &heterogeneous);
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
@@ -841,8 +856,10 @@ TEST_F(SimplePlacerTest, TestHeterogeneousDeviceSetFailure) {
// The error message should contain information that indicates which
// op types have which registered device types.
- EXPECT_TRUE(StringPiece(s.error_message()).contains("VariableGPU: GPU")) << s;
- EXPECT_TRUE(StringPiece(s.error_message()).contains("TestAssign: GPU CPU"))
+ EXPECT_TRUE(StringPiece(s.error_message()).contains("VariableGPU: FakeGPU"))
+ << s;
+ EXPECT_TRUE(
+ StringPiece(s.error_message()).contains("TestAssign: FakeGPU FakeCPU"))
<< s;
}
@@ -932,7 +949,7 @@ TEST_F(SimplePlacerTest, TestNoDevicesRegistered) {
DeviceSet cpu_only;
std::unique_ptr<Device> cpu(
- FakeDevice::MakeCPU("/job:a/replica:0/task:0/cpu:0"));
+ FakeDevice::MakeCPU("/job:a/replica:0/task:0/device:fakecpu:0"));
cpu_only.AddDevice(cpu.get());
Status s = Place(&g, &cpu_only);
@@ -940,7 +957,7 @@ TEST_F(SimplePlacerTest, TestNoDevicesRegistered) {
EXPECT_TRUE(StringPiece(s.error_message())
.contains("No OpKernel was registered to support "
"Op 'VariableGPU'"));
- EXPECT_TRUE(StringPiece(s.error_message()).contains("device='GPU'"));
+ EXPECT_TRUE(StringPiece(s.error_message()).contains("device='FakeGPU'"));
}
// Test that placement fails when a requested device is malformed.
@@ -1000,14 +1017,15 @@ TEST_F(SimplePlacerTest, TestNonexistentGpuAllowSoftPlacement) {
Graph g(OpRegistry::Global());
{ // Scope for temporary variables used to construct g.
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
- ops::SourceOp("TestDevice", b.opts().WithName("in").WithDevice("/gpu:11"));
+ ops::SourceOp("TestDevice",
+ b.opts().WithName("in").WithDevice("/device:fakegpu:11"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
options.config.set_allow_soft_placement(true);
TF_EXPECT_OK(Place(&g, &options));
- EXPECT_DEVICE_CONTAINS(g, "in", "/gpu:0");
+ EXPECT_DEVICE_CONTAINS(g, "in", "/device:fakegpu:0");
}
// Test that ops request to be placed on non-existent devices will fail if
@@ -1016,17 +1034,18 @@ TEST_F(SimplePlacerTest, TestNonexistentGpuNoAllowSoftPlacement) {
Graph g(OpRegistry::Global());
{ // Scope for temporary variables used to construct g.
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
- ops::SourceOp("TestDevice", b.opts().WithName("in").WithDevice("/gpu:11"));
+ ops::SourceOp("TestDevice",
+ b.opts().WithName("in").WithDevice("/device:fakegpu:11"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
Status s = Place(&g, &options);
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
- EXPECT_TRUE(
- StringPiece(s.error_message())
- .contains(
- "Could not satisfy explicit device specification '/gpu:11'"));
+ EXPECT_TRUE(StringPiece(s.error_message())
+ .contains("Could not satisfy explicit "
+ "device specification "
+ "'/device:fakegpu:11'"));
}
// Test that placement fails when a node requests an explicit device that is not
@@ -1035,20 +1054,21 @@ TEST_F(SimplePlacerTest, TestUnsupportedDeviceNoAllowSoftPlacement) {
Graph g(OpRegistry::Global());
{ // Scope for temporary variables used to construct g.
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
- ops::SourceOp("VariableGPU", b.opts().WithName("var").WithDevice("/cpu:0"));
+ ops::SourceOp("VariableGPU",
+ b.opts().WithName("var").WithDevice("/device:fakecpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
Status s = Place(&g, &options);
EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
+ EXPECT_TRUE(StringPiece(s.error_message())
+ .contains("Could not satisfy explicit "
+ "device specification "
+ "'/device:fakecpu:0'"));
EXPECT_TRUE(
StringPiece(s.error_message())
- .contains(
- "Could not satisfy explicit device specification '/cpu:0'"));
- EXPECT_TRUE(
- StringPiece(s.error_message())
- .contains("no supported kernel for CPU devices is available"));
+ .contains("no supported kernel for fakecpu devices is available"));
}
// Test that placement fails when a node requests an explicit device that is not
@@ -1078,7 +1098,8 @@ TEST_F(SimplePlacerTest, TestUnsupportedDeviceAllowSoftPlacement) {
Graph g(OpRegistry::Global());
{ // Scope for temporary variables used to construct g.
GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
- ops::SourceOp("VariableGPU", b.opts().WithName("var").WithDevice("/cpu:0"));
+ ops::SourceOp("VariableGPU",
+ b.opts().WithName("var").WithDevice("/device:fakecpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
@@ -1098,25 +1119,27 @@ TEST_F(SimplePlacerTest, TestDeviceTypeConstraintsAllowSoftPlacement) {
// force_gpu takes var_gpu and requested CPU.
// Verify that both are placed on GPU.
Node* var_gpu = ops::SourceOp("VariableGPU", b.opts().WithName("var_gpu"));
- ops::UnaryOp("TestDeviceEnforce", var_gpu,
- b.opts().WithName("force_gpu").WithDevice("/cpu:0"));
+ ops::UnaryOp(
+ "TestDeviceEnforce", var_gpu,
+ b.opts().WithName("force_gpu").WithDevice("/device:fakecpu:0"));
// var_cpu has ref output and runs on CPU.
// force_cpu takes var_cpu and requested GPU.
// Verify that both are placed on CPU.
Node* var_cpu = ops::SourceOp("VariableCPU", b.opts().WithName("var_cpu"));
- ops::UnaryOp("TestDeviceEnforce", var_cpu,
- b.opts().WithName("force_cpu").WithDevice("/gpu:0"));
+ ops::UnaryOp(
+ "TestDeviceEnforce", var_cpu,
+ b.opts().WithName("force_cpu").WithDevice("/device:fakegpu:0"));
TF_EXPECT_OK(BuildGraph(b, &g));
}
SessionOptions options;
options.config.set_allow_soft_placement(true);
TF_EXPECT_OK(Place(&g, &options));
- EXPECT_DEVICE_TYPE(g, "var_gpu", DEVICE_GPU);
- EXPECT_DEVICE_TYPE(g, "force_gpu", DEVICE_GPU);
+ EXPECT_DEVICE_TYPE(g, "var_gpu", "FakeGPU");
+ EXPECT_DEVICE_TYPE(g, "force_gpu", "FakeGPU");
EXPECT_COLOCATED(g, "var_gpu", "force_gpu");
- EXPECT_DEVICE_TYPE(g, "var_cpu", DEVICE_CPU);
- EXPECT_DEVICE_TYPE(g, "force_cpu", DEVICE_CPU);
+ EXPECT_DEVICE_TYPE(g, "var_cpu", "FakeCPU");
+ EXPECT_DEVICE_TYPE(g, "force_cpu", "FakeCPU");
EXPECT_COLOCATED(g, "var_cpu", "force_cpu");
}
diff --git a/tensorflow/core/common_runtime/sycl/sycl_device_factory.cc b/tensorflow/core/common_runtime/sycl/sycl_device_factory.cc
index cf9e349e01..51eb4973d8 100644
--- a/tensorflow/core/common_runtime/sycl/sycl_device_factory.cc
+++ b/tensorflow/core/common_runtime/sycl/sycl_device_factory.cc
@@ -40,7 +40,7 @@ public:
}
};
-REGISTER_LOCAL_DEVICE_FACTORY("SYCL", SYCLDeviceFactory);
+REGISTER_LOCAL_DEVICE_FACTORY("SYCL", SYCLDeviceFactory, 200);
}
#endif // TENSORFLOW_USE_SYCL
diff --git a/tensorflow/core/common_runtime/threadpool_device_factory.cc b/tensorflow/core/common_runtime/threadpool_device_factory.cc
index 94b9ec31bc..63e40fd82d 100644
--- a/tensorflow/core/common_runtime/threadpool_device_factory.cc
+++ b/tensorflow/core/common_runtime/threadpool_device_factory.cc
@@ -44,6 +44,7 @@ class ThreadPoolDeviceFactory : public DeviceFactory {
return Status::OK();
}
};
-REGISTER_LOCAL_DEVICE_FACTORY("CPU", ThreadPoolDeviceFactory);
+
+REGISTER_LOCAL_DEVICE_FACTORY("CPU", ThreadPoolDeviceFactory, 60);
} // namespace tensorflow