aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/compiler/xla/service/heap_simulator_test.cc
diff options
context:
space:
mode:
authorGravatar Yunxing Dai <yunxing@google.com>2018-06-21 12:32:01 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-06-21 12:35:04 -0700
commitfc4484c359cab66bd5bfdfaab936b1a5128850be (patch)
tree3037681e280ed6729175c2673e4096449d2027e6 /tensorflow/compiler/xla/service/heap_simulator_test.cc
parent1ee5e2ce389a8dbf11db25ff37347715e7dc7efc (diff)
Enable multioutput fusion opearnd buffer reuse.
- Enable multioutput fusion opearnd buffer reuse. - Fix a bug in heap simulator where a buffer can be reused twice. - Add unittest. PiperOrigin-RevId: 201567720
Diffstat (limited to 'tensorflow/compiler/xla/service/heap_simulator_test.cc')
-rw-r--r--tensorflow/compiler/xla/service/heap_simulator_test.cc49
1 files changed, 45 insertions, 4 deletions
diff --git a/tensorflow/compiler/xla/service/heap_simulator_test.cc b/tensorflow/compiler/xla/service/heap_simulator_test.cc
index 93d7a14125..3849b565e3 100644
--- a/tensorflow/compiler/xla/service/heap_simulator_test.cc
+++ b/tensorflow/compiler/xla/service/heap_simulator_test.cc
@@ -198,6 +198,11 @@ class HeapSimulatorTracker {
.ConsumeValueOrDie();
}
+ int64 OffsetAt(const HloInstruction* instruction, const ShapeIndex& index) {
+ const BufferValue* buffer = BufferAt(instruction, index);
+ return result_.chunk_map.at(buffer).offset;
+ }
+
// Ensures the expected sequence of Alloc/Free/Finish calls was performed.
void ExpectCallSequence(const CallSequence& expected) const {
EXPECT_EQ(expected, actual_calls_);
@@ -209,10 +214,9 @@ class HeapSimulatorTracker {
const ShapeIndex& index_a,
const HloInstruction* instruction_b,
const ShapeIndex& index_b) {
- const BufferValue* a = BufferAt(instruction_a, index_a);
- const BufferValue* b = BufferAt(instruction_b, index_b);
- EXPECT_EQ(result_.chunk_map[a].offset, result_.chunk_map[b].offset)
- << *a << ", " << *b;
+ int64 offset_a = OffsetAt(instruction_a, index_a);
+ int64 offset_b = OffsetAt(instruction_b, index_b);
+ EXPECT_EQ(offset_a, offset_b);
}
private:
@@ -311,6 +315,43 @@ TEST_F(HeapSimulatorTest, MultiplyAdd) {
tracker.ExpectSharedBuffers(add, {}, mul, {});
}
+TEST_F(HeapSimulatorTest, BufferReusedOnce) {
+ HeapSimulatorTracker tracker(TestName());
+ auto builder = HloComputation::Builder(TestName());
+
+ HloComputation::Builder fusion_builder("fusion");
+ {
+ HloComputation::Builder& builder = fusion_builder;
+ auto* a_param = builder.AddInstruction(HloInstruction::CreateParameter(
+ /*parameter_number=*/0, f32vec4_, "A"));
+ auto exp = builder.AddInstruction(
+ HloInstruction::CreateUnary(f32vec4_, HloOpcode::kExp, a_param));
+ auto neg = builder.AddInstruction(
+ HloInstruction::CreateUnary(f32vec4_, HloOpcode::kNegate, a_param));
+
+ builder.AddInstruction(HloInstruction::CreateTuple({exp, neg}));
+ }
+ auto fusion_computation =
+ tracker.module()->AddEmbeddedComputation(fusion_builder.Build());
+ auto a_param = builder.AddInstruction(
+ HloInstruction::CreateParameter(0, f32vec4_, "paramA"));
+ auto neg = builder.AddInstruction(
+ HloInstruction::CreateUnary(f32vec4_, HloOpcode::kNegate, a_param));
+ auto fusion = builder.AddInstruction(HloInstruction::CreateFusion(
+ ShapeUtil::MakeTupleShape({f32vec4_, f32vec4_}),
+ HloInstruction::FusionKind::kLoop, {neg}, fusion_computation));
+ tracker.module()->AddEntryComputation(builder.Build());
+
+ tracker.RunWholeModule({a_param, neg, fusion});
+
+ auto neg_buffer = tracker.OffsetAt(neg, {});
+ int64 output_buffer_0 = tracker.OffsetAt(fusion, {0});
+ int64 output_buffer_1 = tracker.OffsetAt(fusion, {1});
+ // Only one buffer should be shared.
+ EXPECT_TRUE((neg_buffer == output_buffer_0) ^
+ (neg_buffer == output_buffer_1));
+}
+
TEST_F(HeapSimulatorTest, MultiplyDot) {
auto builder = HloComputation::Builder(TestName());
auto paramA = builder.AddInstruction(