aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/compiler/xla/service/layout_assignment_test.cc
diff options
context:
space:
mode:
authorGravatar Bixia Zheng <bixia@google.com>2018-02-26 15:42:52 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-02-26 15:50:09 -0800
commit175730d3791618a496a5c66d7d6fef9c7768cf34 (patch)
tree82a51db8533fad6af8b9d8283ea571dfa61b7f51 /tensorflow/compiler/xla/service/layout_assignment_test.cc
parentaa2f0b68fb7052ea46547bf15fb8a46f6447f182 (diff)
[XLA] Fix #17090 a problem in IrArray::Index::SourceIndexOfTranspose.
Agebraic simplification transforms bitcast-equivalent transpose/reshape instructions to bitcast instructions before IR emission. As such, we should skip the checking on whether a transpose/reshape instruction is bitcast-equivalent or not during IR emission. Remove the call from IrArray::Index::SourceIndexOfTranspose to ShapeUtil::TransposeIsBitcast. Also remove the call from IrArray::Index::SourceIndexOfReshape to ShapeUtil::ReshapeIsBitcast. Remove the calls to ShapeUtil::TransposeIsBitcast and ShapeUtil::ReshapeIsBitcast from NotWorthHoistingIndividually because layout assignment hasn't been done there yet. Instead, returns true when the input is a transpose or reshape instruction, to prevent it from being hoisted out of loops. Add a check to ShapeUtil::TransposeIsBitcast and ShapeUtil::ReshapeIsBitcast to make sure that both input shape and output shape have layouts. Add two test cases. PiperOrigin-RevId: 187093399
Diffstat (limited to 'tensorflow/compiler/xla/service/layout_assignment_test.cc')
-rw-r--r--tensorflow/compiler/xla/service/layout_assignment_test.cc79
1 files changed, 79 insertions, 0 deletions
diff --git a/tensorflow/compiler/xla/service/layout_assignment_test.cc b/tensorflow/compiler/xla/service/layout_assignment_test.cc
index 88e5caaf47..62feb7c1e9 100644
--- a/tensorflow/compiler/xla/service/layout_assignment_test.cc
+++ b/tensorflow/compiler/xla/service/layout_assignment_test.cc
@@ -590,6 +590,85 @@ TEST_F(LayoutAssignmentTest, TransposeToBitcastToUser) {
transpose->shape(), {2, 3, 0, 1}));
}
+// TransposeIsBitcast shouldn't be called without layout information.
+TEST_F(LayoutAssignmentTest, TransposeIsBitcastFail) {
+ auto builder = HloComputation::Builder(TestName());
+ Shape input_shape = ShapeUtil::MakeShape(F32, {2, 2, 2});
+ Shape input_shape_with_layout(input_shape);
+ *input_shape_with_layout.mutable_layout() = LayoutUtil::MakeLayout({2, 1, 0});
+ auto param = builder.AddInstruction(
+ HloInstruction::CreateParameter(0, input_shape_with_layout, "param"));
+ auto hlo = builder.AddInstruction(
+ HloInstruction::CreateTranspose(input_shape, param, {0, 2, 1}));
+ // Clear the default layout assigned to the instruction.
+ LayoutUtil::ClearLayout(hlo->mutable_shape());
+ EXPECT_DEATH(ShapeUtil::TransposeIsBitcast(hlo->operand(0)->shape(),
+ hlo->shape(), hlo->dimensions()),
+ "LayoutUtil::HasLayout");
+}
+
+// ReshapeIsBitcast shouldn't be called without layout information.
+TEST_F(LayoutAssignmentTest, ReshapeIsBitcastFail) {
+ auto builder = HloComputation::Builder(TestName());
+ Shape input_shape = ShapeUtil::MakeShape(F32, {2, 2, 2});
+ Shape input_shape_with_layout(input_shape);
+ *input_shape_with_layout.mutable_layout() = LayoutUtil::MakeLayout({2, 1, 0});
+ auto param = builder.AddInstruction(
+ HloInstruction::CreateParameter(0, input_shape_with_layout, "param"));
+ auto hlo =
+ builder.AddInstruction(HloInstruction::CreateReshape(input_shape, param));
+ // Clear the default layout assigned to the instruction.
+ LayoutUtil::ClearLayout(hlo->mutable_shape());
+ EXPECT_DEATH(
+ ShapeUtil::ReshapeIsBitcast(hlo->operand(0)->shape(), hlo->shape()),
+ "LayoutUtil::HasLayout");
+}
+
+// Check that the computation below doesn't crash the compiler.
+//
+// Within a fusion computation, only the parameters and result get assigned a
+// layout. When we run the algebraic simplifier on this computation post layout
+// assignment, it should not call TransposeIsBitcast on the `transpose` node
+// inside the fusion computation as TransposeIsBitcast checks both input_shape
+// and output_shape have layouts.
+TEST_F(LayoutAssignmentTest, TransposeWithinFusionDoesNotCrash) {
+ const char* module_str = R"(
+ HloModule test_module
+
+ fused_computation {
+ param_1 = f32[2,2,2]{2,1,0} parameter(1)
+ transpose = f32[2,2,2]{2,1,0} transpose(param_1), dimensions={0,2,1}
+ reduce_1 = f32[] parameter(0)
+ broadcast_1 = f32[2,2,2]{2,1,0} broadcast(reduce_1), dimensions={}
+ ROOT divide_1 = f32[2,2,2]{2,1,0} divide(transpose, broadcast_1)
+ }
+
+ ENTRY entry_computation {
+ fusion.1 = f32[2,2,2]{2,1,0} parameter(1)
+ reduce.1 = f32[] parameter(0)
+ fusion.2 = f32[2,2,2]{2,1,0} fusion(reduce.1, fusion.1), kind=kLoop, calls=fused_computation
+ ROOT tuple.1 = (f32[2,2,2]{2,1,0}) tuple(fusion.2)
+ }
+ )";
+
+ auto module = tools::Parse(module_str).ValueOrDie();
+
+ module =
+ backend()
+ .compiler()
+ ->RunHloPasses(std::move(module), backend().default_stream_executor(),
+ /*device_allocator=*/nullptr)
+ .ConsumeValueOrDie();
+
+ EXPECT_EQ(
+ ::tensorflow::Status::OK(),
+ backend()
+ .compiler()
+ ->RunBackend(std::move(module), backend().default_stream_executor(),
+ /*device_allocator=*/nullptr)
+ .status());
+}
+
// A GTE inside of a fusion node inherits the layout of its operand (which
// should, if we keep following operands, eventually be a parameter).
TEST_F(LayoutAssignmentTest, GTEInheritsLayoutFromOperand) {