aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/common_runtime/placer_test.cc
diff options
context:
space:
mode:
authorGravatar Akshay Agrawal <akshayka@google.com>2018-07-03 16:43:12 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-07-03 16:50:53 -0700
commitfc61f063cf57c72e11e67d29562c4ed6b87d5145 (patch)
treeb18deddc746d6c00c516e4523158045ec7da2930 /tensorflow/core/common_runtime/placer_test.cc
parentfb58f1d287e7210bebc22e0946b969c2ec0303e7 (diff)
Make sure that that nodes connected by reference/resource edges are colocated.
The Placer is supposed to guarantee that nodes connected by reference/resource edges are colocated. Prior to this change, this constraint was not enforced for ops that had among their inputs at least two resource/reference tensors with different requested devices. Note that we might in the near future want to relax this constraint in order to allow, e.g., function call ops to be agnostic to where their DT_RESOURCE inputs live. PiperOrigin-RevId: 203203579
Diffstat (limited to 'tensorflow/core/common_runtime/placer_test.cc')
-rw-r--r--tensorflow/core/common_runtime/placer_test.cc40
1 files changed, 40 insertions, 0 deletions
diff --git a/tensorflow/core/common_runtime/placer_test.cc b/tensorflow/core/common_runtime/placer_test.cc
index 5ad251c892..07a7724f16 100644
--- a/tensorflow/core/common_runtime/placer_test.cc
+++ b/tensorflow/core/common_runtime/placer_test.cc
@@ -575,6 +575,10 @@ REGISTER_KERNEL_BUILDER(Name("HandleAssignCPU").Device("FakeCPU"), DummyOp);
REGISTER_OP("HandleAssignGPU").Input("i: resource").Input("v: float");
REGISTER_KERNEL_BUILDER(Name("HandleAssignGPU").Device("FakeGPU"), DummyOp);
+REGISTER_OP("TestTwoHandlesIn").Input("i: resource").Input("j: resource");
+REGISTER_KERNEL_BUILDER(Name("TestTwoHandlesIn").Device("FakeCPU"), DummyOp);
+REGISTER_KERNEL_BUILDER(Name("TestTwoHandlesIn").Device("FakeGPU"), DummyOp);
+
// Tests all combinations of resource handles and ops using them.
TEST_F(PlacerTest, TestResourceHandle) {
auto handle_test = [this](const string& var_op_name,
@@ -609,6 +613,42 @@ TEST_F(PlacerTest, TestResourceHandle) {
handle_test("HandleVariableCPU", "HandleAssignGPU", "FakeCPU").ok());
}
+TEST_F(PlacerTest, TestResourceHandlesOnDifferentDevicesFails) {
+ auto handle_test = [this](bool allow_soft_placement) {
+ Graph g(OpRegistry::Global());
+ { // Scope for temporary variables used to construct g.
+ GraphDefBuilder b(GraphDefBuilder::kFailImmediately);
+ Node* var_cpu =
+ ops::SourceOp("TestHandleVariable", b.opts().WithName("var_cpu"));
+ Node* var_gpu =
+ ops::SourceOp("TestHandleVariable", b.opts().WithName("var_gpu"));
+ ops::BinaryOp("TestTwoHandlesIn", var_cpu, var_gpu,
+ b.opts().WithName("two_handles_in"));
+ TF_EXPECT_OK(BuildGraph(b, &g));
+
+ GetNodeByName(g, "var_cpu")
+ ->set_assigned_device_name(
+ "/job:a/replica:0/task:0/device:fakecpu:0");
+ GetNodeByName(g, "var_gpu")
+ ->set_assigned_device_name(
+ "/job:a/replica:0/task:0/device:fakegpu:0");
+ }
+
+ SessionOptions options;
+ options.config.set_allow_soft_placement(allow_soft_placement);
+ options.config.set_log_device_placement(true);
+ Status s = Place(&g, &options);
+ EXPECT_EQ(error::INVALID_ARGUMENT, s.code());
+ EXPECT_TRUE(str_util::StrContains(
+ s.error_message(),
+ "Could not colocate node with its resource and reference inputs"));
+ return Status::OK();
+ };
+
+ TF_EXPECT_OK(handle_test(false));
+ TF_EXPECT_OK(handle_test(true));
+}
+
// Test that an assignment of an operator to the wrong device
// is ignored when it could never be satisfied (due to reference
// edges, for example).