tf_1.8_xla_doc
hlo_ordering.h
Go to the documentation of this file.
1 
3 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 ==============================================================================*/
17 
18 #ifndef TENSORFLOW_COMPILER_XLA_SERVICE_HLO_ORDERING_H_
19 #define TENSORFLOW_COMPILER_XLA_SERVICE_HLO_ORDERING_H_
20 
21 #include <memory>
22 #include <string>
23 #include <utility>
24 
25 #include "tensorflow/compiler/xla/service/call_graph.h"
26 #include "tensorflow/compiler/xla/service/hlo.pb.h"
27 #include "tensorflow/compiler/xla/service/hlo_dataflow_analysis.h"
30 #include "tensorflow/compiler/xla/service/hlo_value.h"
31 #include "tensorflow/compiler/xla/types.h"
32 #include "tensorflow/core/lib/gtl/flatmap.h"
33 
34 namespace xla {
35 
41 class HloOrdering {
42  public:
43  HloOrdering(const HloModule* module)
44  : module_(module), call_graph_(CallGraph::Build(module)) {}
45  virtual ~HloOrdering() = default;
46 
47  // Returns true if instruction 'a' executes before instruction 'b'. This is
48  // not reflexive, that is, an instruction does not execute before itself.
49  bool ExecutesBefore(const HloInstruction* a, const HloInstruction* b) const;
50 
51  // Returns whether the value 'a' is defined before the value 'b' under the
52  // given ordering.
53  bool IsDefinedBefore(const HloValue& a, const HloValue& b) const;
54 
55  // Returns whether the given use is before the given value definition under
56  // the given ordering.
57  bool UseIsBeforeValueDefinition(const HloUse& use, const HloValue& value,
58  const HloDataflowAnalysis& dataflow) const;
59  // Returns whether the given values interfere. Two values interfere if they
60  // may both be simultaneously live.
61  bool MayInterfere(const HloValue& a, const HloValue& b,
62  const HloDataflowAnalysis& dataflow) const;
63 
64  // Returns true if the live range of the given value 'a' is strictly before
65  // the live range of value 'b' using the given HLO ordering.
66  bool LiveRangeStrictlyBefore(const HloValue& a, const HloValue& b,
67  const HloDataflowAnalysis& dataflow) const;
68 
69  // Returns the sequential instruction order for the given computation, or
70  // nullptr if the computation does not have a sequential ordering.
71  virtual const std::vector<const HloInstruction*>* SequentialOrder(
72  const HloComputation& computation) const = 0;
73 
74  // Return the call graph of the module used to compute ordering.
75  const CallGraph& call_graph() const { return *call_graph_; }
76 
77  virtual string ToString() const = 0;
78 
79  // Returns the serialized representation of this ordering.
80  // Only sequential computation orders are represented.
81  HloOrderingProto ToProto() const;
82 
83  protected:
84  // Returns true if instruction 'a' executes before instruction 'b'.
85  // Precondition: 'a' and 'b' are in the same computation.
86  //
87  // Derived classes should implement this method for determining order of
88  // instructions in the same computation. ExecutesBefore() analyzes the
89  // callgraph and uses this method to determine ordering of instructions in
90  // different computations.
91  virtual bool ExecutesBeforeInSameComputation(
92  const HloInstruction* a, const HloInstruction* b) const = 0;
93 
94  const HloModule* module_;
95 
96  std::unique_ptr<CallGraph> call_graph_;
97 };
98 
99 /*
100  * Google Docs:
101  * > Base class for partial orderings implemented by a map of predecessors for
102  * > each instruction. Subclasses should fill in predecessors_.
103  */
104 class PredecessorHloOrdering : public HloOrdering {
105  public:
106  ~PredecessorHloOrdering() override = default;
107 
108  // Returns nullptr indicating the computation does not have a sequential
109  // ordering.
110  const std::vector<const HloInstruction*>* SequentialOrder(
111  const HloComputation& computation) const override {
112  return nullptr;
113  }
114 
115  HloReachabilityMap& reachability_map(const HloComputation* computation) {
116  return *predecessors_.at(computation);
117  }
118  const HloReachabilityMap& reachability_map(
119  const HloComputation* computation) const {
120  return *predecessors_.at(computation);
121  }
122 
123  protected:
124  explicit PredecessorHloOrdering(const HloModule* module);
125  string ToStringHelper(const string& name) const;
126 
127  bool ExecutesBeforeInSameComputation(const HloInstruction* a,
128  const HloInstruction* b) const override;
129 
130  // For each computation in the module, this is the set of the instruction's
131  // predecessors. An instruction is an element of its own predecessor set.
132  //
133  // Subclasses should fill this in to define the desired ordering.
134  tensorflow::gtl::FlatMap<const HloComputation*,
135  std::unique_ptr<HloReachabilityMap>>
136  predecessors_;
137 };
138 
139 /*
140  * The following are all from Google Docs
141  * An HLO ordering based on data dependencies in the HLO graph. In this partial
142  * order, instruction A executes before instruction B only if there is a path
143  * from A to B in the HLO graph. For example, given the following graph:
144  * ```
145  * param
146  * / \
147  * negate exp
148  * \ /
149  * add
150  * ```
151  *
152  * DependencyHloOrdering gives the following executes-before relations:
153  * param executes before negate, exp, and add
154  * negate executes before add
155  * exp executes before add
156  * add executes before nothing
157  * negate and exp are not ordered because the dependencies allow either to
158  * execute before the other (or in parallel). DependencyHloOrdering ordering
159  * allows maximum parallelism and enables any execution order which satisfies
160  * data dependencies. This requires pessimistic assumptions about buffer live
161  * ranges and can result in more memory used than more constrained orderings.
162  */
163 class DependencyHloOrdering : public PredecessorHloOrdering {
164  public:
165  explicit DependencyHloOrdering(const HloModule* module);
166  ~DependencyHloOrdering() override = default;
167 
168  string ToString() const override;
169 };
170 
204  public:
206  using HloModuleSequence =
207  tensorflow::gtl::FlatMap<const HloComputation*,
208  std::vector<const HloInstruction*>>;
209 
210  SequentialHloOrdering(const HloModule* module,
211  const HloModuleSequence& module_sequence);
212  ~SequentialHloOrdering() override = default;
213 
214  // Returns the sequential instruction order for the given computation.
215  const std::vector<const HloInstruction*>* SequentialOrder(
216  const HloComputation& computation) const override;
217 
218  string ToString() const override;
219 
220  protected:
221  bool ExecutesBeforeInSameComputation(const HloInstruction* a,
222  const HloInstruction* b) const override;
223 
224  const HloModuleSequence module_sequence_;
225 
226  // The position of every instruction in the HLO module in its respective
227  // computation sequence (a value of zero indicates the instruction is first in
228  // the sequence, etc). Instructions from all computations are contained in
229  // this map so more than one instruction may have the same position
230  // value. This is not a problem because ExecutesBefore also verifies
231  // instructions are in the same computation.
232  tensorflow::gtl::FlatMap<const HloInstruction*, int> order_position_;
233 };
234 
235 std::ostream& operator<<(
236  std::ostream& out,
237  const SequentialHloOrdering::HloModuleSequence& module_sequence);
238 
239 } // namespace xla
240 
241 #endif // TENSORFLOW_COMPILER_XLA_SERVICE_HLO_ORDERING_H_
Definition: hlo_ordering.h:203
Definition: hlo_computation.h:60
Definition: hlo_instruction.h:165
namespace for xla
Definition: client_library.cc:26
tensorflow::gtl::FlatMap< const HloComputation *, std::vector< const HloInstruction * > > HloModuleSequence
Definition: hlo_ordering.h:208
Definition: hlo_module.h:52
Definition: hlo_ordering.h:41