Improve the accuracy of the upper-bound of the sum of the size of an
authorA. Unique TensorFlower <gardener@tensorflow.org>
Tue, 6 Mar 2018 01:07:39 +0000 (17:07 -0800)
committerTensorFlower Gardener <gardener@tensorflow.org>
Tue, 6 Mar 2018 01:10:39 +0000 (17:10 -0800)
HLO and all its dependencies. The previous implementation computed the
size of an HLO as the sum of dependencies weighted by the number of
paths to the each dependency. In the previous implementation the
"size" of some HLO overflowed an int64 for dependence graphs with a
large number of distinct paths. The new implementation computes the
min of the previous overestimate and the sum of all HLO's
before-and-including the current HLO in a topological sort of the
graph.

Both the current and the previous implementations are linear
time. Since the sum of the size of all HLOs will never overflow, the
"total size" of each HLO will never overflow. The new upper-bound is
the min of the previous upper bound and a new heuristic, so it is
always at least as tight a bound as the old implementation.

RELNOTES: n/a
PiperOrigin-RevId: 187948221

tensorflow/compiler/xla/service/hlo_scheduling.cc

index f6e3340..da448ed 100644 (file)
@@ -348,6 +348,7 @@ StatusOr<std::vector<const HloInstruction*>> RunDFSMemoryScheduler(
   // simply users-1 for each instruction.  By subtracting 1, we're saying that
   // instructions with no users or a single user don't count; instructions with
   // lots of fan-out will be visited earlier.
+  int64 cumulative_total_size = 0;
   tensorflow::gtl::FlatMap<const HloInstruction*, int64> extra_users;
   tensorflow::gtl::FlatMap<const HloInstruction*, int64> total_sizes;
   for (const HloInstruction* hlo : computation.MakeInstructionPostOrder()) {
@@ -357,14 +358,17 @@ StatusOr<std::vector<const HloInstruction*>> RunDFSMemoryScheduler(
       continue;
     }
     extra_users[hlo] = hlo->users().empty() ? 0 : hlo->users().size() - 1;
-    total_sizes[hlo] = SumLogicalBufferSizes(
+    int64 logical_buffer_size = SumLogicalBufferSizes(
         points_to_analysis.GetBuffersDefinedByInstruction(hlo), size_function);
+    total_sizes[hlo] = logical_buffer_size;
+    cumulative_total_size += logical_buffer_size;
     tensorflow::gtl::FlatSet<const HloInstruction*> unique_operands(
         hlo->operands().begin(), hlo->operands().end());
     for (const HloInstruction* operand : unique_operands) {
       extra_users[hlo] += extra_users[operand];
       total_sizes[hlo] += total_sizes[operand];
     }
+    total_sizes[hlo] = std::min(total_sizes[hlo], cumulative_total_size);
   }
   CHECK_EQ(extra_users.size(), computation.instruction_count());
   CHECK_EQ(total_sizes.size(), computation.instruction_count());