diff options
author | 2018-07-03 16:43:12 -0700 | |
---|---|---|
committer | 2018-07-03 16:50:53 -0700 | |
commit | fc61f063cf57c72e11e67d29562c4ed6b87d5145 (patch) | |
tree | b18deddc746d6c00c516e4523158045ec7da2930 /tensorflow/core/common_runtime/placer_test.cc | |
parent | fb58f1d287e7210bebc22e0946b969c2ec0303e7 (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.cc | 40 |
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). |